Annotation of kernel/machdep/ppc/DeviceTree.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: #include <kern/kalloc.h>
        !            26: #include <machdep/ppc/boot.h>
        !            27: #include <machdep/ppc/DeviceTree.h>
        !            28: 
        !            29: /* External declarations */
        !            30: extern boot_args        our_boot_args;
        !            31: 
        !            32: #define NULL 0
        !            33: #define round_long(x)  (((x) + 3) & -4)
        !            34: #define next_prop(x)   ((DeviceTreeNodeProperty *) (((int)x) + sizeof(DeviceTreeNodeProperty) + round_long(x->length)))
        !            35: 
        !            36: /* Entry*/
        !            37: typedef DeviceTreeNode *RealDTEntry;
        !            38: 
        !            39: typedef struct DTSavedScope {
        !            40:        struct DTSavedScope * nextScope;
        !            41:        RealDTEntry scope;
        !            42:        RealDTEntry entry;
        !            43:        unsigned long index;            
        !            44: } *DTSavedScopePtr;
        !            45: 
        !            46: /* Entry Iterator*/
        !            47: typedef struct OpaqueDTEntryIterator {
        !            48:        RealDTEntry outerScope;
        !            49:        RealDTEntry currentScope;
        !            50:        RealDTEntry currentEntry;
        !            51:        DTSavedScopePtr savedScope;
        !            52:        unsigned long currentIndex;             
        !            53: } *RealDTEntryIterator;
        !            54: 
        !            55: /* Property Iterator*/
        !            56: typedef struct OpaqueDTPropertyIterator {
        !            57:        RealDTEntry entry;
        !            58:        DeviceTreeNodeProperty *currentProperty;
        !            59:        unsigned long currentIndex;
        !            60: } *RealDTPropertyIterator;
        !            61: 
        !            62: static RealDTEntry DTRootNode;
        !            63: static int DTInitialized = 0;
        !            64: 
        !            65: /*
        !            66:  * Support Routines
        !            67:  */
        !            68: static RealDTEntry
        !            69: skipProperties(RealDTEntry entry)
        !            70: {
        !            71:        DeviceTreeNodeProperty *prop;
        !            72:        int k;
        !            73: 
        !            74:        if (entry == NULL || entry->nProperties == 0) {
        !            75:                return NULL;
        !            76:        } else {
        !            77:                prop = (DeviceTreeNodeProperty *) (entry + 1);
        !            78:                for (k = 0; k < entry->nProperties; k++) {
        !            79:                        prop = next_prop(prop);
        !            80:                }
        !            81:        }
        !            82:        return ((RealDTEntry) prop);
        !            83: }
        !            84: 
        !            85: static RealDTEntry
        !            86: skipTree(RealDTEntry root)
        !            87: {
        !            88:        RealDTEntry entry;
        !            89:        int k;
        !            90: 
        !            91:        entry = skipProperties(root);
        !            92:        if (entry == NULL) {
        !            93:                return NULL;
        !            94:        }
        !            95:        for (k = 0; k < root->nChildren; k++) {
        !            96:                entry = skipTree(entry);
        !            97:        }
        !            98:        return entry;
        !            99: }
        !           100: 
        !           101: static RealDTEntry
        !           102: GetFirstChild(RealDTEntry parent)
        !           103: {
        !           104:        return skipProperties(parent);
        !           105: }
        !           106: 
        !           107: static RealDTEntry
        !           108: GetNextChild(RealDTEntry sibling)
        !           109: {
        !           110:        return skipTree(sibling);
        !           111: }
        !           112: 
        !           113: static const char *
        !           114: GetNextComponent(const char *cp, char *bp)
        !           115: {
        !           116:        while (*cp != 0) {
        !           117:                if (*cp == kDTPathNameSeparator) {
        !           118:                        cp++;
        !           119:                        break;
        !           120:                }
        !           121:                *bp++ = *cp++;
        !           122:        }
        !           123:        *bp = 0;
        !           124:        return cp;
        !           125: }
        !           126: 
        !           127: static RealDTEntry
        !           128: FindChild(RealDTEntry cur, char *buf)
        !           129: {
        !           130:        RealDTEntry     child;
        !           131:        unsigned long   index;
        !           132:        char *          str;
        !           133:        int             dummy;
        !           134: 
        !           135:        if (cur->nChildren == 0) {
        !           136:                return NULL;
        !           137:        }
        !           138:        index = 1;
        !           139:        child = GetFirstChild(cur);
        !           140:        while (1) {
        !           141:                if (DTGetProperty(child, "name", (void **)&str, &dummy) != kSuccess) {
        !           142:                        break;
        !           143:                }
        !           144:                if (strcmp(str, buf) == 0) {
        !           145:                        return child;
        !           146:                }
        !           147:                if (index >= cur->nChildren) {
        !           148:                        break;
        !           149:                }
        !           150:                child = GetNextChild(child);
        !           151:                index++;
        !           152:        }
        !           153:        return NULL;
        !           154: }
        !           155: 
        !           156: 
        !           157: /*
        !           158:  * External Routines
        !           159:  */
        !           160: void
        !           161: DTInit(void *base)
        !           162: {
        !           163:        DTRootNode = (RealDTEntry) base;
        !           164:        DTInitialized = 1;
        !           165: }
        !           166: 
        !           167: int
        !           168: DTEntryIsEqual(const DTEntry ref1, const DTEntry ref2)
        !           169: {
        !           170:        /* equality of pointers */
        !           171:        return (ref1 == ref2);
        !           172: }
        !           173: 
        !           174: int
        !           175: DTLookupEntry(const DTEntry searchPoint, const char *pathName, DTEntry *foundEntry)
        !           176: {
        !           177:        DTEntryNameBuf  buf;
        !           178:        RealDTEntry     cur;
        !           179:        const char *    cp;
        !           180: 
        !           181:        if (!DTInitialized) {
        !           182:                return kError;
        !           183:        }
        !           184:        if (searchPoint == NULL) {
        !           185:                cur = DTRootNode;
        !           186:        } else {
        !           187:                cur = searchPoint;
        !           188:        }
        !           189:        cp = pathName;
        !           190:        if (*cp == kDTPathNameSeparator) {
        !           191:                cp++;
        !           192:                if (*cp == 0) {
        !           193:                        *foundEntry = cur;
        !           194:                        return kSuccess;
        !           195:                }
        !           196:        }
        !           197:        do {
        !           198:                cp = GetNextComponent(cp, buf);
        !           199: 
        !           200:                /* Check for done */
        !           201:                if (*buf == 0) {
        !           202:                        if (*cp == 0) {
        !           203:                                *foundEntry = cur;
        !           204:                                return kSuccess;
        !           205:                        }
        !           206:                        break;
        !           207:                }
        !           208: 
        !           209:                cur = FindChild(cur, buf);
        !           210: 
        !           211:        } while (cur != NULL);
        !           212: 
        !           213:        return kError;
        !           214: }
        !           215: 
        !           216: int
        !           217: DTCreateEntryIterator(const DTEntry startEntry, DTEntryIterator *iterator)
        !           218: {
        !           219:        RealDTEntryIterator iter;
        !           220: 
        !           221:        if (!DTInitialized) {
        !           222:                return kError;
        !           223:        }
        !           224: 
        !           225:        iter = (RealDTEntryIterator) kalloc(sizeof(struct OpaqueDTEntryIterator));
        !           226:        if (startEntry != NULL) {
        !           227:                iter->outerScope = (RealDTEntry) startEntry;
        !           228:                iter->currentScope = (RealDTEntry) startEntry;
        !           229:        } else {
        !           230:                iter->outerScope = DTRootNode;
        !           231:                iter->currentScope = DTRootNode;
        !           232:        }
        !           233:        iter->currentEntry = NULL;
        !           234:        iter->savedScope = NULL;
        !           235:        iter->currentIndex = 0;
        !           236: 
        !           237:        *iterator = iter;
        !           238:        return kSuccess;
        !           239: }
        !           240: 
        !           241: int
        !           242: DTDisposeEntryIterator(DTEntryIterator iterator)
        !           243: {
        !           244:        RealDTEntryIterator iter = iterator;
        !           245:        DTSavedScopePtr scope;
        !           246: 
        !           247:        while ((scope = iter->savedScope) != NULL) {
        !           248:                iter->savedScope = scope->nextScope;
        !           249:                kfree((vm_offset_t) scope, sizeof(struct DTSavedScope));
        !           250:        }
        !           251:        kfree((vm_offset_t) iterator, sizeof(struct OpaqueDTEntryIterator));
        !           252:        return kSuccess;
        !           253: }
        !           254: 
        !           255: int
        !           256: DTEnterEntry(DTEntryIterator iterator, DTEntry childEntry)
        !           257: {
        !           258:        RealDTEntryIterator iter = iterator;
        !           259:        DTSavedScopePtr newScope;
        !           260: 
        !           261:        if (childEntry == NULL) {
        !           262:                return kError;
        !           263:        }
        !           264:        newScope = (DTSavedScopePtr) kalloc(sizeof(struct DTSavedScope));
        !           265:        newScope->nextScope = iter->savedScope;
        !           266:        newScope->scope = iter->currentScope;
        !           267:        newScope->entry = iter->currentEntry;
        !           268:        newScope->index = iter->currentIndex;           
        !           269: 
        !           270:        iter->currentScope = childEntry;
        !           271:        iter->currentEntry = NULL;
        !           272:        iter->savedScope = newScope;
        !           273:        iter->currentIndex = 0;
        !           274: 
        !           275:        return kSuccess;
        !           276: }
        !           277: 
        !           278: int
        !           279: DTExitEntry(DTEntryIterator iterator, DTEntry *currentPosition)
        !           280: {
        !           281:        RealDTEntryIterator iter = iterator;
        !           282:        DTSavedScopePtr newScope;
        !           283: 
        !           284:        newScope = iter->savedScope;
        !           285:        if (newScope == NULL) {
        !           286:                return kError;
        !           287:        }
        !           288:        iter->savedScope = newScope->nextScope;
        !           289:        iter->currentScope = newScope->scope;
        !           290:        iter->currentEntry = newScope->entry;
        !           291:        iter->currentIndex = newScope->index;
        !           292:        *currentPosition = iter->currentEntry;
        !           293: 
        !           294:        kfree((vm_offset_t) newScope, sizeof(struct DTSavedScope));
        !           295: 
        !           296:        return kSuccess;
        !           297: }
        !           298: 
        !           299: int
        !           300: DTIterateEntries(DTEntryIterator iterator, DTEntry *nextEntry)
        !           301: {
        !           302:        RealDTEntryIterator iter = iterator;
        !           303: 
        !           304:        if (iter->currentIndex >= iter->currentScope->nChildren) {
        !           305:                *nextEntry = NULL;
        !           306:                return kIterationDone;
        !           307:        } else {
        !           308:                iter->currentIndex++;
        !           309:                if (iter->currentIndex == 1) {
        !           310:                        iter->currentEntry = GetFirstChild(iter->currentScope);
        !           311:                } else {
        !           312:                        iter->currentEntry = GetNextChild(iter->currentEntry);
        !           313:                }
        !           314:                *nextEntry = iter->currentEntry;
        !           315:                return kSuccess;
        !           316:        }
        !           317: }
        !           318: 
        !           319: int
        !           320: DTRestartEntryIteration(DTEntryIterator iterator)
        !           321: {
        !           322:        RealDTEntryIterator iter = iterator;
        !           323: #if 0
        !           324:        // This commented out code allows a second argument (outer)
        !           325:        // which (if true) causes restarting at the outer scope
        !           326:        // rather than the current scope.
        !           327:        DTSavedScopePtr scope;
        !           328: 
        !           329:        if (outer) {
        !           330:                while ((scope = iter->savedScope) != NULL) {
        !           331:                        iter->savedScope = scope->nextScope;
        !           332:                        kfree((vm_offset_t) scope, sizeof(struct DTSavedScope));
        !           333:                }
        !           334:                iter->currentScope = iter->outerScope;
        !           335:        }
        !           336: #endif
        !           337:        iter->currentEntry = NULL;
        !           338:        iter->currentIndex = 0;
        !           339:        return kSuccess;
        !           340: }
        !           341: 
        !           342: int
        !           343: DTGetProperty(const DTEntry entry, const char *propertyName, void **propertyValue, int *propertySize)
        !           344: {
        !           345:        DeviceTreeNodeProperty *prop;
        !           346:        int k;
        !           347: 
        !           348:        if (entry == NULL || entry->nProperties == 0) {
        !           349:                return kError;
        !           350:        } else {
        !           351:                prop = (DeviceTreeNodeProperty *) (entry + 1);
        !           352:                for (k = 0; k < entry->nProperties; k++) {
        !           353:                        if (strcmp(prop->name, propertyName) == 0) {
        !           354:                                *propertyValue = (void *) (((int)prop)
        !           355:                                                + sizeof(DeviceTreeNodeProperty));
        !           356:                                *propertySize = prop->length;
        !           357:                                return kSuccess;
        !           358:                        }
        !           359:                        prop = next_prop(prop);
        !           360:                }
        !           361:        }
        !           362:        return kError;
        !           363: }
        !           364: 
        !           365: int
        !           366: DTCreatePropertyIterator(const DTEntry entry, DTPropertyIterator *iterator)
        !           367: {
        !           368:        RealDTPropertyIterator iter;
        !           369: 
        !           370:        iter = (RealDTPropertyIterator) kalloc(sizeof(struct OpaqueDTPropertyIterator));
        !           371:        iter->entry = entry;
        !           372:        iter->currentProperty = NULL;
        !           373:        iter->currentIndex = 0;
        !           374: 
        !           375:        *iterator = iter;
        !           376:        return kSuccess;
        !           377: }
        !           378: 
        !           379: int
        !           380: DTDisposePropertyIterator(DTPropertyIterator iterator)
        !           381: {
        !           382:        kfree((vm_offset_t)iterator, sizeof(struct OpaqueDTPropertyIterator));
        !           383:        return kSuccess;
        !           384: }
        !           385: 
        !           386: int
        !           387: DTIterateProperties(DTPropertyIterator iterator, char **foundProperty)
        !           388: {
        !           389:        RealDTPropertyIterator iter = iterator;
        !           390: 
        !           391:        if (iter->currentIndex >= iter->entry->nProperties) {
        !           392:                *foundProperty = NULL;
        !           393:                return kIterationDone;
        !           394:        } else {
        !           395:                iter->currentIndex++;
        !           396:                if (iter->currentIndex == 1) {
        !           397:                        iter->currentProperty = (DeviceTreeNodeProperty *) (iter->entry + 1);
        !           398:                } else {
        !           399:                        iter->currentProperty = next_prop(iter->currentProperty);
        !           400:                }
        !           401:                *foundProperty = iter->currentProperty->name;
        !           402:                return kSuccess;
        !           403:        }
        !           404: }
        !           405: 
        !           406: int
        !           407: DTRestartPropertyIteration(DTPropertyIterator iterator)
        !           408: {
        !           409:        RealDTPropertyIterator iter = iterator;
        !           410: 
        !           411:        iter->currentProperty = NULL;
        !           412:        iter->currentIndex = 0;
        !           413:        return kSuccess;
        !           414: }
        !           415: 
        !           416: 
        !           417: static char *startingP;                // needed for find_entry
        !           418: int find_entry(const char *propName, const char *propValue, DTEntry *entryH);
        !           419: 
        !           420: /* DTFindEntry:
        !           421:  *
        !           422:  *   Find the device tree entry that contains propName=propValue.  It currently searches the entire
        !           423:  *   tree.  This function should eventually go in DeviceTree.c.
        !           424:  *   Returns:    kSuccess = entry was found.  Entry is in entryH.
        !           425:  *               kError   = entry was not found
        !           426:  */
        !           427: int DTFindEntry(const char *propName, const char *propValue, DTEntry *entryH)
        !           428: {
        !           429:        startingP = our_boot_args.deviceTreeP;
        !           430:        return( find_entry(propName, propValue, entryH));
        !           431: }
        !           432: 
        !           433: int find_entry(const char *propName, const char *propValue, DTEntry *entryH)
        !           434: {
        !           435:        DeviceTreeNode *nodeP = (DeviceTreeNode *) startingP;
        !           436:        int k;
        !           437: 
        !           438:        if (nodeP->nProperties == 0) return kError; // End of the list of nodes
        !           439:        startingP = (char *) (nodeP + 1);
        !           440: 
        !           441:        // Search current entry
        !           442:        for (k = 0; k < nodeP->nProperties; ++k) {
        !           443:                DeviceTreeNodeProperty *propP = (DeviceTreeNodeProperty *) startingP;
        !           444: 
        !           445:                startingP += sizeof (*propP) + ((propP->length + 3) & -4);
        !           446: 
        !           447:                if (strcmp (propP->name, propName) == 0) {
        !           448:                        if (strcmp( (char *)(propP + 1), propValue) == 0)
        !           449:                        {
        !           450:                                *entryH = (DTEntry)nodeP;
        !           451:                                return(kSuccess);
        !           452:                        }
        !           453:                }
        !           454:        }
        !           455: 
        !           456:        // Search child nodes
        !           457:        for (k = 0; k < nodeP->nChildren; ++k)
        !           458:        {
        !           459:                if (find_entry(propName, propValue, entryH) == kSuccess)
        !           460:                        return(kSuccess);
        !           461:        }
        !           462:        return(kError);
        !           463: }
        !           464: 
        !           465: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.