- kern_return_t kr;
- task_t mapTask = NULL;
- vm_map_t vmmap = NULL;
- addr64_t lastIOAddr;
- mach_vm_address_t highestMask = 0;
- bool usePhys;
- IOOptionBits iomdOptions = kIOMemoryTypeVirtual64 | kIOMemoryAsReference;
-
- if (!capacity)
- return false;
-
- _options = options;
- _capacity = capacity;
- _internalFlags = 0;
- _internalReserved = 0;
- _buffer = 0;
-
- _ranges.v64 = IONew(IOAddressRange, 1);
- if (!_ranges.v64)
- return (false);
- _ranges.v64->address = 0;
- _ranges.v64->length = 0;
-
- // Grab IOMD bits from the Buffer MD options
- iomdOptions |= (options & kIOBufferDescriptorMemoryFlags);
-
- if (physicalMask && (alignment <= 1))
- {
- alignment = ((physicalMask ^ (-1ULL)) & (physicalMask - 1));
- highestMask = (physicalMask | alignment);
- alignment++;
- }
-
- if ((options & (kIOMemorySharingTypeMask | kIOMapCacheMask)) && (alignment < page_size))
- alignment = page_size;
-
- if (alignment >= page_size)
- capacity = round_page(capacity);
-
- if (alignment > page_size)
- options |= kIOMemoryPhysicallyContiguous;
-
- _alignment = alignment;
-
- if ((inTask != kernel_task) && !(options & kIOMemoryPageable))
- return false;
-
- if ((options & kIOMemoryPhysicallyContiguous) && !physicalMask)
- physicalMask = 0xFFFFFFFF;
-
- // set flags for entry + object create
- vm_prot_t memEntryCacheMode = VM_PROT_READ | VM_PROT_WRITE;
-
- // set memory entry cache mode
- switch (options & kIOMapCacheMask)
- {
- case kIOMapInhibitCache:
- SET_MAP_MEM(MAP_MEM_IO, memEntryCacheMode);
- break;
-
- case kIOMapWriteThruCache:
- SET_MAP_MEM(MAP_MEM_WTHRU, memEntryCacheMode);
- break;
-
- case kIOMapWriteCombineCache:
- SET_MAP_MEM(MAP_MEM_WCOMB, memEntryCacheMode);
- break;
-
- case kIOMapCopybackCache:
- SET_MAP_MEM(MAP_MEM_COPYBACK, memEntryCacheMode);
- break;
-
- case kIOMapDefaultCache:
- default:
- SET_MAP_MEM(MAP_MEM_NOOP, memEntryCacheMode);
- break;
- }
-
- if (options & kIOMemoryPageable)
- {
- iomdOptions |= kIOMemoryBufferPageable;
-
- // must create the entry before any pages are allocated
-
- // set flags for entry + object create
- memEntryCacheMode |= MAP_MEM_NAMED_CREATE;
-
- if (options & kIOMemoryPurgeable)
- memEntryCacheMode |= MAP_MEM_PURGABLE;
- }
- else
- {
- memEntryCacheMode |= MAP_MEM_NAMED_REUSE;
-
- if (IOMapper::gSystem)
- // assuming mapped space is 2G
- lastIOAddr = (1UL << 31) - PAGE_SIZE;
- else
- lastIOAddr = ptoa_64(gIOHighestAllocatedPage);
-
- usePhys = (highestMask && (lastIOAddr != (lastIOAddr & highestMask))
- && (alignment <= page_size));
-
- if (!usePhys && (options & kIOMemoryPhysicallyContiguous))
- {
- _buffer = (void *) IOKernelAllocateContiguous(capacity, highestMask, alignment);
- usePhys = (NULL == _buffer);
- }
- if (usePhys)
- {
- mach_vm_address_t address;
- iomdOptions &= ~kIOMemoryTypeVirtual64;
- iomdOptions |= kIOMemoryTypePhysical64;
-
- address = IOMallocPhysical(capacity, highestMask);
- _buffer = (void *) address;
- if (!_buffer)