]>
git.saurik.com Git - apple/bootx.git/blob - bootx.tproj/sl.subproj/device_tree.c
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 * device_tree.c - Functions for flattening the Device Tree.
25 * Copyright (c) 1998-2000 Apple Computer, Inc.
31 #include <device_tree.h>
34 static long FlatenNode(CICell ph
, long nodeAddr
, long *nodeSize
);
35 static long FlatenProps(CICell ph
, long propAddr
, long *propSize
,
40 long FlattenDeviceTree(void)
45 gDeviceTreeAddr
= AllocateKernelMemory(0);
48 if (RootPH
== kCIError
) return -1;
50 ret
= FlatenNode(RootPH
, gDeviceTreeAddr
, &gDeviceTreeSize
);
52 AllocateKernelMemory(gDeviceTreeSize
);
58 CICell
SearchForNode(CICell ph
, long top
, char *prop
, char *value
)
60 CICell curChild
, result
;
62 if (ph
== 0) ph
= Peer(0);
65 // Look for it in the current node.
66 if (GetProp(ph
, prop
, gTempStr
, 4095) != -1) {
67 if (strcmp(value
, gTempStr
) == 0) {
73 // Look for it in the children.
76 while (curChild
!= 0) {
77 result
= SearchForNode(curChild
, 0, prop
, value
);
78 if (result
!= 0) return result
;
79 curChild
= Peer(curChild
);
85 while (curChild
!= 0) {
86 result
= SearchForNode(curChild
, 0, prop
, value
);
87 if (result
!= 0) return result
;
88 curChild
= Peer(curChild
);
99 CICell
SearchForNodeMatching(CICell ph
, long top
, char *value
)
101 CICell curChild
, result
;
103 if (ph
== 0) ph
= Peer(0);
106 // Look for it in the current node.
107 if (MatchThis(ph
, value
) == 0) return ph
;
110 // Look for it in the children.
111 curChild
= Child(ph
);
113 while (curChild
!= 0) {
114 result
= SearchForNodeMatching(curChild
, 0, value
);
115 if (result
!= 0) return result
;
116 curChild
= Peer(curChild
);
122 while (curChild
!= 0) {
123 result
= SearchForNodeMatching(curChild
, 0, value
);
124 if (result
!= 0) return result
;
125 curChild
= Peer(curChild
);
137 long FlatenNode(CICell ph
, long nodeAddr
, long *nodeSize
)
142 long propSize
, numProps
, childSize
, numChildren
;
144 node
= (DTNodePtr
)nodeAddr
;
145 curAddr
= nodeAddr
+ sizeof(DTNode
);
149 ret
= FlatenProps(ph
, curAddr
, &propSize
, &numProps
);
150 if (ret
!= 0) return ret
;
153 node
->nProperties
= numProps
;
156 if (childPH
== kCIError
) return -1;
158 while (childPH
!= 0) {
159 ret
= FlatenNode(childPH
, curAddr
, &childSize
);
160 curAddr
+= childSize
;
163 childPH
= Peer(childPH
);
164 if (childPH
== -1) return -1;
167 node
->nChildren
= numChildren
;
168 *nodeSize
= curAddr
- nodeAddr
;
174 long FlatenProps(CICell ph
, long propAddr
, long *propSize
, long *numProps
)
177 long ret
, cnt
, curAddr
, valueAddr
, valueSize
, nProps
;
184 // make the first property the phandle
185 prop
= (DTPropertyPtr
)curAddr
;
186 valueAddr
= curAddr
+ sizeof(DTProperty
);
187 strcpy(prop
->name
, "AAPL,phandle");
188 *((long *)valueAddr
) = ph
;
190 curAddr
= valueAddr
+ 4;
193 // Make the AAPL,unit-string property.
194 ret
= PackageToPath(ph
, gTempStr
, 4095);
197 while (cnt
&& (gTempStr
[cnt
- 1] != '@') &&
198 (gTempStr
[cnt
- 1] != '/')) cnt
--;
200 if (gTempStr
[cnt
- 1] == '@') {
201 prop
= (DTPropertyPtr
)curAddr
;
202 valueAddr
= curAddr
+ sizeof(DTProperty
);
203 strcpy(prop
->name
, "AAPL,unit-string");
204 strcpy((char *)valueAddr
, &gTempStr
[cnt
]);
205 prop
->length
= ret
- cnt
;
206 curAddr
= valueAddr
+ ((prop
->length
+ 3) & ~3);
212 prop
= (DTPropertyPtr
)curAddr
;
213 valueAddr
= curAddr
+ sizeof(DTProperty
);
215 ret
= NextProp(ph
, prevName
, prop
->name
);
216 if (ret
== -1) return -1;
219 valueSize
= GetProp(ph
, prop
->name
, (char *)valueAddr
,
220 kPropValueMaxLength
);
221 if (valueSize
== -1) return -1;
222 prop
->length
= valueSize
;
224 // Save the address of the value if this is
225 // the memory map property for the device tree.
226 if ((ph
== gMemoryMapPH
) && !strcmp(prop
->name
, "DeviceTree")) {
227 gDeviceTreeMMTmp
= (long *)valueAddr
;
231 curAddr
= valueAddr
+ ((valueSize
+ 3) & ~3);
232 prevName
= prop
->name
;
236 *propSize
= curAddr
- propAddr
;