|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.