- /* Do we want a physical address? */
- if (address && physicalAddress)
- {
- do
- {
- /* Get the physical page */
- pagenum = pmap_find_phys(kernel_pmap, (addr64_t) address);
- if(pagenum)
- {
- IOByteCount offset;
- ppnum_t base;
-
- base = IOMapperIOVMAlloc((size + PAGE_MASK) >> PAGE_SHIFT);
- if (base)
- {
- _IOMallocContiguousEntry *
- entry = IONew(_IOMallocContiguousEntry, 1);
- if (!entry)
- {
- IOFreeContiguous((void *) address, size);
- address = 0;
- break;
- }
- entry->virtual = (void *) address;
- entry->ioBase = base;
- mutex_lock(gIOMallocContiguousEntriesLock);
- queue_enter( &gIOMallocContiguousEntries, entry,
- _IOMallocContiguousEntry *, link );
- mutex_unlock(gIOMallocContiguousEntriesLock);
-
- *physicalAddress = (IOPhysicalAddress)((base << PAGE_SHIFT) | (address & PAGE_MASK));
- for (offset = 0; offset < ((size + PAGE_MASK) >> PAGE_SHIFT); offset++, pagenum++)
- IOMapperInsertPage( base, offset, pagenum );
- }
- else
- *physicalAddress = (IOPhysicalAddress)((pagenum << PAGE_SHIFT) | (address & PAGE_MASK));
- }
- else
- /* Did not find, return 0 */
- *physicalAddress = (IOPhysicalAddress) 0;
- }
- while (false);
- }