/* Realtek RTL8169 Family Driver * Copyright (C) 2004 Marcus Overhagen . All rights reserved. * * Permission to use, copy, modify and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies, and that both the * copyright notice and this permission notice appear in supporting documentation. * * Marcus Overhagen makes no representations about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * * MARCUS OVERHAGEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL MARCUS * OVERHAGEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include //#define DEBUG #include "fwdebug.h" #include "util.h" static inline uint32 round_to_pagesize(uint32 size) { return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); } area_id alloc_mem(void **virt, void **phy, size_t size, uint32 protection, const char *name) { // TODO: phy should be phys_addr_t*! physical_entry pe; void *virtadr; area_id area; status_t rv; TRACE("allocating %ld bytes for %s\n", size, name); size = round_to_pagesize(size); area = create_area(name, &virtadr, B_ANY_KERNEL_ADDRESS, size, B_32_BIT_CONTIGUOUS, protection); // TODO: The rest of the code doesn't deal correctly with physical // addresses > 4 GB, so we have to force 32 bit addresses here. if (area < B_OK) { ERROR("couldn't allocate area %s\n", name); return B_ERROR; } rv = get_memory_map(virtadr, size, &pe, 1); if (rv < B_OK) { delete_area(area); ERROR("couldn't get mapping for %s\n", name); return B_ERROR; } memset(virtadr, 0, size); if (virt) *virt = virtadr; if (phy) *phy = (void*)(addr_t)pe.address; TRACE("area = %" B_PRId32 ", size = %ld, virt = %p, phy = %" B_PRIxPHYSADDR "\n", area, size, virtadr, pe.address); return area; } area_id map_mem(void **virt, void *phy, size_t size, uint32 protection, const char *name) { uint32 offset; void *phyadr; void *mapadr; area_id area; TRACE("mapping physical address %p with %ld bytes for %s\n", phy, size, name); offset = (intptr_t)phy & (B_PAGE_SIZE - 1); phyadr = (char *)phy - offset; size = round_to_pagesize(size + offset); area = map_physical_memory(name, (addr_t)phyadr, size, B_ANY_KERNEL_BLOCK_ADDRESS, protection, &mapadr); if (area < B_OK) { ERROR("mapping '%s' failed, error 0x%" B_PRIx32 " (%s)\n", name, area, strerror(area)); return area; } *virt = (char *)mapadr + offset; TRACE("physical = %p, virtual = %p, offset = %" B_PRId32 ", phyadr = %p, " "mapadr = %p, size = %ld, area = 0x%08" B_PRIx32 "\n", phy, *virt, offset, phyadr, mapadr, size, area); return area; }