1\ ***************************************************************************** 2\ * Copyright (c) 2017 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 100 VALUE fdtfl-debug 11 12VARIABLE fdtfl-struct 13VARIABLE fdtfl-struct-here 14VARIABLE fdtfl-strings 15VARIABLE fdtfl-strings-cache 16VARIABLE fdtfl-strings-here 17VARIABLE fdtfl-strings-reused \ debug only 18VARIABLE fdlfl-ms \ debug only 19 20: fdt-skip-string ( cur -- cur ) zcount + char+ 4 #aligned ; 21 22: zstring= ( str len zstr -- flag ) 23 2dup + c@ 0<> IF 24 3drop false 25 EXIT 26 THEN 27 swap comp 0= 28; 29 30: fdt-find-string ( name namelen -- nameoff true | false ) 31 fdtfl-strings @ 32 BEGIN 33 dup fdtfl-strings-cache @ < 34 WHILE 35 3dup zstring= IF 36 nip nip ( curstr ) 37 fdtfl-strings @ - 38 true 39 EXIT 40 THEN 41 fdt-skip-string 42 REPEAT 43 3drop 44 false 45; 46 47: fdt-str-allot ( len -- ) fdtfl-strings-here @ + to fdtfl-strings-here ; 48: fdt-str-c, ( char -- ) fdtfl-strings-here @ 1 fdt-str-allot c! ; 49: fdt-str-align ( -- ) 50 fdtfl-strings-here @ 51 dup dup 4 #aligned swap - ( here bytes-to-erase ) 52 dup -rot 53 erase 54 fdt-str-allot 55; 56: fdt-str-bytes, ( data len -- ) fdtfl-strings-here @ over fdt-str-allot swap move ; 57: fdt-str-ztr, ( str len -- ) fdt-str-bytes, 0 fdt-str-c, ; 58 59: fdt-add-string ( name namelen -- nameoff ) 60 fdtfl-strings-here @ -rot 61 fdt-str-ztr, 62 fdt-str-align 63 fdtfl-strings @ - 64; 65 66: fdt-get-string ( name namelen -- nameoff ) 67 2dup fdt-find-string IF 68 -rot 2drop 69 fdtfl-debug IF 70 1 fdtfl-strings-reused +! 71 THEN 72 EXIT 73 THEN 74 fdt-add-string 75; 76 77: fdt-allot ( len -- ) fdtfl-struct-here @ + to fdtfl-struct-here ; 78: fdt-c, ( char -- ) fdtfl-struct-here @ 1 fdt-allot c! ; 79: fdt-align ( -- ) 80 fdtfl-struct-here @ 81 dup dup 4 #aligned swap - ( here bytes-to-erase ) 82 dup -rot 83 erase 84 fdt-allot 85; 86: fdt-bytes, ( data len -- ) fdtfl-struct-here @ over fdt-allot swap move ; 87: fdt-ztr, ( str len -- ) fdt-bytes, 0 fdt-c, ; 88: fdt-l, ( token -- ) fdtfl-struct-here @ l! /l fdt-allot ; 89 90: fdt-begin-node ( phandle -- ) 91 OF_DT_BEGIN_NODE fdt-l, 92 dup device-tree @ = IF drop s" " ELSE node>qname THEN 93 fdt-ztr, 94 fdt-align 95; 96 97: fdt-end-node ( -- ) OF_DT_END_NODE fdt-l, ; 98 99: fdt-prop ( prop len name namelen -- ) 100 OF_DT_PROP fdt-l, 101 102 \ get string offset 103 fdt-get-string ( prop len nameoff ) 104 105 \ store len and nameoff 106 over fdt-l, 107 fdt-l, ( prop len ) 108 109 \ now store the bytes 110 fdt-bytes, 111 fdt-align 112; 113 114: fdt-end ( -- ) OF_DT_END fdt-l, ; 115 116: fdt-copy-property ( link -- ) 117 dup link> execute 118 rot 119 link>name name>string 120 2dup s" name" str= IF 4drop EXIT THEN \ skipping useless "name" 121 fdt-prop 122; 123 124: for-all-words ( wid xt -- ) \ xt has sig ( lfa -- ) 125 >r 126 cell+ @ BEGIN dup WHILE dup r@ execute @ REPEAT 127 r> 2drop 128; 129 130: fdt-copy-properties ( phandle -- ) 131 dup encode-int s" phandle" fdt-prop 132 node>properties @ 133 ['] fdt-copy-property for-all-words 134; 135 136: fdt-copy-node ( node -- ) 137 fdtfl-debug 1 > IF dup node>path type cr THEN 138 dup fdt-begin-node 139 dup fdt-copy-properties 140 child BEGIN dup WHILE dup recurse peer REPEAT 141 drop 142 fdt-end-node 143; 144 145: fdtfl-strings-preload ( -- ) 146 s" reg" fdt-add-string drop 147 s" status" fdt-add-string drop 148 s" 64-bit" fdt-add-string drop 149 s" phandle" fdt-add-string drop 150 s" ibm,vmx" fdt-add-string drop 151 s" ibm,dfp" fdt-add-string drop 152 s" slb-size" fdt-add-string drop 153 s" ibm,purr" fdt-add-string drop 154 s" vendor-id" fdt-add-string drop 155 s" device-id" fdt-add-string drop 156 s" min-grant" fdt-add-string drop 157 s" class-code" fdt-add-string drop 158 s" compatible" fdt-add-string drop 159 s" interrupts" fdt-add-string drop 160 s" cpu-version" fdt-add-string drop 161 s" #size-cells" fdt-add-string drop 162 s" ibm,req#msi" fdt-add-string drop 163 s" revision-id" fdt-add-string drop 164 s" device_type" fdt-add-string drop 165 s" max-latency" fdt-add-string drop 166 s" ibm,chip-id" fdt-add-string drop 167 s" ibm,pft-size" fdt-add-string drop 168 s" ibm,slb-size" fdt-add-string drop 169 s" devsel-speed" fdt-add-string drop 170 s" ibm,loc-code" fdt-add-string drop 171 s" subsystem-id" fdt-add-string drop 172 s" d-cache-size" fdt-add-string drop 173 s" i-cache-size" fdt-add-string drop 174 s" #address-cells" fdt-add-string drop 175 s" clock-frequency" fdt-add-string drop 176 s" cache-line-size" fdt-add-string drop 177 s" ibm,pa-features" fdt-add-string drop 178 s" ibm,my-drc-index" fdt-add-string drop 179 s" d-cache-line-size" fdt-add-string drop 180 s" i-cache-line-size" fdt-add-string drop 181 s" assigned-addresses" fdt-add-string drop 182 s" d-cache-block-size" fdt-add-string drop 183 s" i-cache-block-size" fdt-add-string drop 184 s" timebase-frequency" fdt-add-string drop 185 s" subsystem-vendor-id" fdt-add-string drop 186 s" ibm,segment-page-sizes" fdt-add-string drop 187 s" ibm,ppc-interrupt-server#s" fdt-add-string drop 188 s" ibm,processor-segment-sizes" fdt-add-string drop 189 s" ibm,ppc-interrupt-gserver#s" fdt-add-string drop 190; 191 192: fdt-append-blob ( bytes cur blob -- cur ) 193 3dup -rot swap move 194 drop + 195; 196 197: fdt-flatten-tree ( -- tree ) 198 100000 alloc-mem dup fdtfl-struct-here ! fdtfl-struct ! 199 100000 alloc-mem dup fdtfl-strings-here ! fdtfl-strings ! 200 201 fdtfl-debug IF 202 0 fdtfl-strings-reused ! 203 milliseconds fdlfl-ms ! 204 THEN 205 206 \ Preload strings cache 207 fdtfl-strings-preload 208 fdtfl-strings-here @ fdtfl-strings-cache ! 209 \ Render the blobs 210 device-tree @ fdt-copy-node 211 fdt-end 212 213 \ Calculate strings and struct sizes 214 fdtfl-struct-here @ fdtfl-struct @ - 215 fdtfl-strings-here @ fdtfl-strings @ - ( struct-len strings-len ) 216 217 2dup + /fdth + 218 10 + \ Reserve 16 bytes for an empty reserved block 219 220 fdtfl-debug IF 221 3dup 222 ." FDTsize=" .d ." Strings=" .d ." Struct=" .d 223 ." Reused str=" fdtfl-strings-reused @ .d 224 milliseconds fdlfl-ms @ - .d ." ms" 225 cr 226 THEN 227 228 \ Allocate flatten DT blob 229 dup alloc-mem ( struct-len strings-len total-len fdt ) 230 >r ( struct-len strings-len total-len r: fdt ) 231 232 \ Write header 233 OF_DT_HEADER r@ >fdth_magic l! 234 dup r@ >fdth_tsize l! 235 /fdth 10 + 2 pick + r@ >fdth_struct_off l! 236 /fdth 10 + r@ >fdth_string_off l! 237 /fdth r@ >fdth_rsvmap_off l! 238 11 r@ >fdth_version l! 239 10 r@ >fdth_compat_vers l! 240 chosen-cpu-unit r@ >fdth_boot_cpu l! 241 over r@ >fdth_string_size l! 242 2 pick r@ >fdth_struct_size l! 243 ( struct-len strings-len total-len r: fdt ) 244 245 drop ( struct-len strings-len r: fdt ) 246 r@ /fdth + ( struct-len strings-len cur r: fdt ) 247 248 \ Write the reserved entry 249 0 over ! cell+ 0 over ! cell+ 250 251 \ Write strings and struct blobs 252 fdtfl-strings @ fdt-append-blob 253 fdtfl-struct @ fdt-append-blob 254 drop 255 256 \ Free temporary blobs 257 fdtfl-struct @ 100000 free-mem 258 fdtfl-strings @ 100000 free-mem 259 260 \ Return fdt 261 r> 262; 263 264: fdt-flatten-tree-free ( tree ) 265 dup >fdth_tsize l@ free-mem 266; 267