aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/ppc/spapr.c3
-rw-r--r--hw/ppc/spapr_rtas.c72
-rw-r--r--include/hw/ppc/spapr.h1
3 files changed, 43 insertions, 33 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8e58d86..17733df 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1165,8 +1165,7 @@ static void ppc_spapr_reset(void)
fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size);
- /* Copy RTAS over */
- cpu_physical_memory_write(rtas_addr, spapr->rtas_blob, spapr->rtas_size);
+ spapr_load_rtas(spapr, fdt, rtas_addr);
rc = fdt_pack(fdt);
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 0db84c8..54b4ad3 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -721,37 +721,6 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
uint64_t max_hotplug_addr = spapr->hotplug_memory.base +
memory_region_size(&spapr->hotplug_memory.mr);
- ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size);
- if (ret < 0) {
- error_report("Couldn't add RTAS reserve entry: %s",
- fdt_strerror(ret));
- return ret;
- }
-
- ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-base",
- rtas_addr);
- if (ret < 0) {
- error_report("Couldn't add linux,rtas-base property: %s",
- fdt_strerror(ret));
- return ret;
- }
-
- ret = qemu_fdt_setprop_cell(fdt, "/rtas", "linux,rtas-entry",
- rtas_addr);
- if (ret < 0) {
- error_report("Couldn't add linux,rtas-entry property: %s",
- fdt_strerror(ret));
- return ret;
- }
-
- ret = qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-size",
- rtas_size);
- if (ret < 0) {
- error_report("Couldn't add rtas-size property: %s",
- fdt_strerror(ret));
- return ret;
- }
-
for (i = 0; i < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; i++) {
struct rtas_call *call = &rtas_table[i];
@@ -784,6 +753,47 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
return 0;
}
+void spapr_load_rtas(sPAPRMachineState *spapr, void *fdt, hwaddr addr)
+{
+ int rtas_node;
+ int ret;
+
+ /* Copy RTAS blob into guest RAM */
+ cpu_physical_memory_write(addr, spapr->rtas_blob, spapr->rtas_size);
+
+ ret = fdt_add_mem_rsv(fdt, addr, spapr->rtas_size);
+ if (ret < 0) {
+ error_report("Couldn't add RTAS reserve entry: %s",
+ fdt_strerror(ret));
+ exit(1);
+ }
+
+ /* Update the device tree with the blob's location */
+ rtas_node = fdt_path_offset(fdt, "/rtas");
+ assert(rtas_node >= 0);
+
+ ret = fdt_setprop_cell(fdt, rtas_node, "linux,rtas-base", addr);
+ if (ret < 0) {
+ error_report("Couldn't add linux,rtas-base property: %s",
+ fdt_strerror(ret));
+ exit(1);
+ }
+
+ ret = fdt_setprop_cell(fdt, rtas_node, "linux,rtas-entry", addr);
+ if (ret < 0) {
+ error_report("Couldn't add linux,rtas-entry property: %s",
+ fdt_strerror(ret));
+ exit(1);
+ }
+
+ ret = fdt_setprop_cell(fdt, rtas_node, "rtas-size", spapr->rtas_size);
+ if (ret < 0) {
+ error_report("Couldn't add rtas-size property: %s",
+ fdt_strerror(ret));
+ exit(1);
+ }
+}
+
static void core_rtas_register_types(void)
{
spapr_rtas_register(RTAS_DISPLAY_CHARACTER, "display-character",
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index a0b4bf8..847ae88 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -532,6 +532,7 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *sm,
uint32_t nret, target_ulong rets);
int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
hwaddr rtas_size);
+void spapr_load_rtas(sPAPRMachineState *spapr, void *fdt, hwaddr addr);
#define SPAPR_TCE_PAGE_SHIFT 12
#define SPAPR_TCE_PAGE_SIZE (1ULL << SPAPR_TCE_PAGE_SHIFT)