- IOLockUnlock(gIODTResolversLock);
- }
-
- if (!compare && (addressCells == childAddressCells)) {
- compare = DefaultCompare;
- }
- if (!compare) {
- 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));
-
- rangeLen = CellsValue(childSizeCells, range + childAddressCells + addressCells);
- AddLengthToCells(childAddressCells, endCell, rangeLen);
-
- diff2 = (*compare)( childAddressCells, cell, endCell );
-
- // if start of cell < start of range, or end of range >= start of cell, skip
- if ((diff < 0) || (diff2 >= 0))
- continue;
-
- len = CellsValue(childSizeCells, cell + childAddressCells);
- ok = (0 == len);
-
- if (!ok)
- {
- // search for cell end
- bcopy(cell, endCell, childAddressCells * sizeof(UInt32));
-
- AddLengthToCells(childAddressCells, endCell, len - 1);
-
- for( lookRange = startRange;
- lookRange < endRanges;
- lookRange += (childCells + addressCells) )
- {
- // make sure end of cell >= range start
- endDiff = (*compare)( childAddressCells, endCell, lookRange );
- if( endDiff < 0)
- continue;
-
- UInt64 rangeStart = CellsValue(addressCells, range + childAddressCells);
- UInt64 lookRangeStart = CellsValue(addressCells, lookRange + childAddressCells);
- if ((endDiff - len + 1 + lookRangeStart) == (diff + rangeStart))
- {
- 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 */
-
- if (regEntry != startEntry) regEntry->release();
- regEntry = parent;
- childSizeCells = sizeCells;
- childAddressCells = addressCells;
- childCells = childAddressCells + childSizeCells;
- }
- while( ok && regEntry);
-
- return( ok);
+
+ parent = regEntry->copyParentEntry( gIODTPlane );
+ IODTGetCellCounts( parent, &sizeCells, &addressCells );
+
+ if ((propLen = prop->getLength())) {
+ // search
+ startRange = (UInt32 *) prop->getBytesNoCopy();
+ range = startRange;
+ endRanges = range + (propLen / sizeof(UInt32));
+
+ compare = NULL;
+ num = OSDynamicCast(OSNumber, regEntry->getProperty(gIODTPersistKey));
+ if (num) {
+ IOLockLock(gIODTResolversLock);
+ index = num->unsigned32BitValue();
+ count = gIODTResolvers->getLength() / sizeof(IODTPersistent);
+ if (index < count) {
+ persist = ((IODTPersistent *) gIODTResolvers->getBytesNoCopy()) + index;
+ compare = persist->compareFunc;
+ }
+ IOLockUnlock(gIODTResolversLock);
+ }
+
+ if (!compare && (addressCells == childAddressCells)) {
+ compare = DefaultCompare;
+ }
+ if (!compare) {
+ 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));
+
+ rangeLen = CellsValue(childSizeCells, range + childAddressCells + addressCells);
+ AddLengthToCells(childAddressCells, endCell, rangeLen);
+
+ diff2 = (*compare)( childAddressCells, cell, endCell );
+
+ // if start of cell < start of range, or end of range >= start of cell, skip
+ if ((diff < 0) || (diff2 >= 0)) {
+ continue;
+ }
+
+ len = CellsValue(childSizeCells, cell + childAddressCells);
+ ok = (0 == len);
+
+ if (!ok) {
+ // search for cell end
+ bcopy(cell, endCell, childAddressCells * sizeof(UInt32));
+
+ AddLengthToCells(childAddressCells, endCell, len - 1);
+
+ for (lookRange = startRange;
+ lookRange < endRanges;
+ lookRange += (childCells + addressCells)) {
+ // make sure end of cell >= range start
+ endDiff = (*compare)( childAddressCells, endCell, lookRange );
+ if (endDiff < 0) {
+ continue;
+ }
+
+ UInt64 rangeStart = CellsValue(addressCells, range + childAddressCells);
+ UInt64 lookRangeStart = CellsValue(addressCells, lookRange + childAddressCells);
+ if ((endDiff - len + 1 + lookRangeStart) == (diff + rangeStart)) {
+ 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 */
+
+ if (regEntry != startEntry) {
+ regEntry->release();
+ }
+ regEntry = parent;
+ childSizeCells = sizeCells;
+ childAddressCells = addressCells;
+ childCells = childAddressCells + childSizeCells;
+ }while (ok && regEntry);
+
+ return ok;