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 thread->user_local_storage = 82 thread->user_stack_base + thread->user_stack_size; 83 return B_OK; 84 } 85 86 87 static void 88 arm64_set_tls_context(Thread *thread) 89 { 90 WRITE_SPECIALREG(tpidrro_el0, thread->user_local_storage); 91 } 92 93 extern "C" void _arch_context_swap(arch_thread *from, arch_thread *to); 94 95 96 void 97 arch_thread_context_switch(Thread *from, Thread *to) 98 { 99 arm64_set_tls_context(to); 100 _arch_context_swap(&from->arch_info, &to->arch_info); 101 } 102 103 104 void 105 arch_thread_dump_info(void *info) 106 { 107 } 108 109 110 extern "C" void _eret_with_iframe(iframe *frame); 111 112 113 status_t 114 arch_thread_enter_userspace(Thread *thread, addr_t entry, 115 void *arg1, void *arg2) 116 { 117 arm64_set_tls_context(thread); 118 119 addr_t threadExitAddr; 120 { 121 addr_t commpageAdr = (addr_t)thread->team->commpage_address; 122 status_t ret = user_memcpy(&threadExitAddr, 123 &((addr_t*)commpageAdr)[COMMPAGE_ENTRY_ARM64_THREAD_EXIT], 124 sizeof(threadExitAddr)); 125 ASSERT(ret == B_OK); 126 threadExitAddr += commpageAdr; 127 } 128 129 iframe frame; 130 memset(&frame, 0, sizeof(frame)); 131 132 frame.spsr = 0; 133 frame.elr = entry; 134 frame.x[0] = (uint64_t)arg1; 135 frame.x[1] = (uint64_t)arg2; 136 frame.lr = threadExitAddr; 137 frame.sp = thread->user_stack_base + thread->user_stack_size; 138 139 _eret_with_iframe(&frame); 140 return B_ERROR; 141 } 142 143 144 bool 145 arch_on_signal_stack(Thread *thread) 146 { 147 return false; 148 } 149 150 151 status_t 152 arch_setup_signal_frame(Thread *thread, struct sigaction *sa, 153 struct signal_frame_data *signalFrameData) 154 { 155 panic("arch_setup_signal_frame"); 156 return B_ERROR; 157 } 158 159 160 int64 161 arch_restore_signal_frame(struct signal_frame_data* signalFrameData) 162 { 163 return 0; 164 } 165 166 167 void 168 arch_store_fork_frame(struct arch_fork_arg *arg) 169 { 170 panic("arch_store_fork_frame"); 171 } 172 173 174 void 175 arch_restore_fork_frame(struct arch_fork_arg *arg) 176 { 177 } 178