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 | B_KERNEL_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