void * IOMallocContiguous(vm_size_t size, vm_size_t alignment, IOPhysicalAddress * physicalAddress) { mach_vm_address_t address = 0; if (size == 0) return 0; if (alignment == 0) alignment = 1; /* Do we want a physical address? */ if (!physicalAddress) { address = IOKernelAllocateWithPhysicalRestrict(size, 0 /*maxPhys*/, alignment, true); } else do { IOBufferMemoryDescriptor * bmd; mach_vm_address_t physicalMask; vm_offset_t alignMask; alignMask = alignment - 1; physicalMask = (0xFFFFFFFF ^ alignMask); bmd = IOBufferMemoryDescriptor::inTaskWithPhysicalMask( kernel_task, kIOMemoryPhysicallyContiguous, size, physicalMask); if (!bmd) break; _IOMallocContiguousEntry * entry = IONew(_IOMallocContiguousEntry, 1); if (!entry) { bmd->release(); break; } entry->virtualAddr = (mach_vm_address_t) bmd->getBytesNoCopy(); entry->md = bmd; lck_mtx_lock(gIOMallocContiguousEntriesLock); queue_enter( &gIOMallocContiguousEntries, entry, _IOMallocContiguousEntry *, link ); lck_mtx_unlock(gIOMallocContiguousEntriesLock); address = (mach_vm_address_t) entry->virtualAddr; *physicalAddress = bmd->getPhysicalAddress(); } while (false); if (address) { IOStatisticsAlloc(kIOStatisticsMallocContiguous, size); } return (void *) address; }
IOBufferMemoryDescriptor *kXAudioEngine::my_alloc_contiguous(mach_vm_size_t size, void **addr, dword *phys) { if(size<PAGE_SIZE) size=PAGE_SIZE; #ifdef DEBUGGING size += 2 * PAGE_SIZE; #endif //void *addr=IOMallocContiguous(size+PAGE_SIZE+PAGE_SIZE,alignment,phys); mach_vm_address_t mask = 0x000000007FFFFFFFULL & ~(PAGE_SIZE - 1); IOBufferMemoryDescriptor *desc = IOBufferMemoryDescriptor::inTaskWithPhysicalMask( kernel_task, kIODirectionInOut | kIOMemoryPhysicallyContiguous, size, mask); if(desc) { desc->prepare(); IOPhysicalAddress pa = desc->getPhysicalAddress(); if (pa & ~mask) debug("kXAudioEngine[%p]::my_alloc_contiguous() - memory misaligned or beyond 2GB limit (%p)\n", this, (void *)pa); *phys = (dword)pa; *addr = desc->getBytesNoCopy(); #ifdef DEBUGGING memset(addr,0x11,PAGE_SIZE); memset((UInt8 *)addr+PAGE_SIZE+size,0x22,PAGE_SIZE); *((UInt8 *)addr) += PAGE_SIZE; *phys += PAGE_SIZE; #endif } else debug("kXAudioEngine[%p]::my_alloc_contiguous() - allocation failed\n",this); return desc; }