pseries: Split device tree construction from device tree load

spapr_finalize_fdt() both finishes building the device tree for the guest
and loads it into guest memory.  For future cleanups, it's going to be
more convenient to do these two things separately.  The loading portion is
pretty trivial, so we move it inline into the caller, ppc_spapr_reset().

We also rename spapr_finalize_fdt(), because the current name is going to
become inaccurate.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
This commit is contained in:
David Gibson 2016-10-25 11:51:33 +11:00
parent 37ad52ba7a
commit 997b6cfc3d
2 changed files with 24 additions and 20 deletions

View File

@ -900,10 +900,9 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
return 0; return 0;
} }
static void spapr_finalize_fdt(sPAPRMachineState *spapr, static void *spapr_build_fdt(sPAPRMachineState *spapr,
hwaddr fdt_addr, hwaddr rtas_addr,
hwaddr rtas_addr, hwaddr rtas_size)
hwaddr rtas_size)
{ {
MachineState *machine = MACHINE(qdev_get_machine()); MachineState *machine = MACHINE(qdev_get_machine());
MachineClass *mc = MACHINE_GET_CLASS(machine); MachineClass *mc = MACHINE_GET_CLASS(machine);
@ -999,19 +998,8 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr,
} }
} }
_FDT((fdt_pack(fdt)));
if (fdt_totalsize(fdt) > FDT_MAX_SIZE) {
error_report("FDT too big ! 0x%x bytes (max is 0x%x)",
fdt_totalsize(fdt), FDT_MAX_SIZE);
exit(1);
}
qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
g_free(bootlist); g_free(bootlist);
g_free(fdt); return fdt;
} }
static uint64_t translate_kernel_address(void *opaque, uint64_t addr) static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
@ -1147,6 +1135,8 @@ static void ppc_spapr_reset(void)
sPAPRMachineState *spapr = SPAPR_MACHINE(machine); sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
PowerPCCPU *first_ppc_cpu; PowerPCCPU *first_ppc_cpu;
uint32_t rtas_limit; uint32_t rtas_limit;
void *fdt;
int rc;
/* Check for unknown sysbus devices */ /* Check for unknown sysbus devices */
foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL); foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
@ -1173,14 +1163,28 @@ static void ppc_spapr_reset(void)
spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE; spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE;
spapr->fdt_addr = spapr->rtas_addr - FDT_MAX_SIZE; spapr->fdt_addr = spapr->rtas_addr - FDT_MAX_SIZE;
/* Load the fdt */ fdt = spapr_build_fdt(spapr, spapr->rtas_addr, spapr->rtas_size);
spapr_finalize_fdt(spapr, spapr->fdt_addr, spapr->rtas_addr,
spapr->rtas_size);
/* Copy RTAS over */ /* Copy RTAS over */
cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob, cpu_physical_memory_write(spapr->rtas_addr, spapr->rtas_blob,
spapr->rtas_size); spapr->rtas_size);
rc = fdt_pack(fdt);
/* Should only fail if we've built a corrupted tree */
assert(rc == 0);
if (fdt_totalsize(fdt) > FDT_MAX_SIZE) {
error_report("FDT too big ! 0x%x bytes (max is 0x%x)",
fdt_totalsize(fdt), FDT_MAX_SIZE);
exit(1);
}
/* Load the fdt */
qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
cpu_physical_memory_write(spapr->fdt_addr, fdt, fdt_totalsize(fdt));
g_free(fdt);
/* Set up the entry state */ /* Set up the entry state */
first_ppc_cpu = POWERPC_CPU(first_cpu); first_ppc_cpu = POWERPC_CPU(first_cpu);
first_ppc_cpu->env.gpr[3] = spapr->fdt_addr; first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;

View File

@ -184,7 +184,7 @@ void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
/* /*
* Setup CPU DT entries only for hotplugged CPUs. For boot time or * Setup CPU DT entries only for hotplugged CPUs. For boot time or
* coldplugged CPUs DT entries are setup in spapr_finalize_fdt(). * coldplugged CPUs DT entries are setup in spapr_build_fdt().
*/ */
if (dev->hotplugged) { if (dev->hotplugged) {
fdt = spapr_populate_hotplug_cpu_dt(cs, &fdt_offset, spapr); fdt = spapr_populate_hotplug_cpu_dt(cs, &fdt_offset, spapr);