aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2016-10-20 15:37:41 +1100
committerDavid Gibson <david@gibson.dropbear.id.au>2016-10-28 09:38:26 +1100
commit2cac78c12ade9a87b6251f8d854c2e43a30f41bf (patch)
tree579bc8d10805b03aee3a8660821da395629d9f1a
parentcf6e522390126bdd20406481f3df79c194a431bd (diff)
downloadmigration-2cac78c12ade9a87b6251f8d854c2e43a30f41bf.tar.gz
pseries: Consolidate RTAS loading
At each system reset, the pseries machine needs to load RTAS (the runtime portion of the guest firmware) into the VM. This means copying the actual RTAS code into guest memory, and also updating the device tree so that the guest OS and boot firmware can locate it. For historical reasons the copy and update to the device tree were in different parts of the code. This cleanup brings them both together in an spapr_load_rtas() function. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Reviewed-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
-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 8e58d8670d4..17733dffa34 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 0db84c816de..54b4ad33054 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 a0b4bf80e04..847ae88186f 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)