Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / forth / admin / devices.fs
diff --git a/qemu/roms/openbios/forth/admin/devices.fs b/qemu/roms/openbios/forth/admin/devices.fs
new file mode 100644 (file)
index 0000000..6f9e8ef
--- /dev/null
@@ -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    ( -- )
+  ;