- /* Allocate some kernel address space. */
- _buffer = IOMallocPageable(capacity, alignment);
- /* Allocate a wired-down buffer inside kernel space. */
- else if (options & kIOMemoryPhysicallyContiguous)
- _buffer = IOMallocContiguous(capacity, alignment, 0);
- else if (alignment > 1)
- _buffer = IOMallocAligned(capacity, alignment);
- else
- _buffer = IOMalloc(capacity);
-
- if (!_buffer)
- return false;
+ {
+ iomdOptions |= kIOMemoryBufferPageable;
+
+ ipc_port_t sharedMem;
+ vm_size_t size = round_page_32(capacity);
+
+ // must create the entry before any pages are allocated
+
+ // set flags for entry + object create
+ vm_prot_t memEntryCacheMode = VM_PROT_READ | VM_PROT_WRITE
+ | MAP_MEM_NAMED_CREATE;
+
+ if (options & kIOMemoryPurgeable)
+ memEntryCacheMode |= MAP_MEM_PURGABLE;
+
+ // 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;
+ }
+
+ kr = mach_make_memory_entry( vmmap,
+ &size, 0,
+ memEntryCacheMode, &sharedMem,
+ NULL );
+
+ if( (KERN_SUCCESS == kr) && (size != round_page_32(capacity))) {
+ ipc_port_release_send( sharedMem );
+ kr = kIOReturnVMError;
+ }
+ if( KERN_SUCCESS != kr)
+ return( false );
+
+ _memEntry = (void *) sharedMem;
+#if IOALLOCDEBUG
+ debug_iomallocpageable_size += size;
+#endif
+ if ((NULL == inTask) && (options & kIOMemoryPageable))
+ inTask = kernel_task;
+ else if (inTask == kernel_task)
+ {
+ vmmap = kernel_map;
+ }
+ else
+ {
+
+ if( !reserved) {
+ reserved = IONew( ExpansionData, 1 );
+ if( !reserved)
+ return( false );
+ }
+ vmmap = get_task_map(inTask);
+ vm_map_reference(vmmap);
+ reserved->map = vmmap;
+ }
+ }
+ else
+ {
+ // @@@ gvdl: Need to remove this
+ // Buffer should never auto prepare they should be prepared explicitly
+ // But it never was enforced so what are you going to do?
+ iomdOptions |= kIOMemoryAutoPrepare;
+
+ /* Allocate a wired-down buffer inside kernel space. */
+ if (options & kIOMemoryPhysicallyContiguous)
+ _buffer = IOMallocContiguous(capacity, alignment, 0);
+ else if (alignment > 1)
+ _buffer = IOMallocAligned(capacity, alignment);
+ else
+ _buffer = IOMalloc(capacity);
+
+ if (!_buffer)
+ return false;
+ }