- do {
- prop = OSDynamicCast( OSData, regEntry->getProperty( gIODTRangeKey ));
- if( 0 == prop) {
- /* end of the road */
- *phys = IOPhysical32( 0, cell[ childAddressCells - 1 ] + offset);
- break;
- }
-
- parent = regEntry->getParentEntry( gIODTPlane );
- IODTGetCellCounts( parent, &sizeCells, &addressCells );
+ do
+ {
+ prop = OSDynamicCast( OSData, regEntry->getProperty( gIODTRangeKey ));
+ if( 0 == prop) {
+ /* end of the road */
+ if (childAddressCells == 2) {
+ *phys = IOPhysical32( cell[ childAddressCells - 1 ], cell [ childAddressCells - 2 ]);
+ } else {
+ *phys = IOPhysical32( 0, cell[ childAddressCells - 1 ]);
+ }
+ *phys += offset;
+ break;
+ }
+
+ parent = regEntry->getParentEntry( gIODTPlane );
+ IODTGetCellCounts( parent, &sizeCells, &addressCells );
+
+ if( (length = prop->getLength())) {
+ // search
+ startRange = (UInt32 *) prop->getBytesNoCopy();
+ range = startRange;
+ endRanges = range + (length / sizeof(UInt32));
+
+ prop = (OSData *) regEntry->getProperty( gIODTPersistKey );
+ if( prop) {
+ persist = (IODTPersistent *) prop->getBytesNoCopy();
+ compare = persist->compareFunc;
+ } else if (addressCells == childAddressCells) {
+ compare = DefaultCompare;
+ } else {
+ panic("There is no mixed comparison function yet...");
+ }
+
+ for( ok = false;
+ range < endRanges;
+ range += (childCells + addressCells) ) {
+
+ // is cell start within range?
+ diff = (*compare)( childAddressCells, cell, range );
+
+ if (childAddressCells > sizeof(endCell)/sizeof(endCell[0]))
+ panic("IODTResolveAddressCell: Invalid device tree (%u)", (uint32_t)childAddressCells);
+
+ bcopy(range, endCell, childAddressCells * sizeof(UInt32));
+
+ if (childAddressCells == 2) {
+ uint64_t sum = endCell[childAddressCells - 2] + IOPhysical32(range[childCells + addressCells - 1], range[childCells + addressCells - 2]);
+ endCell[childAddressCells - 2] = (uint32_t)(sum & 0x00000000FFFFFFFFULL);
+ if (sum > UINT32_MAX) {
+ endCell[childAddressCells - 1] += (uint32_t)((sum & 0xFFFFFFFF00000000ULL) >> 32);
+ }
+ } else {
+ endCell[childAddressCells - 1] += range[childCells + addressCells - 1];
+ }