Exemple #1
0
static void
_PrintFlattenedTree(DTEntry entry, int level)
{
	DTEntryIterator entryIter;

	PrintFlattenedNode(entry, level);

	if (kSuccess != DTCreateEntryIterator(entry, &entryIter))
	{
		printf("Couldn't create entry iterator\n");
		return;
	}
	level++;
	while (kSuccess == DTIterateEntries( entryIter, &entry ))
	{
		_PrintFlattenedTree(entry, level);
	}
	DTDisposeEntryIterator(entryIter);
}
Exemple #2
0
int
main(int argc, char **argv)
{
	DTEntry			dtEntry;
	DTPropertyIterator	propIter;
	DTEntryIterator		entryIter;
	void			*prop;
	int			propSize;
	char			*name;
	void			*flatTree;
	uint32_t		flatSize;

	Node *node;

	node = AddChild(NULL, "device-tree");
	AddProperty(node, "potato", 4, "foo");
	AddProperty(node, "chemistry", 4, "bar");
	AddProperty(node, "physics", 4, "baz");

	node = AddChild(node, "dev");
	AddProperty(node, "one", 4, "one");
	AddProperty(node, "two", 4, "two");
	AddProperty(node, "three", 6, "three");

	node = AddChild(rootNode, "foo");
	AddProperty(node, "aaa", 4, "aab");
	AddProperty(node, "bbb", 4, "bbc");
	AddProperty(node, "cccc", 6, "ccccd");

	node = FindNode("/this/is/a/test", 1);
	AddProperty(node, "dddd", 12, "abcdefghijk");

	printf("In-memory tree:\n\n");

	PrintTree(rootNode);

	FlattenDeviceTree(&flatTree, &flatSize);

	printf("Flat tree = %p, size %d\n", flatTree, flatSize);

	dtEntry = (DTEntry)flatTree;

	printf("\n\nPrinting flat tree\n\n");

	DTInit(dtEntry);

	PrintFlattenedTree((DTEntry)flatTree);
#if 0
	printf("=== Entry %p ===\n", dtEntry);
	if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter))
	{
		printf("Couldn't create property iterator\n");
		return 1;
	}
	while( kSuccess == DTIterateProperties( propIter, &name))
	{
		if(  kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
			continue;
		printf(" Property %s = %s\n", name, prop);
        }
	DTDisposePropertyIterator(propIter);
	printf("========\n");

	if (kSuccess != DTCreateEntryIterator(dtEntry, &entryIter))
	{
		printf("Couldn't create entry iterator\n");
		return 1;
	}
	while (kSuccess == DTIterateEntries( entryIter, &dtEntry ))
	{
		printf("=== Entry %p ===\n", dtEntry);

	if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter))
	{
		printf("Couldn't create property iterator\n");
		return 1;
	}
		while( kSuccess == DTIterateProperties( propIter, &name))
		{
			if(  kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
				continue;
			printf(" Property %s = %s\n", name, prop);
		}
		DTDisposePropertyIterator(propIter);
		printf("========\n");
	}
	DTDisposeEntryIterator(entryIter);
#endif

	return 0;
}
IORegistryEntry *
IODeviceTreeAlloc( void * dtTop )
{
    IORegistryEntry *		parent;
    IORegistryEntry *		child;
    IORegistryIterator *	regIter;
    DTEntryIterator		iter;
    DTEntry			dtChild;
    DTEntry			mapEntry;
    OSArray *			stack;
    OSData *			prop;
    OSDictionary *		allInts;
    vm_offset_t *		dtMap;
    unsigned int		propSize;
    bool			intMap;
    bool			freeDT;

    gIODTPlane = IORegistryEntry::makePlane( kIODeviceTreePlane );

    gIODTNameKey 		= OSSymbol::withCStringNoCopy( "name" );
    gIODTUnitKey 		= OSSymbol::withCStringNoCopy( "AAPL,unit-string" );
    gIODTCompatibleKey 	= OSSymbol::withCStringNoCopy( "compatible" );
    gIODTTypeKey 		= OSSymbol::withCStringNoCopy( "device_type" );
    gIODTModelKey 		= OSSymbol::withCStringNoCopy( "model" );
    gIODTSizeCellKey 	= OSSymbol::withCStringNoCopy( "#size-cells" );
    gIODTAddressCellKey = OSSymbol::withCStringNoCopy( "#address-cells" );
    gIODTRangeKey 		= OSSymbol::withCStringNoCopy( "ranges" );
    gIODTPersistKey		= OSSymbol::withCStringNoCopy( "IODTPersist" );

    assert(    gIODTPlane && gIODTCompatibleKey
            && gIODTTypeKey && gIODTModelKey
            && gIODTSizeCellKey && gIODTAddressCellKey && gIODTRangeKey
            && gIODTPersistKey );

    gIODTDefaultInterruptController
		= OSSymbol::withCStringNoCopy("IOPrimaryInterruptController");
    gIODTNWInterruptMappingKey
		= OSSymbol::withCStringNoCopy("IONWInterrupts");

    gIODTAAPLInterruptsKey
		= OSSymbol::withCStringNoCopy("AAPL,interrupts");
    gIODTPHandleKey
		= OSSymbol::withCStringNoCopy("AAPL,phandle");

    gIODTInterruptParentKey
		= OSSymbol::withCStringNoCopy("interrupt-parent");

    gIODTPHandles	= OSArray::withCapacity( 1 );
    gIODTPHandleMap	= OSArray::withCapacity( 1 );

    gIODTInterruptCellKey
		= OSSymbol::withCStringNoCopy("#interrupt-cells");

    assert(    gIODTDefaultInterruptController && gIODTNWInterruptMappingKey 
	    && gIODTAAPLInterruptsKey
	    && gIODTPHandleKey && gIODTInterruptParentKey
	    && gIODTPHandles && gIODTPHandleMap
            && gIODTInterruptCellKey
	 );

    freeDT = (kSuccess == DTLookupEntry( 0, "/chosen/memory-map", &mapEntry ))
	  && (kSuccess == DTGetProperty( mapEntry,
                "DeviceTree", (void **) &dtMap, &propSize ))
	  && ((2 * sizeof(uint32_t)) == propSize);

    parent = MakeReferenceTable( (DTEntry)dtTop, freeDT );

    stack = OSArray::withObjects( (const OSObject **) &parent, 1, 10 );
    DTCreateEntryIterator( (DTEntry)dtTop, &iter );

    do {
        parent = (IORegistryEntry *)stack->getObject( stack->getCount() - 1);
        //parent->release();
        stack->removeObject( stack->getCount() - 1);

        while( kSuccess == DTIterateEntries( iter, &dtChild) ) {

            child = MakeReferenceTable( dtChild, freeDT );
            child->attachToParent( parent, gIODTPlane);

            AddPHandle( child );

            if( kSuccess == DTEnterEntry( iter, dtChild)) {
                stack->setObject( parent);
                parent = child;
            }
            // only registry holds retain
            child->release();
        }

    } while( stack->getCount()
		&& (kSuccess == DTExitEntry( iter, &dtChild)));

    stack->release();
    DTDisposeEntryIterator( iter);

    // parent is now root of the created tree

    // make root name first compatible entry (purely cosmetic)
    if( (prop = (OSData *) parent->getProperty( gIODTCompatibleKey))) {
        parent->setName( parent->getName(), gIODTPlane );
        parent->setName( (const char *) prop->getBytesNoCopy() );
    }

    // attach tree to meta root
    parent->attachToParent( IORegistryEntry::getRegistryRoot(), gIODTPlane);
    parent->release();

    if( freeDT ) {
        // free original device tree
        DTInit(0);
        IODTFreeLoaderInfo( "DeviceTree",
			    (void *)dtMap[0], (int) round_page(dtMap[1]) );
    }

    // adjust tree

    gIODTSharedInterrupts = OSDictionary::withCapacity(4);
    allInts = OSDictionary::withCapacity(4);
    intMap = false;
    regIter = IORegistryIterator::iterateOver( gIODTPlane,
						kIORegistryIterateRecursively );
    assert( regIter && allInts && gIODTSharedInterrupts );
    if( regIter && allInts && gIODTSharedInterrupts ) {
        while( (child = regIter->getNextObject())) {
            IODTMapInterruptsSharing( child, allInts );
            if( !intMap && child->getProperty( gIODTInterruptParentKey))
                intMap = true;

        }
        regIter->release();
    }

#if IODTSUPPORTDEBUG
    parent->setProperty("allInts", allInts);
    parent->setProperty("sharedInts", gIODTSharedInterrupts);

    regIter = IORegistryIterator::iterateOver( gIODTPlane,
						kIORegistryIterateRecursively );
    if (regIter) {
        while( (child = regIter->getNextObject())) {
	    OSArray *
	    array = OSDynamicCast(OSArray, child->getProperty( gIOInterruptSpecifiersKey ));
	    for( UInt32 i = 0; array && (i < array->getCount()); i++)
	    {
		IOOptionBits options;
		IOReturn ret = IODTGetInterruptOptions( child, i, &options );
		if( (ret != kIOReturnSuccess) || options)
		    IOLog("%s[%ld] %ld (%x)\n", child->getName(), i, options, ret);
	    }
	}
        regIter->release();
    }
#endif

    allInts->release();

    if( intMap)
        // set a key in the root to indicate we found NW interrupt mapping
        parent->setProperty( gIODTNWInterruptMappingKey,
                (OSObject *) gIODTNWInterruptMappingKey );

    return( parent);
}