summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios/forth/admin/devices.fs
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/openbios/forth/admin/devices.fs')
-rw-r--r--qemu/roms/openbios/forth/admin/devices.fs515
1 files changed, 515 insertions, 0 deletions
diff --git a/qemu/roms/openbios/forth/admin/devices.fs b/qemu/roms/openbios/forth/admin/devices.fs
new file mode 100644
index 000000000..6f9e8efbb
--- /dev/null
+++ b/qemu/roms/openbios/forth/admin/devices.fs
@@ -0,0 +1,515 @@
+\ tag: device tree administration
+\
+\ this code implements IEEE 1275-1994
+\
+\ Copyright (C) 2003 Samuel Rydh
+\ Copyright (C) 2003-2006 Stefan Reinauer
+\
+\ See the file "COPYING" for further information about
+\ the copyright and warranty status of this work.
+\
+
+
+\ 7.4.11.1 Device alias
+
+: devalias ( "{alias-name}< >{device-specifier}<cr>" -- )
+ ;
+
+: nvalias ( "alias-name< >device-specifier<cr>" -- )
+ ;
+
+: $nvalias ( name-str name-len dev-str dev-len -- )
+ ;
+
+: nvunalias ( "alias-name< >" -- )
+ ;
+
+: $nvunalias ( name-str name-len -- )
+ ;
+
+
+\ 7.4.11.2 Device tree browsing
+
+: dev ( "<spaces>device-specifier" -- )
+ bl parse
+ find-device
+;
+
+: cd
+ dev
+;
+
+\ find-device ( dev-str dev-len -- )
+\ implemented in pathres.fs
+
+: device-end ( -- )
+ 0 active-package!
+ ;
+
+\ Open selected device node and make it the current instance
+\ section H.8 errata: pre OpenFirmware, but Sun OBP compatible
+: select-dev ( -- )
+ open-dev dup 0= abort" failed opening parent."
+ dup to my-self
+ ihandle>phandle active-package!
+;
+
+\ Close current node, deselect active package and current instance,
+\ leaving no instance selected
+\ section H.8 errata: pre OpenFirmware, but Sun OBP compatible
+: unselect-dev ( -- )
+ my-self close-dev
+ device-end
+ 0 to my-self
+;
+
+: begin-package ( arg-str arg-len reg-str reg-len dev-str dev-len -- )
+ select-dev
+ new-device
+ set-args
+;
+
+: end-package ( -- )
+ finish-device
+ unselect-dev
+;
+
+: ?active-package ( -- phandle )
+ active-package dup 0= abort" no active device"
+;
+
+\ -------------------------------------------------------
+\ path handling
+\ -------------------------------------------------------
+
+\ used if parent lacks an encode-unit method
+: def-encode-unit ( unitaddr ... )
+ pocket tohexstr
+;
+
+: get-encode-unit-xt ( phandle.parent -- xt )
+ >dn.parent @
+ " encode-unit" rot find-method
+ 0= if ['] def-encode-unit then
+;
+
+: get-nodename ( phandle -- str len )
+ " name" rot get-package-property if " <noname>" else 1- then
+;
+
+\ helper, return the node name in the format 'cpus@addr'
+: pnodename ( phandle -- str len )
+ dup get-nodename rot
+ dup " reg" rot get-package-property if drop exit then rot
+
+ \ set active-package and clear my-self (decode-phys needs this)
+ my-self >r 0 to my-self
+ active-package >r
+ dup active-package!
+
+ ( name len prop len phandle )
+ get-encode-unit-xt
+
+ ( name len prop len xt )
+ depth >r >r
+ decode-phys r> execute
+ r> -rot >r >r depth! 3drop
+
+ ( name len R: len str )
+ r> r> " @"
+ here 20 + \ abuse dictionary for temporary storage
+ tmpstrcat >r
+ 2swap r> tmpstrcat drop
+ pocket tmpstrcpy drop
+
+ r> active-package!
+ r> to my-self
+;
+
+: inodename ( ihandle -- str len )
+ my-self over to my-self >r
+ ihandle>phandle get-nodename
+
+ \ nonzero unit number?
+ false >r
+ depth >r my-unit r> 1+
+ begin depth over > while
+ swap 0<> if r> drop true >r then
+ repeat
+ drop
+
+ \ if not... check for presence of "reg" property
+ r> ?dup 0= if
+ " reg" my-self ihandle>phandle get-package-property
+ if false else 2drop true then
+ then
+
+ ( name len print-unit-flag )
+ if
+ my-self ihandle>phandle get-encode-unit-xt
+
+ ( name len xt )
+ depth >r >r
+ my-unit r> execute
+ r> -rot >r >r depth! drop
+ r> r>
+ ( name len str len )
+ here 20 + tmpstrcpy
+ " @" rot tmpstrcat drop
+ 2swap pocket tmpstrcat drop
+ then
+
+ \ add :arguments
+ my-args dup if
+ " :" pocket tmpstrcat drop
+ 2swap pocket tmpstrcat drop
+ else
+ 2drop
+ then
+
+ r> to my-self
+;
+
+\ helper, also used by client interface (package-to-path)
+: get-package-path ( phandle -- str len )
+ ?dup 0= if 0 0 then
+
+ dup >dn.parent @ 0= if drop " /" exit then
+ \ dictionary abused for temporary storage
+ >r 0 0 here 40 +
+ begin r> dup >dn.parent @ dup >r while
+ ( path len tempbuf phandle R: phandle.parent )
+ pnodename rot tmpstrcat
+ " /" rot tmpstrcat
+ repeat
+ r> 3drop
+ pocket tmpstrcpy drop
+;
+
+\ used by client interface (instance-to-path)
+: get-instance-path ( ihandle -- str len )
+ ?dup 0= if 0 0 then
+
+ dup ihandle>phandle >dn.parent @ 0= if drop " /" exit then
+
+ \ dictionary abused for temporary storage
+ >r 0 0 here 40 +
+ begin r> dup >in.my-parent @ dup >r while
+ ( path len tempbuf ihandle R: ihandle.parent )
+ dup >in.interposed @ 0= if
+ inodename rot tmpstrcat
+ " /" rot tmpstrcat
+ else
+ drop
+ then
+ repeat
+ r> 3drop
+ pocket tmpstrcpy drop
+;
+
+\ used by client interface (instance-to-interposed-path)
+: get-instance-interposed-path ( ihandle -- str len )
+ ?dup 0= if 0 0 then
+
+ dup ihandle>phandle >dn.parent @ 0= if drop " /" exit then
+
+ \ dictionary abused for temporary storage
+ >r 0 0 here 40 +
+ begin r> dup >in.my-parent @ dup >r while
+ ( path len tempbuf ihandle R: ihandle.parent )
+ dup >r inodename rot tmpstrcat
+ r> >in.interposed @ if " /%" else " /" then
+ rot tmpstrcat
+ repeat
+ r> 3drop
+ pocket tmpstrcpy drop
+;
+
+: pwd ( -- )
+ ?active-package get-package-path type
+;
+
+: ls ( -- )
+ cr
+ ?active-package >dn.child @
+ begin dup while
+ dup u. dup pnodename type cr
+ >dn.peer @
+ repeat
+ drop
+;
+
+
+\ -------------------------------------------
+\ property printing
+\ -------------------------------------------
+
+: .p-string? ( data len -- true | data len false )
+ \ no trailing zero?
+ 2dup + 1- c@ if 0 exit then
+
+ swap >r 0
+ \ count zeros and detect unprintable characters?
+ over 1- begin 1- dup 0>= while
+ dup r@ + c@
+ ( len zerocnt n ch )
+
+ ?dup 0= if
+ swap 1+ swap
+ else
+ dup 1b <= swap 80 >= or
+ if 2drop r> swap 0 exit then
+ then
+ repeat drop r> -rot
+ ( data len zerocnt )
+
+ \ simple string
+ 0= if
+ ascii " emit 1- type ascii " emit true exit
+ then
+
+ \ make sure there are no double zeros (except possibly at the end)
+ 2dup over + swap
+ ( data len end ptr )
+ begin 2dup <> while
+ dup c@ 0= if
+ 2dup 1+ <> if 2drop false exit then
+ then
+ dup cstrlen 1+ +
+ repeat
+ 2drop
+
+ ." {"
+ 0 -rot over + swap
+ \ multistring ( cnt end ptr )
+ begin 2dup <> while
+ rot dup if ." , " then 1+ -rot
+ dup cstrlen 2dup
+ ascii " emit type ascii " emit
+ 1+ +
+ repeat
+ ." }"
+ 3drop true
+;
+
+: .p-int? ( data len -- 1 | data len 0 )
+ dup 4 <> if false exit then
+ decode-int -rot 2drop true swap
+ dup 0>= if . exit then
+ dup -ff < if u. exit then
+ .
+;
+
+\ Print a number zero-padded
+: 0.r ( u minlen -- )
+ 0 swap <# 1 ?do # loop #s #> type
+;
+
+: .p-bytes? ( data len -- 1 | data len 0 )
+ ." -- " dup . ." : "
+ swap >r 0
+ begin 2dup > while
+ dup r@ + c@
+ ( len n ch )
+
+ 2 0.r space
+ 1+
+ repeat
+ 2drop r> drop 1
+;
+
+\ this function tries to heuristically determine the data format
+: (.property) ( data len -- )
+ dup 0= if 2drop ." <empty>" exit then
+
+ .p-string? if exit then
+ .p-int? if exit then
+ .p-bytes? if exit then
+ 2drop ." <unimplemented type>"
+;
+
+\ Print the value of a property in "reg" format
+: .p-reg ( #acells #scells data len -- )
+ 2dup + -rot ( #acells #scells data+len data len )
+ >r >r -rot ( data+len #acells #scells R: len data )
+ 4 * swap 4 * dup r> r> ( data+len #sbytes #abytes #abytes data len )
+ bounds ( data+len #sbytes #abytes #abytes data+len data ) ?do
+ dup 0= if 2 spaces then \ start of "size" part
+ 2dup <> if \ non-first byte in row
+ dup 3 and 0= if space then \ make numbers more readable
+ then
+ i c@ 2 0.r \ print byte
+ 1- 3dup nip + 0= if \ end of row
+ 3 pick i 1+ > if \ non-last byte
+ cr \ start new line
+ d# 26 spaces \ indentation
+ then
+ drop dup \ update counter
+ then
+ loop
+ 3drop drop
+;
+
+\ Return the number of cells per physical address
+: .p-translations-#pacells ( -- #cells )
+ " /" find-package if
+ " #address-cells" rot get-package-property if
+ 1
+ else
+ decode-int nip nip 1 max
+ then
+ else
+ 1
+ then
+;
+
+\ Return the number of cells per translation entry
+: .p-translations-#cells ( -- #cells )
+ [IFDEF] CONFIG_PPC
+ my-#acells 3 *
+ .p-translations-#pacells +
+ [ELSE]
+ my-#acells 3 *
+ [THEN]
+;
+
+\ Set up column offsets
+: .p-translations-cols ( -- col1 ... coln #cols )
+ .p-translations-#cells 4 *
+ [IFDEF] CONFIG_PPC
+ 4 -
+ dup 4 -
+ dup .p-translations-#pacells 4 * -
+ 3
+ [ELSE]
+ my-#acells 4 * -
+ dup my-#scells 4 * -
+ 2
+ [THEN]
+;
+
+\ Print the value of the MMU translations property
+: .p-translations ( data len -- )
+ >r >r .p-translations-cols r> r> ( col1 ... coln #cols data len )
+ 2dup + -rot ( col1 ... coln #cols data+len data len )
+ >r >r .p-translations-#cells 4 * dup r> r>
+ ( col1 ... coln #cols data+len #bytes #bytes len data )
+ bounds ( col1 ... coln #cols data+len #bytes #bytes data+len data ) ?do
+ 3 pick 4 + 4 ?do \ check all defined columns
+ i pick over = if
+ 2 spaces \ start new column
+ then
+ loop
+ 2dup <> if \ non-first byte in row
+ dup 3 and 0= if space then \ make numbers more readable
+ then
+ i c@ 2 0.r \ print byte
+ 1- dup 0= if \ end of row
+ 2 pick i 1+ > if \ non-last byte
+ cr \ start new line
+ d# 26 spaces \ indentation
+ then
+ drop dup \ update counter
+ then
+ loop
+ 2drop drop 0 ?do drop loop
+;
+
+\ This function hardwires data formats to particular node properties
+: (.property-by-name) ( name-str name-len data len -- )
+ 2over " reg" strcmp 0= if
+ my-#acells my-#scells 2swap .p-reg
+ 2drop exit
+ then
+
+ active-package get-nodename " memory" strcmp 0= if
+ 2over " available" strcmp 0= if
+ my-#acells my-#scells 2swap .p-reg
+ 2drop exit
+ then
+ then
+ " /chosen" find-dev if
+ " mmu" rot get-package-property 0= if
+ decode-int nip nip ihandle>phandle active-package = if
+ 2over " available" strcmp 0= if
+ my-#acells my-#scells 1 max 2swap .p-reg
+ 2drop exit
+ then
+ 2over " translations" strcmp 0= if
+ .p-translations
+ 2drop exit
+ then
+ then
+ then
+ then
+
+ 2swap 2drop ( data len )
+ (.property)
+;
+
+: .properties ( -- )
+ ?active-package dup >r if
+ 0 0
+ begin
+ r@ next-property
+ while
+ cr 2dup dup -rot type
+ begin ." " 1+ dup d# 26 >= until drop
+ 2dup
+ 2dup active-package get-package-property drop
+ ( name-str name-len data len )
+ (.property-by-name)
+ repeat
+ then
+ r> drop
+ cr
+;
+
+
+\ 7.4.11 Device tree
+
+: print-dev ( phandle -- phandle )
+ dup u.
+ dup get-package-path type
+ dup " device_type" rot get-package-property if
+ cr
+ else
+ ." (" decode-string type ." )" cr 2drop
+ then
+ ;
+
+: show-sub-devs ( subtree-phandle -- )
+ print-dev
+ >dn.child @
+ begin dup while
+ dup recurse
+ >dn.peer @
+ repeat
+ drop
+ ;
+
+: show-all-devs ( -- )
+ active-package
+ cr " /" find-device
+ ?active-package show-sub-devs
+ active-package!
+ ;
+
+
+: show-devs ( "{device-specifier}<cr>" -- )
+ active-package
+ cr " /" find-device
+ linefeed parse find-device
+ ?active-package show-sub-devs
+ active-package!
+ ;
+
+
+
+\ 7.4.11.3 Device probing
+
+\ Set to true if the last probe-self was successful
+0 value probe-fcode?
+
+: probe-all ( -- )
+ ;