- // Iterate over the vector of virtual ranges
- Ranges vec = _ranges;
- unsigned int pageIndex = 0;
- IOByteCount mdOffset = 0;
- ppnum_t highestPage = 0;
-
- IOMemoryEntry * memRefEntry = 0;
- if (_memRef) memRefEntry = &_memRef->entries[0];
-
- for (UInt range = 0; range < _rangesCount; range++) {
- ioPLBlock iopl;
- mach_vm_address_t startPage;
- mach_vm_size_t numBytes;
- ppnum_t highPage = 0;
-
- // Get the startPage address and length of vec[range]
- getAddrLenForInd(startPage, numBytes, type, vec, range);
- iopl.fPageOffset = startPage & PAGE_MASK;
- numBytes += iopl.fPageOffset;
- startPage = trunc_page_64(startPage);
-
- if (mapper)
- iopl.fMappedPage = mapBase + pageIndex;
- else
- iopl.fMappedPage = 0;
-
- // Iterate over the current range, creating UPLs
- while (numBytes) {
- vm_address_t kernelStart = (vm_address_t) startPage;
- vm_map_t theMap;
- if (curMap) theMap = curMap;
- else if (_memRef)
- {
- theMap = NULL;
- }
- else
- {
- assert(_task == kernel_task);
- theMap = IOPageableMapForAddress(kernelStart);
- }
-
- // ioplFlags is an in/out parameter
- upl_control_flags_t ioplFlags = uplFlags;
- dataP = getDataP(_memoryEntries);
- pageInfo = getPageList(dataP);
- upl_page_list_ptr_t baseInfo = &pageInfo[pageIndex];
-
- upl_size_t ioplSize = round_page(numBytes);
- unsigned int numPageInfo = atop_32(ioplSize);
-
- if ((theMap == kernel_map)
- && (kernelStart >= io_kernel_static_start)
- && (kernelStart < io_kernel_static_end)) {
- error = io_get_kernel_static_upl(theMap,
- kernelStart,
- &ioplSize,
- &iopl.fIOPL,
- baseInfo,
- &numPageInfo,
- &highPage);
- }
- else if (_memRef) {
- memory_object_offset_t entryOffset;
-
- entryOffset = mdOffset;
- entryOffset = (entryOffset - iopl.fPageOffset - memRefEntry->offset);
- if (entryOffset >= memRefEntry->size) {
- memRefEntry++;
- if (memRefEntry >= &_memRef->entries[_memRef->count]) panic("memRefEntry");
- entryOffset = 0;
- }
- if (ioplSize > (memRefEntry->size - entryOffset)) ioplSize = (memRefEntry->size - entryOffset);
- error = memory_object_iopl_request(memRefEntry->entry,
- entryOffset,
- &ioplSize,
- &iopl.fIOPL,
- baseInfo,
- &numPageInfo,
- &ioplFlags);
- }
- else {
- assert(theMap);
- error = vm_map_create_upl(theMap,
- startPage,
- (upl_size_t*)&ioplSize,
- &iopl.fIOPL,
- baseInfo,
- &numPageInfo,
- &ioplFlags);
- }