xref: /haiku/src/system/kernel/commpage.cpp (revision e6b30aee0fd7a23d6a6baab9f3718945a0cd838a)
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 <vm.h>
13 #include <vm_types.h>
14 
15 
16 static area_id	sCommPageArea;
17 static area_id	sUserCommPageArea;
18 static addr_t*	sCommPageAddress;
19 static addr_t*	sUserCommPageAddress;
20 static void*	sFreeCommPageSpace;
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)sUserCommPageAddress
32 		+ ((addr_t)space - (addr_t)sCommPageAddress);
33 dprintf("allocate_commpage_entry(%d, %lu) -> %p\n", entry, size, (void*)sCommPageAddress[entry]);
34 	return space;
35 }
36 
37 
38 void*
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 space;
44 }
45 
46 
47 status_t
48 commpage_init(void)
49 {
50 	// create a read/write kernel area
51 	sCommPageArea = create_area("commpage", (void **)&sCommPageAddress,
52 		B_ANY_ADDRESS, COMMPAGE_SIZE, B_FULL_LOCK,
53 		B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA);
54 
55 	// clone it at a fixed address with user read/only permissions
56 	sUserCommPageAddress = (addr_t*)USER_COMMPAGE_ADDR;
57 	sUserCommPageArea = clone_area("user_commpage",
58 		(void **)&sUserCommPageAddress, B_EXACT_ADDRESS,
59 		B_READ_AREA | B_EXECUTE_AREA, sCommPageArea);
60 
61 	// zero it out
62 	memset(sCommPageAddress, 0, COMMPAGE_SIZE);
63 
64 	// fill in some of the table
65 	sCommPageAddress[0] = COMMPAGE_SIGNATURE;
66 	sCommPageAddress[1] = COMMPAGE_VERSION;
67 
68 	// the next slot to allocate space is after the table
69 	sFreeCommPageSpace = ALIGN_ENTRY(&sCommPageAddress[COMMPAGE_TABLE_ENTRIES]);
70 
71 	arch_commpage_init();
72 
73 	return B_OK;
74 }
75 
76