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 30void 31arm64_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 38void 39arm64_pop_iframe(struct iframe_stack *stack) 40{ 41 ASSERT(stack->index > 0); 42 stack->index--; 43} 44 45 46status_t 47arch_thread_init(struct kernel_args *args) 48{ 49 return B_OK; 50} 51 52 53status_t 54arch_team_init_team_struct(Team *team, bool kernel) 55{ 56 return B_OK; 57} 58 59 60status_t 61arch_thread_init_thread_struct(Thread *thread) 62{ 63 return B_OK; 64} 65 66 67void 68arch_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 78status_t 79arch_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 87static void 88arm64_set_tls_context(Thread *thread) 89{ 90 WRITE_SPECIALREG(tpidrro_el0, thread->user_local_storage); 91} 92 93extern "C" void _arch_context_swap(arch_thread *from, arch_thread *to); 94 95 96void 97arch_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 104void 105arch_thread_dump_info(void *info) 106{ 107} 108 109 110extern "C" void _eret_with_iframe(iframe *frame); 111 112 113status_t 114arch_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 144bool 145arch_on_signal_stack(Thread *thread) 146{ 147 return false; 148} 149 150 151status_t 152arch_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 160int64 161arch_restore_signal_frame(struct signal_frame_data* signalFrameData) 162{ 163 return 0; 164} 165 166 167void 168arch_store_fork_frame(struct arch_fork_arg *arg) 169{ 170 panic("arch_store_fork_frame"); 171} 172 173 174void 175arch_restore_fork_frame(struct arch_fork_arg *arg) 176{ 177} 178