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