|
|
1.1 root 1: \ *****************************************************************************
2: \ * Copyright (c) 2011 IBM Corporation
3: \ * All rights reserved.
4: \ * This program and the accompanying materials
5: \ * are made available under the terms of the BSD License
6: \ * which accompanies this distribution, and is available at
7: \ * http://www.opensource.org/licenses/bsd-license.php
8: \ *
9: \ * Contributors:
10: \ * IBM Corporation - initial implementation
11: \ ****************************************************************************/
12:
13: 0 VALUE fdt-debug
14:
15: \ Bail out if no fdt
16: fdt-start 0 = IF -1 throw THEN
17:
18: struct
19: 4 field >fdth_magic
20: 4 field >fdth_tsize
21: 4 field >fdth_struct_off
22: 4 field >fdth_string_off
23: 4 field >fdth_rsvmap_off
24: 4 field >fdth_version
25: 4 field >fdth_compat_vers
26: 4 field >fdth_boot_cpu
27: 4 field >fdth_string_size
28: 4 field >fdth_struct_size
29: drop
30:
31: h# d00dfeed constant OF_DT_HEADER
32: h# 1 constant OF_DT_BEGIN_NODE
33: h# 2 constant OF_DT_END_NODE
34: h# 3 constant OF_DT_PROP
35: h# 4 constant OF_DT_NOP
36: h# 9 constant OF_DT_END
37:
38: \ Create some variables early
39: fdt-start
40: dup dup >fdth_struct_off l@ + value fdt-struct
41: dup dup >fdth_string_off l@ + value fdt-strings
42: drop
43:
44: \ Dump fdt header for all to see and check FDT validity
45: : fdt-check-header ( -- )
46: fdt-start dup 0 = IF
47: ." No flat device tree !" cr drop -1 throw EXIT THEN
48: hex
49: fdt-debug IF
50: ." Flat device tree header at 0x" dup . s" :" type cr
51: ." magic : 0x" dup >fdth_magic l@ . cr
52: ." total size : 0x" dup >fdth_tsize l@ . cr
53: ." offset to struct : 0x" dup >fdth_struct_off l@ . cr
54: ." offset to strings: 0x" dup >fdth_string_off l@ . cr
55: ." offset to rsvmap : 0x" dup >fdth_rsvmap_off l@ . cr
56: ." version : " dup >fdth_version l@ decimal . hex cr
57: ." last compat vers : " dup >fdth_compat_vers l@ decimal . hex cr
58: dup >fdth_version l@ 2 >= IF
59: ." boot CPU : 0x" dup >fdth_boot_cpu l@ . cr
60: THEN
61: dup >fdth_version l@ 3 >= IF
62: ." strings size : 0x" dup >fdth_string_size l@ . cr
63: THEN
64: dup >fdth_version l@ 17 >= IF
65: ." struct size : 0x" dup >fdth_struct_size l@ . cr
66: THEN
67: THEN
68: dup >fdth_magic l@ OF_DT_HEADER <> IF
69: ." Flat device tree has incorrect magic value !" cr
70: drop -1 throw EXIT
71: THEN
72: dup >fdth_version l@ 10 < IF
73: ." Flat device tree has usupported version !" cr
74: drop -1 throw EXIT
75: THEN
76:
77: drop
78: ;
79: fdt-check-header
80:
81: \ Fetch next tag, skip nops and increment address
82: : fdt-next-tag ( addr -- nextaddr tag )
83: 0 ( dummy tag on stack for loop )
84: BEGIN
85: drop ( drop previous tag )
86: dup l@ ( read new tag )
87: swap 4 + swap ( increment addr )
88: dup OF_DT_NOP <> UNTIL ( loop until not nop )
89: ;
90:
91: \ Parse unit name and advance addr
92: : fdt-fetch-unit ( addr -- addr $name )
93: dup from-cstring \ get string size
94: 2dup + 1 + 3 + fffffffc and -rot
95: ;
96:
1.1.1.3 ! root 97: \ Update unit with information from the reg property...
! 98: \ ... this is required for the PCI nodes for example.
! 99: : fdt-reg-unit ( prop-addr prop-len -- )
! 100: s" #address-cells" get-parent get-package-property IF
! 101: 2drop
! 102: ELSE
! 103: decode-int nip nip ( prop-addr prop-len #addr-cells )
! 104: 3 <> IF
! 105: \ Ignore if #addr-cells is not 3, i.e. no PCI
! 106: 2drop EXIT
! 107: THEN
! 108: decode-phys ( prop-addr' prop-len' phys.lo ... phys.hi )
! 109: set-unit ( prop-addr' prop-len' )
! 110: 2drop
! 111: THEN
! 112: ;
! 113:
1.1 root 114: \ Lookup a string by index
1.1.1.3 ! root 115: : fdt-fetch-string ( index -- str-addr str-len )
1.1 root 116: fdt-strings + dup from-cstring
117: ;
118:
119: : fdt-create-dec s" decode-unit" $CREATE , DOES> @ hex-decode-unit ;
120: : fdt-create-enc s" encode-unit" $CREATE , DOES> @ hex-encode-unit ;
121:
1.1.1.3 ! root 122: \ Check whether array contains an zero-terminated ASCII string:
! 123: : fdt-prop-is-string? ( addr len -- string? )
! 124: dup 1 < IF 2drop FALSE EXIT THEN \ Check for valid length
! 125: 1-
! 126: 2dup + c@ 0<> IF 2drop FALSE EXIT THEN \ Check zero-termination
! 127: test-string
! 128: ;
! 129:
! 130: \ Encode fdt property to OF property
! 131: : fdt-encode-prop ( addr len -- )
! 132: 2dup fdt-prop-is-string? IF
! 133: 1- encode-string
! 134: ELSE
! 135: encode-bytes
! 136: THEN
! 137: ;
! 138:
1.1 root 139: \ Method to unflatten a node
140: : fdt-unflatten-node ( start -- end )
141: \ this can and will recurse
142: recursive
143:
144: \ Get & check first tag of node ( addr -- addr)
145: fdt-next-tag dup OF_DT_BEGIN_NODE <> IF
146: s" Weird tag 0x" type . " at start of node" type cr
147: -1 throw
148: THEN drop
149:
150: new-device
151:
152: \ Parse name, split unit address
153: fdt-fetch-unit
154: dup 0 = IF drop drop " /" THEN
155: 40 left-parse-string
156: \ Set name
157: device-name
158:
1.1.1.3 ! root 159: \ Set preliminary unit address - might get overwritten by reg property
1.1 root 160: dup IF
161: " #address-cells" get-parent get-package-property IF
162: 2drop
163: ELSE
164: decode-int nip nip
165: hex-decode-unit
166: set-unit
167: THEN
168: ELSE 2drop THEN
169:
170: \ Iterate sub tags
171: BEGIN
172: fdt-next-tag dup OF_DT_END_NODE <>
173: WHILE
174: dup OF_DT_PROP = IF
175: \ Found property
176: drop dup ( drop tag, dup addr : a1 a1 )
177: dup l@ dup rot 4 + ( fetch size, stack is : a1 s s a2)
178: dup l@ swap 4 + ( fetch nameid, stack is : a1 s s i a3 )
1.1.1.3 ! root 179: rot ( we now have: a1 s i a3 s )
! 180: fdt-encode-prop rot ( a1 s pa ps i)
! 181: fdt-fetch-string ( a1 s pa ps na ns )
! 182: 2dup s" reg" str= IF
! 183: 2swap 2dup fdt-reg-unit 2swap
! 184: THEN
1.1 root 185: property
186: + 8 + 3 + fffffffc and
187: ELSE dup OF_DT_BEGIN_NODE = IF
188: drop ( drop tag )
189: 4 -
190: fdt-unflatten-node
191: ELSE
192: drop -1 throw
193: THEN THEN
194: REPEAT drop \ drop tag
195:
196: \ Create encode/decode unit
197: " #address-cells" get-node get-package-property IF ELSE
198: decode-int dup fdt-create-dec fdt-create-enc 2drop
199: THEN
200:
201: finish-device
202: ;
203:
204: \ Start unflattening
205: : fdt-unflatten-tree
206: fdt-debug IF
207: ." Unflattening device tree..." cr THEN
208: fdt-struct fdt-unflatten-node drop
209: fdt-debug IF
210: ." Done !" cr THEN
211: ;
212: fdt-unflatten-tree
213:
214: \ Find memory size
215: : fdt-parse-memory
216: " /memory" find-device
217: " reg" get-node get-package-property IF throw -1 THEN
218:
219: \ XXX FIXME Assume one entry only in "reg" property for now
220: decode-phys 2drop decode-phys
221: my-#address-cells 1 > IF 20 << or THEN
222:
223: fdt-debug IF
224: dup ." Memory size: " . cr
225: THEN
1.1.1.2 root 226: \ claim.fs already released the memory between 0 and MIN-RAM-SIZE,
227: \ so we've got only to release the remaining memory now:
228: MIN-RAM-SIZE swap MIN-RAM-SIZE - release
1.1 root 229: 2drop device-end
230: ;
231: fdt-parse-memory
232:
233:
234: \ Claim fdt memory and reserve map
235: : fdt-claim-reserve
236: fdt-start
237: dup dup >fdth_tsize l@ 0 claim drop
238: dup >fdth_rsvmap_off l@ +
239: BEGIN
240: dup dup x@ swap 8 + x@
241: dup 0 <>
242: WHILE
243: fdt-debug IF
244: 2dup swap ." Reserve map entry: " . ." : " . cr
245: THEN
246: 0 claim drop
247: 10 +
248: REPEAT drop drop drop
249: ;
250: fdt-claim-reserve
251:
1.1.1.3 ! root 252:
! 253: \ The following functions are use to replace the FDT phandle and
! 254: \ linux,phandle properties with our own OF1275 phandles...
! 255:
! 256: \ This is used to check whether we successfully replaced a phandle value
! 257: 0 VALUE (fdt-phandle-replaced)
! 258:
! 259: \ Replace phandle value in "interrupt-map" property
! 260: : fdt-replace-interrupt-map ( old new prop-addr prop-len -- old new )
! 261: BEGIN
! 262: dup ( old new prop-addr prop-len prop-len )
! 263: WHILE
! 264: \ This is a little bit ugly ... we're accessing the property at
! 265: \ hard-coded offsets instead of analyzing it completely...
! 266: swap dup 10 + ( old new prop-len prop-addr prop-addr+10 )
! 267: dup l@ 5 pick = IF
! 268: \ it matches the old phandle value!
! 269: 3 pick swap l!
! 270: TRUE TO (fdt-phandle-replaced)
! 271: ELSE
! 272: drop
! 273: THEN
! 274: ( old new prop-len prop-addr )
! 275: 1c + swap 1c -
! 276: ( old new new-prop-addr new-prop-len )
! 277: REPEAT
! 278: 2drop
! 279: ;
! 280:
! 281: \ Replace one FDT phandle "old" with a OF1275 phandle "new" in the
! 282: \ whole tree:
! 283: : fdt-replace-all-phandles ( old new node -- )
! 284: \ ." Replacing in " dup node>path type cr
! 285: >r
! 286: s" interrupt-map" r@ get-property 0= IF
! 287: ( old new prop-addr prop-len R: node )
! 288: fdt-replace-interrupt-map
! 289: THEN
! 290: s" interrupt-parent" r@ get-property 0= IF
! 291: ( old new prop-addr prop-len R: node )
! 292: decode-int -rot 2drop ( old new val R: node )
! 293: 2 pick = IF ( old new R: node )
! 294: dup encode-int s" interrupt-parent" r@ set-property
! 295: TRUE TO (fdt-phandle-replaced)
! 296: THEN
! 297: THEN
! 298: \ ... add more properties that have to be fixed here ...
! 299: r>
! 300: \ Now recurse over all child nodes: ( old new node )
! 301: child BEGIN
! 302: dup
! 303: WHILE
! 304: 3dup RECURSE
! 305: PEER
! 306: REPEAT
! 307: 3drop
! 308: ;
! 309:
! 310: \ Check whether a node has "phandle" or "linux,phandle" properties
! 311: \ and replace them:
! 312: : fdt-fix-node-phandle ( node -- )
! 313: >r
! 314: FALSE TO (fdt-phandle-replaced)
! 315: s" phandle" r@ get-property 0= IF
! 316: decode-int ( p-addr2 p-len2 val )
! 317: \ ." found phandle: " dup . cr
! 318: r@ s" /" find-node ( p-addr2 p-len2 val node root )
! 319: fdt-replace-all-phandles ( p-addr2 p-len2 )
! 320: 2drop
! 321: (fdt-phandle-replaced) IF
! 322: r@ set-node
! 323: s" phandle" delete-property
! 324: s" linux,phandle" delete-property
! 325: ELSE
! 326: diagnostic-mode? IF
! 327: cr ." Warning: Did not replace phandle in " r@ node>path type cr
! 328: THEN
! 329: THEN
! 330: THEN
! 331: r> drop
! 332: ;
! 333:
! 334: \ Recursively walk through all nodes to fix their phandles:
! 335: : fdt-fix-phandles ( node -- )
! 336: \ ." fixing phandles of " dup node>path type cr
! 337: dup fdt-fix-node-phandle
! 338: child BEGIN
! 339: dup
! 340: WHILE
! 341: dup RECURSE
! 342: PEER
! 343: REPEAT
! 344: drop
! 345: device-end
! 346: ;
! 347: s" /" find-node fdt-fix-phandles
! 348:
! 349:
1.1 root 350: \ Remaining bits from root.fs
351:
352: defer (client-exec)
353: defer client-exec
354:
355: \ defined in slof/fs/client.fs
356: defer callback
357: defer continue-client
358:
359: : set-chosen ( prop len name len -- )
360: s" /chosen" find-node set-property ;
361:
362: : get-chosen ( name len -- [ prop len ] success )
363: s" /chosen" find-node get-property 0= ;
364:
365: " /" find-device
366:
367: new-device
368: s" aliases" device-name
369: finish-device
370:
371: new-device
372: s" options" device-name
373: finish-device
374:
375: new-device
376: s" openprom" device-name
377: s" BootROM" device-type
378: finish-device
379:
380: new-device
381: #include <packages.fs>
382: finish-device
383:
384: : open true ;
385: : close ;
386:
387: device-end
388:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.