Annotation of kernel/machdep/ppc/DeviceTree.c, revision 1.1.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.