void *phys_map(phys_addr_t addr, size_t size, int mmflag) { phys_addr_t base; phys_addr_t end; void *ret = NULL; if (!size) { /* What do you want to do??? */ ASSERT(0); goto out; } /* Use the physical map area if the range lies within it. For more * information please refer to the memory layout of our system. */ if (PMAP_CONTAINS(addr, size)) { ret = (void *)addr; goto out; } base = ROUND_DOWN(addr, PAGE_SIZE); end = ROUND_UP(addr + size, PAGE_SIZE); ASSERT(end > base); /* Map pages from kernel memory */ ret = kmem_map(base, end - base, mmflag); if (ret) { ret = (char *)ret + (addr - base); // Don't miss the offset } DEBUG(DL_DBG, ("addr(%x), size(%x), ret(%p).\n", addr, size, ret)); out: return ret; }
/** Map physical memory into the kernel address space. * @param addr Physical address to map. * @param size Size of range to map. * @param mmflag Allocation flags. * @return Pointer to mapped data. */ void *phys_map(phys_ptr_t addr, size_t size, unsigned mmflag) { phys_ptr_t base, end; if(unlikely(!size)) return NULL; /* Use the physical map area if the range lies within it. */ if(PMAP_CONTAINS(addr, size)) return (void *)(KERNEL_PMAP_BASE + (addr - KERNEL_PMAP_OFFSET)); /* Outside the physical map area. Must instead allocate some kernel * memory space and map there. */ base = round_down(addr, PAGE_SIZE); end = round_up(addr + size, PAGE_SIZE); return kmem_map(base, end - base, mmflag); }