aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board-qemu/slof/OF.fs2
-rw-r--r--board-qemu/slof/fdt-fl.fs266
-rw-r--r--board-qemu/slof/rtas.fs6
-rw-r--r--lib/libhvcall/hvcall.code5
-rw-r--r--lib/libhvcall/hvcall.in1
-rw-r--r--lib/libhvcall/libhvcall.h3
6 files changed, 282 insertions, 1 deletions
diff --git a/board-qemu/slof/OF.fs b/board-qemu/slof/OF.fs
index 4e04b84..35fe233 100644
--- a/board-qemu/slof/OF.fs
+++ b/board-qemu/slof/OF.fs
@@ -119,6 +119,8 @@ check-boot-menu
380 cp
+#include "fdt-fl.fs"
+
\ Grab rtas from qemu
#include "rtas.fs"
diff --git a/board-qemu/slof/fdt-fl.fs b/board-qemu/slof/fdt-fl.fs
new file mode 100644
index 0000000..71b2efc
--- /dev/null
+++ b/board-qemu/slof/fdt-fl.fs
@@ -0,0 +1,266 @@
+\ *****************************************************************************
+\ * 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
+;
diff --git a/board-qemu/slof/rtas.fs b/board-qemu/slof/rtas.fs
index b17157e..f1a4abe 100644
--- a/board-qemu/slof/rtas.fs
+++ b/board-qemu/slof/rtas.fs
@@ -98,6 +98,12 @@ find-qemu-rtas
;
: rtas-quiesce ( -- )
+ fdt-flatten-tree
+ dup hv-update-dt ?dup IF
+ \ Ignore hcall not implemented error, print error otherwise
+ dup -2 <> IF ." HV-UPDATE-DT error: " . cr ELSE drop THEN
+ THEN
+ fdt-flatten-tree-free
" quiesce" rtas-get-token rtas-cb rtas>token l!
0 rtas-cb rtas>nargs l!
0 rtas-cb rtas>nret l!
diff --git a/lib/libhvcall/hvcall.code b/lib/libhvcall/hvcall.code
index 744469f..5918c90 100644
--- a/lib/libhvcall/hvcall.code
+++ b/lib/libhvcall/hvcall.code
@@ -123,3 +123,8 @@ PRIM(check_X2d_and_X2d_patch_X2d_sc1)
patch_broken_sc1((void*)start, (void*)end, (void*)patch_ins);
MIRP
+
+PRIM(hv_X2d_update_X2d_dt)
+ unsigned long dt = TOS.u;
+ TOS.u = hv_generic(KVMPPC_H_UPDATE_DT, dt);
+MIRP
diff --git a/lib/libhvcall/hvcall.in b/lib/libhvcall/hvcall.in
index e99d6d1..9193162 100644
--- a/lib/libhvcall/hvcall.in
+++ b/lib/libhvcall/hvcall.in
@@ -30,4 +30,5 @@ cod(RX!)
cod(hv-logical-memop)
cod(hv-cas)
+cod(hv-update-dt)
cod(get-print-version)
diff --git a/lib/libhvcall/libhvcall.h b/lib/libhvcall/libhvcall.h
index 6356a62..3fa4398 100644
--- a/lib/libhvcall/libhvcall.h
+++ b/lib/libhvcall/libhvcall.h
@@ -24,7 +24,8 @@
#define KVMPPC_H_LOGICAL_MEMOP (KVMPPC_HCALL_BASE + 0x1)
/* Client Architecture support */
#define KVMPPC_H_CAS (KVMPPC_HCALL_BASE + 0x2)
-#define KVMPPC_HCALL_MAX KVMPPC_H_CAS
+#define KVMPPC_H_UPDATE_DT (KVMPPC_HCALL_BASE + 0x3)
+#define KVMPPC_HCALL_MAX KVMPPC_H_UPDATE_DT
#ifndef __ASSEMBLY__