1 /* 2 * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de> 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without restriction, 7 * including without limitation the rights to use, copy, modify, 8 * merge, publish, distribute, sublicense, and/or sell copies of 9 * the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 #include <KernelExport.h> 26 #include <Errors.h> 27 #include <OS.h> 28 #include <string.h> 29 #include "util.h" 30 31 #define TRACE_UTIL 32 #ifdef TRACE_UTIL 33 #define TRACE dprintf 34 #else 35 #define TRACE(a...) 36 #endif 37 38 39 area_id 40 map_mem(void **virt, phys_addr_t phy, size_t size, uint32 protection, 41 const char *name) 42 { 43 uint32 offset; 44 phys_addr_t phyadr; 45 void *mapadr; 46 area_id area; 47 48 TRACE("mapping physical address %" B_PRIxPHYSADDR " with %ld bytes for %s\n", 49 phy, size, name); 50 51 offset = (uint32)phy & (B_PAGE_SIZE - 1); 52 phyadr = phy - offset; 53 size = ROUNDUP(size + offset, B_PAGE_SIZE); 54 area = map_physical_memory(name, phyadr, size, 55 B_ANY_KERNEL_BLOCK_ADDRESS, protection, &mapadr); 56 if (area < B_OK) { 57 TRACE("mapping '%s' failed, error 0x%" B_PRIx32 " (%s)\n", name, area, 58 strerror(area)); 59 return area; 60 } 61 62 *virt = (char *)mapadr + offset; 63 64 TRACE("physical = %" B_PRIxPHYSADDR ", virtual = %p, offset = %" B_PRIu32 65 ", phyadr = %" B_PRIxPHYSADDR ", mapadr = %p, size = %" B_PRIuSIZE 66 ", area = 0x%08" B_PRIx32 "\n", phy, *virt, offset, phyadr, mapadr, 67 size, area); 68 69 return area; 70 } 71 72 73 area_id 74 alloc_mem(void **virt, phys_addr_t *phy, size_t size, uint32 protection, 75 const char *name) 76 { 77 physical_entry pe; 78 void * virtadr; 79 area_id areaid; 80 status_t rv; 81 82 TRACE("allocating %" B_PRIuSIZE " bytes for %s\n", size, name); 83 84 size = ROUNDUP(size, B_PAGE_SIZE); 85 areaid = create_area(name, &virtadr, B_ANY_KERNEL_ADDRESS, size, 86 B_32_BIT_CONTIGUOUS, protection); 87 // TODO: The rest of the code doesn't deal correctly with physical 88 // addresses > 4 GB, so we have to force 32 bit addresses here. 89 if (areaid < B_OK) { 90 TRACE("couldn't allocate area %s\n", name); 91 return B_ERROR; 92 } 93 rv = get_memory_map(virtadr, size, &pe, 1); 94 if (rv < B_OK) { 95 delete_area(areaid); 96 TRACE("couldn't map %s\n", name); 97 return B_ERROR; 98 } 99 if (virt) 100 *virt = virtadr; 101 if (phy) 102 *phy = pe.address; 103 TRACE("area = %" B_PRId32 ", size = %" B_PRIuSIZE ", virt = %p, phy = %" 104 B_PRIxPHYSADDR "\n", areaid, size, virtadr, pe.address); 105 return areaid; 106 } 107