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
26static area_id	sCommPageArea;
27static ADDRESS_TYPE*	sCommPageAddress;
28static void*	sFreeCommPageSpace;
29static image_id	sCommPageImage;
30
31
32#define ALIGN_ENTRY(pointer)	(void*)ROUNDUP((addr_t)(pointer), 8)
33
34
35void*
36allocate_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
47addr_t
48fill_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
56image_id
57get_commpage_image()
58{
59	return sCommPageImage;
60}
61
62
63area_id
64clone_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 | B_KERNEL_AREA,
70		REGION_PRIVATE_MAP, sCommPageArea, true);
71}
72
73
74status_t
75commpage_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
105status_t
106commpage_init_post_cpus(void)
107{
108	return arch_commpage_init_post_cpus();
109}
110