]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IODeviceTreeSupport.cpp
xnu-2050.18.24.tar.gz
[apple/xnu.git] / iokit / Kernel / IODeviceTreeSupport.cpp
index afb221cf4805d3cec221a5c603f02af00d5176f7..4ee53e5668203b8e239fc9334f82a16324d215cd 100644 (file)
 
 #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>
@@ -209,26 +211,6 @@ IODeviceTreeAlloc( void * dtTop )
             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();
     }
@@ -265,7 +247,7 @@ IODeviceTreeAlloc( void * dtTop )
     return( parent);
 }
 
-int IODTGetLoaderInfo( char *key, void **infoAddr, int *infoSize )
+int IODTGetLoaderInfo( const char *key, void **infoAddr, int *infoSize )
 {
     IORegistryEntry            *chosen;
     OSData                             *propObj;
@@ -290,7 +272,7 @@ int IODTGetLoaderInfo( char *key, void **infoAddr, int *infoSize )
     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;
@@ -307,6 +289,26 @@ void IODTFreeLoaderInfo( char *key, void *infoAddr, int infoSize )
     }
 }
 
+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;
@@ -919,6 +921,7 @@ void IODTSetResolving( IORegistryEntry *    regEntry,
     if( !prop)
         return;
 
+    prop->setSerializable(false);
     regEntry->setProperty( gIODTPersistKey, prop);
     prop->release();
     return;
@@ -926,8 +929,8 @@ void IODTSetResolving( IORegistryEntry *    regEntry,
 
 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,
@@ -957,14 +960,15 @@ bool IODTResolveAddressCell( 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;
@@ -972,10 +976,13 @@ bool IODTResolveAddressCell( IORegistryEntry * regEntry,
     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 ] );
 
@@ -983,8 +990,13 @@ bool IODTResolveAddressCell( IORegistryEntry * regEntry,
     {
        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;
        }
 
@@ -1001,8 +1013,11 @@ bool IODTResolveAddressCell( IORegistryEntry * regEntry,
            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;
@@ -1011,8 +1026,21 @@ bool IODTResolveAddressCell( IORegistryEntry * regEntry,
                // 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))
@@ -1023,7 +1051,17 @@ bool IODTResolveAddressCell( IORegistryEntry * regEntry,
                {
                    // 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;
@@ -1047,6 +1085,9 @@ bool IODTResolveAddressCell( IORegistryEntry * regEntry,
                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 );