| \ ***************************************************************************** |
| \ * Copyright (c) 2017 IBM Corporation |
| \ * All rights reserved. |
| \ * This program and the accompanying materials |
| \ * are made available under the terms of the BSD License |
| \ * which accompanies this distribution, and is available at |
| \ * http://www.opensource.org/licenses/bsd-license.php |
| \ ****************************************************************************/ |
| |
| 0 VALUE fdtfl-debug |
| |
| VARIABLE fdtfl-struct |
| VARIABLE fdtfl-struct-here |
| VARIABLE fdtfl-strings |
| VARIABLE fdtfl-strings-cache |
| VARIABLE fdtfl-strings-here |
| VARIABLE fdtfl-strings-reused \ debug only |
| VARIABLE fdlfl-ms \ debug only |
| |
| : fdt-skip-string ( cur -- cur ) zcount + char+ 4 #aligned ; |
| |
| : zstring= ( str len zstr -- flag ) |
| 2dup + c@ 0<> IF |
| 3drop false |
| EXIT |
| THEN |
| swap comp 0= |
| ; |
| |
| : fdt-find-string ( name namelen -- nameoff true | false ) |
| fdtfl-strings @ |
| BEGIN |
| dup fdtfl-strings-cache @ < |
| WHILE |
| 3dup zstring= IF |
| nip nip ( curstr ) |
| fdtfl-strings @ - |
| true |
| EXIT |
| THEN |
| fdt-skip-string |
| REPEAT |
| 3drop |
| false |
| ; |
| |
| : fdt-str-allot ( len -- ) fdtfl-strings-here @ + to fdtfl-strings-here ; |
| : fdt-str-c, ( char -- ) fdtfl-strings-here @ 1 fdt-str-allot c! ; |
| : fdt-str-align ( -- ) |
| fdtfl-strings-here @ |
| dup dup 4 #aligned swap - ( here bytes-to-erase ) |
| dup -rot |
| erase |
| fdt-str-allot |
| ; |
| : fdt-str-bytes, ( data len -- ) fdtfl-strings-here @ over fdt-str-allot swap move ; |
| : fdt-str-ztr, ( str len -- ) fdt-str-bytes, 0 fdt-str-c, ; |
| |
| : fdt-add-string ( name namelen -- nameoff ) |
| fdtfl-strings-here @ -rot |
| fdt-str-ztr, |
| fdt-str-align |
| fdtfl-strings @ - |
| ; |
| |
| : fdt-get-string ( name namelen -- nameoff ) |
| 2dup fdt-find-string IF |
| -rot 2drop |
| fdtfl-debug IF |
| 1 fdtfl-strings-reused +! |
| THEN |
| EXIT |
| THEN |
| fdt-add-string |
| ; |
| |
| : fdt-allot ( len -- ) fdtfl-struct-here @ + to fdtfl-struct-here ; |
| : fdt-c, ( char -- ) fdtfl-struct-here @ 1 fdt-allot c! ; |
| : fdt-align ( -- ) |
| fdtfl-struct-here @ |
| dup dup 4 #aligned swap - ( here bytes-to-erase ) |
| dup -rot |
| erase |
| fdt-allot |
| ; |
| : fdt-bytes, ( data len -- ) fdtfl-struct-here @ over fdt-allot swap move ; |
| : fdt-ztr, ( str len -- ) fdt-bytes, 0 fdt-c, ; |
| : fdt-l, ( token -- ) fdtfl-struct-here @ l! /l fdt-allot ; |
| |
| : fdt-begin-node ( phandle -- ) |
| OF_DT_BEGIN_NODE fdt-l, |
| dup device-tree @ = IF drop s" " ELSE node>qname THEN |
| fdt-ztr, |
| fdt-align |
| ; |
| |
| : fdt-end-node ( -- ) OF_DT_END_NODE fdt-l, ; |
| |
| : fdt-prop ( prop len name namelen -- ) |
| OF_DT_PROP fdt-l, |
| |
| \ get string offset |
| fdt-get-string ( prop len nameoff ) |
| |
| \ store len and nameoff |
| over fdt-l, |
| fdt-l, ( prop len ) |
| |
| \ now store the bytes |
| fdt-bytes, |
| fdt-align |
| ; |
| |
| : fdt-end ( -- ) OF_DT_END fdt-l, ; |
| |
| : fdt-copy-property ( link -- ) |
| dup link> execute |
| rot |
| link>name name>string |
| 2dup s" name" str= IF 4drop EXIT THEN \ skipping useless "name" |
| fdt-prop |
| ; |
| |
| : for-all-words ( wid xt -- ) \ xt has sig ( lfa -- ) |
| >r |
| cell+ @ BEGIN dup WHILE dup r@ execute @ REPEAT |
| r> 2drop |
| ; |
| |
| : fdt-copy-properties ( phandle -- ) |
| dup encode-int s" phandle" fdt-prop |
| node>properties @ |
| ['] fdt-copy-property for-all-words |
| ; |
| |
| : fdt-copy-node ( node -- ) |
| fdtfl-debug 1 > IF dup node>path type cr THEN |
| dup fdt-begin-node |
| dup fdt-copy-properties |
| child BEGIN dup WHILE dup recurse peer REPEAT |
| drop |
| fdt-end-node |
| ; |
| |
| : fdtfl-strings-preload ( -- ) |
| s" reg" fdt-add-string drop |
| s" status" fdt-add-string drop |
| s" 64-bit" fdt-add-string drop |
| s" phandle" fdt-add-string drop |
| s" ibm,vmx" fdt-add-string drop |
| s" ibm,dfp" fdt-add-string drop |
| s" slb-size" fdt-add-string drop |
| s" ibm,purr" fdt-add-string drop |
| s" vendor-id" fdt-add-string drop |
| s" device-id" fdt-add-string drop |
| s" min-grant" fdt-add-string drop |
| s" class-code" fdt-add-string drop |
| s" compatible" fdt-add-string drop |
| s" interrupts" fdt-add-string drop |
| s" cpu-version" fdt-add-string drop |
| s" #size-cells" fdt-add-string drop |
| s" ibm,req#msi" fdt-add-string drop |
| s" revision-id" fdt-add-string drop |
| s" device_type" fdt-add-string drop |
| s" max-latency" fdt-add-string drop |
| s" ibm,chip-id" fdt-add-string drop |
| s" ibm,pft-size" fdt-add-string drop |
| s" ibm,slb-size" fdt-add-string drop |
| s" devsel-speed" fdt-add-string drop |
| s" ibm,loc-code" fdt-add-string drop |
| s" subsystem-id" fdt-add-string drop |
| s" d-cache-size" fdt-add-string drop |
| s" i-cache-size" fdt-add-string drop |
| s" #address-cells" fdt-add-string drop |
| s" clock-frequency" fdt-add-string drop |
| s" cache-line-size" fdt-add-string drop |
| s" ibm,pa-features" fdt-add-string drop |
| s" ibm,my-drc-index" fdt-add-string drop |
| s" d-cache-line-size" fdt-add-string drop |
| s" i-cache-line-size" fdt-add-string drop |
| s" assigned-addresses" fdt-add-string drop |
| s" d-cache-block-size" fdt-add-string drop |
| s" i-cache-block-size" fdt-add-string drop |
| s" timebase-frequency" fdt-add-string drop |
| s" subsystem-vendor-id" fdt-add-string drop |
| s" ibm,segment-page-sizes" fdt-add-string drop |
| s" ibm,ppc-interrupt-server#s" fdt-add-string drop |
| s" ibm,processor-segment-sizes" fdt-add-string drop |
| s" ibm,ppc-interrupt-gserver#s" fdt-add-string drop |
| ; |
| |
| : fdt-append-blob ( bytes cur blob -- cur ) |
| 3dup -rot swap move |
| drop + |
| ; |
| |
| : fdt-flatten-tree ( -- tree ) |
| 100000 alloc-mem dup fdtfl-struct-here ! fdtfl-struct ! |
| 100000 alloc-mem dup fdtfl-strings-here ! fdtfl-strings ! |
| |
| fdtfl-debug IF |
| 0 fdtfl-strings-reused ! |
| milliseconds fdlfl-ms ! |
| THEN |
| |
| \ Preload strings cache |
| fdtfl-strings-preload |
| fdtfl-strings-here @ fdtfl-strings-cache ! |
| \ Render the blobs |
| device-tree @ fdt-copy-node |
| fdt-end |
| |
| \ Calculate strings and struct sizes |
| fdtfl-struct-here @ fdtfl-struct @ - |
| fdtfl-strings-here @ fdtfl-strings @ - ( struct-len strings-len ) |
| |
| 2dup + /fdth + |
| 10 + \ Reserve 16 bytes for an empty reserved block |
| |
| fdtfl-debug IF |
| 3dup |
| ." FDTsize=" .d ." Strings=" .d ." Struct=" .d |
| ." Reused str=" fdtfl-strings-reused @ .d |
| milliseconds fdlfl-ms @ - .d ." ms" |
| cr |
| THEN |
| |
| \ Allocate flatten DT blob |
| dup alloc-mem ( struct-len strings-len total-len fdt ) |
| >r ( struct-len strings-len total-len r: fdt ) |
| |
| \ Write header |
| OF_DT_HEADER r@ >fdth_magic l! |
| dup r@ >fdth_tsize l! |
| /fdth 10 + 2 pick + r@ >fdth_struct_off l! |
| /fdth 10 + r@ >fdth_string_off l! |
| /fdth r@ >fdth_rsvmap_off l! |
| 11 r@ >fdth_version l! |
| 10 r@ >fdth_compat_vers l! |
| chosen-cpu-unit r@ >fdth_boot_cpu l! |
| over r@ >fdth_string_size l! |
| 2 pick r@ >fdth_struct_size l! |
| ( struct-len strings-len total-len r: fdt ) |
| |
| drop ( struct-len strings-len r: fdt ) |
| r@ /fdth + ( struct-len strings-len cur r: fdt ) |
| |
| \ Write the reserved entry |
| 0 over ! cell+ 0 over ! cell+ |
| |
| \ Write strings and struct blobs |
| fdtfl-strings @ fdt-append-blob |
| fdtfl-struct @ fdt-append-blob |
| drop |
| |
| \ Free temporary blobs |
| fdtfl-struct @ 100000 free-mem |
| fdtfl-strings @ 100000 free-mem |
| |
| \ Return fdt |
| r> |
| ; |
| |
| : fdt-flatten-tree-free ( tree ) |
| dup >fdth_tsize l@ free-mem |
| ; |