#include <pexpert/device_tree.h>
+#include <machine/machine_routines.h>
+
extern "C" {
- #include <machine/machine_routines.h>
- void DTInit( void * data );
- int IODTGetLoaderInfo( char *key, void **infoAddr, int *infosize );
- void IODTFreeLoaderInfo( char *key, void *infoAddr, int infoSize );
+int IODTGetLoaderInfo( const char *key, void **infoAddr, int *infosize );
+void IODTFreeLoaderInfo( const char *key, void *infoAddr, int infoSize );
+int IODTGetDefault(const char *key, void *infoAddr, unsigned int infoSize );
+
}
#include <IOKit/assert.h>
if( !intMap && child->getProperty( gIODTInterruptParentKey))
intMap = true;
-#if __ppc__
- OSObject * obj;
-
- // Look for a "driver,AAPL,MacOSX,PowerPC" property.
- if( (obj = child->getProperty( "driver,AAPL,MacOSX,PowerPC"))) {
- gIOCatalogue->addExtensionsFromArchive((OSData *)obj);
- child->removeProperty( "driver,AAPL,MacOSX,PowerPC");
- }
-
- // some gross pruning
- child->removeProperty( "lanLib,AAPL,MacOS,PowerPC");
-
- if( (obj = child->getProperty( "driver,AAPL,MacOS,PowerPC"))) {
-
- if( (0 == (prop = (OSData *)child->getProperty( gIODTTypeKey )))
- || (strncmp("display", (char *)prop->getBytesNoCopy(), sizeof("display"))) ) {
- child->removeProperty( "driver,AAPL,MacOS,PowerPC");
- }
- }
-#endif /* __ppc__ */
}
regIter->release();
}
return( parent);
}
-int IODTGetLoaderInfo( char *key, void **infoAddr, int *infoSize )
+int IODTGetLoaderInfo( const char *key, void **infoAddr, int *infoSize )
{
IORegistryEntry *chosen;
OSData *propObj;
return 0;
}
-void IODTFreeLoaderInfo( char *key, void *infoAddr, int infoSize )
+void IODTFreeLoaderInfo( const char *key, void *infoAddr, int infoSize )
{
vm_offset_t range[2];
IORegistryEntry *chosen;
}
}
+int IODTGetDefault(const char *key, void *infoAddr, unsigned int infoSize )
+{
+ IORegistryEntry *defaults;
+ OSData *defaultObj;
+ unsigned int defaultSize;
+
+ defaults = IORegistryEntry::fromPath( "/defaults", gIODTPlane );
+ if ( defaults == 0 ) return -1;
+
+ defaultObj = OSDynamicCast( OSData, defaults->getProperty(key) );
+ if ( defaultObj == 0 ) return -1;
+
+ defaultSize = defaultObj->getLength();
+ if ( defaultSize > infoSize) return -1;
+
+ memcpy( infoAddr, defaultObj->getBytesNoCopy(), defaultSize );
+
+ return 0;
+}
+
static void FreePhysicalMemory( vm_offset_t * range )
{
vm_offset_t virt;
if( !prop)
return;
+ prop->setSerializable(false);
regEntry->setProperty( gIODTPersistKey, prop);
prop->release();
return;
static SInt32 DefaultCompare( UInt32 cellCount, UInt32 left[], UInt32 right[] )
{
- cellCount--;
- return( left[ cellCount ] - right[ cellCount ] );
+ cellCount--;
+ return( left[ cellCount ] - right[ cellCount ] );
}
void IODTGetCellCounts( IORegistryEntry * regEntry,
// cells in addresses below regEntry
UInt32 childSizeCells, childAddressCells;
UInt32 childCells;
- UInt32 cell[ 5 ], offset = 0, length;
- UInt32 endCell[ 5 ];
+ UInt32 cell[ 8 ], length;
+ UInt64 offset = 0;
+ UInt32 endCell[ 8 ];
UInt32 *range;
UInt32 *lookRange;
UInt32 *startRange;
UInt32 *endRanges;
bool ok = true;
- SInt32 diff, diff2, endDiff;
+ SInt64 diff, diff2, endDiff;
IODTPersistent *persist;
IODTCompareAddressCellFunc compare;
IODTGetCellCounts( regEntry, &childSizeCells, &childAddressCells );
childCells = childAddressCells + childSizeCells;
+ if (childCells > sizeof(cell)/sizeof(cell[0]))
+ panic("IODTResolveAddressCell: Invalid device tree (%u,%u)", (uint32_t)childAddressCells, (uint32_t)childSizeCells);
+
bcopy( cellsIn, cell, sizeof(UInt32) * childCells );
if( childSizeCells > 1)
- *len = IOPhysical32( cellsIn[ childAddressCells ],
- cellsIn[ childAddressCells + 1 ] );
+ *len = IOPhysical32( cellsIn[ childAddressCells + 1],
+ cellsIn[ childAddressCells] );
else
*len = IOPhysical32( 0, cellsIn[ childAddressCells ] );
{
prop = OSDynamicCast( OSData, regEntry->getProperty( gIODTRangeKey ));
if( 0 == prop) {
- /* end of the road */
- *phys = IOPhysical32( 0, cell[ childAddressCells - 1 ] + offset);
+ /* 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;
}
if( prop) {
persist = (IODTPersistent *) prop->getBytesNoCopy();
compare = persist->compareFunc;
- } else
+ } else if (addressCells == childAddressCells) {
compare = DefaultCompare;
+ } else {
+ panic("There is no mixed comparison function yet...");
+ }
for( ok = false;
range < endRanges;
// 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));
- endCell[childAddressCells - 1] += range[childCells + addressCells - 1];
+
+ 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];
+ }
+
diff2 = (*compare)( childAddressCells, cell, endCell );
if ((diff < 0) || (diff2 >= 0))
{
// search for cell end
bcopy(cell, endCell, childAddressCells * sizeof(UInt32));
- endCell[childAddressCells - 1] += cell[childCells - 1] - 1;
+
+ 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;
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 );