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