2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * @OSF_FREE_COPYRIGHT@
29 #include <pexpert/protos.h>
30 #include <pexpert/boot.h>
31 #include <pexpert/device_tree.h>
32 #include <mach/machine/vm_types.h>
33 #include <sys/types.h>
35 #include <i386/fakePPCStructs.h>
39 #define NULL ((void *) 0)
42 #define round_long(x) (((x) + 3) & -4)
43 #define next_prop(x) ((DeviceTreeNodeProperty *) (((int)x) + sizeof(DeviceTreeNodeProperty) + round_long(x->length)))
46 typedef DeviceTreeNode
*RealDTEntry
;
48 typedef struct DTSavedScope
{
49 struct DTSavedScope
* nextScope
;
56 typedef struct OpaqueDTEntryIterator
{
57 RealDTEntry outerScope
;
58 RealDTEntry currentScope
;
59 RealDTEntry currentEntry
;
60 DTSavedScopePtr savedScope
;
61 unsigned long currentIndex
;
62 } *RealDTEntryIterator
;
64 /* Property Iterator*/
65 typedef struct OpaqueDTPropertyIterator
{
67 DeviceTreeNodeProperty
*currentProperty
;
68 unsigned long currentIndex
;
69 } *RealDTPropertyIterator
;
71 static int DTInitialized
;
72 static RealDTEntry DTRootNode
;
74 void DTInit(void *base
);
80 skipProperties(RealDTEntry entry
)
82 DeviceTreeNodeProperty
*prop
;
85 if (entry
== NULL
|| entry
->nProperties
== 0) {
88 prop
= (DeviceTreeNodeProperty
*) (entry
+ 1);
89 for (k
= 0; k
< entry
->nProperties
; k
++) {
90 prop
= next_prop(prop
);
93 return ((RealDTEntry
) prop
);
97 skipTree(RealDTEntry root
)
102 entry
= skipProperties(root
);
106 for (k
= 0; k
< root
->nChildren
; k
++) {
107 entry
= skipTree(entry
);
113 GetFirstChild(RealDTEntry parent
)
115 return skipProperties(parent
);
119 GetNextChild(RealDTEntry sibling
)
121 return skipTree(sibling
);
125 GetNextComponent(const char *cp
, char *bp
)
128 if (*cp
== kDTPathNameSeparator
) {
139 FindChild(RealDTEntry cur
, char *buf
)
146 if (cur
->nChildren
== 0) {
150 child
= GetFirstChild(cur
);
152 if (DTGetProperty(child
, "name", (void **)&str
, &dummy
) != kSuccess
) {
155 if (strcmp(str
, buf
) == 0) {
158 if (index
>= cur
->nChildren
) {
161 child
= GetNextChild(child
);
174 DTRootNode
= (RealDTEntry
) base
;
175 DTInitialized
= (DTRootNode
!= 0);
179 DTEntryIsEqual(const DTEntry ref1
, const DTEntry ref2
)
181 /* equality of pointers */
182 return (ref1
== ref2
);
185 static char *startingP
; // needed for find_entry
186 int find_entry(const char *propName
, const char *propValue
, DTEntry
*entryH
);
188 int DTFindEntry(const char *propName
, const char *propValue
, DTEntry
*entryH
)
190 if (!DTInitialized
) {
194 startingP
= (char *)DTRootNode
;
195 return(find_entry(propName
, propValue
, entryH
));
198 int find_entry(const char *propName
, const char *propValue
, DTEntry
*entryH
)
200 DeviceTreeNode
*nodeP
= (DeviceTreeNode
*) startingP
;
203 if (nodeP
->nProperties
== 0) return(kError
); // End of the list of nodes
204 startingP
= (char *) (nodeP
+ 1);
206 // Search current entry
207 for (k
= 0; k
< nodeP
->nProperties
; ++k
) {
208 DeviceTreeNodeProperty
*propP
= (DeviceTreeNodeProperty
*) startingP
;
210 startingP
+= sizeof (*propP
) + ((propP
->length
+ 3) & -4);
212 if (strcmp (propP
->name
, propName
) == 0) {
213 if (strcmp( (char *)(propP
+ 1), propValue
) == 0)
215 *entryH
= (DTEntry
)nodeP
;
221 // Search child nodes
222 for (k
= 0; k
< nodeP
->nChildren
; ++k
)
224 if (find_entry(propName
, propValue
, entryH
) == kSuccess
)
231 DTLookupEntry(const DTEntry searchPoint
, const char *pathName
, DTEntry
*foundEntry
)
237 if (!DTInitialized
) {
240 if (searchPoint
== NULL
) {
246 if (*cp
== kDTPathNameSeparator
) {
254 cp
= GetNextComponent(cp
, buf
);
265 cur
= FindChild(cur
, buf
);
267 } while (cur
!= NULL
);
273 DTCreateEntryIterator(const DTEntry startEntry
, DTEntryIterator
*iterator
)
275 RealDTEntryIterator iter
;
277 if (!DTInitialized
) {
281 iter
= (RealDTEntryIterator
) kalloc(sizeof(struct OpaqueDTEntryIterator
));
282 if (startEntry
!= NULL
) {
283 iter
->outerScope
= (RealDTEntry
) startEntry
;
284 iter
->currentScope
= (RealDTEntry
) startEntry
;
286 iter
->outerScope
= DTRootNode
;
287 iter
->currentScope
= DTRootNode
;
289 iter
->currentEntry
= NULL
;
290 iter
->savedScope
= NULL
;
291 iter
->currentIndex
= 0;
298 DTDisposeEntryIterator(DTEntryIterator iterator
)
300 RealDTEntryIterator iter
= iterator
;
301 DTSavedScopePtr scope
;
303 while ((scope
= iter
->savedScope
) != NULL
) {
304 iter
->savedScope
= scope
->nextScope
;
305 kfree((vm_offset_t
) scope
, sizeof(struct DTSavedScope
));
307 kfree((vm_offset_t
) iterator
, sizeof(struct OpaqueDTEntryIterator
));
312 DTEnterEntry(DTEntryIterator iterator
, DTEntry childEntry
)
314 RealDTEntryIterator iter
= iterator
;
315 DTSavedScopePtr newScope
;
317 if (childEntry
== NULL
) {
320 newScope
= (DTSavedScopePtr
) kalloc(sizeof(struct DTSavedScope
));
321 newScope
->nextScope
= iter
->savedScope
;
322 newScope
->scope
= iter
->currentScope
;
323 newScope
->entry
= iter
->currentEntry
;
324 newScope
->index
= iter
->currentIndex
;
326 iter
->currentScope
= childEntry
;
327 iter
->currentEntry
= NULL
;
328 iter
->savedScope
= newScope
;
329 iter
->currentIndex
= 0;
335 DTExitEntry(DTEntryIterator iterator
, DTEntry
*currentPosition
)
337 RealDTEntryIterator iter
= iterator
;
338 DTSavedScopePtr newScope
;
340 newScope
= iter
->savedScope
;
341 if (newScope
== NULL
) {
344 iter
->savedScope
= newScope
->nextScope
;
345 iter
->currentScope
= newScope
->scope
;
346 iter
->currentEntry
= newScope
->entry
;
347 iter
->currentIndex
= newScope
->index
;
348 *currentPosition
= iter
->currentEntry
;
350 kfree((vm_offset_t
) newScope
, sizeof(struct DTSavedScope
));
356 DTIterateEntries(DTEntryIterator iterator
, DTEntry
*nextEntry
)
358 RealDTEntryIterator iter
= iterator
;
360 if (iter
->currentIndex
>= iter
->currentScope
->nChildren
) {
362 return kIterationDone
;
364 iter
->currentIndex
++;
365 if (iter
->currentIndex
== 1) {
366 iter
->currentEntry
= GetFirstChild(iter
->currentScope
);
368 iter
->currentEntry
= GetNextChild(iter
->currentEntry
);
370 *nextEntry
= iter
->currentEntry
;
376 DTRestartEntryIteration(DTEntryIterator iterator
)
378 RealDTEntryIterator iter
= iterator
;
380 // This commented out code allows a second argument (outer)
381 // which (if true) causes restarting at the outer scope
382 // rather than the current scope.
383 DTSavedScopePtr scope
;
386 while ((scope
= iter
->savedScope
) != NULL
) {
387 iter
->savedScope
= scope
->nextScope
;
388 kfree((vm_offset_t
) scope
, sizeof(struct DTSavedScope
));
390 iter
->currentScope
= iter
->outerScope
;
393 iter
->currentEntry
= NULL
;
394 iter
->currentIndex
= 0;
399 DTGetProperty(const DTEntry entry
, const char *propertyName
, void **propertyValue
, int *propertySize
)
401 DeviceTreeNodeProperty
*prop
;
404 if (entry
== NULL
|| entry
->nProperties
== 0) {
407 prop
= (DeviceTreeNodeProperty
*) (entry
+ 1);
408 for (k
= 0; k
< entry
->nProperties
; k
++) {
409 if (strcmp(prop
->name
, propertyName
) == 0) {
410 *propertyValue
= (void *) (((int)prop
)
411 + sizeof(DeviceTreeNodeProperty
));
412 *propertySize
= prop
->length
;
415 prop
= next_prop(prop
);
422 DTCreatePropertyIterator(const DTEntry entry
, DTPropertyIterator
*iterator
)
424 RealDTPropertyIterator iter
;
426 iter
= (RealDTPropertyIterator
) kalloc(sizeof(struct OpaqueDTPropertyIterator
));
428 iter
->currentProperty
= NULL
;
429 iter
->currentIndex
= 0;
436 DTDisposePropertyIterator(DTPropertyIterator iterator
)
438 kfree((vm_offset_t
)iterator
, sizeof(struct OpaqueDTPropertyIterator
));
443 DTIterateProperties(DTPropertyIterator iterator
, char **foundProperty
)
445 RealDTPropertyIterator iter
= iterator
;
447 if (iter
->currentIndex
>= iter
->entry
->nProperties
) {
448 *foundProperty
= NULL
;
449 return kIterationDone
;
451 iter
->currentIndex
++;
452 if (iter
->currentIndex
== 1) {
453 iter
->currentProperty
= (DeviceTreeNodeProperty
*) (iter
->entry
+ 1);
455 iter
->currentProperty
= next_prop(iter
->currentProperty
);
457 *foundProperty
= iter
->currentProperty
->name
;
463 DTRestartPropertyIteration(DTPropertyIterator iterator
)
465 RealDTPropertyIterator iter
= iterator
;
467 iter
->currentProperty
= NULL
;
468 iter
->currentIndex
= 0;