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