1 /* Copyright 2019, Adrien Destugues, pulkomandy@pulkomandy.tk 2 * Distributed under the terms of the MIT License. 3 */ 4 5 6 #include <string.h> 7 8 #include <arch_cpu.h> 9 #include <arch/thread.h> 10 #include <boot/stage2.h> 11 #include <kernel.h> 12 #include <thread.h> 13 #include <vm/vm_types.h> 14 15 16 status_t 17 arch_thread_init(struct kernel_args *args) 18 { 19 // Initialize the static initial arch_thread state (sInitialState). 20 // Currently nothing to do, i.e. zero initialized is just fine. 21 22 return B_OK; 23 } 24 25 26 status_t 27 arch_team_init_team_struct(Team *team, bool kernel) 28 { 29 // Nothing to do. The structure is empty. 30 return B_OK; 31 } 32 33 34 status_t 35 arch_thread_init_thread_struct(Thread *thread) 36 { 37 // set up an initial state (stack & fpu) 38 //memcpy(&thread->arch_info, &sInitialState, sizeof(struct arch_thread)); 39 40 return B_OK; 41 } 42 43 44 void 45 arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop, 46 void (*function)(void*), const void* data) 47 { 48 #if 0 49 addr_t *kstack = (addr_t *)t->kernel_stack_base; 50 addr_t *kstackTop = (addr_t *)t->kernel_stack_base; 51 52 // clear the kernel stack 53 #ifdef DEBUG_KERNEL_STACKS 54 # ifdef STACK_GROWS_DOWNWARDS 55 memset((void *)((addr_t)kstack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE), 0, 56 KERNEL_STACK_SIZE); 57 # else 58 memset(kstack, 0, KERNEL_STACK_SIZE); 59 # endif 60 #else 61 memset(kstack, 0, KERNEL_STACK_SIZE); 62 #endif 63 64 // space for frame pointer and return address, and stack frames must be 65 // 16 byte aligned 66 kstackTop -= 2; 67 kstackTop = (addr_t*)((addr_t)kstackTop & ~0xf); 68 69 // LR, CR, r2, r13-r31, f13-f31, as pushed by m68k_context_switch() 70 kstackTop -= 22 + 2 * 19; 71 72 // let LR point to m68k_kernel_thread_root() 73 kstackTop[0] = (addr_t)&m68k_kernel_thread_root; 74 75 // the arguments of m68k_kernel_thread_root() are the functions to call, 76 // provided in registers r13-r15 77 kstackTop[3] = (addr_t)entry_func; 78 kstackTop[4] = (addr_t)start_func; 79 kstackTop[5] = (addr_t)exit_func; 80 81 // save this stack position 82 t->arch_info.sp = (void *)kstackTop; 83 84 return B_OK; 85 #else 86 panic("arch_thread_init_kthread_stack(): Implement me!"); 87 #endif 88 } 89 90 91 status_t 92 arch_thread_init_tls(Thread *thread) 93 { 94 // TODO: Implement! 95 return B_OK; 96 } 97 98 99 void 100 arch_thread_context_switch(Thread *from, Thread *to) 101 { 102 } 103 104 105 void 106 arch_thread_dump_info(void *info) 107 { 108 } 109 110 111 status_t 112 arch_thread_enter_userspace(Thread *thread, addr_t entry, void *arg1, void *arg2) 113 { 114 panic("arch_thread_enter_uspace(): not yet implemented\n"); 115 return B_ERROR; 116 } 117 118 119 bool 120 arch_on_signal_stack(Thread *thread) 121 { 122 return false; 123 } 124 125 126 status_t 127 arch_setup_signal_frame(Thread *thread, struct sigaction *sa, 128 struct signal_frame_data *signalFrameData) 129 { 130 return B_ERROR; 131 } 132 133 134 int64 135 arch_restore_signal_frame(struct signal_frame_data* signalFrameData) 136 { 137 return 0; 138 } 139 140 141 /** Saves everything needed to restore the frame in the child fork in the 142 * arch_fork_arg structure to be passed to arch_restore_fork_frame(). 143 * Also makes sure to return the right value. 144 */ 145 146 void 147 arch_store_fork_frame(struct arch_fork_arg *arg) 148 { 149 } 150 151 152 /** Restores the frame from a forked team as specified by the provided 153 * arch_fork_arg structure. 154 * Needs to be called from within the child team, ie. instead of 155 * arch_thread_enter_uspace() as thread "starter". 156 * This function does not return to the caller, but will enter userland 157 * in the child team at the same position where the parent team left of. 158 */ 159 160 void 161 arch_restore_fork_frame(struct arch_fork_arg *arg) 162 { 163 } 164 165