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