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