The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pexpert/gen/device_tree.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 8fa7efb29047f9c93e7a74f1c648edfb


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.