Annotation of qemu/roms/openbios/forth/admin/devices.fs, revision 1.1.1.1

1.1       root        1: \ tag: device tree administration
                      2: \ 
                      3: \ this code implements IEEE 1275-1994 
                      4: \ 
                      5: \ Copyright (C) 2003 Samuel Rydh
                      6: \ Copyright (C) 2003-2006 Stefan Reinauer
                      7: \ 
                      8: \ See the file "COPYING" for further information about
                      9: \ the copyright and warranty status of this work.
                     10: \ 
                     11: 
                     12: 
                     13: \ 7.4.11.1 Device alias
                     14: 
                     15: : devalias    ( "{alias-name}< >{device-specifier}<cr>" -- )
                     16:   ;
                     17:   
                     18: : nvalias    ( "alias-name< >device-specifier<cr>" -- )
                     19:   ;
                     20:   
                     21: : $nvalias    ( name-str name-len dev-str dev-len -- )
                     22:   ;
                     23: 
                     24: : nvunalias    ( "alias-name< >" -- )
                     25:   ;
                     26:   
                     27: : $nvunalias    ( name-str name-len -- )
                     28:   ;
                     29: 
                     30: 
                     31: \ 7.4.11.2 Device tree browsing
                     32: 
                     33: : dev    ( "<spaces>device-specifier" -- )
                     34:   bl parse
                     35:   find-device
                     36: ;
                     37: 
                     38: : cd
                     39:   dev
                     40: ;
                     41:   
                     42: \ find-device    ( dev-str dev-len -- )
                     43: \ implemented in pathres.fs
                     44: 
                     45: : device-end    ( -- )
                     46:   0 active-package!
                     47:   ;
                     48: 
                     49: \ Open selected device node and make it the current instance
                     50: \   section H.8 errata: pre OpenFirmware, but Sun OBP compatible
                     51: : select-dev    ( -- )
                     52:   open-dev dup 0= abort" failed opening parent."
                     53:   dup to my-self
                     54:   ihandle>phandle active-package!
                     55: ;
                     56: 
                     57: \ Close current node, deselect active package and current instance,
                     58: \ leaving no instance selected
                     59: \   section H.8 errata: pre OpenFirmware, but Sun OBP compatible
                     60: : unselect-dev ( -- )
                     61:   my-self close-dev
                     62:   device-end
                     63:   0 to my-self
                     64: ;
                     65: 
                     66: : begin-package ( arg-str arg-len reg-str reg-len dev-str dev-len -- )
                     67:   select-dev
                     68:   new-device
                     69:   set-args
                     70: ;
                     71: 
                     72: : end-package   ( -- )
                     73:   finish-device
                     74:   unselect-dev
                     75: ;
                     76:  
                     77: : ?active-package ( -- phandle )
                     78:   active-package dup 0= abort" no active device"
                     79: ;
                     80: 
                     81: \ -------------------------------------------------------
                     82: \  path handling
                     83: \ -------------------------------------------------------
                     84: 
                     85: \ used if parent lacks an encode-unit method
                     86: : def-encode-unit ( unitaddr ... )
                     87:     pocket tohexstr
                     88: ;
                     89: 
                     90: : get-encode-unit-xt ( phandle.parent -- xt )
                     91:   >dn.parent @
                     92:   " encode-unit" rot find-method
                     93:   0= if ['] def-encode-unit then
                     94: ;
                     95: 
                     96: : get-nodename ( phandle -- str len )
                     97:   " name" rot get-package-property if " <noname>" else 1- then  
                     98: ;
                     99: 
                    100: \ helper, return the node name in the format 'cpus@addr'
                    101: : pnodename ( phandle -- str len )
                    102:   dup get-nodename rot
                    103:   dup " reg" rot get-package-property if drop exit then rot
                    104: 
                    105:   \ set active-package and clear my-self (decode-phys needs this)
                    106:   my-self >r 0 to my-self
                    107:   active-package >r
                    108:   dup active-package!
                    109: 
                    110:   ( name len prop len phandle )
                    111:   get-encode-unit-xt
                    112: 
                    113:   ( name len prop len xt )
                    114:   depth >r >r
                    115:   decode-phys r> execute
                    116:   r> -rot >r >r depth! 3drop
                    117: 
                    118:   ( name len R: len str )
                    119:   r> r> " @"
                    120:   here 20 +              \ abuse dictionary for temporary storage
                    121:   tmpstrcat >r
                    122:   2swap r> tmpstrcat drop
                    123:   pocket tmpstrcpy drop
                    124:   
                    125:   r> active-package!
                    126:   r> to my-self
                    127: ;
                    128: 
                    129: : inodename ( ihandle -- str len )
                    130:   my-self over to my-self >r
                    131:   ihandle>phandle get-nodename
                    132:   
                    133:   \ nonzero unit number?
                    134:   false >r
                    135:   depth >r my-unit r> 1+
                    136:   begin depth over > while
                    137:     swap 0<> if r> drop true >r then
                    138:   repeat
                    139:   drop
                    140: 
                    141:   \ if not... check for presence of "reg" property
                    142:   r> ?dup 0= if
                    143:     " reg" my-self ihandle>phandle get-package-property
                    144:     if false else 2drop true then
                    145:   then
                    146:   
                    147:   ( name len print-unit-flag )
                    148:   if
                    149:     my-self ihandle>phandle get-encode-unit-xt
                    150: 
                    151:     ( name len xt )
                    152:     depth >r >r
                    153:     my-unit r> execute
                    154:     r> -rot >r >r depth! drop
                    155:     r> r>
                    156:     ( name len str len )
                    157:     here 20 + tmpstrcpy 
                    158:     " @" rot tmpstrcat drop
                    159:     2swap pocket tmpstrcat drop
                    160:   then
                    161: 
                    162:   \ add :arguments
                    163:   my-args dup if
                    164:     " :" pocket tmpstrcat drop
                    165:     2swap pocket tmpstrcat drop
                    166:   else
                    167:     2drop
                    168:   then
                    169:   
                    170:   r> to my-self
                    171: ;
                    172: 
                    173: \ helper, also used by client interface (package-to-path)
                    174: : get-package-path ( phandle -- str len )
                    175:   ?dup 0= if 0 0 then
                    176: 
                    177:   dup >dn.parent @ 0= if drop " /" exit then
                    178:   \ dictionary abused for temporary storage
                    179:   >r 0 0 here 40 + 
                    180:   begin r> dup >dn.parent @ dup >r while
                    181:     ( path len tempbuf phandle R: phandle.parent )
                    182:     pnodename rot tmpstrcat
                    183:     " /" rot tmpstrcat
                    184:   repeat
                    185:   r> 3drop
                    186:   pocket tmpstrcpy drop
                    187: ;
                    188: 
                    189: \ used by client interface (instance-to-path)
                    190: : get-instance-path ( ihandle -- str len )
                    191:   ?dup 0= if 0 0 then
                    192: 
                    193:   dup ihandle>phandle >dn.parent @ 0= if drop " /" exit then
                    194:     
                    195:   \ dictionary abused for temporary storage
                    196:   >r 0 0 here 40 + 
                    197:   begin r> dup >in.my-parent @ dup >r while
                    198:     ( path len tempbuf ihandle R: ihandle.parent )
                    199:     dup >in.interposed @ 0= if
                    200:       inodename rot tmpstrcat
                    201:       " /" rot tmpstrcat
                    202:     else
                    203:       drop
                    204:     then
                    205:   repeat
                    206:   r> 3drop
                    207:   pocket tmpstrcpy drop
                    208: ;
                    209: 
                    210: \ used by client interface (instance-to-interposed-path)
                    211: : get-instance-interposed-path ( ihandle -- str len )
                    212:   ?dup 0= if 0 0 then
                    213: 
                    214:   dup ihandle>phandle >dn.parent @ 0= if drop " /" exit then
                    215:     
                    216:   \ dictionary abused for temporary storage
                    217:   >r 0 0 here 40 + 
                    218:   begin r> dup >in.my-parent @ dup >r while
                    219:     ( path len tempbuf ihandle R: ihandle.parent )
                    220:     dup >r inodename rot tmpstrcat
                    221:     r> >in.interposed @ if " /%" else " /" then
                    222:     rot tmpstrcat
                    223:   repeat
                    224:   r> 3drop
                    225:   pocket tmpstrcpy drop
                    226: ;
                    227: 
                    228: : pwd    ( -- )
                    229:   ?active-package get-package-path type
                    230: ;
                    231:   
                    232: : ls    ( -- )
                    233:   cr
                    234:   ?active-package >dn.child @
                    235:   begin dup while
                    236:     dup u. dup pnodename type cr
                    237:     >dn.peer @
                    238:   repeat
                    239:   drop
                    240: ;
                    241:   
                    242: 
                    243: \ -------------------------------------------
                    244: \  property printing
                    245: \ -------------------------------------------
                    246: 
                    247: : .p-string? ( data len -- true | data len false )
                    248:   \ no trailing zero?
                    249:   2dup + 1- c@ if 0 exit then
                    250: 
                    251:   swap >r 0 
                    252:   \ count zeros and detect unprintable characters?
                    253:   over 1- begin 1- dup 0>= while
                    254:     dup r@ + c@
                    255:     ( len zerocnt n ch )
                    256: 
                    257:     ?dup 0= if
                    258:       swap 1+ swap
                    259:     else
                    260:       dup 1b <= swap 80 >= or
                    261:       if 2drop r> swap 0 exit then
                    262:     then
                    263:   repeat drop r> -rot
                    264:   ( data len zerocnt )
                    265:   
                    266:   \ simple string
                    267:   0= if
                    268:     ascii " emit 1- type ascii " emit true exit
                    269:   then
                    270: 
                    271:   \ make sure there are no double zeros (except possibly at the end)
                    272:   2dup over + swap
                    273:   ( data len end ptr )
                    274:   begin 2dup <> while
                    275:     dup c@ 0= if
                    276:       2dup 1+ <> if 2drop false exit then
                    277:     then
                    278:     dup cstrlen 1+ +
                    279:   repeat
                    280:   2drop
                    281:   
                    282:   ." {"
                    283:   0 -rot over + swap
                    284:   \ multistring ( cnt end ptr )
                    285:   begin 2dup <> while
                    286:     rot dup if ." , " then 1+ -rot
                    287:     dup cstrlen 2dup
                    288:     ascii " emit type ascii " emit
                    289:     1+ +
                    290:   repeat
                    291:   ." }"
                    292:   3drop true
                    293: ;
                    294: 
                    295: : .p-int? ( data len -- 1 | data len 0 )
                    296:   dup 4 <> if false exit then
                    297:   decode-int -rot 2drop true swap
                    298:   dup 0>= if . exit then
                    299:   dup -ff < if u. exit then
                    300:   .
                    301: ;
                    302: 
                    303: \ Print a number zero-padded
                    304: : 0.r ( u minlen -- )
                    305:   0 swap <# 1 ?do # loop #s #> type
                    306: ;
                    307: 
                    308: : .p-bytes? ( data len -- 1 | data len 0 )
                    309:   ." -- " dup . ." : "
                    310:   swap >r 0
                    311:   begin 2dup > while
                    312:     dup r@ + c@
                    313:     ( len n ch )
                    314: 
                    315:     2 0.r space
                    316:     1+
                    317:   repeat 
                    318:   2drop r> drop 1
                    319: ;
                    320: 
                    321: \ this function tries to heuristically determine the data format
                    322: : (.property) ( data len -- )
                    323:   dup 0= if 2drop ." <empty>" exit then
                    324: 
                    325:   .p-string? if exit then
                    326:   .p-int? if exit then
                    327:   .p-bytes? if exit then
                    328:   2drop ." <unimplemented type>"
                    329: ;
                    330: 
                    331: \ Print the value of a property in "reg" format
                    332: : .p-reg ( #acells #scells data len -- )
                    333:   2dup + -rot ( #acells #scells data+len data len )
                    334:   >r >r -rot ( data+len #acells #scells  R: len data )
                    335:   4 * swap 4 * dup r> r> ( data+len #sbytes #abytes #abytes data len )
                    336:   bounds ( data+len #sbytes #abytes #abytes data+len data ) ?do
                    337:     dup 0= if 2 spaces then                    \ start of "size" part
                    338:     2dup <> if                                         \ non-first byte in row
                    339:       dup 3 and 0= if space then       \ make numbers more readable
                    340:     then
                    341:     i c@ 2 0.r                                         \ print byte
                    342:     1- 3dup nip + 0= if                                \ end of row
                    343:       3 pick i 1+ > if                         \ non-last byte
                    344:         cr                                                     \ start new line
                    345:         d# 26 spaces                           \ indentation
                    346:       then
                    347:       drop dup                                         \ update counter
                    348:     then
                    349:   loop
                    350:   3drop drop
                    351: ;
                    352: 
                    353: \ Return the number of cells per physical address
                    354: : .p-translations-#pacells ( -- #cells )
                    355:   " /" find-package if
                    356:     " #address-cells" rot get-package-property if
                    357:       1
                    358:     else
                    359:       decode-int nip nip 1 max
                    360:     then
                    361:   else
                    362:     1
                    363:   then
                    364: ;
                    365: 
                    366: \ Return the number of cells per translation entry
                    367: : .p-translations-#cells ( -- #cells )
                    368:   [IFDEF] CONFIG_PPC
                    369:     my-#acells 3 *
                    370:     .p-translations-#pacells +
                    371:   [ELSE]
                    372:     my-#acells 3 *
                    373:   [THEN]
                    374: ;
                    375: 
                    376: \ Set up column offsets
                    377: : .p-translations-cols ( -- col1 ... coln #cols )
                    378:   .p-translations-#cells 4 *
                    379:   [IFDEF] CONFIG_PPC
                    380:     4 -
                    381:     dup 4 -
                    382:     dup .p-translations-#pacells 4 * -
                    383:     3
                    384:   [ELSE]
                    385:     my-#acells 4 * -
                    386:     dup my-#scells 4 * -
                    387:     2
                    388:   [THEN]
                    389: ;
                    390: 
                    391: \ Print the value of the MMU translations property
                    392: : .p-translations ( data len -- )
                    393:   >r >r .p-translations-cols r> r> ( col1 ... coln #cols data len )
                    394:   2dup + -rot ( col1 ... coln #cols data+len data len )
                    395:   >r >r .p-translations-#cells 4 * dup r> r>
                    396:   ( col1 ... coln #cols data+len #bytes #bytes len data )
                    397:   bounds ( col1 ... coln #cols data+len #bytes #bytes data+len data ) ?do
                    398:     3 pick 4 + 4 ?do                           \ check all defined columns
                    399:       i pick over = if
                    400:         2 spaces                                       \ start new column
                    401:       then
                    402:     loop
                    403:     2dup <> if                                         \ non-first byte in row
                    404:       dup 3 and 0= if space then       \ make numbers more readable
                    405:     then
                    406:     i c@ 2 0.r                                         \ print byte
                    407:     1- dup 0= if                                       \ end of row
                    408:       2 pick i 1+ > if                         \ non-last byte
                    409:         cr                                                     \ start new line
                    410:         d# 26 spaces                           \ indentation
                    411:       then
                    412:       drop dup                                         \ update counter
                    413:     then
                    414:   loop
                    415:   2drop drop 0 ?do drop loop
                    416: ;
                    417: 
                    418: \ This function hardwires data formats to particular node properties
                    419: : (.property-by-name) ( name-str name-len data len -- )
                    420:   2over " reg" strcmp 0= if
                    421:     my-#acells my-#scells 2swap .p-reg
                    422:     2drop exit
                    423:   then
                    424: 
                    425:   active-package get-nodename " memory" strcmp 0= if
                    426:     2over " available" strcmp 0= if
                    427:       my-#acells my-#scells 2swap .p-reg
                    428:       2drop exit
                    429:     then
                    430:   then
                    431:   " /chosen" find-dev if
                    432:     " mmu" rot get-package-property 0= if
                    433:       decode-int nip nip ihandle>phandle active-package = if
                    434:         2over " available" strcmp 0= if
                    435:           my-#acells my-#scells 1 max 2swap .p-reg
                    436:           2drop exit
                    437:         then
                    438:         2over " translations" strcmp 0= if
                    439:           .p-translations
                    440:           2drop exit
                    441:         then
                    442:       then
                    443:     then
                    444:   then
                    445: 
                    446:   2swap 2drop ( data len )
                    447:   (.property)
                    448: ;
                    449: 
                    450: : .properties    ( -- )
                    451:   ?active-package dup >r if
                    452:     0 0
                    453:     begin
                    454:       r@ next-property
                    455:     while
                    456:       cr 2dup dup -rot type
                    457:       begin ."  " 1+ dup d# 26 >= until drop
                    458:       2dup
                    459:       2dup active-package get-package-property drop
                    460:       ( name-str name-len data len )
                    461:       (.property-by-name)
                    462:     repeat
                    463:   then
                    464:   r> drop
                    465:   cr
                    466: ;
                    467: 
                    468: 
                    469: \ 7.4.11    Device tree
                    470: 
                    471: : print-dev ( phandle -- phandle )
                    472:   dup u. 
                    473:   dup get-package-path type
                    474:   dup " device_type" rot get-package-property if
                    475:     cr 
                    476:   else
                    477:     ."  (" decode-string type ." )" cr 2drop
                    478:   then
                    479:   ;
                    480: 
                    481: : show-sub-devs ( subtree-phandle -- )
                    482:   print-dev
                    483:   >dn.child @
                    484:     begin dup while
                    485:       dup recurse
                    486:       >dn.peer @
                    487:     repeat
                    488:     drop
                    489:   ;
                    490: 
                    491: : show-all-devs    ( -- )
                    492:   active-package
                    493:   cr " /" find-device
                    494:   ?active-package show-sub-devs
                    495:   active-package!
                    496:   ;
                    497: 
                    498: 
                    499: : show-devs    ( "{device-specifier}<cr>" -- )
                    500:   active-package
                    501:   cr " /" find-device
                    502:   linefeed parse find-device
                    503:   ?active-package show-sub-devs
                    504:   active-package!
                    505:   ;
                    506: 
                    507: 
                    508: 
                    509: \ 7.4.11.3 Device probing
                    510: 
                    511: : probe-all    ( -- )
                    512:   ;

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.