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