]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IODeviceTreeSupport.cpp
xnu-3789.51.2.tar.gz
[apple/xnu.git] / iokit / Kernel / IODeviceTreeSupport.cpp
index 5d61880867fbf17a9b6dd9f6195496e0a4fd6ec1..e115584ce9f7785c29998eb9dc84172131dd102d 100644 (file)
@@ -37,6 +37,8 @@
 
 #include <pexpert/device_tree.h>
 
+typedef UInt32  dtptr_t;
+
 #include <machine/machine_routines.h>
 
 extern "C" {
@@ -61,6 +63,7 @@ const OSSymbol *      gIODTUnitKey;
 const OSSymbol *       gIODTCompatibleKey;
 const OSSymbol *       gIODTTypeKey;
 const OSSymbol *       gIODTModelKey;
+const OSSymbol *       gIODTTargetTypeKey;
 
 const OSSymbol *       gIODTSizeCellKey;
 const OSSymbol *       gIODTAddressCellKey;
@@ -106,6 +109,7 @@ IODeviceTreeAlloc( void * dtTop )
     gIODTCompatibleKey         = OSSymbol::withCStringNoCopy( "compatible" );
     gIODTTypeKey               = OSSymbol::withCStringNoCopy( "device_type" );
     gIODTModelKey              = OSSymbol::withCStringNoCopy( "model" );
+    gIODTTargetTypeKey         = OSSymbol::withCStringNoCopy( "target-type" );
     gIODTSizeCellKey   = OSSymbol::withCStringNoCopy( "#size-cells" );
     gIODTAddressCellKey = OSSymbol::withCStringNoCopy( "#address-cells" );
     gIODTRangeKey              = OSSymbol::withCStringNoCopy( "ranges" );
@@ -251,25 +255,31 @@ int IODTGetLoaderInfo( const char *key, void **infoAddr, int *infoSize )
 {
     IORegistryEntry            *chosen;
     OSData                             *propObj;
-    unsigned int               *propPtr;
+    dtptr_t                            *propPtr;
     unsigned int               propSize;
+    int ret = -1;
 
     chosen = IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane );
     if ( chosen == 0 ) return -1;
 
     propObj = OSDynamicCast( OSData, chosen->getProperty(key) );
-    if ( propObj == 0 ) return -1;
+    if ( propObj == 0 ) goto cleanup;
 
     propSize = propObj->getLength();
-    if ( propSize != (2 * sizeof(UInt32)) ) return -1;
+    if ( propSize != (2 * sizeof(dtptr_t)) ) goto cleanup;
  
-    propPtr = (unsigned int *)propObj->getBytesNoCopy();
-    if ( propPtr == 0 ) return -1;
+    propPtr = (dtptr_t *)propObj->getBytesNoCopy();
+    if ( propPtr == 0 ) goto cleanup;
 
     *infoAddr = (void *)(uintptr_t) (propPtr[0]);
     *infoSize = (int)               (propPtr[1]);
 
-    return 0;
+    ret = 0;
+
+cleanup:
+    chosen->release();
+
+    return ret;
 }
 
 void IODTFreeLoaderInfo( const char *key, void *infoAddr, int infoSize )
@@ -285,6 +295,7 @@ void IODTFreeLoaderInfo( const char *key, void *infoAddr, int infoSize )
         chosen = IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane );
         if ( chosen != 0 ) {
             chosen->removeProperty(key);
+            chosen->release();
         }
     }
 }
@@ -333,6 +344,7 @@ MakeReferenceTable( DTEntry dtEntry, bool copy )
     char                               *name;
     char                               location[ 32 ];
     bool                               noLocation = true;
+    bool                               kernelOnly;
 
     regEntry = new IOService;
 
@@ -344,6 +356,7 @@ MakeReferenceTable( DTEntry dtEntry, bool copy )
     if( regEntry &&
       (kSuccess == DTCreatePropertyIterator( dtEntry, &dtIter))) {
 
+        kernelOnly = (kSuccess == DTGetProperty(dtEntry, "kernel-only", &prop, &propSize));
         propTable = regEntry->getPropertyTable();
 
         while( kSuccess == DTIterateProperties( dtIter, &name)) {
@@ -360,6 +373,9 @@ MakeReferenceTable( DTEntry dtEntry, bool copy )
             }
             assert( nameKey && data );
 
+            if (kernelOnly)
+                data->setSerializable(false);
+
             propTable->setObject( nameKey, data);
             data->release();
             nameKey->release();
@@ -426,14 +442,17 @@ static IORegistryEntry * FindPHandle( UInt32 phandle )
 static bool GetUInt32( IORegistryEntry * regEntry, const OSSymbol * name,
                        UInt32 * value )
 {
-    OSData     *data;
+    OSObject * obj;
+    OSData   * data;
+    bool       result;
 
-    if( (data = OSDynamicCast( OSData, regEntry->getProperty( name )))
-      && (4 == data->getLength())) {
-        *value = *((UInt32 *) data->getBytesNoCopy());
-        return( true );
-    } else
-        return( false );
+    if (!(obj = regEntry->copyProperty(name))) return (false);
+
+    result = ((data = OSDynamicCast(OSData, obj)) && (sizeof(UInt32) == data->getLength()));
+    if (result) *value = *((UInt32 *) data->getBytesNoCopy());
+
+    obj->release();
+    return(result);
 }
 
 static IORegistryEntry * IODTFindInterruptParent( IORegistryEntry * regEntry, IOItemCount index )
@@ -767,23 +786,24 @@ bool IODTMapInterrupts( IORegistryEntry * regEntry )
 /*
  */
 
-static const char *
+static bool
 CompareKey( OSString * key,
-               const IORegistryEntry * table, const OSSymbol * propName )
+               const IORegistryEntry * table, const OSSymbol * propName,
+               OSString ** matchingName )
 {
     OSObject           *prop;
     OSData                     *data;
     OSString           *string;
     const char         *ckey;
     UInt32                     keyLen;
+    UInt32          nlen;
     const char         *names;
     const char         *lastName;
     bool                       wild;
     bool                       matched;
     const char         *result = 0;
 
-    if( 0 == (prop = table->getProperty( propName )))
-       return( 0 );
+    if( 0 == (prop = table->copyProperty( propName ))) return( 0 );
 
     if( (data = OSDynamicCast( OSData, prop ))) {
         names = (const char *) data->getBytesNoCopy();
@@ -791,47 +811,48 @@ CompareKey( OSString * key,
     } else if( (string = OSDynamicCast( OSString, prop ))) {
         names = string->getCStringNoCopy();
         lastName = names + string->getLength() + 1;
-    } else
-               return( 0 );
+    } else names = 0;
 
-    ckey = key->getCStringNoCopy();
-    keyLen = key->getLength();
-    wild = ('*' == key->getChar( keyLen - 1 ));
+       if (names) {
+               ckey = key->getCStringNoCopy();
+               keyLen = key->getLength();
+               wild = ('*' == key->getChar( keyLen - 1 ));
 
-    do {
-        // for each name in the property
-        if( wild)
-            matched = (0 == strncmp( ckey, names, keyLen - 1 ));
-        else
-            matched = (keyLen == strlen( names ))
-                    && (0 == strncmp( ckey, names, keyLen ));
+               do {
+                       // for each name in the property
+                       nlen = strnlen(names, lastName - names);
+                       if( wild)
+                               matched = ((nlen >= (keyLen - 1)) && (0 == strncmp(ckey, names, keyLen - 1)));
+                       else
+                               matched = (keyLen == nlen) && (0 == strncmp(ckey, names, keyLen));
 
-        if( matched)
-            result = names;
+                       if( matched)
+                               result = names;
 
-        names = names + strlen( names) + 1;
+                       names = names + nlen + 1;
+
+               } while( (names < lastName) && (false == matched));
+       }
 
-    } while( (names < lastName) && (false == matched));
+    if (result && matchingName)        *matchingName = OSString::withCString( result );
 
-    return( result);
+       if (prop) prop->release();
+
+    return (result != 0);
 }
 
 
 bool IODTCompareNubName( const IORegistryEntry * regEntry,
                         OSString * name, OSString ** matchingName )
 {
-    const char         *result;
-    bool                       matched;
-
-    matched =  (0 != (result = CompareKey( name, regEntry, gIODTNameKey)))
-           || (0 != (result = CompareKey( name, regEntry, gIODTCompatibleKey)))
-           || (0 != (result = CompareKey( name, regEntry, gIODTTypeKey)))
-           || (0 != (result = CompareKey( name, regEntry, gIODTModelKey)));
+    bool matched;
 
-    if( result && matchingName)
-       *matchingName = OSString::withCString( result );
+    matched = CompareKey( name, regEntry, gIODTNameKey,       matchingName)
+                  || CompareKey( name, regEntry, gIODTCompatibleKey, matchingName)
+                  || CompareKey( name, regEntry, gIODTTypeKey,       matchingName)
+                  || CompareKey( name, regEntry, gIODTModelKey,      matchingName);
 
-    return( result != 0 );
+    return (matched);
 }
 
 bool IODTMatchNubWithKeys( IORegistryEntry * regEntry,
@@ -897,7 +918,7 @@ OSCollectionIterator * IODTFindMatchingEntries( IORegistryEntry * from,
     }
 
     cIter = OSCollectionIterator::withCollection( result);
-    result->release();
+    if (result) result->release();
 
     return( cIter);
 }
@@ -927,7 +948,7 @@ void IODTSetResolving( IORegistryEntry *    regEntry,
     return;
 }
 
-#if defined(__arm__) || defined(__i386__) || defined(__x86_64__)
+#if   defined(__arm__) || defined(__i386__) || defined(__x86_64__)
 static SInt32 DefaultCompare( UInt32 cellCount, UInt32 left[], UInt32 right[] )
 {
        cellCount--;
@@ -1239,6 +1260,7 @@ OSData * IODTFindSlotName( IORegistryEntry * regEntry, UInt32 deviceNumber )
     OSData                             *ret = 0;
     UInt32                             *bits;
     UInt32                             i;
+    size_t              nlen;
     char                               *names;
     char                               *lastName;
     UInt32                             mask;
@@ -1266,15 +1288,16 @@ OSData * IODTFindSlotName( IORegistryEntry * regEntry, UInt32 deviceNumber )
     for( i = 0; (i <= deviceNumber) && (names < lastName); i++ ) {
 
         if( mask & (1 << i)) {
+            nlen = 1 + strnlen(names, lastName - names);
             if( i == deviceNumber) {
-                data = OSData::withBytesNoCopy( names, 1 + strlen( names));
+                data = OSData::withBytesNoCopy(names, nlen);
                 if( data) {
                     regEntry->setProperty("AAPL,slot-name", data);
                     ret = data;
                     data->release();
                 }
             } else
-                names += 1 + strlen( names);
+                names += nlen;
         }
     }