Loading...
--- xnu/xnu-201/iokit/Kernel/IOMemoryDescriptor.cpp
+++ xnu/xnu-124.7/iokit/Kernel/IOMemoryDescriptor.cpp
@@ -38,26 +38,10 @@
__BEGIN_DECLS
#include <vm/pmap.h>
-#include <device/device_port.h>
-void bcopy_phys(char *from, char *to, int size);
void pmap_enter(pmap_t pmap, vm_offset_t va, vm_offset_t pa,
vm_prot_t prot, boolean_t wired);
void ipc_port_release_send(ipc_port_t port);
vm_offset_t vm_map_get_phys_page(vm_map_t map, vm_offset_t offset);
-
-memory_object_t
-device_pager_setup(
- memory_object_t pager,
- int device_handle,
- vm_size_t size,
- int flags);
-kern_return_t
-device_pager_populate_object(
- memory_object_t pager,
- vm_object_offset_t offset,
- vm_offset_t phys_addr,
- vm_size_t size);
-
__END_DECLS
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -69,16 +53,7 @@
OSDefineMetaClassAndStructors(IOGeneralMemoryDescriptor, IOMemoryDescriptor)
-extern "C" {
-
-vm_map_t IOPageableMapForAddress( vm_address_t address );
-
-typedef kern_return_t (*IOIteratePageableMapsCallback)(vm_map_t map, void * ref);
-
-kern_return_t IOIteratePageableMaps(vm_size_t size,
- IOIteratePageableMapsCallback callback, void * ref);
-
-}
+extern "C" vm_map_t IOPageableMapForAddress( vm_address_t address );
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -88,62 +63,6 @@
return( IOPageableMapForAddress( address ) );
else
return( get_task_map( task ));
-}
-
-inline vm_offset_t pmap_extract_safe(task_t task, vm_offset_t va)
-{
- vm_offset_t pa = pmap_extract(get_task_pmap(task), va);
-
- if ( pa == 0 )
- {
- pa = vm_map_get_phys_page(get_task_map(task), trunc_page(va));
- if ( pa ) pa += va - trunc_page(va);
- }
-
- return pa;
-}
-
-inline void bcopy_phys_safe(char * from, char * to, int size)
-{
- boolean_t enabled = ml_set_interrupts_enabled(FALSE);
-
- bcopy_phys(from, to, size);
-
- ml_set_interrupts_enabled(enabled);
-}
-
-#define next_page(a) ( trunc_page(a) + page_size )
-
-
-extern "C" {
-
-kern_return_t device_data_action(
- int device_handle,
- ipc_port_t device_pager,
- vm_prot_t protection,
- vm_object_offset_t offset,
- vm_size_t size)
-{
- IOMemoryDescriptor * memDesc = (IOMemoryDescriptor *) device_handle;
-
- assert( OSDynamicCast( IOMemoryDescriptor, memDesc ));
-
- return( memDesc->handleFault( device_pager, 0, 0,
- offset, size, kIOMapDefaultCache /*?*/));
-}
-
-kern_return_t device_close(
- int device_handle)
-{
- IOMemoryDescriptor * memDesc = (IOMemoryDescriptor *) device_handle;
-
- assert( OSDynamicCast( IOMemoryDescriptor, memDesc ));
-
- memDesc->release();
-
- return( kIOReturnSuccess );
-}
-
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -423,86 +342,86 @@
super::free();
}
-/* DEPRECATED */ void IOGeneralMemoryDescriptor::unmapFromKernel()
-/* DEPRECATED */ {
-/* DEPRECATED */ kern_return_t krtn;
-/* DEPRECATED */ vm_offset_t off;
-/* DEPRECATED */ // Pull the shared pages out of the task map
-/* DEPRECATED */ // Do we need to unwire it first?
-/* DEPRECATED */ for ( off = 0; off < _kernSize; off += page_size )
-/* DEPRECATED */ {
-/* DEPRECATED */ pmap_change_wiring(
-/* DEPRECATED */ kernel_pmap,
-/* DEPRECATED */ _kernPtrAligned + off,
-/* DEPRECATED */ FALSE);
-/* DEPRECATED */
-/* DEPRECATED */ pmap_remove(
-/* DEPRECATED */ kernel_pmap,
-/* DEPRECATED */ _kernPtrAligned + off,
-/* DEPRECATED */ _kernPtrAligned + off + page_size);
-/* DEPRECATED */ }
-/* DEPRECATED */ // Free the former shmem area in the task
-/* DEPRECATED */ krtn = vm_deallocate(kernel_map,
-/* DEPRECATED */ _kernPtrAligned,
-/* DEPRECATED */ _kernSize );
-/* DEPRECATED */ assert(krtn == KERN_SUCCESS);
-/* DEPRECATED */ _kernPtrAligned = 0;
-/* DEPRECATED */ }
-/* DEPRECATED */
-/* DEPRECATED */ void IOGeneralMemoryDescriptor::mapIntoKernel(unsigned rangeIndex)
-/* DEPRECATED */ {
-/* DEPRECATED */ kern_return_t krtn;
-/* DEPRECATED */ vm_offset_t off;
-/* DEPRECATED */
-/* DEPRECATED */ if (_kernPtrAligned)
-/* DEPRECATED */ {
-/* DEPRECATED */ if (_kernPtrAtIndex == rangeIndex) return;
-/* DEPRECATED */ unmapFromKernel();
-/* DEPRECATED */ assert(_kernPtrAligned == 0);
-/* DEPRECATED */ }
-/* DEPRECATED */
-/* DEPRECATED */ vm_offset_t srcAlign = trunc_page(_ranges.v[rangeIndex].address);
-/* DEPRECATED */
-/* DEPRECATED */ _kernSize = trunc_page(_ranges.v[rangeIndex].address +
-/* DEPRECATED */ _ranges.v[rangeIndex].length +
-/* DEPRECATED */ page_size - 1) - srcAlign;
-/* DEPRECATED */
-/* DEPRECATED */ /* Find some memory of the same size in kernel task. We use vm_allocate() */
-/* DEPRECATED */ /* to do this. vm_allocate inserts the found memory object in the */
-/* DEPRECATED */ /* target task's map as a side effect. */
-/* DEPRECATED */ krtn = vm_allocate( kernel_map,
-/* DEPRECATED */ &_kernPtrAligned,
-/* DEPRECATED */ _kernSize,
-/* DEPRECATED */ VM_FLAGS_ANYWHERE|VM_MAKE_TAG(VM_MEMORY_IOKIT) ); // Find first fit
-/* DEPRECATED */ assert(krtn == KERN_SUCCESS);
-/* DEPRECATED */ if(krtn) return;
-/* DEPRECATED */
-/* DEPRECATED */ /* For each page in the area allocated from the kernel map, */
-/* DEPRECATED */ /* find the physical address of the page. */
-/* DEPRECATED */ /* Enter the page in the target task's pmap, at the */
-/* DEPRECATED */ /* appropriate target task virtual address. */
-/* DEPRECATED */ for ( off = 0; off < _kernSize; off += page_size )
-/* DEPRECATED */ {
-/* DEPRECATED */ vm_offset_t kern_phys_addr, phys_addr;
-/* DEPRECATED */ if( _task)
-/* DEPRECATED */ phys_addr = pmap_extract( get_task_pmap(_task), srcAlign + off );
-/* DEPRECATED */ else
-/* DEPRECATED */ phys_addr = srcAlign + off;
-/* DEPRECATED */ assert(phys_addr);
-/* DEPRECATED */ if(phys_addr == 0) return;
-/* DEPRECATED */
-/* DEPRECATED */ // Check original state.
-/* DEPRECATED */ kern_phys_addr = pmap_extract( kernel_pmap, _kernPtrAligned + off );
-/* DEPRECATED */ // Set virtual page to point to the right physical one
-/* DEPRECATED */ pmap_enter(
-/* DEPRECATED */ kernel_pmap,
-/* DEPRECATED */ _kernPtrAligned + off,
-/* DEPRECATED */ phys_addr,
-/* DEPRECATED */ VM_PROT_READ|VM_PROT_WRITE,
-/* DEPRECATED */ TRUE);
-/* DEPRECATED */ }
-/* DEPRECATED */ _kernPtrAtIndex = rangeIndex;
-/* DEPRECATED */ }
+void IOGeneralMemoryDescriptor::unmapFromKernel()
+{
+ kern_return_t krtn;
+ vm_offset_t off;
+ // Pull the shared pages out of the task map
+ // Do we need to unwire it first?
+ for ( off = 0; off < _kernSize; off += page_size )
+ {
+ pmap_change_wiring(
+ kernel_pmap,
+ _kernPtrAligned + off,
+ FALSE);
+
+ pmap_remove(
+ kernel_pmap,
+ _kernPtrAligned + off,
+ _kernPtrAligned + off + page_size);
+ }
+ // Free the former shmem area in the task
+ krtn = vm_deallocate(kernel_map,
+ _kernPtrAligned,
+ _kernSize );
+ assert(krtn == KERN_SUCCESS);
+ _kernPtrAligned = 0;
+}
+
+void IOGeneralMemoryDescriptor::mapIntoKernel(unsigned rangeIndex)
+{
+ kern_return_t krtn;
+ vm_offset_t off;
+
+ if (_kernPtrAligned)
+ {
+ if (_kernPtrAtIndex == rangeIndex) return;
+ unmapFromKernel();
+ assert(_kernPtrAligned == 0);
+ }
+
+ vm_offset_t srcAlign = trunc_page(_ranges.v[rangeIndex].address);
+
+ _kernSize = trunc_page(_ranges.v[rangeIndex].address +
+ _ranges.v[rangeIndex].length +
+ page_size - 1) - srcAlign;
+
+ /* Find some memory of the same size in kernel task. We use vm_allocate()
+ to do this. vm_allocate inserts the found memory object in the
+ target task's map as a side effect. */
+ krtn = vm_allocate( kernel_map,
+ &_kernPtrAligned,
+ _kernSize,
+ VM_FLAGS_ANYWHERE|VM_MAKE_TAG(VM_MEMORY_IOKIT) ); // Find first fit
+ assert(krtn == KERN_SUCCESS);
+ if(krtn) return;
+
+ /* For each page in the area allocated from the kernel map,
+ find the physical address of the page.
+ Enter the page in the target task's pmap, at the
+ appropriate target task virtual address. */
+ for ( off = 0; off < _kernSize; off += page_size )
+ {
+ vm_offset_t kern_phys_addr, phys_addr;
+ if( _task)
+ phys_addr = pmap_extract( get_task_pmap(_task), srcAlign + off );
+ else
+ phys_addr = srcAlign + off;
+ assert(phys_addr);
+ if(phys_addr == 0) return;
+
+ // Check original state.
+ kern_phys_addr = pmap_extract( kernel_pmap, _kernPtrAligned + off );
+ // Set virtual page to point to the right physical one
+ pmap_enter(
+ kernel_pmap,
+ _kernPtrAligned + off,
+ phys_addr,
+ VM_PROT_READ|VM_PROT_WRITE,
+ TRUE);
+ }
+ _kernPtrAtIndex = rangeIndex;
+}
/*
* getDirection:
@@ -535,333 +454,318 @@
return( _tag);
}
-IOPhysicalAddress IOMemoryDescriptor::getSourceSegment( IOByteCount offset,
- IOByteCount * length )
-{
- IOPhysicalAddress physAddr;
-
- prepare();
- physAddr = getPhysicalSegment( offset, length );
- complete();
-
- return( physAddr );
-}
-
-IOByteCount IOMemoryDescriptor::readBytes( IOByteCount offset,
- void * bytes,
- IOByteCount withLength )
-{
- IOByteCount bytesCopied = 0;
-
- assert(offset <= _length);
- assert(offset <= _length - withLength);
-
- if ( offset < _length )
- {
- withLength = min(withLength, _length - offset);
-
- while ( withLength ) // (process another source segment?)
- {
- IOPhysicalAddress sourceSegment;
- IOByteCount sourceSegmentLength;
-
- sourceSegment = getPhysicalSegment(offset, &sourceSegmentLength);
- if ( sourceSegment == 0 ) goto readBytesErr;
-
- sourceSegmentLength = min(sourceSegmentLength, withLength);
-
- while ( sourceSegmentLength ) // (process another target segment?)
- {
- IOPhysicalAddress targetSegment;
- IOByteCount targetSegmentLength;
-
- targetSegment = pmap_extract_safe(kernel_task, (vm_offset_t) bytes);
- if ( targetSegment == 0 ) goto readBytesErr;
-
- targetSegmentLength = min(next_page(targetSegment) - targetSegment, sourceSegmentLength);
-
- if ( sourceSegment + targetSegmentLength > next_page(sourceSegment) )
- {
- IOByteCount pageLength;
-
- pageLength = next_page(sourceSegment) - sourceSegment;
-
- bcopy_phys_safe( /* from */ (char *) sourceSegment,
- /* to */ (char *) targetSegment,
- /* size */ (int ) pageLength );
-
- ((UInt8 *) bytes) += pageLength;
- bytesCopied += pageLength;
- offset += pageLength;
- sourceSegment += pageLength;
- sourceSegmentLength -= pageLength;
- targetSegment += pageLength;
- targetSegmentLength -= pageLength;
- withLength -= pageLength;
- }
-
- bcopy_phys_safe( /* from */ (char *) sourceSegment,
- /* to */ (char *) targetSegment,
- /* size */ (int ) targetSegmentLength );
-
- ((UInt8 *) bytes) += targetSegmentLength;
- bytesCopied += targetSegmentLength;
- offset += targetSegmentLength;
- sourceSegment += targetSegmentLength;
- sourceSegmentLength -= targetSegmentLength;
- withLength -= targetSegmentLength;
- }
- }
- }
-
-readBytesErr:
-
- if ( bytesCopied )
- {
- // We mark the destination pages as modified, just
- // in case they are made pageable later on in life.
-
- pmap_modify_pages( /* pmap */ kernel_pmap,
- /* start */ trunc_page(((vm_offset_t) bytes) - bytesCopied),
- /* end */ round_page(((vm_offset_t) bytes)) );
- }
-
- return bytesCopied;
-}
-
-IOByteCount IOMemoryDescriptor::writeBytes( IOByteCount offset,
- const void * bytes,
- IOByteCount withLength )
-{
- IOByteCount bytesCopied = 0;
-
- assert(offset <= _length);
- assert(offset <= _length - withLength);
-
- if ( offset < _length )
- {
- withLength = min(withLength, _length - offset);
-
- while ( withLength ) // (process another target segment?)
- {
- IOPhysicalAddress targetSegment;
- IOByteCount targetSegmentLength;
-
- targetSegment = getPhysicalSegment(offset, &targetSegmentLength);
- if ( targetSegment == 0 ) goto writeBytesErr;
-
- targetSegmentLength = min(targetSegmentLength, withLength);
-
- while ( targetSegmentLength ) // (process another source segment?)
- {
- IOPhysicalAddress sourceSegment;
- IOByteCount sourceSegmentLength;
-
- sourceSegment = pmap_extract_safe(kernel_task, (vm_offset_t) bytes);
- if ( sourceSegment == 0 ) goto writeBytesErr;
-
- sourceSegmentLength = min(next_page(sourceSegment) - sourceSegment, targetSegmentLength);
-
- if ( targetSegment + sourceSegmentLength > next_page(targetSegment) )
- {
- IOByteCount pageLength;
-
- pageLength = next_page(targetSegment) - targetSegment;
-
- bcopy_phys_safe( /* from */ (char *) sourceSegment,
- /* to */ (char *) targetSegment,
- /* size */ (int ) pageLength );
-
- // We flush the data cache in case it is code we've copied,
- // such that the instruction cache is in the know about it.
-
- flush_dcache(targetSegment, pageLength, true);
-
- ((UInt8 *) bytes) += pageLength;
- bytesCopied += pageLength;
- offset += pageLength;
- sourceSegment += pageLength;
- sourceSegmentLength -= pageLength;
- targetSegment += pageLength;
- targetSegmentLength -= pageLength;
- withLength -= pageLength;
- }
-
- bcopy_phys_safe( /* from */ (char *) sourceSegment,
- /* to */ (char *) targetSegment,
- /* size */ (int ) sourceSegmentLength );
-
- // We flush the data cache in case it is code we've copied,
- // such that the instruction cache is in the know about it.
-
- flush_dcache(targetSegment, sourceSegmentLength, true);
-
- ((UInt8 *) bytes) += sourceSegmentLength;
- bytesCopied += sourceSegmentLength;
- offset += sourceSegmentLength;
- targetSegment += sourceSegmentLength;
- targetSegmentLength -= sourceSegmentLength;
- withLength -= sourceSegmentLength;
- }
- }
- }
-
-writeBytesErr:
-
- return bytesCopied;
-}
-
-/* DEPRECATED */ void IOGeneralMemoryDescriptor::setPosition(IOByteCount position)
-/* DEPRECATED */ {
-/* DEPRECATED */ assert(position <= _length);
-/* DEPRECATED */
-/* DEPRECATED */ if (position >= _length)
-/* DEPRECATED */ {
-/* DEPRECATED */ _position = _length;
-/* DEPRECATED */ _positionAtIndex = _rangesCount; /* careful: out-of-bounds */
-/* DEPRECATED */ _positionAtOffset = 0;
-/* DEPRECATED */ return;
-/* DEPRECATED */ }
-/* DEPRECATED */
-/* DEPRECATED */ if (position < _position)
-/* DEPRECATED */ {
-/* DEPRECATED */ _positionAtOffset = position;
-/* DEPRECATED */ _positionAtIndex = 0;
-/* DEPRECATED */ }
-/* DEPRECATED */ else
-/* DEPRECATED */ {
-/* DEPRECATED */ _positionAtOffset += (position - _position);
-/* DEPRECATED */ }
-/* DEPRECATED */ _position = position;
-/* DEPRECATED */
-/* DEPRECATED */ while (_positionAtOffset >= _ranges.v[_positionAtIndex].length)
-/* DEPRECATED */ {
-/* DEPRECATED */ _positionAtOffset -= _ranges.v[_positionAtIndex].length;
-/* DEPRECATED */ _positionAtIndex++;
-/* DEPRECATED */ }
-/* DEPRECATED */ }
-
-IOPhysicalAddress IOGeneralMemoryDescriptor::getPhysicalSegment( IOByteCount offset,
- IOByteCount * lengthOfSegment )
-{
- IOPhysicalAddress address = 0;
- IOPhysicalLength length = 0;
-
-
-// assert(offset <= _length);
-
- if ( offset < _length ) // (within bounds?)
- {
- unsigned rangesIndex = 0;
-
- for ( ; offset >= _ranges.v[rangesIndex].length; rangesIndex++ )
- {
- offset -= _ranges.v[rangesIndex].length; // (make offset relative)
- }
-
- if ( _task == 0 ) // (physical memory?)
- {
- address = _ranges.v[rangesIndex].address + offset;
- length = _ranges.v[rangesIndex].length - offset;
-
- for ( ++rangesIndex; rangesIndex < _rangesCount; rangesIndex++ )
- {
- if ( address + length != _ranges.v[rangesIndex].address ) break;
-
- length += _ranges.v[rangesIndex].length; // (coalesce ranges)
- }
- }
- else // (virtual memory?)
- {
- vm_address_t addressVirtual = _ranges.v[rangesIndex].address + offset;
-
- assert((0 == (kIOMemoryRequiresWire & _flags)) || _wireCount);
-
- address = pmap_extract_safe(_task, addressVirtual);
- length = next_page(addressVirtual) - addressVirtual;
- length = min(_ranges.v[rangesIndex].length - offset, length);
- }
-
- assert(address);
- if ( address == 0 ) length = 0;
- }
-
- if ( lengthOfSegment ) *lengthOfSegment = length;
-
- return address;
-}
-
-IOPhysicalAddress IOGeneralMemoryDescriptor::getSourceSegment( IOByteCount offset,
- IOByteCount * lengthOfSegment )
-{
- IOPhysicalAddress address = 0;
- IOPhysicalLength length = 0;
-
- assert(offset <= _length);
-
- if ( offset < _length ) // (within bounds?)
- {
- unsigned rangesIndex = 0;
-
- for ( ; offset >= _ranges.v[rangesIndex].length; rangesIndex++ )
- {
- offset -= _ranges.v[rangesIndex].length; // (make offset relative)
- }
-
- address = _ranges.v[rangesIndex].address + offset;
- length = _ranges.v[rangesIndex].length - offset;
-
- for ( ++rangesIndex; rangesIndex < _rangesCount; rangesIndex++ )
- {
- if ( address + length != _ranges.v[rangesIndex].address ) break;
-
- length += _ranges.v[rangesIndex].length; // (coalesce ranges)
- }
-
- assert(address);
- if ( address == 0 ) length = 0;
- }
-
- if ( lengthOfSegment ) *lengthOfSegment = length;
-
- return address;
-}
-
-/* DEPRECATED */ /* USE INSTEAD: map(), readBytes(), writeBytes() */
-/* DEPRECATED */ void * IOGeneralMemoryDescriptor::getVirtualSegment(IOByteCount offset,
-/* DEPRECATED */ IOByteCount * lengthOfSegment)
-/* DEPRECATED */ {
-/* DEPRECATED */ if( offset != _position)
-/* DEPRECATED */ setPosition( offset );
-/* DEPRECATED */
-/* DEPRECATED */ assert(_position <= _length);
-/* DEPRECATED */
-/* DEPRECATED */ /* Fail gracefully if the position is at (or past) the end-of-buffer. */
-/* DEPRECATED */ if (_position >= _length)
-/* DEPRECATED */ {
-/* DEPRECATED */ *lengthOfSegment = 0;
-/* DEPRECATED */ return 0;
-/* DEPRECATED */ }
-/* DEPRECATED */
-/* DEPRECATED */ /* Compute the relative length to the end of this virtual segment. */
-/* DEPRECATED */ *lengthOfSegment = _ranges.v[_positionAtIndex].length - _positionAtOffset;
-/* DEPRECATED */
-/* DEPRECATED */ /* Compute the relative address of this virtual segment. */
-/* DEPRECATED */ if (_task == kernel_task)
-/* DEPRECATED */ return (void *)(_ranges.v[_positionAtIndex].address + _positionAtOffset);
-/* DEPRECATED */ else
-/* DEPRECATED */ {
-/* DEPRECATED */ vm_offset_t off;
-/* DEPRECATED */
-/* DEPRECATED */ mapIntoKernel(_positionAtIndex);
-/* DEPRECATED */
-/* DEPRECATED */ off = _ranges.v[_kernPtrAtIndex].address;
-/* DEPRECATED */ off -= trunc_page(off);
-/* DEPRECATED */
-/* DEPRECATED */ return (void *) (_kernPtrAligned + off + _positionAtOffset);
-/* DEPRECATED */ }
-/* DEPRECATED */ }
-/* DEPRECATED */ /* USE INSTEAD: map(), readBytes(), writeBytes() */
+/*
+ * setPosition
+ *
+ * Set the logical start position inside the client buffer.
+ *
+ * It is convention that the position reflect the actual byte count that
+ * is successfully transferred into or out of the buffer, before the I/O
+ * request is "completed" (ie. sent back to its originator).
+ */
+
+void IOGeneralMemoryDescriptor::setPosition(IOByteCount position)
+{
+ assert(position <= _length);
+
+ if (position >= _length)
+ {
+ _position = _length;
+ _positionAtIndex = _rangesCount; /* careful: out-of-bounds */
+ _positionAtOffset = 0;
+ return;
+ }
+
+ if (position < _position)
+ {
+ _positionAtOffset = position;
+ _positionAtIndex = 0;
+ }
+ else
+ {
+ _positionAtOffset += (position - _position);
+ }
+ _position = position;
+
+ while (_positionAtOffset >= _ranges.v[_positionAtIndex].length)
+ {
+ _positionAtOffset -= _ranges.v[_positionAtIndex].length;
+ _positionAtIndex++;
+ }
+}
+
+/*
+ * readBytes:
+ *
+ * Copy data from the memory descriptor's buffer into the specified buffer,
+ * relative to the current position. The memory descriptor's position is
+ * advanced based on the number of bytes copied.
+ */
+
+IOByteCount IOGeneralMemoryDescriptor::readBytes(IOByteCount offset,
+ void * bytes, IOByteCount withLength)
+{
+ IOByteCount bytesLeft;
+ void * segment;
+ IOByteCount segmentLength;
+
+ if( offset != _position)
+ setPosition( offset );
+
+ withLength = min(withLength, _length - _position);
+ bytesLeft = withLength;
+
+#if 0
+ while (bytesLeft && (_position < _length))
+ {
+ /* Compute the relative length to the end of this virtual segment. */
+ segmentLength = min(_ranges.v[_positionAtIndex].length - _positionAtOffset, bytesLeft);
+
+ /* Compute the relative address of this virtual segment. */
+ segment = (void *)(_ranges.v[_positionAtIndex].address + _positionAtOffset);
+
+ if (KERN_SUCCESS != vm_map_read_user(getMapForTask(_task, segment),
+ /* from */ (vm_offset_t) segment, /* to */ (vm_offset_t) bytes,
+ /* size */ segmentLength))
+ {
+ assert( false );
+ bytesLeft = withLength;
+ break;
+ }
+ bytesLeft -= segmentLength;
+ offset += segmentLength;
+ setPosition(offset);
+ }
+#else
+ while (bytesLeft && (segment = getVirtualSegment(offset, &segmentLength)))
+ {
+ segmentLength = min(segmentLength, bytesLeft);
+ bcopy(/* from */ segment, /* to */ bytes, /* size */ segmentLength);
+ bytesLeft -= segmentLength;
+ offset += segmentLength;
+ bytes = (void *) (((UInt32) bytes) + segmentLength);
+ }
+#endif
+
+ return withLength - bytesLeft;
+}
+
+/*
+ * writeBytes:
+ *
+ * Copy data to the memory descriptor's buffer from the specified buffer,
+ * relative to the current position. The memory descriptor's position is
+ * advanced based on the number of bytes copied.
+ */
+IOByteCount IOGeneralMemoryDescriptor::writeBytes(IOByteCount offset,
+ const void* bytes,IOByteCount withLength)
+{
+ IOByteCount bytesLeft;
+ void * segment;
+ IOByteCount segmentLength;
+
+ if( offset != _position)
+ setPosition( offset );
+
+ withLength = min(withLength, _length - _position);
+ bytesLeft = withLength;
+
+#if 0
+ while (bytesLeft && (_position < _length))
+ {
+ assert(_position <= _length);
+
+ /* Compute the relative length to the end of this virtual segment. */
+ segmentLength = min(_ranges.v[_positionAtIndex].length - _positionAtOffset, bytesLeft);
+
+ /* Compute the relative address of this virtual segment. */
+ segment = (void *)(_ranges.v[_positionAtIndex].address + _positionAtOffset);
+
+ if (KERN_SUCCESS != vm_map_write_user(getMapForTask(_task, segment),
+ /* from */ (vm_offset_t) bytes,
+ /* to */ (vm_offset_t) segment,
+ /* size */ segmentLength))
+ {
+ assert( false );
+ bytesLeft = withLength;
+ break;
+ }
+ bytesLeft -= segmentLength;
+ offset += segmentLength;
+ setPosition(offset);
+ }
+#else
+ while (bytesLeft && (segment = getVirtualSegment(offset, &segmentLength)))
+ {
+ segmentLength = min(segmentLength, bytesLeft);
+ bcopy(/* from */ bytes, /* to */ segment, /* size */ segmentLength);
+ // Flush cache in case we're copying code around, eg. handling a code page fault
+ IOFlushProcessorCache(kernel_task, (vm_offset_t) segment, segmentLength );
+
+ bytesLeft -= segmentLength;
+ offset += segmentLength;
+ bytes = (void *) (((UInt32) bytes) + segmentLength);
+ }
+#endif
+
+ return withLength - bytesLeft;
+}
+
+/*
+ * getPhysicalSegment:
+ *
+ * Get the physical address of the buffer, relative to the current position.
+ * If the current position is at the end of the buffer, a zero is returned.
+ */
+IOPhysicalAddress
+IOGeneralMemoryDescriptor::getPhysicalSegment(IOByteCount offset,
+ IOByteCount * lengthOfSegment)
+{
+ vm_address_t virtualAddress;
+ IOByteCount virtualLength;
+ pmap_t virtualPMap;
+ IOPhysicalAddress physicalAddress;
+ IOPhysicalLength physicalLength;
+
+ if( kIOMemoryRequiresWire & _flags)
+ assert( _wireCount );
+
+ if ((0 == _task) && (1 == _rangesCount))
+ {
+ assert(offset <= _length);
+ if (offset >= _length)
+ {
+ physicalAddress = 0;
+ physicalLength = 0;
+ }
+ else
+ {
+ physicalLength = _length - offset;
+ physicalAddress = offset + _ranges.v[0].address;
+ }
+
+ if (lengthOfSegment)
+ *lengthOfSegment = physicalLength;
+ return physicalAddress;
+ }
+
+ if( offset != _position)
+ setPosition( offset );
+
+ assert(_position <= _length);
+
+ /* Fail gracefully if the position is at (or past) the end-of-buffer. */
+ if (_position >= _length)
+ {
+ *lengthOfSegment = 0;
+ return 0;
+ }
+
+ /* Prepare to compute the largest contiguous physical length possible. */
+
+ virtualAddress = _ranges.v[_positionAtIndex].address + _positionAtOffset;
+ virtualLength = _ranges.v[_positionAtIndex].length - _positionAtOffset;
+ vm_address_t virtualPage = trunc_page(virtualAddress);
+ if( _task)
+ virtualPMap = get_task_pmap(_task);
+ else
+ virtualPMap = 0;
+
+ physicalAddress = (virtualAddress == _cachedVirtualAddress) ?
+ _cachedPhysicalAddress : /* optimization */
+ virtualPMap ?
+ pmap_extract(virtualPMap, virtualAddress) :
+ virtualAddress;
+ physicalLength = trunc_page(physicalAddress) + page_size - physicalAddress;
+
+ if (!physicalAddress && _task)
+ {
+ physicalAddress =
+ vm_map_get_phys_page(get_task_map(_task), virtualPage);
+ physicalAddress += virtualAddress - virtualPage;
+ }
+
+ if (physicalAddress == 0) /* memory must be wired in order to proceed */
+ {
+ assert(physicalAddress);
+ *lengthOfSegment = 0;
+ return 0;
+ }
+
+ /* Compute the largest contiguous physical length possible, within range. */
+ IOPhysicalAddress physicalPage = trunc_page(physicalAddress);
+
+ while (physicalLength < virtualLength)
+ {
+ physicalPage += page_size;
+ virtualPage += page_size;
+ _cachedVirtualAddress = virtualPage;
+ _cachedPhysicalAddress = virtualPMap ?
+ pmap_extract(virtualPMap, virtualPage) :
+ virtualPage;
+ if (!_cachedPhysicalAddress && _task)
+ {
+ _cachedPhysicalAddress =
+ vm_map_get_phys_page(get_task_map(_task), virtualPage);
+ }
+
+ if (_cachedPhysicalAddress != physicalPage) break;
+
+ physicalLength += page_size;
+ }
+
+ /* Clip contiguous physical length at the end of this range. */
+ if (physicalLength > virtualLength)
+ physicalLength = virtualLength;
+
+ if( lengthOfSegment)
+ *lengthOfSegment = physicalLength;
+
+ return physicalAddress;
+}
+
+
+/*
+ * getVirtualSegment:
+ *
+ * Get the virtual address of the buffer, relative to the current position.
+ * If the memory wasn't mapped into the caller's address space, it will be
+ * mapped in now. If the current position is at the end of the buffer, a
+ * null is returned.
+ */
+void * IOGeneralMemoryDescriptor::getVirtualSegment(IOByteCount offset,
+ IOByteCount * lengthOfSegment)
+{
+ if( offset != _position)
+ setPosition( offset );
+
+ assert(_position <= _length);
+
+ /* Fail gracefully if the position is at (or past) the end-of-buffer. */
+ if (_position >= _length)
+ {
+ *lengthOfSegment = 0;
+ return 0;
+ }
+
+ /* Compute the relative length to the end of this virtual segment. */
+ *lengthOfSegment = _ranges.v[_positionAtIndex].length - _positionAtOffset;
+
+ /* Compute the relative address of this virtual segment. */
+ if (_task == kernel_task)
+ return (void *)(_ranges.v[_positionAtIndex].address + _positionAtOffset);
+ else
+ {
+ vm_offset_t off;
+
+ mapIntoKernel(_positionAtIndex);
+
+ off = _ranges.v[_kernPtrAtIndex].address;
+ off -= trunc_page(off);
+
+ return (void *) (_kernPtrAligned + off + _positionAtOffset);
+ }
+}
/*
* prepare
@@ -883,22 +787,7 @@
if(forDirection == kIODirectionNone)
forDirection = _direction;
- vm_prot_t access;
-
- switch (forDirection)
- {
- case kIODirectionIn:
- access = VM_PROT_WRITE;
- break;
-
- case kIODirectionOut:
- access = VM_PROT_READ;
- break;
-
- default:
- access = VM_PROT_READ | VM_PROT_WRITE;
- break;
- }
+ vm_prot_t access = VM_PROT_DEFAULT; // Could be cleverer using direction
//
// Check user read/write access to the data buffer.
@@ -948,6 +837,12 @@
vm_map_t taskVMMap = getMapForTask(_task, srcAlign);
+ rc = vm_map_wire(taskVMMap, srcAlign, srcAlignEnd, access, FALSE);
+ if (KERN_SUCCESS != rc) {
+ IOLog("IOMemoryDescriptor::prepare vm_map_wire failed: %d\n", rc);
+ goto abortExit;
+ }
+
// If this I/O is for a user land task then protect ourselves
// against COW and other vm_shenanigans
if (_task && _task != kernel_task) {
@@ -980,12 +875,6 @@
} while (desiredSize);
}
}
-
- rc = vm_map_wire(taskVMMap, srcAlign, srcAlignEnd, access, FALSE);
- if (KERN_SUCCESS != rc) {
- IOLog("IOMemoryDescriptor::prepare vm_map_wire failed: %d\n", rc);
- goto abortExit;
- }
}
}
_wireCount++;
@@ -1073,6 +962,8 @@
_memoryEntries->release();
_memoryEntries = 0;
}
+
+ _cachedVirtualAddress = 0;
}
return kIOReturnSuccess;
}
@@ -1085,7 +976,6 @@
IOByteCount length = 0 )
{
kern_return_t kr;
- ipc_port_t sharedMem = (ipc_port_t) _memEntry;
// mapping source == dest? (could be much better)
if( _task && (addressMap == get_task_map(_task)) && (options & kIOMapAnywhere)
@@ -1095,73 +985,53 @@
return( kIOReturnSuccess );
}
- if( 0 == sharedMem) {
-
- vm_size_t size = 0;
-
- for (unsigned index = 0; index < _rangesCount; index++)
- size += round_page(_ranges.v[index].address + _ranges.v[index].length)
- - trunc_page(_ranges.v[index].address);
-
- if( _task) {
-#if NOTYET
- vm_object_offset_t actualSize = size;
- kr = mach_make_memory_entry_64( get_task_map(_task),
- &actualSize, _ranges.v[0].address,
- VM_PROT_READ | VM_PROT_WRITE, &sharedMem,
- NULL );
-
- if( (KERN_SUCCESS == kr) && (actualSize != size)) {
-#if IOASSERT
- IOLog("mach_make_memory_entry_64 (%08lx) size (%08lx:%08lx)\n",
- _ranges.v[0].address, (UInt32)actualSize, size);
-#endif
+ if( _task && _memEntry && (_flags & kIOMemoryRequiresWire)) {
+
+ do {
+
+ if( (1 != _rangesCount)
+ || (kIOMapDefaultCache != (options & kIOMapCacheMask)) ) {
+ kr = kIOReturnUnsupported;
+ continue;
+ }
+
+ if( 0 == length)
+ length = getLength();
+ if( (sourceOffset + length) > _ranges.v[0].length) {
+ kr = kIOReturnBadArgument;
+ continue;
+ }
+
+ ipc_port_t sharedMem = (ipc_port_t) _memEntry;
+ vm_prot_t prot = VM_PROT_READ
+ | ((options & kIOMapReadOnly) ? 0 : VM_PROT_WRITE);
+
+ // vm_map looks for addresses above here, even when VM_FLAGS_ANYWHERE
+ if( options & kIOMapAnywhere)
+ *atAddress = 0;
+
+ if( 0 == sharedMem)
kr = kIOReturnVMError;
- ipc_port_release_send( sharedMem );
- }
-
- if( KERN_SUCCESS != kr)
-#endif /* NOTYET */
- sharedMem = MACH_PORT_NULL;
-
- } else do {
-
- memory_object_t pager;
-
- if( !reserved) {
- reserved = IONew( ExpansionData, 1 );
- if( !reserved)
- continue;
- }
- reserved->pagerContig = (1 == _rangesCount);
-
- pager = device_pager_setup( (memory_object_t) 0, (int) this, size,
- reserved->pagerContig ? DEVICE_PAGER_CONTIGUOUS : 0 );
- assert( pager );
-
- if( pager) {
- retain(); // pager has a ref
- kr = mach_memory_object_memory_entry_64( (host_t) 1, false /*internal*/,
- size, VM_PROT_READ | VM_PROT_WRITE, pager, &sharedMem );
-
- assert( KERN_SUCCESS == kr );
- if( KERN_SUCCESS != kr) {
-// chris?
-// ipc_port_release_send( (ipc_port_t) pager );
- pager = MACH_PORT_NULL;
- sharedMem = MACH_PORT_NULL;
- }
- }
- reserved->devicePager = pager;
-
+ else
+ kr = KERN_SUCCESS;
+
+ if( KERN_SUCCESS == kr)
+ kr = vm_map( addressMap,
+ atAddress,
+ length, 0 /* mask */,
+ (( options & kIOMapAnywhere ) ? VM_FLAGS_ANYWHERE : VM_FLAGS_FIXED)
+ | VM_MAKE_TAG(VM_MEMORY_IOKIT),
+ sharedMem, sourceOffset,
+ false, // copy
+ prot, // cur
+ prot, // max
+ VM_INHERIT_NONE);
+
} while( false );
- _memEntry = (void *) sharedMem;
- }
-
- kr = super::doMap( addressMap, atAddress,
+ } else
+ kr = super::doMap( addressMap, atAddress,
options, sourceOffset, length );
-
return( kr );
}
@@ -1185,7 +1055,6 @@
// osfmk/device/iokit_rpc.c
extern kern_return_t IOMapPages( vm_map_t map, vm_offset_t va, vm_offset_t pa,
vm_size_t length, unsigned int mapFlags);
-extern kern_return_t IOUnmapPages(vm_map_t map, vm_offset_t va, vm_size_t length);
};
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -1253,9 +1122,6 @@
IOOptionBits options,
IOByteCount offset,
IOByteCount length );
-
- IOReturn redirect(
- task_t intoTask, bool redirect );
};
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -1338,68 +1204,11 @@
options, offset, length ));
if( !ok) {
logical = 0;
- memory->release();
- memory = 0;
+ _memory->release();
vm_map_deallocate(addressMap);
addressMap = 0;
}
return( ok );
-}
-
-struct IOMemoryDescriptorMapAllocRef
-{
- ipc_port_t sharedMem;
- vm_size_t size;
- vm_offset_t mapped;
- IOByteCount sourceOffset;
- IOOptionBits options;
-};
-
-static kern_return_t IOMemoryDescriptorMapAlloc(vm_map_t map, void * _ref)
-{
- IOMemoryDescriptorMapAllocRef * ref = (IOMemoryDescriptorMapAllocRef *)_ref;
- IOReturn err;
-
- do {
- if( ref->sharedMem) {
- vm_prot_t prot = VM_PROT_READ
- | ((ref->options & kIOMapReadOnly) ? 0 : VM_PROT_WRITE);
-
- err = vm_map( map,
- &ref->mapped,
- ref->size, 0 /* mask */,
- (( ref->options & kIOMapAnywhere ) ? VM_FLAGS_ANYWHERE : VM_FLAGS_FIXED)
- | VM_MAKE_TAG(VM_MEMORY_IOKIT),
- ref->sharedMem, ref->sourceOffset,
- false, // copy
- prot, // cur
- prot, // max
- VM_INHERIT_NONE);
-
- if( KERN_SUCCESS != err) {
- ref->mapped = 0;
- continue;
- }
-
- } else {
-
- err = vm_allocate( map, &ref->mapped, ref->size,
- ((ref->options & kIOMapAnywhere) ? VM_FLAGS_ANYWHERE : VM_FLAGS_FIXED)
- | VM_MAKE_TAG(VM_MEMORY_IOKIT) );
-
- if( KERN_SUCCESS != err) {
- ref->mapped = 0;
- continue;
- }
-
- // we have to make sure that these guys don't get copied if we fork.
- err = vm_inherit( map, ref->mapped, ref->size, VM_INHERIT_NONE);
- assert( KERN_SUCCESS == err );
- }
-
- } while( false );
-
- return( err );
}
IOReturn IOMemoryDescriptor::doMap(
@@ -1410,117 +1219,55 @@
IOByteCount length = 0 )
{
IOReturn err = kIOReturnSuccess;
- memory_object_t pager;
+ vm_size_t ourSize;
+ vm_size_t bytes;
+ vm_offset_t mapped;
vm_address_t logical;
- IOByteCount pageOffset;
- IOPhysicalAddress sourceAddr;
- IOMemoryDescriptorMapAllocRef ref;
-
- ref.sharedMem = (ipc_port_t) _memEntry;
- ref.sourceOffset = sourceOffset;
- ref.options = options;
-
- do {
-
- if( 0 == length)
- length = getLength();
-
- sourceAddr = getSourceSegment( sourceOffset, NULL );
- assert( sourceAddr );
- pageOffset = sourceAddr - trunc_page( sourceAddr );
-
- ref.size = round_page( length + pageOffset );
-
- logical = *atAddress;
- if( options & kIOMapAnywhere)
- // vm_map looks for addresses above here, even when VM_FLAGS_ANYWHERE
- ref.mapped = 0;
- else {
- ref.mapped = trunc_page( logical );
- if( (logical - ref.mapped) != pageOffset) {
- err = kIOReturnVMError;
- continue;
- }
- }
-
- if( ref.sharedMem && (addressMap == kernel_map) && (kIOMemoryRequiresWire & _flags))
- err = IOIteratePageableMaps( ref.size, &IOMemoryDescriptorMapAlloc, &ref );
- else
- err = IOMemoryDescriptorMapAlloc( addressMap, &ref );
-
- if( err != KERN_SUCCESS)
- continue;
-
- if( reserved)
- pager = (memory_object_t) reserved->devicePager;
- else
- pager = MACH_PORT_NULL;
-
- if( !ref.sharedMem || pager )
- err = handleFault( pager, addressMap, ref.mapped, sourceOffset, length, options );
-
- } while( false );
-
- if( err != KERN_SUCCESS) {
- if( ref.mapped)
- doUnmap( addressMap, ref.mapped, ref.size );
- *atAddress = NULL;
- } else
- *atAddress = ref.mapped + pageOffset;
-
- return( err );
-}
-
-enum {
- kIOMemoryRedirected = 0x00010000
-};
-
-IOReturn IOMemoryDescriptor::handleFault(
- void * _pager,
- vm_map_t addressMap,
- IOVirtualAddress address,
- IOByteCount sourceOffset,
- IOByteCount length,
- IOOptionBits options )
-{
- IOReturn err = kIOReturnSuccess;
- memory_object_t pager = (memory_object_t) _pager;
- vm_size_t size;
- vm_size_t bytes;
- vm_size_t page;
IOByteCount pageOffset;
IOPhysicalLength segLen;
IOPhysicalAddress physAddr;
- if( !addressMap) {
-
- LOCK;
-
- if( kIOMemoryRedirected & _flags) {
-#ifdef DEBUG
- IOLog("sleep mem redirect %x, %lx\n", address, sourceOffset);
-#endif
- do {
- assert_wait( (event_t) this, THREAD_UNINT );
- UNLOCK;
- thread_block((void (*)(void)) 0);
- LOCK;
- } while( kIOMemoryRedirected & _flags );
- }
-
- UNLOCK;
- return( kIOReturnSuccess );
- }
+ if( 0 == length)
+ length = getLength();
physAddr = getPhysicalSegment( sourceOffset, &segLen );
assert( physAddr );
+
pageOffset = physAddr - trunc_page( physAddr );
-
- size = length + pageOffset;
+ ourSize = length + pageOffset;
physAddr -= pageOffset;
+ logical = *atAddress;
+ if( 0 == (options & kIOMapAnywhere)) {
+ mapped = trunc_page( logical );
+ if( (logical - mapped) != pageOffset)
+ err = kIOReturnVMError;
+ }
+ if( kIOReturnSuccess == err)
+ err = vm_allocate( addressMap, &mapped, ourSize,
+ ((options & kIOMapAnywhere) ? VM_FLAGS_ANYWHERE : VM_FLAGS_FIXED)
+ | VM_MAKE_TAG(VM_MEMORY_IOKIT) );
+
+ if( err) {
+#ifdef DEBUG
+ kprintf("IOMemoryDescriptor::doMap: vm_allocate() "
+ "returned %08x\n", err);
+#endif
+ return( err);
+ }
+
+ // we have to make sure that these guys don't get copied if we fork.
+ err = vm_inherit( addressMap, mapped, ourSize, VM_INHERIT_NONE);
+ if( err != KERN_SUCCESS) {
+ doUnmap( addressMap, mapped, ourSize); // back out
+ return( err);
+ }
+
+ logical = mapped;
+ *atAddress = mapped + pageOffset;
+
segLen += pageOffset;
- bytes = size;
+ bytes = ourSize;
do {
// in the middle of the loop only map whole pages
if( segLen >= bytes)
@@ -1532,41 +1279,18 @@
#ifdef DEBUG
if( kIOLogMapping & gIOKitDebug)
- IOLog("_IOMemoryMap::map(%p) %08lx->%08lx:%08lx\n",
- addressMap, address + pageOffset, physAddr + pageOffset,
+ kprintf("_IOMemoryMap::map(%x) %08x->%08x:%08x\n",
+ addressMap, mapped + pageOffset, physAddr + pageOffset,
segLen - pageOffset);
#endif
- if( addressMap && (kIOReturnSuccess == err))
- err = IOMapPages( addressMap, address, physAddr, segLen, options );
- assert( KERN_SUCCESS == err );
+ if( kIOReturnSuccess == err)
+ err = IOMapPages( addressMap, mapped, physAddr, segLen, options );
if( err)
break;
- if( pager) {
- if( reserved && reserved->pagerContig) {
- IOPhysicalLength allLen;
- IOPhysicalAddress allPhys;
-
- allPhys = getPhysicalSegment( 0, &allLen );
- assert( allPhys );
- err = device_pager_populate_object( pager, 0, trunc_page(allPhys), round_page(allPhys + allLen) );
-
- } else {
-
- for( page = 0;
- (page < segLen) && (KERN_SUCCESS == err);
- page += page_size) {
- err = device_pager_populate_object( pager, sourceOffset + page,
- physAddr + page, page_size );
- }
- }
- assert( KERN_SUCCESS == err );
- if( err)
- break;
- }
sourceOffset += segLen - pageOffset;
- address += segLen;
+ mapped += segLen;
bytes -= segLen;
pageOffset = 0;
@@ -1575,6 +1299,10 @@
if( bytes)
err = kIOReturnBadArgument;
+ if( err)
+ doUnmap( addressMap, logical, ourSize );
+ else
+ mapped = true;
return( err );
}
@@ -1592,87 +1320,10 @@
addressMap, logical, length );
#endif
- if( (addressMap == kernel_map) || (addressMap == get_task_map(current_task()))) {
-
- if( _memEntry && (addressMap == kernel_map) && (kIOMemoryRequiresWire & _flags))
- addressMap = IOPageableMapForAddress( logical );
-
+ if( (addressMap == kernel_map) || (addressMap == get_task_map(current_task())))
err = vm_deallocate( addressMap, logical, length );
-
- } else
- err = kIOReturnSuccess;
-
- return( err );
-}
-
-IOReturn IOMemoryDescriptor::redirect( task_t safeTask, bool redirect )
-{
- IOReturn err;
- _IOMemoryMap * mapping = 0;
- OSIterator * iter;
-
- LOCK;
-
- do {
- if( (iter = OSCollectionIterator::withCollection( _mappings))) {
- while( (mapping = (_IOMemoryMap *) iter->getNextObject()))
- mapping->redirect( safeTask, redirect );
-
- iter->release();
- }
- } while( false );
-
- if( redirect)
- _flags |= kIOMemoryRedirected;
- else {
- _flags &= ~kIOMemoryRedirected;
- thread_wakeup( (event_t) this);
- }
-
- UNLOCK;
-
- // temporary binary compatibility
- IOSubMemoryDescriptor * subMem;
- if( (subMem = OSDynamicCast( IOSubMemoryDescriptor, this)))
- err = subMem->redirect( safeTask, redirect );
else
err = kIOReturnSuccess;
-
- return( err );
-}
-
-IOReturn IOSubMemoryDescriptor::redirect( task_t safeTask, bool redirect )
-{
- return( _parent->redirect( safeTask, redirect ));
-}
-
-IOReturn _IOMemoryMap::redirect( task_t safeTask, bool redirect )
-{
- IOReturn err = kIOReturnSuccess;
-
- if( superMap) {
-// err = ((_IOMemoryMap *)superMap)->redirect( safeTask, redirect );
- } else {
-
- LOCK;
- if( logical && addressMap
- && (get_task_map( safeTask) != addressMap)
- && (0 == (options & kIOMapStatic))) {
-
- IOUnmapPages( addressMap, logical, length );
- if( !redirect) {
- err = vm_deallocate( addressMap, logical, length );
- err = memory->doMap( addressMap, &logical,
- (options & ~kIOMapAnywhere) /*| kIOMapReserve*/,
- offset, length );
- } else
- err = kIOReturnSuccess;
-#ifdef DEBUG
- IOLog("IOMemoryMap::redirect(%d, %x) %x from %p\n", redirect, err, logical, addressMap);
-#endif
- }
- UNLOCK;
- }
return( err );
}
@@ -1828,9 +1479,6 @@
{
if( _mappings)
_mappings->release();
-
- if( reserved)
- IODelete( reserved, ExpansionData, 1 );
super::free();
}
@@ -2021,28 +1669,6 @@
return( address );
}
-IOPhysicalAddress IOSubMemoryDescriptor::getSourceSegment( IOByteCount offset,
- IOByteCount * length )
-{
- IOPhysicalAddress address;
- IOByteCount actualLength;
-
- assert(offset <= _length);
-
- if( length)
- *length = 0;
-
- if( offset >= _length)
- return( 0 );
-
- address = _parent->getSourceSegment( offset + _start, &actualLength );
-
- if( address && length)
- *length = min( _length - offset, actualLength );
-
- return( address );
-}
-
void * IOSubMemoryDescriptor::getVirtualSegment(IOByteCount offset,
IOByteCount * lengthOfSegment)
{
@@ -2126,12 +1752,6 @@
_start + offset, length );
if( !mapping)
- mapping = (IOMemoryMap *) _parent->makeMapping(
- _parent, intoTask,
- toAddress,
- options, _start + offset, length );
-
- if( !mapping)
mapping = super::makeMapping( owner, intoTask, toAddress, options,
offset, length );
@@ -2188,7 +1808,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-OSMetaClassDefineReservedUsed(IOMemoryDescriptor, 0);
+OSMetaClassDefineReservedUnused(IOMemoryDescriptor, 0);
OSMetaClassDefineReservedUnused(IOMemoryDescriptor, 1);
OSMetaClassDefineReservedUnused(IOMemoryDescriptor, 2);
OSMetaClassDefineReservedUnused(IOMemoryDescriptor, 3);