xref: /haiku/src/system/kernel/arch/arm64/arch_thread.cpp (revision fc7456e9b1ec38c941134ed6d01c438cf289381e)
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