- _flags |= kIOMemoryRequiresWire;
-
- kern_return_t kr;
- ipc_port_t sharedMem = (ipc_port_t) _memEntry;
- vm_size_t size = round_page(_ranges.v[0].length);
-
- // must create the entry before any pages are allocated
- if( 0 == sharedMem) {
- kr = mach_make_memory_entry( map,
- &size, _ranges.v[0].address,
- VM_PROT_READ | VM_PROT_WRITE, &sharedMem,
- NULL );
- if( (KERN_SUCCESS == kr) && (size != round_page(_ranges.v[0].length))) {
- ipc_port_release_send( sharedMem );
- kr = kIOReturnVMError;
- }
- if( KERN_SUCCESS != kr)
- sharedMem = 0;
- _memEntry = (void *) sharedMem;
- }
- }
- else
- {
- /* Precompute virtual-to-physical page mappings. */
- vm_address_t inBuffer = (vm_address_t) _buffer;
- _physSegCount = atop(trunc_page(inBuffer + capacity - 1) -
- trunc_page(inBuffer)) + 1;
- _physAddrs = IONew(IOPhysicalAddress, _physSegCount);
- if (!_physAddrs)
- return false;
-
- inBuffer = trunc_page(inBuffer);
- for (unsigned i = 0; i < _physSegCount; i++) {
- _physAddrs[i] = pmap_extract(get_task_pmap(kernel_task), inBuffer);
- assert(_physAddrs[i]); /* supposed to be wired */
- inBuffer += page_size;
- }
+ if (!reserved) {
+ reserved = IONew( ExpansionData, 1 );
+ if( !reserved)
+ return( false );
+ }
+ reserved->map = createMappingInTask(mapTask, 0,
+ kIOMapAnywhere | (options & kIOMapCacheMask), 0, 0);
+ if (!reserved->map)
+ {
+ _buffer = 0;
+ return( false );
+ }
+ release(); // map took a retain on this
+ reserved->map->retain();
+ removeMapping(reserved->map);
+ mach_vm_address_t buffer = reserved->map->getAddress();
+ _buffer = (void *) buffer;
+ if (kIOMemoryTypeVirtual64 == (kIOMemoryTypeMask & iomdOptions))
+ _ranges.v64->address = buffer;