xref: /haiku/src/system/kernel/commpage.cpp (revision c5287be1f3d70804d8ea3bcf035ea60ed961fe26)
1 /*
2  * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com.
3  * Copyright 2007, Travis Geiselbrecht. All rights reserved.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 #ifdef COMMPAGE_COMPAT
9 #include <commpage_compat.h>
10 #else
11 #include <commpage.h>
12 #endif
13 
14 #include <string.h>
15 
16 #include <KernelExport.h>
17 
18 #include <elf.h>
19 #include <vm/vm.h>
20 #include <vm/vm_types.h>
21 
22 #ifndef ADDRESS_TYPE
23 #define ADDRESS_TYPE addr_t
24 #endif
25 
26 static area_id	sCommPageArea;
27 static ADDRESS_TYPE*	sCommPageAddress;
28 static void*	sFreeCommPageSpace;
29 static image_id	sCommPageImage;
30 
31 
32 #define ALIGN_ENTRY(pointer)	(void*)ROUNDUP((addr_t)(pointer), 8)
33 
34 
35 void*
36 allocate_commpage_entry(int entry, size_t size)
37 {
38 	void* space = sFreeCommPageSpace;
39 	sFreeCommPageSpace = ALIGN_ENTRY((addr_t)sFreeCommPageSpace + size);
40 	sCommPageAddress[entry] = (addr_t)space - (addr_t)sCommPageAddress;
41 	dprintf("allocate_commpage_entry(%d, %lu) -> %p\n", entry, size,
42 		(void*)sCommPageAddress[entry]);
43 	return space;
44 }
45 
46 
47 addr_t
48 fill_commpage_entry(int entry, const void* copyFrom, size_t size)
49 {
50 	void* space = allocate_commpage_entry(entry, size);
51 	memcpy(space, copyFrom, size);
52 	return (addr_t)space - (addr_t)sCommPageAddress;
53 }
54 
55 
56 image_id
57 get_commpage_image()
58 {
59 	return sCommPageImage;
60 }
61 
62 
63 area_id
64 clone_commpage_area(team_id team, void** address)
65 {
66 	if (*address == NULL)
67 		*address = (void*)KERNEL_USER_DATA_BASE;
68 	return vm_clone_area(team, "commpage", address,
69 		B_RANDOMIZED_BASE_ADDRESS, B_READ_AREA | B_EXECUTE_AREA,
70 		REGION_PRIVATE_MAP, sCommPageArea, true);
71 }
72 
73 
74 status_t
75 commpage_init(void)
76 {
77 	// create a read/write kernel area
78 	sCommPageArea = create_area("kernel_commpage", (void **)&sCommPageAddress,
79 		B_ANY_ADDRESS, COMMPAGE_SIZE, B_FULL_LOCK,
80 		B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA);
81 
82 	// zero it out
83 	memset(sCommPageAddress, 0, COMMPAGE_SIZE);
84 
85 	// fill in some of the table
86 	sCommPageAddress[0] = COMMPAGE_SIGNATURE;
87 	sCommPageAddress[1] = COMMPAGE_VERSION;
88 
89 	// the next slot to allocate space is after the table
90 	sFreeCommPageSpace = ALIGN_ENTRY(&sCommPageAddress[COMMPAGE_TABLE_ENTRIES]);
91 
92 	// create the image for the commpage
93 	sCommPageImage = elf_create_memory_image("commpage", 0, COMMPAGE_SIZE, 0,
94 		0);
95 	elf_add_memory_image_symbol(sCommPageImage, "commpage_table",
96 		0, COMMPAGE_TABLE_ENTRIES * sizeof(addr_t),
97 		B_SYMBOL_TYPE_DATA);
98 
99 	arch_commpage_init();
100 
101 	return B_OK;
102 }
103 
104 
105 status_t
106 commpage_init_post_cpus(void)
107 {
108 	return arch_commpage_init_post_cpus();
109 }
110