From 62790afc9d910936fa19566eb4d7af36587836d5 Mon Sep 17 00:00:00 2001 From: X512 Date: Sun, 6 Jun 2021 22:42:23 +0900 Subject: [PATCH] kernel/arch/commpage: implement for riscv64 Change-Id: Id7f495896a08a237db85dcedd1174e4c181e373d Reviewed-on: https://review.haiku-os.org/c/haiku/+/4056 Reviewed-by: Alex von Gluck IV --- .../system/arch/riscv64/arch_commpage_defs.h | 8 +-- src/system/kernel/arch/riscv64/arch_asm.S | 10 ++- .../kernel/arch/riscv64/arch_commpage.cpp | 63 ++++++++++++++++++- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/headers/private/system/arch/riscv64/arch_commpage_defs.h b/headers/private/system/arch/riscv64/arch_commpage_defs.h index 18f187011f..df081b57e6 100644 --- a/headers/private/system/arch/riscv64/arch_commpage_defs.h +++ b/headers/private/system/arch/riscv64/arch_commpage_defs.h @@ -10,9 +10,9 @@ # error Must not be included directly. Include instead! #endif -/* -#define COMMPAGE_ENTRY_RISCV64_SYSCALL (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) -#define COMMPAGE_ENTRY_RISCV64_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) -*/ +#define COMMPAGE_ENTRY_RISCV64_SIGNAL_HANDLER \ + (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0) +#define COMMPAGE_ENTRY_RISCV64_SIGNAL_THREAD_EXIT \ + (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1) #endif /* _SYSTEM_ARCH_RISCV64_COMMPAGE_DEFS_H */ diff --git a/src/system/kernel/arch/riscv64/arch_asm.S b/src/system/kernel/arch/riscv64/arch_asm.S index d19d713d88..d434dde193 100644 --- a/src/system/kernel/arch/riscv64/arch_asm.S +++ b/src/system/kernel/arch/riscv64/arch_asm.S @@ -1,10 +1,11 @@ /* - * Copyright 2019, Haiku, Inc. All Rights Reserved + * Copyright 2019-2021, Haiku, Inc. All Rights Reserved * Distributed under the terms of the MIT License. */ #include +#include "syscall_numbers.h" .text @@ -160,3 +161,10 @@ FUNCTION(arch_longjmp_iframe): mv sp, a0 call SVecURet FUNCTION_END(arch_longjmp_iframe) + + +FUNCTION(arch_user_thread_exit): + li t0, SYSCALL_EXIT_THREAD + ecall + ret +FUNCTION_END(arch_user_thread_exit) diff --git a/src/system/kernel/arch/riscv64/arch_commpage.cpp b/src/system/kernel/arch/riscv64/arch_commpage.cpp index b7378611ab..e604192902 100644 --- a/src/system/kernel/arch/riscv64/arch_commpage.cpp +++ b/src/system/kernel/arch/riscv64/arch_commpage.cpp @@ -13,6 +13,60 @@ #include #include +#include "syscall_numbers.h" + + +extern "C" void arch_user_thread_exit(); + +typedef void (*SignalHandler)(int signal, siginfo_t* signalInfo, + ucontext_t* ctx); + + +extern "C" void +arch_user_signal_handler(signal_frame_data* data) +{ + SignalHandler handler = (SignalHandler)data->handler; + handler(data->info.si_signo, &data->info, &data->context); + + #define TO_STRING_LITERAL_HELPER(number) #number + #define TO_STRING_LITERAL(number) TO_STRING_LITERAL_HELPER(number) + + // _kern_restore_signal_frame(data) + asm volatile( + "mv a0, %0;" + "li t0, " TO_STRING_LITERAL(SYSCALL_RESTORE_SIGNAL_FRAME) ";" + "ecall;" + :: "r"(data) + ); + + #undef TO_STRING_LITERAL_HELPER + #undef TO_STRING_LITERAL +} + + +static void +register_commpage_function(const char* functionName, int32 commpageIndex, + const char* commpageSymbolName, addr_t expectedAddress) +{ + // get address and size of function + elf_symbol_info symbolInfo; + if (elf_lookup_kernel_symbol(functionName, &symbolInfo) != B_OK) { + panic("register_commpage_function(): Failed to find " + "signal frame function \"%s\"!", functionName); + } + + ASSERT(expectedAddress == symbolInfo.address); + + // fill in the commpage table entry + addr_t position = fill_commpage_entry(commpageIndex, + (void*)symbolInfo.address, symbolInfo.size); + + // add symbol to the commpage image + image_id image = get_commpage_image(); + elf_add_memory_image_symbol(image, commpageSymbolName, position, + symbolInfo.size, B_SYMBOL_TYPE_TEXT); +} + status_t arch_commpage_init(void) @@ -24,6 +78,13 @@ arch_commpage_init(void) status_t arch_commpage_init_post_cpus(void) { + register_commpage_function("arch_user_signal_handler", + COMMPAGE_ENTRY_RISCV64_SIGNAL_HANDLER, "commpage_signal_handler", + (addr_t)&arch_user_signal_handler); + + register_commpage_function("arch_user_thread_exit", + COMMPAGE_ENTRY_RISCV64_SIGNAL_THREAD_EXIT, "commpage_thread_exit", + (addr_t)&arch_user_thread_exit); + return B_OK; } -