blob: 71b2efce6071ce7eb0166675d29094d774629b6d [file] [log] [blame]
\ *****************************************************************************
\ * 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
;