xref: /haiku/src/system/kernel/arch/riscv64/arch_commpage.cpp (revision 610f99c838cb661ff85377789ffd3ad4ff672a08)
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