|
|
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: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.