2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * @OSF_FREE_COPYRIGHT@
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>
32 #include <i386/fakePPCStructs.h>
36 #define NULL ((void *) 0)
39 #define round_long(x) (((x) + 3) & -4)
40 #define next_prop(x) ((DeviceTreeNodeProperty *) (((int)x) + sizeof(DeviceTreeNodeProperty) + round_long(x->length)))
43 typedef DeviceTreeNode
*RealDTEntry
;
45 typedef struct DTSavedScope
{
46 struct DTSavedScope
* nextScope
;
53 typedef struct OpaqueDTEntryIterator
{
54 RealDTEntry outerScope
;
55 RealDTEntry currentScope
;
56 RealDTEntry currentEntry
;
57 DTSavedScopePtr savedScope
;
58 unsigned long currentIndex
;
59 } *RealDTEntryIterator
;
61 /* Property Iterator*/
62 typedef struct OpaqueDTPropertyIterator
{
64 DeviceTreeNodeProperty
*currentProperty
;
65 unsigned long currentIndex
;
66 } *RealDTPropertyIterator
;
68 static int DTInitialized
;
69 static RealDTEntry DTRootNode
;
71 void DTInit(void *base
);
77 skipProperties(RealDTEntry entry
)
79 DeviceTreeNodeProperty
*prop
;
82 if (entry
== NULL
|| entry
->nProperties
== 0) {
85 prop
= (DeviceTreeNodeProperty
*) (entry
+ 1);
86 for (k
= 0; k
< entry
->nProperties
; k
++) {
87 prop
= next_prop(prop
);
90 return ((RealDTEntry
) prop
);
94 skipTree(RealDTEntry root
)
99 entry
= skipProperties(root
);
103 for (k
= 0; k
< root
->nChildren
; k
++) {
104 entry
= skipTree(entry
);
110 GetFirstChild(RealDTEntry parent
)
112 return skipProperties(parent
);
116 GetNextChild(RealDTEntry sibling
)
118 return skipTree(sibling
);
122 GetNextComponent(const char *cp
, char *bp
)
125 if (*cp
== kDTPathNameSeparator
) {
136 FindChild(RealDTEntry cur
, char *buf
)
143 if (cur
->nChildren
== 0) {
147 child
= GetFirstChild(cur
);
149 if (DTGetProperty(child
, "name", (void **)&str
, &dummy
) != kSuccess
) {
152 if (strcmp(str
, buf
) == 0) {
155 if (index
>= cur
->nChildren
) {
158 child
= GetNextChild(child
);
171 DTRootNode
= (RealDTEntry
) base
;
172 DTInitialized
= (DTRootNode
!= 0);
176 DTEntryIsEqual(const DTEntry ref1
, const DTEntry ref2
)
178 /* equality of pointers */
179 return (ref1
== ref2
);
182 static char *startingP
; // needed for find_entry
183 int find_entry(const char *propName
, const char *propValue
, DTEntry
*entryH
);
185 int DTFindEntry(const char *propName
, const char *propValue
, DTEntry
*entryH
)
187 if (!DTInitialized
) {
191 startingP
= (char *)DTRootNode
;
192 return(find_entry(propName
, propValue
, entryH
));
195 int find_entry(const char *propName
, const char *propValue
, DTEntry
*entryH
)
197 DeviceTreeNode
*nodeP
= (DeviceTreeNode
*) startingP
;
200 if (nodeP
->nProperties
== 0) return(kError
); // End of the list of nodes
201 startingP
= (char *) (nodeP
+ 1);
203 // Search current entry
204 for (k
= 0; k
< nodeP
->nProperties
; ++k
) {
205 DeviceTreeNodeProperty
*propP
= (DeviceTreeNodeProperty
*) startingP
;
207 startingP
+= sizeof (*propP
) + ((propP
->length
+ 3) & -4);
209 if (strcmp (propP
->name
, propName
) == 0) {
210 if (strcmp( (char *)(propP
+ 1), propValue
) == 0)
212 *entryH
= (DTEntry
)nodeP
;
218 // Search child nodes
219 for (k
= 0; k
< nodeP
->nChildren
; ++k
)
221 if (find_entry(propName
, propValue
, entryH
) == kSuccess
)
228 DTLookupEntry(const DTEntry searchPoint
, const char *pathName
, DTEntry
*foundEntry
)
234 if (!DTInitialized
) {
237 if (searchPoint
== NULL
) {
243 if (*cp
== kDTPathNameSeparator
) {
251 cp
= GetNextComponent(cp
, buf
);
262 cur
= FindChild(cur
, buf
);
264 } while (cur
!= NULL
);
270 DTCreateEntryIterator(const DTEntry startEntry
, DTEntryIterator
*iterator
)
272 RealDTEntryIterator iter
;
274 if (!DTInitialized
) {
278 iter
= (RealDTEntryIterator
) kalloc(sizeof(struct OpaqueDTEntryIterator
));
279 if (startEntry
!= NULL
) {
280 iter
->outerScope
= (RealDTEntry
) startEntry
;
281 iter
->currentScope
= (RealDTEntry
) startEntry
;
283 iter
->outerScope
= DTRootNode
;
284 iter
->currentScope
= DTRootNode
;
286 iter
->currentEntry
= NULL
;
287 iter
->savedScope
= NULL
;
288 iter
->currentIndex
= 0;
295 DTDisposeEntryIterator(DTEntryIterator iterator
)
297 RealDTEntryIterator iter
= iterator
;
298 DTSavedScopePtr scope
;
300 while ((scope
= iter
->savedScope
) != NULL
) {
301 iter
->savedScope
= scope
->nextScope
;
302 kfree((vm_offset_t
) scope
, sizeof(struct DTSavedScope
));
304 kfree((vm_offset_t
) iterator
, sizeof(struct OpaqueDTEntryIterator
));
309 DTEnterEntry(DTEntryIterator iterator
, DTEntry childEntry
)
311 RealDTEntryIterator iter
= iterator
;
312 DTSavedScopePtr newScope
;
314 if (childEntry
== NULL
) {
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
;
323 iter
->currentScope
= childEntry
;
324 iter
->currentEntry
= NULL
;
325 iter
->savedScope
= newScope
;
326 iter
->currentIndex
= 0;
332 DTExitEntry(DTEntryIterator iterator
, DTEntry
*currentPosition
)
334 RealDTEntryIterator iter
= iterator
;
335 DTSavedScopePtr newScope
;
337 newScope
= iter
->savedScope
;
338 if (newScope
== NULL
) {
341 iter
->savedScope
= newScope
->nextScope
;
342 iter
->currentScope
= newScope
->scope
;
343 iter
->currentEntry
= newScope
->entry
;
344 iter
->currentIndex
= newScope
->index
;
345 *currentPosition
= iter
->currentEntry
;
347 kfree((vm_offset_t
) newScope
, sizeof(struct DTSavedScope
));
353 DTIterateEntries(DTEntryIterator iterator
, DTEntry
*nextEntry
)
355 RealDTEntryIterator iter
= iterator
;
357 if (iter
->currentIndex
>= iter
->currentScope
->nChildren
) {
359 return kIterationDone
;
361 iter
->currentIndex
++;
362 if (iter
->currentIndex
== 1) {
363 iter
->currentEntry
= GetFirstChild(iter
->currentScope
);
365 iter
->currentEntry
= GetNextChild(iter
->currentEntry
);
367 *nextEntry
= iter
->currentEntry
;
373 DTRestartEntryIteration(DTEntryIterator iterator
)
375 RealDTEntryIterator iter
= iterator
;
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
;
383 while ((scope
= iter
->savedScope
) != NULL
) {
384 iter
->savedScope
= scope
->nextScope
;
385 kfree((vm_offset_t
) scope
, sizeof(struct DTSavedScope
));
387 iter
->currentScope
= iter
->outerScope
;
390 iter
->currentEntry
= NULL
;
391 iter
->currentIndex
= 0;
396 DTGetProperty(const DTEntry entry
, const char *propertyName
, void **propertyValue
, int *propertySize
)
398 DeviceTreeNodeProperty
*prop
;
401 if (entry
== NULL
|| entry
->nProperties
== 0) {
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
;
412 prop
= next_prop(prop
);
419 DTCreatePropertyIterator(const DTEntry entry
, DTPropertyIterator
*iterator
)
421 RealDTPropertyIterator iter
;
423 iter
= (RealDTPropertyIterator
) kalloc(sizeof(struct OpaqueDTPropertyIterator
));
425 iter
->currentProperty
= NULL
;
426 iter
->currentIndex
= 0;
433 DTDisposePropertyIterator(DTPropertyIterator iterator
)
435 kfree((vm_offset_t
)iterator
, sizeof(struct OpaqueDTPropertyIterator
));
440 DTIterateProperties(DTPropertyIterator iterator
, char **foundProperty
)
442 RealDTPropertyIterator iter
= iterator
;
444 if (iter
->currentIndex
>= iter
->entry
->nProperties
) {
445 *foundProperty
= NULL
;
446 return kIterationDone
;
448 iter
->currentIndex
++;
449 if (iter
->currentIndex
== 1) {
450 iter
->currentProperty
= (DeviceTreeNodeProperty
*) (iter
->entry
+ 1);
452 iter
->currentProperty
= next_prop(iter
->currentProperty
);
454 *foundProperty
= iter
->currentProperty
->name
;
460 DTRestartPropertyIteration(DTPropertyIterator iterator
)
462 RealDTPropertyIterator iter
= iterator
;
464 iter
->currentProperty
= NULL
;
465 iter
->currentIndex
= 0;