]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IORegistryEntry.cpp
xnu-4570.61.1.tar.gz
[apple/xnu.git] / iokit / Kernel / IORegistryEntry.cpp
index c4bbb35135a11069ad792088fc1d5d47d62f61b9..f07b4231805428004c7417c315a87b4d645e3730 100644 (file)
  * 
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
-/*
- * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved. 
- *
- * HISTORY
- * 12 Nov 98 sdouglas created.
- *
- */
 
 #include <IOKit/IORegistryEntry.h>
 #include <libkern/c++/OSContainers.h>
 #include <IOKit/IOService.h>
 #include <IOKit/IOKitKeys.h>
+#include <IOKit/IOTimeStamp.h>
 
 #include <IOKit/IOLib.h>
 
 #include <IOKit/assert.h>
 
+#include "IOKitKernelInternal.h"
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 #define super OSObject
@@ -62,12 +58,21 @@ OSDefineMetaClassAndStructors(IORegistryEntry, OSObject)
 
 #define KASLR_IOREG_DEBUG 0
 
+struct IORegistryEntry::ExpansionData
+{
+    IORecursiveLock * fLock;
+    uint64_t         fRegistryEntryID;
+    SInt32            fRegistryEntryGenerationCount;
+};
+
+
 static IORegistryEntry * gRegistryRoot;
 static OSDictionary *   gIORegistryPlanes;
 
 const OSSymbol *       gIONameKey;
 const OSSymbol *       gIOLocationKey;
 const OSSymbol *       gIORegistryEntryIDKey;
+const OSSymbol *       gIORegistryEntryPropertyKeysKey;
 
 enum {
     kParentSetIndex    = 0,
@@ -95,7 +100,7 @@ class IORegistryPlane : public OSObject {
     int                        reserved[2];
 
 public:
-    virtual bool serialize(OSSerialize *s) const;
+    virtual bool serialize(OSSerialize *s) const APPLE_KEXT_OVERRIDE;
 };
 
 OSDefineMetaClassAndStructors(IORegistryPlane, OSObject)
@@ -110,8 +115,8 @@ static SInt32                       gIORegistryGenerationCount;
                gIORegistryGenerationCount++
                // make atomic
 
-#define PUNLOCK        IORecursiveLockUnlock( gPropertiesLock )
-#define PLOCK  IORecursiveLockLock( gPropertiesLock )
+#define PUNLOCK        IORecursiveLockUnlock( reserved->fLock )
+#define PLOCK  IORecursiveLockLock( reserved->fLock )
 
 #define IOREGSPLITTABLES
 
@@ -162,6 +167,7 @@ IORegistryEntry * IORegistryEntry::initialize( void )
        gIONameKey = OSSymbol::withCStringNoCopy( "IOName" );
        gIOLocationKey = OSSymbol::withCStringNoCopy( "IOLocation" );
        gIORegistryEntryIDKey = OSSymbol::withCStringNoCopy( kIORegistryEntryIDKey );
+        gIORegistryEntryPropertyKeysKey = OSSymbol::withCStringNoCopy( kIORegistryEntryPropertyKeysKey );
 
        assert( ok && gIONameKey && gIOLocationKey );
 
@@ -182,6 +188,10 @@ SInt32 IORegistryEntry::getGenerationCount( void )
     return( gIORegistryGenerationCount );
 }
 
+SInt32 IORegistryEntry::getRegistryEntryGenerationCount(void) const
+{
+    return (reserved->fRegistryEntryGenerationCount);
+}
 
 const IORegistryPlane * IORegistryEntry::makePlane( const char * name )
 {
@@ -278,6 +288,8 @@ bool IORegistryEntry::init( OSDictionary * dict )
        if (!reserved)
            return (false);
        bzero(reserved, sizeof(ExpansionData));
+       reserved->fLock = IORecursiveLockAlloc();
+       if (!reserved->fLock) return (false);
     }
     if( dict) {
        if (OSCollection::kImmutable & dict->setOptions(0, 0)) {
@@ -328,13 +340,20 @@ bool IORegistryEntry::init( IORegistryEntry * old,
     if( !super::init())
        return( false);
 
+    if (!reserved)
+    {
+       reserved = IONew(ExpansionData, 1);
+       if (!reserved) return (false);
+       bzero(reserved, sizeof(ExpansionData));
+       reserved->fLock = IORecursiveLockAlloc();
+       if (!reserved->fLock) return (false);
+    }
+
     WLOCK;
 
-    reserved = old->reserved;
-    old->reserved = NULL;
+    reserved->fRegistryEntryID = old->reserved->fRegistryEntryID;
 
-    fPropertyTable = old->getPropertyTable();
-    fPropertyTable->retain();
+    fPropertyTable = old->dictionaryWithProperties();
 #ifdef IOREGSPLITTABLES
     fRegistryTable = old->fRegistryTable;
     old->fRegistryTable = (OSDictionary *) fRegistryTable->copyCollection();
@@ -384,17 +403,21 @@ void IORegistryEntry::free( void )
 #endif /* IOREGSPLITTABLES */
 
     if (reserved)
+    {
+       if (reserved->fLock) IORecursiveLockFree(reserved->fLock);
        IODelete(reserved, ExpansionData, 1);
+    }
 
     super::free();
 }
 
 void IORegistryEntry::setPropertyTable( OSDictionary * dict )
 {
-    if( fPropertyTable)
-       fPropertyTable->release();
     if( dict)
        dict->retain();
+    if( fPropertyTable)
+       fPropertyTable->release();
+
     fPropertyTable = dict;
 }
 
@@ -473,11 +496,22 @@ bool IORegistryEntry::serializeProperties( OSSerialize * s ) const
     OSCollection *snapshotProperties = getPropertyTable()->copyCollection();
     PUNLOCK;
 
+    if (!snapshotProperties) return (false);
+
     bool ok =  snapshotProperties->serialize( s );
     snapshotProperties->release();
     return( ok );
 }
 
+OSArray * IORegistryEntry::copyPropertyKeys(void) const
+{
+    PLOCK;
+    OSArray * keys = getPropertyTable()->copyKeys();
+    PUNLOCK;
+
+    return (keys);
+}
+
 OSDictionary * IORegistryEntry::dictionaryWithProperties( void ) const
 {
     OSDictionary *     dict;
@@ -790,6 +824,19 @@ void IORegistryEntry::setName( const OSSymbol * name,
         else
             key = gIONameKey;
 
+        if (gIOKitTrace && reserved && reserved->fRegistryEntryID)
+        {
+            uint64_t str_id = 0;
+            uint64_t __unused regID = getRegistryEntryID();
+            kernel_debug_string(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME_STRING), &str_id, name->getCStringNoCopy());
+            KERNEL_DEBUG_CONSTANT(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME),
+                (uintptr_t) regID,
+                (uintptr_t) (regID >> 32),
+                (uintptr_t) str_id,
+                (uintptr_t) (str_id >> 32),
+                0);
+        }
+
        WLOCK;
         registryTable()->setObject( key, (OSObject *) name);
        UNLOCK;
@@ -1334,6 +1381,7 @@ bool IORegistryEntry::makeLink( IORegistryEntry * to,
             links->release();
        }
     }
+    reserved->fRegistryEntryGenerationCount++;
 
     return( result);
 }
@@ -1354,6 +1402,7 @@ void IORegistryEntry::breakLink( IORegistryEntry * to,
                 registryTable()->removeObject( plane->keys[ relation ]);
            }
     }
+    reserved->fRegistryEntryGenerationCount++;
 }
 
 
@@ -1453,6 +1502,18 @@ OSIterator * IORegistryEntry::getChildIterator( const IORegistryPlane * plane )
     return( iter );
 }
 
+uint32_t IORegistryEntry::getChildCount( const IORegistryPlane * plane ) const
+{
+    OSArray * links;
+    uint32_t  count = 0;
+
+    RLOCK;
+    links = getChildSetReference( plane );
+    if (links) count = links->getCount();
+    UNLOCK;
+
+    return (count);
+}
 
 IORegistryEntry * IORegistryEntry::copyChildEntry(
                                const IORegistryPlane * plane ) const
@@ -1623,6 +1684,7 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
     OSArray *  links;
     bool       ret;
     bool       needParent;
+    bool        traceName = false;
 
     if( this == parent)
        return( false );
@@ -1630,7 +1692,10 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
     WLOCK;
 
     if (!reserved->fRegistryEntryID)
+    {
        reserved->fRegistryEntryID = ++gIORegistryLastID;
+       traceName = (0 != gIOKitTrace);
+    }
 
     ret = makeLink( parent, kParentSetIndex, plane );
 
@@ -1641,6 +1706,19 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
 
     UNLOCK;
 
+    if (traceName)
+    {
+        uint64_t str_id = 0;
+        uint64_t __unused regID = getRegistryEntryID();
+        kernel_debug_string(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME_STRING), &str_id, getName());
+        KERNEL_DEBUG_CONSTANT(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME),
+            (uintptr_t) regID,
+            (uintptr_t) (regID >> 32),
+            (uintptr_t) str_id,
+            (uintptr_t) (str_id >> 32),
+            0);
+    }
+
     PLOCK;
 
     // Mark any collections in the property list as immutable