673 lines
18 KiB
Forth
673 lines
18 KiB
Forth
\ *****************************************************************************
|
|
\ * Copyright (c) 2011 IBM Corporation
|
|
\ * All rights reserved.
|
|
\ * This program and the accompanying materials
|
|
\ * are made available under the terms of the BSD License
|
|
\ * which accompanies this distribution, and is available at
|
|
\ * http://www.opensource.org/licenses/bsd-license.php
|
|
\ *
|
|
\ * Contributors:
|
|
\ * IBM Corporation - initial implementation
|
|
\ ****************************************************************************/
|
|
|
|
0 VALUE fdt-debug
|
|
TRUE VALUE fdt-cas-fix?
|
|
0 VALUE fdt-cas-pass
|
|
0 VALUE fdt-generation#
|
|
|
|
: fdt-update-from-fdt ( -- )
|
|
fdt-generation# encode-int s" slof,from-fdt" property
|
|
;
|
|
|
|
\ Bail out if no fdt
|
|
fdt-start 0 = IF -1 throw THEN
|
|
|
|
struct
|
|
4 field >fdth_magic
|
|
4 field >fdth_tsize
|
|
4 field >fdth_struct_off
|
|
4 field >fdth_string_off
|
|
4 field >fdth_rsvmap_off
|
|
4 field >fdth_version
|
|
4 field >fdth_compat_vers
|
|
4 field >fdth_boot_cpu
|
|
4 field >fdth_string_size
|
|
4 field >fdth_struct_size
|
|
constant /fdth
|
|
|
|
h# d00dfeed constant OF_DT_HEADER
|
|
h# 1 constant OF_DT_BEGIN_NODE
|
|
h# 2 constant OF_DT_END_NODE
|
|
h# 3 constant OF_DT_PROP
|
|
h# 4 constant OF_DT_NOP
|
|
h# 9 constant OF_DT_END
|
|
|
|
\ Create some variables early
|
|
0 value fdt-start-addr
|
|
0 value fdt-struct
|
|
0 value fdt-strings
|
|
|
|
: fdt-init ( fdt-start -- )
|
|
dup to fdt-start-addr
|
|
dup dup >fdth_struct_off l@ + to fdt-struct
|
|
dup dup >fdth_string_off l@ + to fdt-strings
|
|
drop
|
|
;
|
|
fdt-start fdt-init
|
|
|
|
\ Dump fdt header for all to see and check FDT validity
|
|
: fdt-check-header ( -- )
|
|
fdt-start-addr dup 0 = IF
|
|
." No flat device tree !" cr drop -1 throw EXIT THEN
|
|
hex
|
|
fdt-debug IF
|
|
." Flat device tree header at 0x" dup . s" :" type cr
|
|
." magic : 0x" dup >fdth_magic l@ . cr
|
|
." total size : 0x" dup >fdth_tsize l@ . cr
|
|
." offset to struct : 0x" dup >fdth_struct_off l@ . cr
|
|
." offset to strings: 0x" dup >fdth_string_off l@ . cr
|
|
." offset to rsvmap : 0x" dup >fdth_rsvmap_off l@ . cr
|
|
." version : " dup >fdth_version l@ decimal . hex cr
|
|
." last compat vers : " dup >fdth_compat_vers l@ decimal . hex cr
|
|
dup >fdth_version l@ 2 >= IF
|
|
." boot CPU : 0x" dup >fdth_boot_cpu l@ . cr
|
|
THEN
|
|
dup >fdth_version l@ 3 >= IF
|
|
." strings size : 0x" dup >fdth_string_size l@ . cr
|
|
THEN
|
|
dup >fdth_version l@ 11 >= IF
|
|
." struct size : 0x" dup >fdth_struct_size l@ . cr
|
|
THEN
|
|
THEN
|
|
dup >fdth_magic l@ OF_DT_HEADER <> IF
|
|
." Flat device tree has incorrect magic value !" cr
|
|
drop -1 throw EXIT
|
|
THEN
|
|
dup >fdth_version l@ 10 < IF
|
|
." Flat device tree has usupported version !" cr
|
|
drop -1 throw EXIT
|
|
THEN
|
|
|
|
drop
|
|
;
|
|
fdt-check-header
|
|
|
|
\ Fetch next tag, skip nops and increment address
|
|
: fdt-next-tag ( addr -- nextaddr tag )
|
|
0 ( dummy tag on stack for loop )
|
|
BEGIN
|
|
drop ( drop previous tag )
|
|
dup l@ ( read new tag )
|
|
swap 4 + swap ( increment addr )
|
|
dup OF_DT_NOP <> UNTIL ( loop until not nop )
|
|
;
|
|
|
|
\ Parse unit name and advance addr
|
|
: fdt-fetch-unit ( addr -- addr $name )
|
|
dup from-cstring \ get string size
|
|
2dup + 1 + 3 + fffffffc and -rot
|
|
;
|
|
|
|
\ Update unit with information from the reg property...
|
|
\ ... this is required for the PCI nodes for example.
|
|
: fdt-reg-unit ( prop-addr prop-len -- )
|
|
decode-phys ( prop-addr' prop-len' phys.lo ... phys.hi )
|
|
set-unit ( prop-addr' prop-len' )
|
|
2drop
|
|
;
|
|
|
|
\ Lookup a string by index
|
|
: fdt-fetch-string ( index -- str-addr str-len )
|
|
fdt-strings + dup from-cstring
|
|
;
|
|
|
|
: fdt-create-dec s" decode-unit" $CREATE , DOES> @ hex64-decode-unit ;
|
|
: fdt-create-enc s" encode-unit" $CREATE , DOES> @ hex64-encode-unit ;
|
|
|
|
\ Check whether array contains an zero-terminated ASCII string:
|
|
: fdt-prop-is-string? ( addr len -- string? )
|
|
dup 1 < IF 2drop FALSE EXIT THEN \ Check for valid length
|
|
1-
|
|
2dup + c@ 0<> IF 2drop FALSE EXIT THEN \ Check zero-termination
|
|
test-string
|
|
;
|
|
|
|
\ Encode fdt property to OF property
|
|
: fdt-encode-prop ( addr len -- pa ps )
|
|
2dup fdt-prop-is-string? IF
|
|
1- encode-string
|
|
ELSE
|
|
encode-bytes
|
|
THEN
|
|
;
|
|
|
|
\ Method to unflatten a node
|
|
: fdt-unflatten-node ( start -- end )
|
|
\ this can and will recurse
|
|
recursive
|
|
|
|
\ Get & check first tag of node ( addr -- addr)
|
|
fdt-next-tag dup OF_DT_BEGIN_NODE <> IF
|
|
s" Weird tag 0x" type . " at start of node" type cr
|
|
-1 throw
|
|
THEN drop
|
|
|
|
new-device
|
|
|
|
\ Parse name, split unit address
|
|
fdt-fetch-unit
|
|
dup 0 = IF drop drop " /" THEN
|
|
40 left-parse-string
|
|
\ Set name
|
|
device-name
|
|
|
|
\ Set preliminary unit address - might get overwritten by reg property
|
|
dup IF
|
|
" #address-cells" get-parent get-package-property IF
|
|
2drop
|
|
ELSE
|
|
decode-int nip nip
|
|
hex-decode-unit
|
|
set-unit
|
|
THEN
|
|
ELSE 2drop THEN
|
|
|
|
\ Iterate sub tags
|
|
BEGIN
|
|
fdt-next-tag dup OF_DT_END_NODE <>
|
|
WHILE
|
|
dup OF_DT_PROP = IF
|
|
\ Found property
|
|
drop dup ( drop tag, dup addr : a1 a1 )
|
|
dup l@ dup rot 4 + ( fetch size, stack is : a1 s s a2)
|
|
dup l@ swap 4 + ( fetch nameid, stack is : a1 s s i a3 )
|
|
rot ( we now have: a1 s i a3 s )
|
|
fdt-encode-prop rot ( a1 s pa ps i)
|
|
fdt-fetch-string ( a1 s pa ps na ns )
|
|
2dup s" reg" str= IF
|
|
2swap 2dup fdt-reg-unit 2swap
|
|
THEN
|
|
property
|
|
+ 8 + 3 + fffffffc and
|
|
ELSE dup OF_DT_BEGIN_NODE = IF
|
|
drop ( drop tag )
|
|
4 -
|
|
fdt-unflatten-node
|
|
ELSE
|
|
drop -1 throw
|
|
THEN THEN
|
|
REPEAT drop \ drop tag
|
|
|
|
\ Create encode/decode unit
|
|
" #address-cells" get-node get-package-property IF ELSE
|
|
decode-int dup fdt-create-dec fdt-create-enc 2drop
|
|
THEN
|
|
|
|
fdt-update-from-fdt
|
|
|
|
finish-device
|
|
;
|
|
|
|
\ Start unflattening
|
|
: fdt-unflatten-tree
|
|
fdt-debug IF
|
|
." Unflattening device tree..." cr THEN
|
|
fdt-struct fdt-unflatten-node drop
|
|
fdt-debug IF
|
|
." Done !" cr THEN
|
|
;
|
|
fdt-unflatten-tree
|
|
|
|
\ Find memory size
|
|
: fdt-parse-memory
|
|
\ XXX FIXME Handle more than one memory node, and deal
|
|
\ with RMA vs. full access
|
|
" /memory@0" find-device
|
|
" reg" get-node get-package-property IF throw -1 THEN
|
|
|
|
\ XXX FIXME Assume one entry only in "reg" property for now
|
|
decode-phys 2drop decode-phys
|
|
my-#address-cells 1 > IF 20 << or THEN
|
|
|
|
fdt-debug IF
|
|
dup ." Memory size: " . cr
|
|
THEN
|
|
\ claim.fs already released the memory between 0 and MIN-RAM-SIZE,
|
|
\ so we've got only to release the remaining memory now:
|
|
MIN-RAM-SIZE swap MIN-RAM-SIZE - release
|
|
2drop device-end
|
|
;
|
|
fdt-parse-memory
|
|
|
|
|
|
\ Claim fdt memory and reserve map
|
|
: fdt-claim-reserve
|
|
fdt-start-addr
|
|
dup dup >fdth_tsize l@ 0 claim drop
|
|
dup >fdth_rsvmap_off l@ +
|
|
BEGIN
|
|
dup dup x@ swap 8 + x@
|
|
dup 0 <>
|
|
WHILE
|
|
fdt-debug IF
|
|
2dup swap ." Reserve map entry: " . ." : " . cr
|
|
THEN
|
|
0 claim drop
|
|
10 +
|
|
REPEAT drop drop drop
|
|
;
|
|
fdt-claim-reserve
|
|
|
|
|
|
\ The following functions are use to replace the FDT phandle and
|
|
\ linux,phandle properties with our own OF1275 phandles...
|
|
|
|
\ This is used to check whether we successfully replaced a phandle value
|
|
0 VALUE (fdt-phandle-replaced)
|
|
|
|
\ Replace phandle value in "interrupt-map" property
|
|
: fdt-replace-interrupt-map ( old new prop-addr prop-len -- old new )
|
|
BEGIN
|
|
dup ( old new prop-addr prop-len prop-len )
|
|
WHILE
|
|
\ This is a little bit ugly ... we're accessing the property at
|
|
\ hard-coded offsets instead of analyzing it completely...
|
|
swap dup 10 + ( old new prop-len prop-addr prop-addr+10 )
|
|
dup l@ 5 pick = IF
|
|
\ it matches the old phandle value!
|
|
3 pick swap l!
|
|
TRUE TO (fdt-phandle-replaced)
|
|
ELSE
|
|
drop
|
|
THEN
|
|
( old new prop-len prop-addr )
|
|
1c + swap 1c -
|
|
( old new new-prop-addr new-prop-len )
|
|
REPEAT
|
|
2drop
|
|
;
|
|
|
|
: (fdt-replace-phandles) ( old new propname propnamelen node -- )
|
|
get-property IF 2drop EXIT THEN
|
|
BEGIN
|
|
dup
|
|
WHILE ( old new prop-addr prop-len )
|
|
over l@
|
|
4 pick = IF
|
|
2 pick 2 pick l! \ replace old with new in place
|
|
TRUE TO (fdt-phandle-replaced)
|
|
THEN
|
|
4 - swap 4 + swap
|
|
REPEAT
|
|
2drop 2drop
|
|
;
|
|
|
|
: (phandle>node) ( phandle current -- node|0 )
|
|
dup s" phandle" rot get-property 0= IF
|
|
decode-int nip nip ( phandle current phandle-prop )
|
|
2 pick = IF
|
|
fdt-debug IF ." Found phandle; " dup . ." <= " over . cr THEN
|
|
nip ( current )
|
|
EXIT
|
|
THEN
|
|
ELSE
|
|
dup s" linux-phandle" rot get-property 0= IF
|
|
decode-int nip nip ( phandle current phandle-prop )
|
|
2 pick = IF
|
|
fdt-debug IF ." Found linux-phandle; " dup . ." <= " over . cr THEN
|
|
nip ( current )
|
|
EXIT
|
|
THEN
|
|
THEN
|
|
THEN
|
|
child BEGIN
|
|
dup
|
|
WHILE
|
|
2dup
|
|
RECURSE
|
|
?dup 0<> IF
|
|
nip nip
|
|
EXIT
|
|
THEN
|
|
PEER
|
|
REPEAT
|
|
2drop 0
|
|
;
|
|
|
|
: phandle>node ( phandle -- node ) s" /" find-node (phandle>node) ;
|
|
|
|
: (fdt-patch-phandles) ( prop-addr prop-len -- )
|
|
BEGIN
|
|
dup
|
|
WHILE ( prop-addr prop-len )
|
|
over l@ phandle>node
|
|
?dup 0<> IF
|
|
fdt-debug IF ." ### Patching phandle=" 2 pick l@ . cr THEN
|
|
2 pick l!
|
|
TRUE TO (fdt-phandle-replaced)
|
|
THEN
|
|
4 - swap 4 + swap
|
|
REPEAT
|
|
2drop
|
|
;
|
|
|
|
: (fdt-patch-interrupt-map) ( prop-addr prop-len -- )
|
|
\ interrupt-controller phandle is expected to be the same accross the map
|
|
over 10 + l@ phandle>node ?dup 0= IF 2drop EXIT THEN
|
|
-rot
|
|
fdt-debug IF ." ### Patching interrupt-map: " over 10 + l@ . ." => " 2 pick . cr THEN
|
|
|
|
TRUE TO (fdt-phandle-replaced)
|
|
BEGIN
|
|
dup
|
|
WHILE ( newph prop-addr prop-len )
|
|
2 pick 2 pick 10 + l!
|
|
1c - swap 1c + swap
|
|
REPEAT
|
|
3drop
|
|
;
|
|
|
|
: fdt-patch-phandles ( prop-addr prop-len nameadd namelen -- )
|
|
2dup s" interrupt-map" str= IF 2drop (fdt-patch-interrupt-map) EXIT THEN
|
|
2dup s" interrupt-parent" str= IF 2drop (fdt-patch-phandles) EXIT THEN
|
|
2dup s" ibm,gpu" str= IF 2drop (fdt-patch-phandles) EXIT THEN
|
|
2dup s" ibm,npu" str= IF 2drop (fdt-patch-phandles) EXIT THEN
|
|
2dup s" ibm,nvlink" str= IF 2drop (fdt-patch-phandles) EXIT THEN
|
|
2dup s" memory-region" str= IF 2drop (fdt-patch-phandles) EXIT THEN
|
|
4drop
|
|
;
|
|
|
|
\ Replace one phandle "old" with a phandle "new" in "node" and recursively
|
|
\ in its child nodes:
|
|
: fdt-replace-all-phandles ( old new node -- )
|
|
\ ." Replacing in " dup node>path type cr
|
|
>r
|
|
s" interrupt-map" r@ get-property 0= IF
|
|
( old new prop-addr prop-len R: node )
|
|
fdt-replace-interrupt-map
|
|
THEN
|
|
|
|
2dup s" interrupt-parent" r@ (fdt-replace-phandles)
|
|
2dup s" ibm,gpu" r@ (fdt-replace-phandles)
|
|
2dup s" ibm,npu" r@ (fdt-replace-phandles)
|
|
2dup s" ibm,nvlink" r@ (fdt-replace-phandles)
|
|
2dup s" memory-region" r@ (fdt-replace-phandles)
|
|
|
|
\ ... add more properties that have to be fixed here ...
|
|
r>
|
|
\ Now recurse over all child nodes: ( old new node )
|
|
child BEGIN
|
|
dup
|
|
WHILE
|
|
3dup RECURSE
|
|
PEER
|
|
REPEAT
|
|
3drop
|
|
;
|
|
|
|
\ Replace one FDT phandle "val" with a OF1275 phandle "node" in the
|
|
\ whole tree:
|
|
: fdt-update-phandle ( val node -- )
|
|
>r
|
|
FALSE TO (fdt-phandle-replaced)
|
|
r@ s" /" find-node ( val node root )
|
|
fdt-replace-all-phandles
|
|
(fdt-phandle-replaced) IF
|
|
r@ set-node
|
|
s" phandle" delete-property
|
|
s" linux,phandle" delete-property
|
|
ELSE
|
|
diagnostic-mode? IF
|
|
cr ." Warning: Did not replace phandle in " r@ node>path type cr
|
|
THEN
|
|
THEN
|
|
r> drop
|
|
;
|
|
|
|
\ Check whether a node has "phandle" or "linux,phandle" properties
|
|
\ and replace them:
|
|
: fdt-fix-node-phandle ( node -- )
|
|
>r
|
|
s" phandle" r@ get-property 0= IF
|
|
decode-int nip nip
|
|
\ ." found phandle: " dup . cr
|
|
r@ fdt-update-phandle
|
|
THEN
|
|
r> drop
|
|
;
|
|
|
|
\ Recursively walk through all nodes to fix their phandles:
|
|
: fdt-fix-phandles ( node -- )
|
|
\ ." fixing phandles of " dup node>path type cr
|
|
dup fdt-fix-node-phandle
|
|
child BEGIN
|
|
dup
|
|
WHILE
|
|
dup RECURSE
|
|
PEER
|
|
REPEAT
|
|
drop
|
|
device-end
|
|
;
|
|
|
|
: str=phandle? ( s len -- true|false )
|
|
2dup s" phandle" str= >r
|
|
s" linux,phandle" str=
|
|
r> or
|
|
;
|
|
|
|
: fdt-cas-finish-device ( -- )
|
|
" reg" get-node get-package-property IF ELSE fdt-reg-unit THEN
|
|
get-node finish-device set-node
|
|
;
|
|
|
|
: (fdt-fix-cas-node) ( start -- end )
|
|
recursive
|
|
fdt-next-tag dup OF_DT_BEGIN_NODE <> IF
|
|
." Error " cr
|
|
false to fdt-cas-fix?
|
|
EXIT
|
|
THEN drop
|
|
fdt-fetch-unit ( a1 $name )
|
|
dup 0 = IF drop drop " /" THEN
|
|
40 left-parse-string
|
|
2swap ?dup 0 <> IF
|
|
nip
|
|
1 + + \ Add the string len +@
|
|
ELSE
|
|
drop
|
|
THEN
|
|
|
|
fdt-cas-pass 0= IF
|
|
\ The guest might have asked to change the interrupt controller
|
|
\ type. It doesn't make sense to merge the new node and the
|
|
\ existing "interrupt-controller" node in this case. Delete the
|
|
\ latter. A brand new one will be created with the appropriate
|
|
\ properties and unit name.
|
|
2dup " interrupt-controller" find-substr 0= IF
|
|
" interrupt-controller" find-node ?dup 0 <> IF
|
|
fdt-debug IF ." Deleting existing node: " dup .node cr THEN
|
|
delete-node
|
|
THEN
|
|
THEN
|
|
THEN
|
|
2dup find-node ?dup 0 <> IF
|
|
set-node
|
|
fdt-debug IF ." Setting node: " 2dup type cr THEN
|
|
2drop
|
|
\ newnode?=0: updating the existing node, i.e. pass1 adds only phandles
|
|
0
|
|
ELSE
|
|
fdt-cas-pass 0 <> IF
|
|
\ We could not find the node added in the previous pass,
|
|
\ most likely because it is hotplug-under-hotplug case
|
|
\ (such as PCI brigde under bridge) when missing new node methods
|
|
\ such as "decode-unit" are critical.
|
|
\ Reboot when detect such case which is expected as it is a part of
|
|
\ ibm,client-architecture-support.
|
|
." Cannot handle FDT update for the " 2dup type
|
|
." node, rebooting" cr
|
|
reset-all
|
|
THEN
|
|
fdt-debug IF ." Creating node: " 2dup type cr THEN
|
|
new-device
|
|
2dup " @" find-substr nip
|
|
device-name
|
|
\ newnode?=1: adding new node, i.e. pass1 adds all properties,
|
|
\ most importantly "reg". After reading properties, we call
|
|
\ "fdt-cas-finish-device" which sets the unit address from "reg".
|
|
1
|
|
THEN
|
|
swap ( newnode? a1 )
|
|
|
|
fdt-debug IF ." Current now: " pwd get-node ." = " . cr THEN
|
|
fdt-cas-pass 0= IF
|
|
fdt-update-from-fdt
|
|
THEN
|
|
BEGIN
|
|
fdt-next-tag dup OF_DT_END_NODE <>
|
|
WHILE
|
|
( newnode? a1 tag )
|
|
dup OF_DT_PROP = IF
|
|
drop dup ( newnode? a1 a1 )
|
|
dup l@ dup rot 4 + ( newnode? a1 s s a2)
|
|
dup l@ swap 4 + ( newnode? a1 s s i a3 )
|
|
rot ( newnode? a1 s i a3 s )
|
|
fdt-encode-prop rot ( newnode? a1 s pa ps i)
|
|
fdt-fetch-string ( newnode? a1 s pa ps na ns )
|
|
|
|
fdt-cas-pass CASE
|
|
0 OF
|
|
2dup str=phandle? 7 pick or IF
|
|
fdt-debug IF 4dup ." Property: " type ." =" swap ." @" . ." " .d ." bytes" cr THEN
|
|
property
|
|
ELSE
|
|
4drop
|
|
THEN
|
|
ENDOF
|
|
1 OF
|
|
2dup str=phandle? not IF
|
|
fdt-debug IF 4dup ." Property: " type ." =" swap ." @" . ." " .d ." bytes" cr THEN
|
|
4dup fdt-patch-phandles
|
|
property
|
|
ELSE
|
|
4drop
|
|
THEN
|
|
ENDOF
|
|
2 OF
|
|
2dup str=phandle? IF
|
|
fdt-debug IF 4dup ." Deleting: " type ." =" swap ." @" . ." " .d ." bytes" cr THEN
|
|
delete-property
|
|
2drop
|
|
ELSE
|
|
4drop
|
|
THEN
|
|
ENDOF
|
|
ENDCASE
|
|
|
|
+ 8 + 3 + fffffffc and
|
|
ELSE ( newnode? a1 tag )
|
|
dup OF_DT_BEGIN_NODE = IF
|
|
2 pick IF
|
|
rot drop 0 -rot
|
|
fdt-cas-finish-device
|
|
fdt-debug IF ." Finished node: " pwd get-node ." = " . cr THEN
|
|
THEN
|
|
drop ( a1 )
|
|
4 -
|
|
(fdt-fix-cas-node)
|
|
get-parent set-node
|
|
ELSE
|
|
." Error " cr
|
|
drop
|
|
false to fdt-cas-fix?
|
|
EXIT
|
|
THEN
|
|
THEN
|
|
REPEAT
|
|
( newnode? a1 tag )
|
|
drop
|
|
swap ( a1 newnode? )
|
|
IF
|
|
fdt-cas-finish-device
|
|
fdt-debug IF ." Finished subnode: " pwd get-node ." = " . cr THEN
|
|
THEN
|
|
;
|
|
|
|
: alias-dev-path ( xt -- dev-path len )
|
|
link> execute decode-string 2swap 2drop
|
|
;
|
|
|
|
: alias-name ( xt -- alias-name len )
|
|
link> >name name>string
|
|
;
|
|
|
|
: fdt-cas-alias-obsolete? ( xt -- true|false )
|
|
alias-dev-path find-node 0=
|
|
;
|
|
|
|
: (fdt-cas-delete-obsolete-aliases) ( xt -- )
|
|
dup IF
|
|
dup @
|
|
recurse
|
|
dup alias-name s" name" str= IF ELSE
|
|
dup fdt-cas-alias-obsolete? IF
|
|
fdt-debug IF ." Deleting obsolete alias: " dup alias-name type ." -> " dup alias-dev-path type cr THEN
|
|
dup alias-name
|
|
delete-property
|
|
THEN
|
|
THEN
|
|
THEN
|
|
drop
|
|
;
|
|
|
|
: fdt-cas-delete-obsolete-aliases ( -- )
|
|
s" /aliases" find-device
|
|
get-node node>properties @ cell+ @ (fdt-cas-delete-obsolete-aliases)
|
|
device-end
|
|
;
|
|
|
|
: fdt-cas-node-obsolete? ( node -- true|false)
|
|
s" slof,from-fdt" rot get-package-property IF
|
|
\ Not a QEMU originated node
|
|
false
|
|
ELSE
|
|
decode-int nip nip fdt-generation# <
|
|
THEN
|
|
;
|
|
|
|
: (fdt-cas-search-obsolete-nodes) ( node -- )
|
|
dup child
|
|
BEGIN
|
|
dup
|
|
WHILE
|
|
dup recurse
|
|
peer
|
|
REPEAT
|
|
drop
|
|
dup fdt-cas-node-obsolete? IF
|
|
fdt-debug IF dup ." Deleting obsolete node: " dup .node ." = " . cr THEN
|
|
dup delete-node
|
|
THEN
|
|
drop
|
|
;
|
|
|
|
: fdt-cas-delete-obsolete-nodes ( -- )
|
|
s" /" find-device get-node (fdt-cas-search-obsolete-nodes)
|
|
fdt-cas-delete-obsolete-aliases
|
|
;
|
|
|
|
: fdt-fix-cas-node ( start -- )
|
|
fdt-generation# 1+ to fdt-generation#
|
|
0 to fdt-cas-pass dup (fdt-fix-cas-node) drop \ Add phandles
|
|
fdt-cas-delete-obsolete-nodes \ Delete removed devices
|
|
1 to fdt-cas-pass dup (fdt-fix-cas-node) drop \ Patch+add other properties
|
|
2 to fdt-cas-pass dup (fdt-fix-cas-node) drop \ Delete phandles from pass 0
|
|
drop
|
|
;
|
|
|
|
: fdt-fix-cas-success
|
|
fdt-cas-fix?
|
|
;
|
|
|
|
s" /" find-node fdt-fix-phandles
|