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 <kallisti5@unixzen.com>
This commit is contained in:
X512 2021-06-06 22:42:23 +09:00 committed by Alex von Gluck IV
parent d6a257bbe9
commit 62790afc9d
3 changed files with 75 additions and 6 deletions

View File

@ -10,9 +10,9 @@
# error Must not be included directly. Include <commpage_defs.h> 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 */

View File

@ -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 <asm_defs.h>
#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)

View File

@ -13,6 +13,60 @@
#include <elf.h>
#include <smp.h>
#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;
}