2 * SPAPR machine hooks to Virtual Open Firmware,
4 * SPDX-License-Identifier: GPL-2.0-or-later
6 #include "qemu/osdep.h"
7 #include "qemu-common.h"
8 #include "qapi/error.h"
9 #include "hw/ppc/spapr.h"
10 #include "hw/ppc/spapr_vio.h"
11 #include "hw/ppc/spapr_cpu_core.h"
12 #include "hw/ppc/fdt.h"
13 #include "hw/ppc/vof.h"
14 #include "sysemu/sysemu.h"
15 #include "qom/qom-qobject.h"
18 target_ulong
spapr_h_vof_client(PowerPCCPU
*cpu
, SpaprMachineState
*spapr
,
19 target_ulong opcode
, target_ulong
*_args
)
21 int ret
= vof_client_call(MACHINE(spapr
), spapr
->vof
, spapr
->fdt_blob
,
22 ppc64_phys_to_real(_args
[0]));
30 void spapr_vof_client_dt_finalize(SpaprMachineState
*spapr
, void *fdt
)
32 char *stdout_path
= spapr_vio_stdout_path(spapr
->vio_bus
);
34 vof_build_dt(fdt
, spapr
->vof
);
36 if (spapr
->vof
->bootargs
) {
39 _FDT(chosen
= fdt_path_offset(fdt
, "/chosen"));
41 * If the client did not change "bootargs", spapr_dt_chosen() must have
42 * stored machine->kernel_cmdline in it before getting here.
44 _FDT(fdt_setprop_string(fdt
, chosen
, "bootargs", spapr
->vof
->bootargs
));
48 * SLOF-less setup requires an open instance of stdout for early
49 * kernel printk. By now all phandles are settled so we can open
50 * the default serial console.
53 _FDT(vof_client_open_store(fdt
, spapr
->vof
, "/chosen", "stdout",
58 void spapr_vof_reset(SpaprMachineState
*spapr
, void *fdt
, Error
**errp
)
60 target_ulong stack_ptr
;
61 Vof
*vof
= spapr
->vof
;
62 PowerPCCPU
*first_ppc_cpu
= POWERPC_CPU(first_cpu
);
64 vof_init(vof
, spapr
->rma_size
, errp
);
66 stack_ptr
= vof_claim(vof
, 0, VOF_STACK_SIZE
, VOF_STACK_SIZE
);
67 if (stack_ptr
== -1) {
68 error_setg(errp
, "Memory allocation for stack failed");
71 /* Stack grows downwards plus reserve space for the minimum stack frame */
72 stack_ptr
+= VOF_STACK_SIZE
- 0x20;
74 if (spapr
->kernel_size
&&
75 vof_claim(vof
, spapr
->kernel_addr
, spapr
->kernel_size
, 0) == -1) {
76 error_setg(errp
, "Memory for kernel is in use");
80 if (spapr
->initrd_size
&&
81 vof_claim(vof
, spapr
->initrd_base
, spapr
->initrd_size
, 0) == -1) {
82 error_setg(errp
, "Memory for initramdisk is in use");
86 spapr_vof_client_dt_finalize(spapr
, fdt
);
88 spapr_cpu_set_entry_state(first_ppc_cpu
, SPAPR_ENTRY_POINT
,
89 stack_ptr
, spapr
->initrd_base
,
91 /* VOF is 32bit BE so enforce MSR here */
92 first_ppc_cpu
->env
.msr
&= ~((1ULL << MSR_SF
) | (1ULL << MSR_LE
));
95 * At this point the expected allocation map is:
97 * 0..c38 - the initial firmware
100 * 3ea0000.. - initramdisk
102 * We skip writing FDT as nothing expects it; OF client interface is
103 * going to be used for reading the device tree.
107 void spapr_vof_quiesce(MachineState
*ms
)
109 SpaprMachineState
*spapr
= SPAPR_MACHINE(ms
);
111 spapr
->fdt_size
= fdt_totalsize(spapr
->fdt_blob
);
112 spapr
->fdt_initial_size
= spapr
->fdt_size
;
115 bool spapr_vof_setprop(MachineState
*ms
, const char *path
, const char *propname
,
116 void *val
, int vallen
)
118 SpaprMachineState
*spapr
= SPAPR_MACHINE(ms
);
121 * We only allow changing properties which we know how to update in QEMU
123 * the ones which we know that they need to survive during "quiesce".
126 if (strcmp(path
, "/rtas") == 0) {
127 if (strcmp(propname
, "linux,rtas-base") == 0 ||
128 strcmp(propname
, "linux,rtas-entry") == 0) {
129 /* These need to survive quiesce so let them store in the FDT */
134 if (strcmp(path
, "/chosen") == 0) {
135 if (strcmp(propname
, "bootargs") == 0) {
136 Vof
*vof
= spapr
->vof
;
138 g_free(vof
->bootargs
);
139 vof
->bootargs
= g_strndup(val
, vallen
);
142 if (strcmp(propname
, "linux,initrd-start") == 0) {
143 if (vallen
== sizeof(uint32_t)) {
144 spapr
->initrd_base
= ldl_be_p(val
);
147 if (vallen
== sizeof(uint64_t)) {
148 spapr
->initrd_base
= ldq_be_p(val
);
153 if (strcmp(propname
, "linux,initrd-end") == 0) {
154 if (vallen
== sizeof(uint32_t)) {
155 spapr
->initrd_size
= ldl_be_p(val
) - spapr
->initrd_base
;
158 if (vallen
== sizeof(uint64_t)) {
159 spapr
->initrd_size
= ldq_be_p(val
) - spapr
->initrd_base
;