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 19 extern "C" void arch_user_thread_exit(); 20 21 typedef void (*SignalHandler)(int signal, siginfo_t* signalInfo, 22 ucontext_t* ctx); 23 24 25 extern "C" void 26 arch_user_signal_handler(signal_frame_data* data) 27 { 28 SignalHandler handler = (SignalHandler)data->handler; 29 handler(data->info.si_signo, &data->info, &data->context); 30 31 #define TO_STRING_LITERAL_HELPER(number) #number 32 #define TO_STRING_LITERAL(number) TO_STRING_LITERAL_HELPER(number) 33 34 // _kern_restore_signal_frame(data) 35 asm volatile( 36 "mv a0, %0;" 37 "li t0, " TO_STRING_LITERAL(SYSCALL_RESTORE_SIGNAL_FRAME) ";" 38 "ecall;" 39 :: "r"(data) 40 ); 41 42 #undef TO_STRING_LITERAL_HELPER 43 #undef TO_STRING_LITERAL 44 } 45 46 47 static void 48 register_commpage_function(const char* functionName, int32 commpageIndex, 49 const char* commpageSymbolName, addr_t expectedAddress) 50 { 51 // get address and size of function 52 elf_symbol_info symbolInfo; 53 if (elf_lookup_kernel_symbol(functionName, &symbolInfo) != B_OK) { 54 panic("register_commpage_function(): Failed to find " 55 "signal frame function \"%s\"!", functionName); 56 } 57 58 ASSERT(expectedAddress == symbolInfo.address); 59 60 // fill in the commpage table entry 61 addr_t position = fill_commpage_entry(commpageIndex, 62 (void*)symbolInfo.address, symbolInfo.size); 63 64 // add symbol to the commpage image 65 image_id image = get_commpage_image(); 66 elf_add_memory_image_symbol(image, commpageSymbolName, position, 67 symbolInfo.size, B_SYMBOL_TYPE_TEXT); 68 } 69 70 71 status_t 72 arch_commpage_init(void) 73 { 74 return B_OK; 75 } 76 77 78 status_t 79 arch_commpage_init_post_cpus(void) 80 { 81 register_commpage_function("arch_user_signal_handler", 82 COMMPAGE_ENTRY_RISCV64_SIGNAL_HANDLER, "commpage_signal_handler", 83 (addr_t)&arch_user_signal_handler); 84 85 register_commpage_function("arch_user_thread_exit", 86 COMMPAGE_ENTRY_RISCV64_THREAD_EXIT, "commpage_thread_exit", 87 (addr_t)&arch_user_thread_exit); 88 89 return B_OK; 90 } 91