Annotation of qemu/roms/SLOF/board-qemu/slof/fdt.fs, revision 1.1.1.3

1.1       root        1: \ *****************************************************************************
                      2: \ * Copyright (c) 2011 IBM Corporation
                      3: \ * All rights reserved.
                      4: \ * This program and the accompanying materials
                      5: \ * are made available under the terms of the BSD License
                      6: \ * which accompanies this distribution, and is available at
                      7: \ * http://www.opensource.org/licenses/bsd-license.php
                      8: \ *
                      9: \ * Contributors:
                     10: \ *     IBM Corporation - initial implementation
                     11: \ ****************************************************************************/
                     12: 
                     13: 0 VALUE fdt-debug
                     14: 
                     15: \ Bail out if no fdt
                     16: fdt-start 0 = IF -1 throw THEN
                     17: 
                     18: struct
                     19:   4 field >fdth_magic
                     20:   4 field >fdth_tsize
                     21:   4 field >fdth_struct_off
                     22:   4 field >fdth_string_off
                     23:   4 field >fdth_rsvmap_off
                     24:   4 field >fdth_version
                     25:   4 field >fdth_compat_vers
                     26:   4 field >fdth_boot_cpu
                     27:   4 field >fdth_string_size
                     28:   4 field >fdth_struct_size
                     29: drop
                     30: 
                     31: h# d00dfeed constant OF_DT_HEADER
                     32: h#        1 constant OF_DT_BEGIN_NODE
                     33: h#        2 constant OF_DT_END_NODE
                     34: h#        3 constant OF_DT_PROP
                     35: h#        4 constant OF_DT_NOP
                     36: h#        9 constant OF_DT_END
                     37: 
                     38: \ Create some variables early
                     39: fdt-start
                     40: dup dup >fdth_struct_off l@ + value fdt-struct
                     41: dup dup >fdth_string_off l@ + value fdt-strings
                     42: drop
                     43: 
                     44: \ Dump fdt header for all to see and check FDT validity
                     45: : fdt-check-header ( -- )
                     46:     fdt-start dup 0 = IF
                     47:         ." No flat device tree !" cr drop -1 throw EXIT THEN
                     48:     hex
                     49:     fdt-debug IF
                     50:         ." Flat device tree header at 0x" dup . s" :" type cr
                     51:         ."  magic            : 0x" dup >fdth_magic l@ . cr
                     52:         ."  total size       : 0x" dup >fdth_tsize l@ . cr
                     53:         ."  offset to struct : 0x" dup >fdth_struct_off l@ . cr
                     54:         ."  offset to strings: 0x" dup >fdth_string_off l@ . cr
                     55:         ."  offset to rsvmap : 0x" dup >fdth_rsvmap_off l@ . cr
                     56:         ."  version          : " dup >fdth_version l@ decimal . hex cr
                     57:         ."  last compat vers : " dup >fdth_compat_vers l@ decimal . hex cr
                     58:         dup >fdth_version l@ 2 >= IF
                     59:             ."  boot CPU         : 0x" dup >fdth_boot_cpu l@ . cr
                     60:         THEN
                     61:         dup >fdth_version l@ 3 >= IF
                     62:             ."  strings size     : 0x" dup >fdth_string_size l@ . cr
                     63:         THEN
                     64:         dup >fdth_version l@ 17 >= IF
                     65:             ."  struct size      : 0x" dup >fdth_struct_size l@ . cr
                     66:         THEN
                     67:     THEN
                     68:     dup >fdth_magic l@ OF_DT_HEADER <> IF
                     69:         ." Flat device tree has incorrect magic value !" cr
                     70:        drop -1 throw EXIT
                     71:     THEN
                     72:     dup >fdth_version l@ 10 < IF
                     73:         ." Flat device tree has usupported version !" cr
                     74:        drop -1 throw EXIT
                     75:     THEN
                     76: 
                     77:     drop
                     78: ;
                     79: fdt-check-header
                     80: 
                     81: \ Fetch next tag, skip nops and increment address
                     82: : fdt-next-tag ( addr -- nextaddr tag )
                     83:   0                            ( dummy tag on stack for loop )
                     84:   BEGIN
                     85:     drop                       ( drop previous tag )
                     86:     dup l@                     ( read new tag )
                     87:     swap 4 + swap              ( increment addr )
                     88:   dup OF_DT_NOP <> UNTIL       ( loop until not nop )
                     89: ;
                     90: 
                     91: \ Parse unit name and advance addr
                     92: : fdt-fetch-unit ( addr -- addr $name )
                     93:   dup from-cstring            \  get string size
                     94:   2dup + 1 + 3 + fffffffc and -rot
                     95: ;
                     96: 
1.1.1.3 ! root       97: \ Update unit with information from the reg property...
        !            98: \ ... this is required for the PCI nodes for example.
        !            99: : fdt-reg-unit ( prop-addr prop-len -- )
        !           100:    s" #address-cells" get-parent get-package-property IF
        !           101:       2drop
        !           102:    ELSE
        !           103:       decode-int nip nip        ( prop-addr prop-len #addr-cells )
        !           104:       3 <> IF
        !           105:          \ Ignore if #addr-cells is not 3, i.e. no PCI
        !           106:          2drop EXIT
        !           107:       THEN
        !           108:       decode-phys               ( prop-addr' prop-len' phys.lo ... phys.hi )
        !           109:       set-unit                  ( prop-addr' prop-len' )
        !           110:       2drop
        !           111:    THEN
        !           112: ;
        !           113: 
1.1       root      114: \ Lookup a string by index
1.1.1.3 ! root      115: : fdt-fetch-string ( index -- str-addr str-len )  
1.1       root      116:   fdt-strings + dup from-cstring
                    117: ;
                    118: 
                    119: : fdt-create-dec  s" decode-unit" $CREATE , DOES> @ hex-decode-unit ;
                    120: : fdt-create-enc  s" encode-unit" $CREATE , DOES> @ hex-encode-unit ;
                    121: 
1.1.1.3 ! root      122: \ Check whether array contains an zero-terminated ASCII string:
        !           123: : fdt-prop-is-string?  ( addr len -- string? )
        !           124:    dup 1 < IF 2drop FALSE EXIT THEN                \ Check for valid length
        !           125:    1-
        !           126:    2dup + c@ 0<> IF 2drop FALSE EXIT THEN          \ Check zero-termination
        !           127:    test-string
        !           128: ;
        !           129: 
        !           130: \ Encode fdt property to OF property
        !           131: : fdt-encode-prop  ( addr len -- )
        !           132:    2dup fdt-prop-is-string? IF
        !           133:       1- encode-string
        !           134:    ELSE
        !           135:       encode-bytes
        !           136:    THEN
        !           137: ;
        !           138: 
1.1       root      139: \ Method to unflatten a node
                    140: : fdt-unflatten-node ( start -- end )
                    141:   \ this can and will recurse
                    142:   recursive
                    143: 
                    144:   \ Get & check first tag of node ( addr -- addr)
                    145:   fdt-next-tag dup OF_DT_BEGIN_NODE <> IF
                    146:     s" Weird tag 0x" type . " at start of node" type cr
                    147:     -1 throw
                    148:   THEN drop
                    149: 
                    150:   new-device
                    151: 
                    152:   \ Parse name, split unit address
                    153:   fdt-fetch-unit
                    154:   dup 0 = IF drop drop " /" THEN
                    155:   40 left-parse-string
                    156:   \ Set name
                    157:   device-name
                    158: 
1.1.1.3 ! root      159:   \ Set preliminary unit address - might get overwritten by reg property
1.1       root      160:   dup IF
                    161:      " #address-cells" get-parent get-package-property IF
                    162:         2drop
                    163:      ELSE
                    164:         decode-int nip nip
                    165:        hex-decode-unit
                    166:        set-unit
                    167:      THEN
                    168:   ELSE 2drop THEN
                    169: 
                    170:   \ Iterate sub tags
                    171:   BEGIN
                    172:     fdt-next-tag dup OF_DT_END_NODE <>
                    173:   WHILE
                    174:     dup OF_DT_PROP = IF
                    175:       \ Found property
                    176:       drop dup                 ( drop tag, dup addr     : a1 a1 )
                    177:       dup l@ dup rot 4 +       ( fetch size, stack is   : a1 s s a2)
                    178:       dup l@ swap 4 +          ( fetch nameid, stack is : a1 s s i a3 )
1.1.1.3 ! root      179:       rot                      ( we now have: a1 s i a3 s )
        !           180:       fdt-encode-prop rot      ( a1 s pa ps i)
        !           181:       fdt-fetch-string         ( a1 s pa ps na ns )
        !           182:       2dup s" reg" str= IF
        !           183:           2swap 2dup fdt-reg-unit 2swap
        !           184:       THEN
1.1       root      185:       property
                    186:       + 8 + 3 + fffffffc and
                    187:     ELSE dup OF_DT_BEGIN_NODE = IF
                    188:       drop                     ( drop tag )
                    189:       4 -
                    190:       fdt-unflatten-node
                    191:     ELSE
                    192:       drop -1 throw
                    193:     THEN THEN
                    194:   REPEAT drop \ drop tag
                    195: 
                    196:   \ Create encode/decode unit
                    197:   " #address-cells" get-node get-package-property IF ELSE
                    198:     decode-int dup fdt-create-dec fdt-create-enc 2drop
                    199:   THEN
                    200: 
                    201:   finish-device  
                    202: ;
                    203: 
                    204: \ Start unflattening
                    205: : fdt-unflatten-tree
                    206:     fdt-debug IF
                    207:         ." Unflattening device tree..." cr THEN
                    208:     fdt-struct fdt-unflatten-node drop
                    209:     fdt-debug IF
                    210:         ." Done !" cr THEN
                    211: ;
                    212: fdt-unflatten-tree
                    213: 
                    214: \ Find memory size
                    215: : fdt-parse-memory
                    216:     " /memory" find-device
                    217:     " reg" get-node get-package-property IF throw -1 THEN
                    218: 
                    219:     \ XXX FIXME Assume one entry only in "reg" property for now
                    220:     decode-phys 2drop decode-phys
                    221:     my-#address-cells 1 > IF 20 << or THEN
                    222:     
                    223:     fdt-debug IF
                    224:         dup ." Memory size: " . cr
                    225:     THEN
1.1.1.2   root      226:     \ claim.fs already released the memory between 0 and MIN-RAM-SIZE,
                    227:     \ so we've got only to release the remaining memory now:
                    228:     MIN-RAM-SIZE swap MIN-RAM-SIZE - release
1.1       root      229:     2drop device-end
                    230: ;
                    231: fdt-parse-memory
                    232: 
                    233: 
                    234: \ Claim fdt memory and reserve map
                    235: : fdt-claim-reserve
                    236:     fdt-start
                    237:     dup dup >fdth_tsize l@ 0 claim drop
                    238:     dup >fdth_rsvmap_off l@ +
                    239:     BEGIN
                    240:         dup dup x@ swap 8 + x@
                    241:        dup 0 <>
                    242:     WHILE
                    243:        fdt-debug IF
                    244:            2dup swap ." Reserve map entry: " . ." : " . cr
                    245:        THEN
                    246:        0 claim drop
                    247:        10 +
                    248:     REPEAT drop drop drop
                    249: ;
                    250: fdt-claim-reserve 
                    251: 
1.1.1.3 ! root      252: 
        !           253: \ The following functions are use to replace the FDT phandle and
        !           254: \ linux,phandle properties with our own OF1275 phandles...
        !           255: 
        !           256: \ This is used to check whether we successfully replaced a phandle value
        !           257: 0 VALUE (fdt-phandle-replaced)
        !           258: 
        !           259: \ Replace phandle value in "interrupt-map" property
        !           260: : fdt-replace-interrupt-map  ( old new prop-addr prop-len -- old new )
        !           261:    BEGIN
        !           262:       dup                    ( old new prop-addr prop-len prop-len )
        !           263:    WHILE
        !           264:       \ This is a little bit ugly ... we're accessing the property at
        !           265:       \ hard-coded offsets instead of analyzing it completely...
        !           266:       swap dup 10 +          ( old new prop-len prop-addr prop-addr+10 )
        !           267:       dup l@ 5 pick = IF
        !           268:           \ it matches the old phandle value!
        !           269:           3 pick swap l!
        !           270:           TRUE TO (fdt-phandle-replaced)
        !           271:       ELSE
        !           272:           drop
        !           273:       THEN
        !           274:       ( old new prop-len prop-addr )
        !           275:       1c + swap 1c -
        !           276:       ( old new new-prop-addr new-prop-len )
        !           277:    REPEAT
        !           278:    2drop
        !           279: ;
        !           280: 
        !           281: \ Replace one FDT phandle "old" with a OF1275 phandle "new" in the
        !           282: \ whole tree:
        !           283: : fdt-replace-all-phandles ( old new node -- )
        !           284:    \ ." Replacing in " dup node>path type cr
        !           285:    >r
        !           286:    s" interrupt-map" r@ get-property 0= IF
        !           287:       ( old new prop-addr prop-len  R: node )
        !           288:       fdt-replace-interrupt-map
        !           289:    THEN
        !           290:    s" interrupt-parent" r@ get-property 0= IF
        !           291:       ( old new prop-addr prop-len  R: node )
        !           292:       decode-int -rot 2drop                  ( old new val  R: node )
        !           293:       2 pick = IF                            ( old new      R: node )
        !           294:          dup encode-int s" interrupt-parent" r@ set-property
        !           295:          TRUE TO (fdt-phandle-replaced)
        !           296:       THEN
        !           297:    THEN
        !           298:    \ ... add more properties that have to be fixed here ...
        !           299:    r>
        !           300:    \ Now recurse over all child nodes:       ( old new node )
        !           301:    child BEGIN
        !           302:       dup
        !           303:    WHILE
        !           304:       3dup RECURSE
        !           305:       PEER
        !           306:    REPEAT
        !           307:    3drop
        !           308: ;
        !           309: 
        !           310: \ Check whether a node has "phandle" or "linux,phandle" properties
        !           311: \ and replace them:
        !           312: : fdt-fix-node-phandle  ( node -- )
        !           313:    >r
        !           314:    FALSE TO (fdt-phandle-replaced)
        !           315:    s" phandle" r@ get-property 0= IF
        !           316:       decode-int                       ( p-addr2 p-len2 val )
        !           317:       \ ." found phandle: " dup . cr
        !           318:       r@ s" /" find-node               ( p-addr2 p-len2 val node root )  
        !           319:       fdt-replace-all-phandles         ( p-addr2 p-len2 )
        !           320:       2drop
        !           321:       (fdt-phandle-replaced) IF
        !           322:          r@ set-node
        !           323:          s" phandle" delete-property
        !           324:          s" linux,phandle" delete-property
        !           325:       ELSE
        !           326:          diagnostic-mode? IF
        !           327:             cr ." Warning: Did not replace phandle in " r@ node>path type cr
        !           328:          THEN
        !           329:       THEN
        !           330:    THEN
        !           331:    r> drop
        !           332: ;
        !           333: 
        !           334: \ Recursively walk through all nodes to fix their phandles:
        !           335: : fdt-fix-phandles  ( node -- )
        !           336:    \ ." fixing phandles of " dup node>path type cr
        !           337:    dup fdt-fix-node-phandle
        !           338:    child BEGIN
        !           339:       dup
        !           340:    WHILE
        !           341:       dup RECURSE
        !           342:       PEER
        !           343:    REPEAT
        !           344:    drop
        !           345:    device-end
        !           346: ;
        !           347: s" /" find-node fdt-fix-phandles
        !           348: 
        !           349: 
1.1       root      350: \ Remaining bits from root.fs
                    351: 
                    352: defer (client-exec)
                    353: defer client-exec
                    354: 
                    355: \ defined in slof/fs/client.fs
                    356: defer callback
                    357: defer continue-client
                    358: 
                    359: : set-chosen ( prop len name len -- )
                    360:   s" /chosen" find-node set-property ;
                    361: 
                    362: : get-chosen ( name len -- [ prop len ] success )
                    363:   s" /chosen" find-node get-property 0= ;
                    364: 
                    365: " /" find-device
                    366: 
                    367: new-device
                    368:   s" aliases" device-name
                    369: finish-device
                    370: 
                    371: new-device
                    372:   s" options" device-name
                    373: finish-device
                    374: 
                    375: new-device
                    376:   s" openprom" device-name
                    377:   s" BootROM" device-type
                    378: finish-device
                    379: 
                    380: new-device 
                    381: #include <packages.fs>
                    382: finish-device
                    383: 
                    384: : open true ;
                    385: : close ;
                    386: 
                    387: device-end
                    388: 

unix.superglobalmegacorp.com

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