1 /* Realtek RTL8169 Family Driver 2 * Copyright (C) 2004 Marcus Overhagen <marcus@overhagen.de>. All rights reserved. 3 * 4 * Permission to use, copy, modify and distribute this software and its 5 * documentation for any purpose and without fee is hereby granted, provided 6 * that the above copyright notice appear in all copies, and that both the 7 * copyright notice and this permission notice appear in supporting documentation. 8 * 9 * Marcus Overhagen makes no representations about the suitability of this software 10 * for any purpose. It is provided "as is" without express or implied warranty. 11 * 12 * MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 13 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS 14 * OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 15 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 #include <Errors.h> 20 #include <OS.h> 21 #include <string.h> 22 23 //#define DEBUG 24 25 #include "fwdebug.h" 26 #include "util.h" 27 28 29 static inline uint32 30 round_to_pagesize(uint32 size) 31 { 32 return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); 33 } 34 35 36 area_id 37 alloc_mem(void **virt, void **phy, size_t size, uint32 protection, 38 const char *name) 39 { 40 // TODO: phy should be phys_addr_t*! 41 physical_entry pe; 42 void *virtadr; 43 area_id area; 44 status_t rv; 45 46 TRACE("allocating %ld bytes for %s\n", size, name); 47 48 size = round_to_pagesize(size); 49 area = create_area(name, &virtadr, B_ANY_KERNEL_ADDRESS, size, 50 B_32_BIT_CONTIGUOUS, protection); 51 // TODO: The rest of the code doesn't deal correctly with physical 52 // addresses > 4 GB, so we have to force 32 bit addresses here. 53 if (area < B_OK) { 54 ERROR("couldn't allocate area %s\n", name); 55 return B_ERROR; 56 } 57 rv = get_memory_map(virtadr, size, &pe, 1); 58 if (rv < B_OK) { 59 delete_area(area); 60 ERROR("couldn't get mapping for %s\n", name); 61 return B_ERROR; 62 } 63 memset(virtadr, 0, size); 64 if (virt) 65 *virt = virtadr; 66 if (phy) 67 *phy = (void*)(addr_t)pe.address; 68 TRACE("area = %ld, size = %ld, virt = %p, phy = %" B_PRIxPHYSADDR "\n", area, size, virtadr, 69 pe.address); 70 return area; 71 } 72 73 74 area_id 75 map_mem(void **virt, void *phy, size_t size, uint32 protection, 76 const char *name) 77 { 78 uint32 offset; 79 void *phyadr; 80 void *mapadr; 81 area_id area; 82 83 TRACE("mapping physical address %p with %ld bytes for %s\n", phy, size, 84 name); 85 86 offset = (uint32)phy & (B_PAGE_SIZE - 1); 87 phyadr = (char *)phy - offset; 88 size = round_to_pagesize(size + offset); 89 area = map_physical_memory(name, (addr_t)phyadr, size, 90 B_ANY_KERNEL_BLOCK_ADDRESS, protection, &mapadr); 91 if (area < B_OK) { 92 ERROR("mapping '%s' failed, error 0x%lx (%s)\n", name, area, 93 strerror(area)); 94 return area; 95 } 96 97 *virt = (char *)mapadr + offset; 98 99 TRACE("physical = %p, virtual = %p, offset = %ld, phyadr = %p, mapadr = " 100 "%p, size = %ld, area = 0x%08lx\n", phy, *virt, offset, phyadr, mapadr, 101 size, area); 102 103 return area; 104 } 105