]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IODeviceTreeSupport.cpp
xnu-3789.31.2.tar.gz
[apple/xnu.git] / iokit / Kernel / IODeviceTreeSupport.cpp
index 965670f373a9bbe132264421a7b64aef93efd1c4..e115584ce9f7785c29998eb9dc84172131dd102d 100644 (file)
@@ -37,6 +37,8 @@
 
 #include <pexpert/device_tree.h>
 
+typedef UInt32  dtptr_t;
+
 #include <machine/machine_routines.h>
 
 extern "C" {
@@ -253,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 )
@@ -287,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();
         }
     }
 }
@@ -335,6 +344,7 @@ MakeReferenceTable( DTEntry dtEntry, bool copy )
     char                               *name;
     char                               location[ 32 ];
     bool                               noLocation = true;
+    bool                               kernelOnly;
 
     regEntry = new IOService;
 
@@ -346,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)) {
@@ -362,6 +373,9 @@ MakeReferenceTable( DTEntry dtEntry, bool copy )
             }
             assert( nameKey && data );
 
+            if (kernelOnly)
+                data->setSerializable(false);
+
             propTable->setObject( nameKey, data);
             data->release();
             nameKey->release();
@@ -428,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 )
@@ -769,9 +786,10 @@ 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;
@@ -785,8 +803,7 @@ CompareKey( OSString * key,
     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();
@@ -794,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
-        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));
+               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 + nlen + 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,