diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2023-04-22 16:29:17 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-04-23 14:30:59 +0200 |
commit | d205814da672985e26db40e9dc3962c6222834a0 (patch) | |
tree | cf6b868ec1cf63fface3eba135e499b29a14d94f | |
parent | 9b9cc76b1d0389dc24f278044bbbe8fb6d83a766 (diff) | |
download | serenity-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.h | 8 | ||||
-rw-r--r-- | Kernel/Syscalls/thread.cpp | 19 | ||||
-rw-r--r-- | Userland/Libraries/LibC/pthread.cpp | 15 |
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 |