Annotation of XNU/pexpert/gen/device_tree.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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