1 /* 2 * Copyright 2019-2022 Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #include <thread.h> 6 #include <arch_thread.h> 7 8 #include <arch_cpu.h> 9 #include <arch/thread.h> 10 #include <boot/stage2.h> 11 #include <commpage_defs.h> 12 #include <kernel.h> 13 #include <thread.h> 14 #include <tls.h> 15 #include <vm/vm_types.h> 16 #include <vm/VMAddressSpace.h> 17 #include <arch_vm.h> 18 #include <arch/vm_translation_map.h> 19 20 #include <string.h> 21 22 //#define TRACE_ARCH_THREAD 23 #ifdef TRACE_ARCH_THREAD 24 # define TRACE(x) dprintf x 25 #else 26 # define TRACE(x) ; 27 #endif 28 29 30 void 31 arm64_push_iframe(struct iframe_stack *stack, struct iframe *frame) 32 { 33 ASSERT(stack->index < IFRAME_TRACE_DEPTH); 34 stack->frames[stack->index++] = frame; 35 } 36 37 38 void 39 arm64_pop_iframe(struct iframe_stack *stack) 40 { 41 ASSERT(stack->index > 0); 42 stack->index--; 43 } 44 45 46 status_t 47 arch_thread_init(struct kernel_args *args) 48 { 49 return B_OK; 50 } 51 52 53 status_t 54 arch_team_init_team_struct(Team *team, bool kernel) 55 { 56 return B_OK; 57 } 58 59 60 status_t 61 arch_thread_init_thread_struct(Thread *thread) 62 { 63 return B_OK; 64 } 65 66 67 void 68 arch_thread_init_kthread_stack(Thread* thread, void* _stack, void* _stackTop, 69 void (*function)(void*), const void* data) 70 { 71 memset(&thread->arch_info, 0, sizeof(arch_thread)); 72 thread->arch_info.regs[10] = (uint64_t)data; 73 thread->arch_info.regs[11] = (uint64_t)function; 74 thread->arch_info.regs[12] = (uint64_t)_stackTop; 75 } 76 77 78 status_t 79 arch_thread_init_tls(Thread *thread) 80 { 81 uint32 tls[TLS_FIRST_FREE_SLOT]; 82 83 thread->user_local_storage = thread->user_stack_base 84 + thread->user_stack_size; 85 86 // initialize default TLS fields 87 memset(tls, 0, sizeof(tls)); 88 tls[TLS_BASE_ADDRESS_SLOT] = thread->user_local_storage; 89 tls[TLS_THREAD_ID_SLOT] = thread->id; 90 tls[TLS_USER_THREAD_SLOT] = (addr_t)thread->user_thread; 91 92 return user_memcpy((void *)thread->user_local_storage, tls, sizeof(tls)); 93 } 94 95 96 static void 97 arm64_set_tls_context(Thread *thread) 98 { 99 WRITE_SPECIALREG(tpidrro_el0, thread->user_local_storage); 100 } 101 102 extern "C" void _arch_context_swap(arch_thread *from, arch_thread *to); 103 104 105 void 106 arch_thread_context_switch(Thread *from, Thread *to) 107 { 108 arm64_set_tls_context(to); 109 _arch_context_swap(&from->arch_info, &to->arch_info); 110 } 111 112 113 void 114 arch_thread_dump_info(void *info) 115 { 116 } 117 118 119 extern "C" void _eret_with_iframe(iframe *frame); 120 121 122 status_t 123 arch_thread_enter_userspace(Thread *thread, addr_t entry, 124 void *arg1, void *arg2) 125 { 126 arm64_set_tls_context(thread); 127 128 addr_t threadExitAddr; 129 { 130 addr_t commpageAdr = (addr_t)thread->team->commpage_address; 131 status_t ret = user_memcpy(&threadExitAddr, 132 &((addr_t*)commpageAdr)[COMMPAGE_ENTRY_ARM64_THREAD_EXIT], 133 sizeof(threadExitAddr)); 134 ASSERT(ret == B_OK); 135 threadExitAddr += commpageAdr; 136 } 137 138 iframe frame; 139 memset(&frame, 0, sizeof(frame)); 140 141 frame.spsr = 0; 142 frame.elr = entry; 143 frame.x[0] = (uint64_t)arg1; 144 frame.x[1] = (uint64_t)arg2; 145 frame.lr = threadExitAddr; 146 frame.sp = thread->user_stack_base + thread->user_stack_size; 147 148 _eret_with_iframe(&frame); 149 return B_ERROR; 150 } 151 152 153 bool 154 arch_on_signal_stack(Thread *thread) 155 { 156 return false; 157 } 158 159 160 status_t 161 arch_setup_signal_frame(Thread *thread, struct sigaction *sa, 162 struct signal_frame_data *signalFrameData) 163 { 164 panic("arch_setup_signal_frame"); 165 return B_ERROR; 166 } 167 168 169 int64 170 arch_restore_signal_frame(struct signal_frame_data* signalFrameData) 171 { 172 return 0; 173 } 174 175 176 void 177 arch_check_syscall_restart(Thread *thread) 178 { 179 } 180 181 182 void 183 arch_store_fork_frame(struct arch_fork_arg *arg) 184 { 185 panic("arch_store_fork_frame"); 186 } 187 188 189 void 190 arch_restore_fork_frame(struct arch_fork_arg *arg) 191 { 192 } 193