1 /* 2 * Copyright 2003-2010, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler <axeld@pinc-software.de> 7 * Ingo Weinhold <bonefish@cs.tu-berlin.de> 8 * François Revol <revol@free.fr> 9 * 10 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 11 * Distributed under the terms of the NewOS License. 12 */ 13 14 15 #include <thread.h> 16 #include <arch_thread.h> 17 18 #include <arch_cpu.h> 19 #include <arch/thread.h> 20 #include <boot/stage2.h> 21 #include <kernel.h> 22 #include <thread.h> 23 #include <tls.h> 24 #include <vm/vm_types.h> 25 #include <vm/VMAddressSpace.h> 26 #include <arch_vm.h> 27 #include <arch/vm_translation_map.h> 28 29 #include <string.h> 30 31 //#define TRACE_ARCH_THREAD 32 #ifdef TRACE_ARCH_THREAD 33 # define TRACE(x) dprintf x 34 #else 35 # define TRACE(x) ; 36 #endif 37 38 // Valid initial arch_thread state. We just memcpy() it when initializing 39 // a new thread structure. 40 static struct arch_thread sInitialState; 41 42 Thread *gCurrentThread; 43 44 45 void 46 arm_push_iframe(struct iframe_stack *stack, struct iframe *frame) 47 { 48 ASSERT(stack->index < IFRAME_TRACE_DEPTH); 49 stack->frames[stack->index++] = frame; 50 } 51 52 53 void 54 arm_pop_iframe(struct iframe_stack *stack) 55 { 56 ASSERT(stack->index > 0); 57 stack->index--; 58 } 59 60 61 62 status_t 63 arch_thread_init(struct kernel_args *args) 64 { 65 // Initialize the static initial arch_thread state (sInitialState). 66 // Currently nothing to do, i.e. zero initialized is just fine. 67 68 return B_OK; 69 } 70 71 72 status_t 73 arch_team_init_team_struct(Team *team, bool kernel) 74 { 75 // Nothing to do. The structure is empty. 76 return B_OK; 77 } 78 79 80 status_t 81 arch_thread_init_thread_struct(Thread *thread) 82 { 83 // set up an initial state (stack & fpu) 84 memcpy(&thread->arch_info, &sInitialState, sizeof(struct arch_thread)); 85 86 return B_OK; 87 } 88 89 90 void 91 arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop, 92 void (*function)(void*), const void* data) 93 { 94 addr_t* stackTop = (addr_t*)_stackTop; 95 96 TRACE(("arch_thread_init_kthread_stack(%s): stack top %p, function %p, data: " 97 "%p\n", thread->name, stackTop, function, data)); 98 99 // push the function address -- that's the return address used after the 100 // context switch (lr/r14 register) 101 *--stackTop = (addr_t)function; 102 103 // simulate storing registers r1-r12 104 for (int i = 1; i <= 12; i++) 105 *--stackTop = 0; 106 107 // push the function argument as r0 108 *--stackTop = (addr_t)data; 109 110 // save the stack position 111 thread->arch_info.sp = stackTop; 112 } 113 114 115 status_t 116 arch_thread_init_tls(Thread *thread) 117 { 118 uint32 tls[TLS_USER_THREAD_SLOT + 1]; 119 120 thread->user_local_storage = thread->user_stack_base 121 + thread->user_stack_size; 122 123 // initialize default TLS fields 124 memset(tls, 0, sizeof(tls)); 125 tls[TLS_BASE_ADDRESS_SLOT] = thread->user_local_storage; 126 tls[TLS_THREAD_ID_SLOT] = thread->id; 127 tls[TLS_USER_THREAD_SLOT] = (addr_t)thread->user_thread; 128 129 return user_memcpy((void *)thread->user_local_storage, tls, sizeof(tls)); 130 } 131 132 extern "C" void arm_context_switch(void *from, void *to); 133 134 void 135 arch_thread_context_switch(Thread *from, Thread *to) 136 { 137 TRACE(("arch_thread_context_switch: %p(%s/%p) -> %p(%s/%p)\n", 138 from, from->name, from->arch_info.sp, to, to->name, to->arch_info.sp)); 139 arm_context_switch(&from->arch_info, &to->arch_info); 140 TRACE(("arch_thread_context_switch %p %p\n", to, from)); 141 } 142 143 144 void 145 arch_thread_dump_info(void *info) 146 { 147 struct arch_thread *at = (struct arch_thread *)info; 148 149 dprintf("\tsp: %p\n", at->sp); 150 } 151 152 153 status_t 154 arch_thread_enter_userspace(Thread *thread, addr_t entry, 155 void *arg1, void *arg2) 156 { 157 panic("arch_thread_enter_uspace(): not yet implemented\n"); 158 return B_ERROR; 159 } 160 161 162 bool 163 arch_on_signal_stack(Thread *thread) 164 { 165 return false; 166 } 167 168 169 status_t 170 arch_setup_signal_frame(Thread *thread, struct sigaction *sa, 171 struct signal_frame_data *signalFrameData) 172 { 173 return B_ERROR; 174 } 175 176 177 int64 178 arch_restore_signal_frame(struct signal_frame_data* signalFrameData) 179 { 180 return 0; 181 } 182 183 184 void 185 arch_check_syscall_restart(Thread *thread) 186 { 187 } 188 189 190 /** Saves everything needed to restore the frame in the child fork in the 191 * arch_fork_arg structure to be passed to arch_restore_fork_frame(). 192 * Also makes sure to return the right value. 193 */ 194 void 195 arch_store_fork_frame(struct arch_fork_arg *arg) 196 { 197 } 198 199 200 /** Restores the frame from a forked team as specified by the provided 201 * arch_fork_arg structure. 202 * Needs to be called from within the child team, ie. instead of 203 * arch_thread_enter_uspace() as thread "starter". 204 * This function does not return to the caller, but will enter userland 205 * in the child team at the same position where the parent team left of. 206 */ 207 void 208 arch_restore_fork_frame(struct arch_fork_arg *arg) 209 { 210 } 211