xref: /haiku/src/system/kernel/commpage.cpp (revision aa4b5749d64af0c0573513c27296af16f4680367)
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 <elf.h>
13 #include <vm/vm.h>
14 #include <vm/vm_types.h>
15 
16 
17 static area_id	sCommPageArea;
18 static addr_t*	sCommPageAddress;
19 static void*	sFreeCommPageSpace;
20 static image_id	sCommPageImage;
21 
22 
23 #define ALIGN_ENTRY(pointer)	(void*)ROUNDUP((addr_t)(pointer), 8)
24 
25 
26 void*
27 allocate_commpage_entry(int entry, size_t size)
28 {
29 	void* space = sFreeCommPageSpace;
30 	sFreeCommPageSpace = ALIGN_ENTRY((addr_t)sFreeCommPageSpace + size);
31 	sCommPageAddress[entry] = (addr_t)space - (addr_t)sCommPageAddress;
32 	dprintf("allocate_commpage_entry(%d, %lu) -> %p\n", entry, size,
33 		(void*)sCommPageAddress[entry]);
34 	return space;
35 }
36 
37 
38 addr_t
39 fill_commpage_entry(int entry, const void* copyFrom, size_t size)
40 {
41 	void* space = allocate_commpage_entry(entry, size);
42 	memcpy(space, copyFrom, size);
43 	return (addr_t)space - (addr_t)sCommPageAddress;
44 }
45 
46 
47 image_id
48 get_commpage_image()
49 {
50 	return sCommPageImage;
51 }
52 
53 
54 area_id
55 clone_commpage_area(team_id team, void** address)
56 {
57 	*address = (void*)KERNEL_USER_DATA_BASE;
58 	return vm_clone_area(team, "commpage", address,
59 		B_RANDOMIZED_BASE_ADDRESS, B_READ_AREA | B_EXECUTE_AREA | B_KERNEL_AREA,
60 		REGION_PRIVATE_MAP, sCommPageArea, true);
61 }
62 
63 
64 status_t
65 commpage_init(void)
66 {
67 	// create a read/write kernel area
68 	sCommPageArea = create_area("kernel_commpage", (void **)&sCommPageAddress,
69 		B_ANY_ADDRESS, COMMPAGE_SIZE, B_FULL_LOCK,
70 		B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA);
71 
72 	// zero it out
73 	memset(sCommPageAddress, 0, COMMPAGE_SIZE);
74 
75 	// fill in some of the table
76 	sCommPageAddress[0] = COMMPAGE_SIGNATURE;
77 	sCommPageAddress[1] = COMMPAGE_VERSION;
78 
79 	// the next slot to allocate space is after the table
80 	sFreeCommPageSpace = ALIGN_ENTRY(&sCommPageAddress[COMMPAGE_TABLE_ENTRIES]);
81 
82 	// create the image for the commpage
83 	sCommPageImage = elf_create_memory_image("commpage", 0, COMMPAGE_SIZE, 0,
84 		0);
85 	elf_add_memory_image_symbol(sCommPageImage, "commpage_table",
86 		0, COMMPAGE_TABLE_ENTRIES * sizeof(addr_t),
87 		B_SYMBOL_TYPE_DATA);
88 
89 	arch_commpage_init();
90 
91 	return B_OK;
92 }
93 
94 
95 status_t
96 commpage_init_post_cpus(void)
97 {
98 	return arch_commpage_init_post_cpus();
99 }
100