+
+ for (srcoffset = 0; srcoffset < bsize; srcoffset = ((srcoffset << 1) + 0x40c))
+ {
+ for (srcsize = 4; srcsize < (bsize - srcoffset - 1); srcsize = ((srcsize << 1) + 0x3fc))
+ {
+ IOAddressRange ranges[3];
+ uint32_t rangeCount = 1;
+
+ bzero(&ranges[0], sizeof(ranges));
+ ranges[0].address = data[0] + srcoffset;
+ ranges[0].length = srcsize;
+
+ if (srcsize > 5*page_size)
+ {
+ ranges[0].length = 7634;
+ ranges[1].length = 9870;
+ ranges[2].length = srcsize - ranges[0].length - ranges[1].length;
+ ranges[1].address = ranges[0].address + ranges[0].length;
+ ranges[2].address = ranges[1].address + ranges[1].length;
+ rangeCount = 3;
+ }
+ else if ((srcsize > 2*page_size) && !(page_mask & srcoffset))
+ {
+ ranges[0].length = 4096;
+ ranges[1].length = 4096;
+ ranges[2].length = srcsize - ranges[0].length - ranges[1].length;
+ ranges[0].address = data[0] + srcoffset + 4096;
+ ranges[1].address = data[0] + srcoffset;
+ ranges[2].address = ranges[0].address + ranges[0].length;
+ rangeCount = 3;
+ }
+
+ md = OSDynamicCast(IOGeneralMemoryDescriptor,
+ IOMemoryDescriptor::withAddressRanges(&ranges[0], rangeCount, kIODirectionInOut, kernel_task));
+ assert(md);
+
+ kprintf("IOMemoryReferenceCreate [0x%lx @ 0x%lx]\n[0x%llx, 0x%llx],\n[0x%llx, 0x%llx],\n[0x%llx, 0x%llx]\n",
+ (long) srcsize, (long) srcoffset,
+ (long long) ranges[0].address - data[0], (long long) ranges[0].length,
+ (long long) ranges[1].address - data[0], (long long) ranges[1].length,
+ (long long) ranges[2].address - data[0], (long long) ranges[2].length);
+
+ if (kIOReturnSuccess == kr)
+ {
+ for (mapoffset = 0; mapoffset < srcsize; mapoffset = ((mapoffset << 1) + 0xf00))
+ {
+ for (size = 4; size < (srcsize - mapoffset - 1); size = ((size << 1) + 0x20))
+ {
+ IOMemoryMap * map;
+ mach_vm_address_t addr = 0;
+ uint32_t data;
+
+ kprintf("<mapRef [0x%lx @ 0x%lx]\n", (long) size, (long) mapoffset);
+
+ map = md->createMappingInTask(kernel_task, 0, kIOMapAnywhere, mapoffset, size);
+ if (map) addr = map->getAddress();
+ else kr = kIOReturnError;
+
+ kprintf(">mapRef 0x%x %llx\n", kr, addr);
+
+ if (kIOReturnSuccess != kr) break;
+ kr = md->prepare();
+ if (kIOReturnSuccess != kr)
+ {
+ kprintf("prepare() fail 0x%x\n", kr);
+ break;
+ }
+ for (idx = 0; idx < size; idx += sizeof(uint32_t))
+ {
+ offidx = (idx + mapoffset + srcoffset);
+ if ((srcsize <= 5*page_size) && (srcsize > 2*page_size) && !(page_mask & srcoffset))
+ {
+ if (offidx < 8192) offidx ^= 0x1000;
+ }
+ offidx /= sizeof(uint32_t);
+
+ if (offidx != ((uint32_t*)addr)[idx/sizeof(uint32_t)])
+ {
+ kprintf("vm mismatch @ 0x%x, 0x%lx, 0x%lx, \n", idx, (long) srcoffset, (long) mapoffset);
+ kr = kIOReturnBadMedia;
+ }
+ else
+ {
+ if (sizeof(data) != md->readBytes(mapoffset + idx, &data, sizeof(data))) data = 0;
+ if (offidx != data)
+ {
+ kprintf("phys mismatch @ 0x%x, 0x%lx, 0x%lx, \n", idx, (long) srcoffset, (long) mapoffset);
+ kr = kIOReturnBadMedia;
+ }
+ }
+ }
+ md->complete();
+ map->release();
+ kprintf("unmapRef %llx\n", addr);
+ }
+ if (kIOReturnSuccess != kr) break;
+ }
+ }
+ if (kIOReturnSuccess != kr) break;
+ }
+ if (kIOReturnSuccess != kr) break;