+ diff2 = (*compare)( childAddressCells, cell, endCell );
+
+ if ((diff < 0) || (diff2 >= 0))
+ continue;
+
+ ok = (0 == cell[childCells - 1]);
+ if (!ok)
+ {
+ // search for cell end
+ bcopy(cell, endCell, childAddressCells * sizeof(UInt32));
+
+ if (childSizeCells == 2) {
+ uint64_t sum;
+ sum = endCell[childAddressCells - 2] + IOPhysical32(cell[childCells - 1], cell[childCells - 2]) - 1;
+ endCell[childAddressCells - 2] = (uint32_t)(sum & 0x00000000FFFFFFFFULL);
+ if (sum > UINT32_MAX) {
+ endCell[childAddressCells - 1] += (uint32_t)((sum & 0xFFFFFFFF00000000ULL) >> 32);
+ }
+ } else {
+ endCell[childAddressCells - 1] += cell[childCells - 1] - 1;
+ }
+ lookRange = startRange;
+ for( ;
+ lookRange < endRanges;
+ lookRange += (childCells + addressCells) )
+ {
+ // is cell >= range start?
+ endDiff = (*compare)( childAddressCells, endCell, lookRange );
+ if( endDiff < 0)
+ continue;
+ if ((endDiff - cell[childCells - 1] + 1 + lookRange[childAddressCells + addressCells - 1])
+ == (diff + range[childAddressCells + addressCells - 1]))
+ {
+ ok = true;
+ break;
+ }
+ }
+ if (!ok)
+ continue;
+ }
+ offset += diff;
+ break;
+ }
+
+ if (addressCells + sizeCells > sizeof(cell)/sizeof(cell[0]))
+ panic("IODTResolveAddressCell: Invalid device tree (%u, %u)", (uint32_t)addressCells, (uint32_t)sizeCells);
+
+ // Get the physical start of the range from our parent
+ bcopy( range + childAddressCells, cell, sizeof(UInt32) * addressCells );
+ bzero( cell + addressCells, sizeof(UInt32) * sizeCells );
+
+ } /* else zero length range => pass thru to parent */