1/* 2 * Copyright 2007, Travis Geiselbrecht. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#include <commpage.h> 7 8#include <string.h> 9 10#include <KernelExport.h> 11 12#include <cpu.h> 13#include <elf.h> 14#include <smp.h> 15 16#include "syscall_numbers.h" 17 18 19extern "C" void arch_user_thread_exit(); 20 21 22extern "C" void __attribute__((noreturn)) 23arch_user_signal_handler(signal_frame_data* data) 24{ 25 if (data->siginfo_handler) { 26 auto handler = (void (*)(int, siginfo_t*, void*, void*))data->handler; 27 handler(data->info.si_signo, &data->info, &data->context, data->user_data); 28 } else { 29 auto handler = (void (*)(int, void*, vregs*))data->handler; 30 handler(data->info.si_signo, data->user_data, &data->context.uc_mcontext); 31 } 32 33 #define TO_STRING_LITERAL_HELPER(number) #number 34 #define TO_STRING_LITERAL(number) TO_STRING_LITERAL_HELPER(number) 35 36 // _kern_restore_signal_frame(data) 37 asm volatile( 38 "mv a0, %0;" 39 "li t0, " TO_STRING_LITERAL(SYSCALL_RESTORE_SIGNAL_FRAME) ";" 40 "ecall;" 41 :: "r"(data) 42 ); 43 44 #undef TO_STRING_LITERAL_HELPER 45 #undef TO_STRING_LITERAL 46 47 __builtin_unreachable(); 48} 49 50 51static void 52register_commpage_function(const char* functionName, int32 commpageIndex, 53 const char* commpageSymbolName, addr_t expectedAddress) 54{ 55 // get address and size of function 56 elf_symbol_info symbolInfo; 57 if (elf_lookup_kernel_symbol(functionName, &symbolInfo) != B_OK) { 58 panic("register_commpage_function(): Failed to find " 59 "signal frame function \"%s\"!", functionName); 60 } 61 62 ASSERT(expectedAddress == symbolInfo.address); 63 64 // fill in the commpage table entry 65 addr_t position = fill_commpage_entry(commpageIndex, 66 (void*)symbolInfo.address, symbolInfo.size); 67 68 // add symbol to the commpage image 69 image_id image = get_commpage_image(); 70 elf_add_memory_image_symbol(image, commpageSymbolName, position, 71 symbolInfo.size, B_SYMBOL_TYPE_TEXT); 72} 73 74 75status_t 76arch_commpage_init(void) 77{ 78 return B_OK; 79} 80 81 82status_t 83arch_commpage_init_post_cpus(void) 84{ 85 register_commpage_function("arch_user_signal_handler", 86 COMMPAGE_ENTRY_RISCV64_SIGNAL_HANDLER, "commpage_signal_handler", 87 (addr_t)&arch_user_signal_handler); 88 89 register_commpage_function("arch_user_thread_exit", 90 COMMPAGE_ENTRY_RISCV64_THREAD_EXIT, "commpage_thread_exit", 91 (addr_t)&arch_user_thread_exit); 92 93 return B_OK; 94} 95