summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Bertalan <dani@danielbertalan.dev>2023-04-22 16:29:17 +0200
committerAndreas Kling <kling@serenityos.org>2023-04-23 14:30:59 +0200
commitd205814da672985e26db40e9dc3962c6222834a0 (patch)
treecf6b868ec1cf63fface3eba135e499b29a14d94f
parent9b9cc76b1d0389dc24f278044bbbe8fb6d83a766 (diff)
downloadserenity-d205814da672985e26db40e9dc3962c6222834a0.zip
Kernel+LibC: Implement `pthread_create` for AArch64
Instead of storing x86_64 register names in `SC_create_thread_params`, let the Kernel figure out how to pass the parameters to `pthread_create_helper`.
-rw-r--r--Kernel/API/Syscall.h8
-rw-r--r--Kernel/Syscalls/thread.cpp19
-rw-r--r--Userland/Libraries/LibC/pthread.cpp15
3 files changed, 20 insertions, 22 deletions
diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h
index 19b7074197..b2de4d1808 100644
--- a/Kernel/API/Syscall.h
+++ b/Kernel/API/Syscall.h
@@ -370,12 +370,8 @@ struct SC_create_thread_params {
unsigned int reported_guard_page_size = 0; // The lie we tell callers
unsigned int stack_size = 1 * MiB; // Equal to Thread::default_userspace_stack_size
void* stack_location; // nullptr means any, o.w. process virtual address
-# if ARCH(X86_64)
- FlatPtr rdi;
- FlatPtr rsi;
- FlatPtr rcx;
- FlatPtr rdx;
-# endif
+ void* (*entry)(void*);
+ void* entry_argument;
};
struct SC_realpath_params {
diff --git a/Kernel/Syscalls/thread.cpp b/Kernel/Syscalls/thread.cpp
index 8e5dfabb38..1afc29dd78 100644
--- a/Kernel/Syscalls/thread.cpp
+++ b/Kernel/Syscalls/thread.cpp
@@ -63,10 +63,21 @@ ErrorOr<FlatPtr> Process::sys$create_thread(void* (*entry)(void*), Userspace<Sys
regs.set_flags(0x0202);
regs.cr3 = address_space().with([](auto& space) { return space->page_directory().cr3(); });
- regs.rdi = params.rdi;
- regs.rsi = params.rsi;
- regs.rdx = params.rdx;
- regs.rcx = params.rcx;
+ // Set up the argument registers expected by pthread_create_helper.
+ regs.rdi = (FlatPtr)params.entry;
+ regs.rsi = (FlatPtr)params.entry_argument;
+ regs.rdx = (FlatPtr)params.stack_location;
+ regs.rcx = (FlatPtr)params.stack_size;
+#elif ARCH(AARCH64)
+ regs.ttbr0_el1 = address_space().with([](auto& space) { return space->page_directory().ttbr0(); });
+
+ // Set up the argument registers expected by pthread_create_helper.
+ regs.x[0] = (FlatPtr)params.entry;
+ regs.x[1] = (FlatPtr)params.entry_argument;
+ regs.x[2] = (FlatPtr)params.stack_location;
+ regs.x[3] = (FlatPtr)params.stack_size;
+#else
+# error Unknown architecture
#endif
TRY(thread->make_thread_specific_region({}));
diff --git a/Userland/Libraries/LibC/pthread.cpp b/Userland/Libraries/LibC/pthread.cpp
index ab7c5e25f9..6dbce4a45f 100644
--- a/Userland/Libraries/LibC/pthread.cpp
+++ b/Userland/Libraries/LibC/pthread.cpp
@@ -90,18 +90,9 @@ static int create_thread(pthread_t* thread, void* (*entry)(void*), void* argumen
while (((uintptr_t)stack - 16) % 16 != 0)
push_on_stack(nullptr);
-#if ARCH(X86_64)
- thread_params->rdi = (FlatPtr)entry;
- thread_params->rsi = (FlatPtr)argument;
- thread_params->rdx = (FlatPtr)thread_params->stack_location;
- thread_params->rcx = thread_params->stack_size;
-#elif ARCH(AARCH64)
- (void)entry;
- (void)argument;
- TODO_AARCH64();
-#else
-# error Unknown architecture
-#endif
+ thread_params->entry = entry;
+ thread_params->entry_argument = argument;
+
VERIFY((uintptr_t)stack % 16 == 0);
// Push a fake return address