Hi,
This is a refinement of the Xen loader I posted a few weeks ago. Rather than complicate the generic loader with extra options I went for the more expedient approach of adding a completely new device called the guest-loader. As it didn't need to deal with any of the subtleties of the generic-loader it also worked out somewhat simpler.
Instead of allowing the user to hand hack FDT blobs we simply add syntactic sugar that understands the difference between a kernel and initrd. This could be expanded in future if we want although at the moment I don't know what else you would add.
The new syntax is now simpler:
-device guest-loader,addr=0x42000000,kernel=Image,bootargs="console=hvc0 earlyprintk=xen" \ -device guest-loader,addr=0x47000000,initrd=rootfs.cpio
So any objections? It would be nice to get in this cycle but we only have a week left until soft-freeze.
Alex Bennée (4): hw/board: promote fdt from ARM VirtMachineState to MachineState hw/riscv: migrate fdt field to generic MachineState device_tree: add qemu_fdt_setprop_string_array helper hw/core: implement a guest-loader to support static hypervisor guests
hw/core/guest-loader.h | 34 ++++ include/hw/arm/virt.h | 1 - include/hw/boards.h | 1 + include/hw/riscv/virt.h | 1 - include/sysemu/device_tree.h | 17 ++ hw/arm/virt.c | 322 ++++++++++++++++++----------------- hw/core/guest-loader.c | 140 +++++++++++++++ hw/riscv/virt.c | 18 +- softmmu/device_tree.c | 26 +++ hw/core/meson.build | 2 + 10 files changed, 398 insertions(+), 164 deletions(-) create mode 100644 hw/core/guest-loader.h create mode 100644 hw/core/guest-loader.c
The use of FDT's is quite common across our various platforms. To allow the generic loader to tweak it we need to make it available in the generic state. This creates the field and migrates the initial user to use the generic field. Other boards will be updated in later patches.
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- include/hw/arm/virt.h | 1 - include/hw/boards.h | 1 + hw/arm/virt.c | 322 ++++++++++++++++++++++-------------------- 3 files changed, 170 insertions(+), 154 deletions(-)
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index aad6d69841..648e5d6791 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -152,7 +152,6 @@ struct VirtMachineState { char *pciehb_nodename; const int *irqmap; int smp_cpus; - void *fdt; int fdt_size; uint32_t clock_phandle; uint32_t gic_phandle; diff --git a/include/hw/boards.h b/include/hw/boards.h index bf53e8a16e..4da71decf2 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -257,6 +257,7 @@ struct MachineState {
/*< public >*/
+ void *fdt; char *dtb; char *dumpdtb; int phandle_start; diff --git a/hw/arm/virt.c b/hw/arm/virt.c index e465a988d6..1ca04c597e 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -216,14 +216,14 @@ static bool cpu_type_valid(const char *cpu) return false; }
-static void create_kaslr_seed(VirtMachineState *vms, const char *node) +static void create_kaslr_seed(MachineState *ms, const char *node) { uint64_t seed;
if (qemu_guest_getrandom(&seed, sizeof(seed), NULL)) { return; } - qemu_fdt_setprop_u64(vms->fdt, node, "kaslr-seed", seed); + qemu_fdt_setprop_u64(ms->fdt, node, "kaslr-seed", seed); }
static void create_fdt(VirtMachineState *vms) @@ -237,7 +237,7 @@ static void create_fdt(VirtMachineState *vms) exit(1); }
- vms->fdt = fdt; + ms->fdt = fdt;
/* Header */ qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,dummy-virt"); @@ -246,11 +246,11 @@ static void create_fdt(VirtMachineState *vms)
/* /chosen must exist for load_dtb to fill in necessary properties later */ qemu_fdt_add_subnode(fdt, "/chosen"); - create_kaslr_seed(vms, "/chosen"); + create_kaslr_seed(ms, "/chosen");
if (vms->secure) { qemu_fdt_add_subnode(fdt, "/secure-chosen"); - create_kaslr_seed(vms, "/secure-chosen"); + create_kaslr_seed(ms, "/secure-chosen"); }
/* Clock node, for the benefit of the UART. The kernel device tree @@ -314,6 +314,7 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms) ARMCPU *armcpu; VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI; + MachineState *ms = MACHINE(vms);
if (vmc->claim_edge_triggered_timers) { irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI; @@ -325,19 +326,19 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms) (1 << vms->smp_cpus) - 1); }
- qemu_fdt_add_subnode(vms->fdt, "/timer"); + qemu_fdt_add_subnode(ms->fdt, "/timer");
armcpu = ARM_CPU(qemu_get_cpu(0)); if (arm_feature(&armcpu->env, ARM_FEATURE_V8)) { const char compat[] = "arm,armv8-timer\0arm,armv7-timer"; - qemu_fdt_setprop(vms->fdt, "/timer", "compatible", + qemu_fdt_setprop(ms->fdt, "/timer", "compatible", compat, sizeof(compat)); } else { - qemu_fdt_setprop_string(vms->fdt, "/timer", "compatible", + qemu_fdt_setprop_string(ms->fdt, "/timer", "compatible", "arm,armv7-timer"); } - qemu_fdt_setprop(vms->fdt, "/timer", "always-on", NULL, 0); - qemu_fdt_setprop_cells(vms->fdt, "/timer", "interrupts", + qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0); + qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts", GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags, GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags, GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags, @@ -372,36 +373,36 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms) } }
- qemu_fdt_add_subnode(vms->fdt, "/cpus"); - qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#address-cells", addr_cells); - qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#size-cells", 0x0); + qemu_fdt_add_subnode(ms->fdt, "/cpus"); + qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", addr_cells); + qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
for (cpu = vms->smp_cpus - 1; cpu >= 0; cpu--) { char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu); ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu)); CPUState *cs = CPU(armcpu);
- qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_string(vms->fdt, nodename, "device_type", "cpu"); - qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu"); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", armcpu->dtb_compatible);
if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED && vms->smp_cpus > 1) { - qemu_fdt_setprop_string(vms->fdt, nodename, + qemu_fdt_setprop_string(ms->fdt, nodename, "enable-method", "psci"); }
if (addr_cells == 2) { - qemu_fdt_setprop_u64(vms->fdt, nodename, "reg", + qemu_fdt_setprop_u64(ms->fdt, nodename, "reg", armcpu->mp_affinity); } else { - qemu_fdt_setprop_cell(vms->fdt, nodename, "reg", + qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", armcpu->mp_affinity); }
if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) { - qemu_fdt_setprop_cell(vms->fdt, nodename, "numa-node-id", + qemu_fdt_setprop_cell(ms->fdt, nodename, "numa-node-id", ms->possible_cpus->cpus[cs->cpu_index].props.node_id); }
@@ -412,71 +413,74 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms) static void fdt_add_its_gic_node(VirtMachineState *vms) { char *nodename; + MachineState *ms = MACHINE(vms);
- vms->msi_phandle = qemu_fdt_alloc_phandle(vms->fdt); + vms->msi_phandle = qemu_fdt_alloc_phandle(ms->fdt); nodename = g_strdup_printf("/intc/its@%" PRIx64, vms->memmap[VIRT_GIC_ITS].base); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "arm,gic-v3-its"); - qemu_fdt_setprop(vms->fdt, nodename, "msi-controller", NULL, 0); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_setprop(ms->fdt, nodename, "msi-controller", NULL, 0); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, vms->memmap[VIRT_GIC_ITS].base, 2, vms->memmap[VIRT_GIC_ITS].size); - qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->msi_phandle); + qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", vms->msi_phandle); g_free(nodename); }
static void fdt_add_v2m_gic_node(VirtMachineState *vms) { + MachineState *ms = MACHINE(vms); char *nodename;
nodename = g_strdup_printf("/intc/v2m@%" PRIx64, vms->memmap[VIRT_GIC_V2M].base); - vms->msi_phandle = qemu_fdt_alloc_phandle(vms->fdt); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", + vms->msi_phandle = qemu_fdt_alloc_phandle(ms->fdt); + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "arm,gic-v2m-frame"); - qemu_fdt_setprop(vms->fdt, nodename, "msi-controller", NULL, 0); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_setprop(ms->fdt, nodename, "msi-controller", NULL, 0); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, vms->memmap[VIRT_GIC_V2M].base, 2, vms->memmap[VIRT_GIC_V2M].size); - qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->msi_phandle); + qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", vms->msi_phandle); g_free(nodename); }
static void fdt_add_gic_node(VirtMachineState *vms) { + MachineState *ms = MACHINE(vms); char *nodename;
- vms->gic_phandle = qemu_fdt_alloc_phandle(vms->fdt); - qemu_fdt_setprop_cell(vms->fdt, "/", "interrupt-parent", vms->gic_phandle); + vms->gic_phandle = qemu_fdt_alloc_phandle(ms->fdt); + qemu_fdt_setprop_cell(ms->fdt, "/", "interrupt-parent", vms->gic_phandle);
nodename = g_strdup_printf("/intc@%" PRIx64, vms->memmap[VIRT_GIC_DIST].base); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_cell(vms->fdt, nodename, "#interrupt-cells", 3); - qemu_fdt_setprop(vms->fdt, nodename, "interrupt-controller", NULL, 0); - qemu_fdt_setprop_cell(vms->fdt, nodename, "#address-cells", 0x2); - qemu_fdt_setprop_cell(vms->fdt, nodename, "#size-cells", 0x2); - qemu_fdt_setprop(vms->fdt, nodename, "ranges", NULL, 0); + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 3); + qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 0x2); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 0x2); + qemu_fdt_setprop(ms->fdt, nodename, "ranges", NULL, 0); if (vms->gic_version == VIRT_GIC_VERSION_3) { int nb_redist_regions = virt_gicv3_redist_region_count(vms);
- qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "arm,gic-v3");
- qemu_fdt_setprop_cell(vms->fdt, nodename, + qemu_fdt_setprop_cell(ms->fdt, nodename, "#redistributor-regions", nb_redist_regions);
if (nb_redist_regions == 1) { - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, vms->memmap[VIRT_GIC_DIST].base, 2, vms->memmap[VIRT_GIC_DIST].size, 2, vms->memmap[VIRT_GIC_REDIST].base, 2, vms->memmap[VIRT_GIC_REDIST].size); } else { - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, vms->memmap[VIRT_GIC_DIST].base, 2, vms->memmap[VIRT_GIC_DIST].size, 2, vms->memmap[VIRT_GIC_REDIST].base, @@ -486,22 +490,22 @@ static void fdt_add_gic_node(VirtMachineState *vms) }
if (vms->virt) { - qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts", + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ, GIC_FDT_IRQ_FLAGS_LEVEL_HI); } } else { /* 'cortex-a15-gic' means 'GIC v2' */ - qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "arm,cortex-a15-gic"); if (!vms->virt) { - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, vms->memmap[VIRT_GIC_DIST].base, 2, vms->memmap[VIRT_GIC_DIST].size, 2, vms->memmap[VIRT_GIC_CPU].base, 2, vms->memmap[VIRT_GIC_CPU].size); } else { - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, vms->memmap[VIRT_GIC_DIST].base, 2, vms->memmap[VIRT_GIC_DIST].size, 2, vms->memmap[VIRT_GIC_CPU].base, @@ -510,13 +514,13 @@ static void fdt_add_gic_node(VirtMachineState *vms) 2, vms->memmap[VIRT_GIC_HYP].size, 2, vms->memmap[VIRT_GIC_VCPU].base, 2, vms->memmap[VIRT_GIC_VCPU].size); - qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts", + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ, GIC_FDT_IRQ_FLAGS_LEVEL_HI); } }
- qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->gic_phandle); + qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", vms->gic_phandle); g_free(nodename); }
@@ -524,6 +528,7 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms) { ARMCPU *armcpu = ARM_CPU(first_cpu); uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI; + MachineState *ms = MACHINE(vms);
if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU)) { assert(!object_property_get_bool(OBJECT(armcpu), "pmu", NULL)); @@ -536,12 +541,12 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms) (1 << vms->smp_cpus) - 1); }
- qemu_fdt_add_subnode(vms->fdt, "/pmu"); + qemu_fdt_add_subnode(ms->fdt, "/pmu"); if (arm_feature(&armcpu->env, ARM_FEATURE_V8)) { const char compat[] = "arm,armv8-pmuv3"; - qemu_fdt_setprop(vms->fdt, "/pmu", "compatible", + qemu_fdt_setprop(ms->fdt, "/pmu", "compatible", compat, sizeof(compat)); - qemu_fdt_setprop_cells(vms->fdt, "/pmu", "interrupts", + qemu_fdt_setprop_cells(ms->fdt, "/pmu", "interrupts", GIC_FDT_IRQ_TYPE_PPI, VIRTUAL_PMU_IRQ, irqflags); } } @@ -747,6 +752,7 @@ static void create_uart(const VirtMachineState *vms, int uart, const char clocknames[] = "uartclk\0apb_pclk"; DeviceState *dev = qdev_new(TYPE_PL011); SysBusDevice *s = SYS_BUS_DEVICE(dev); + MachineState *ms = MACHINE(vms);
qdev_prop_set_chr(dev, "chardev", chr); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); @@ -755,28 +761,28 @@ static void create_uart(const VirtMachineState *vms, int uart, sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
nodename = g_strdup_printf("/pl011@%" PRIx64, base); - qemu_fdt_add_subnode(vms->fdt, nodename); + qemu_fdt_add_subnode(ms->fdt, nodename); /* Note that we can't use setprop_string because of the embedded NUL */ - qemu_fdt_setprop(vms->fdt, nodename, "compatible", + qemu_fdt_setprop(ms->fdt, nodename, "compatible", compat, sizeof(compat)); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); - qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts", + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", GIC_FDT_IRQ_TYPE_SPI, irq, GIC_FDT_IRQ_FLAGS_LEVEL_HI); - qemu_fdt_setprop_cells(vms->fdt, nodename, "clocks", + qemu_fdt_setprop_cells(ms->fdt, nodename, "clocks", vms->clock_phandle, vms->clock_phandle); - qemu_fdt_setprop(vms->fdt, nodename, "clock-names", + qemu_fdt_setprop(ms->fdt, nodename, "clock-names", clocknames, sizeof(clocknames));
if (uart == VIRT_UART) { - qemu_fdt_setprop_string(vms->fdt, "/chosen", "stdout-path", nodename); + qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename); } else { /* Mark as not usable by the normal world */ - qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled"); - qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay"); + qemu_fdt_setprop_string(ms->fdt, nodename, "status", "disabled"); + qemu_fdt_setprop_string(ms->fdt, nodename, "secure-status", "okay");
- qemu_fdt_setprop_string(vms->fdt, "/secure-chosen", "stdout-path", + qemu_fdt_setprop_string(ms->fdt, "/secure-chosen", "stdout-path", nodename); }
@@ -790,19 +796,20 @@ static void create_rtc(const VirtMachineState *vms) hwaddr size = vms->memmap[VIRT_RTC].size; int irq = vms->irqmap[VIRT_RTC]; const char compat[] = "arm,pl031\0arm,primecell"; + MachineState *ms = MACHINE(vms);
sysbus_create_simple("pl031", base, qdev_get_gpio_in(vms->gic, irq));
nodename = g_strdup_printf("/pl031@%" PRIx64, base); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop(vms->fdt, nodename, "compatible", compat, sizeof(compat)); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop(ms->fdt, nodename, "compatible", compat, sizeof(compat)); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); - qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts", + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", GIC_FDT_IRQ_TYPE_SPI, irq, GIC_FDT_IRQ_FLAGS_LEVEL_HI); - qemu_fdt_setprop_cell(vms->fdt, nodename, "clocks", vms->clock_phandle); - qemu_fdt_setprop_string(vms->fdt, nodename, "clock-names", "apb_pclk"); + qemu_fdt_setprop_cell(ms->fdt, nodename, "clocks", vms->clock_phandle); + qemu_fdt_setprop_string(ms->fdt, nodename, "clock-names", "apb_pclk"); g_free(nodename); }
@@ -827,38 +834,39 @@ static void create_gpio(const VirtMachineState *vms) hwaddr size = vms->memmap[VIRT_GPIO].size; int irq = vms->irqmap[VIRT_GPIO]; const char compat[] = "arm,pl061\0arm,primecell"; + MachineState *ms = MACHINE(vms);
pl061_dev = sysbus_create_simple("pl061", base, qdev_get_gpio_in(vms->gic, irq));
- uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt); + uint32_t phandle = qemu_fdt_alloc_phandle(ms->fdt); nodename = g_strdup_printf("/pl061@%" PRIx64, base); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); - qemu_fdt_setprop(vms->fdt, nodename, "compatible", compat, sizeof(compat)); - qemu_fdt_setprop_cell(vms->fdt, nodename, "#gpio-cells", 2); - qemu_fdt_setprop(vms->fdt, nodename, "gpio-controller", NULL, 0); - qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts", + qemu_fdt_setprop(ms->fdt, nodename, "compatible", compat, sizeof(compat)); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#gpio-cells", 2); + qemu_fdt_setprop(ms->fdt, nodename, "gpio-controller", NULL, 0); + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", GIC_FDT_IRQ_TYPE_SPI, irq, GIC_FDT_IRQ_FLAGS_LEVEL_HI); - qemu_fdt_setprop_cell(vms->fdt, nodename, "clocks", vms->clock_phandle); - qemu_fdt_setprop_string(vms->fdt, nodename, "clock-names", "apb_pclk"); - qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle); + qemu_fdt_setprop_cell(ms->fdt, nodename, "clocks", vms->clock_phandle); + qemu_fdt_setprop_string(ms->fdt, nodename, "clock-names", "apb_pclk"); + qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", phandle);
gpio_key_dev = sysbus_create_simple("gpio-key", -1, qdev_get_gpio_in(pl061_dev, 3)); - qemu_fdt_add_subnode(vms->fdt, "/gpio-keys"); - qemu_fdt_setprop_string(vms->fdt, "/gpio-keys", "compatible", "gpio-keys"); - qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#size-cells", 0); - qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#address-cells", 1); + qemu_fdt_add_subnode(ms->fdt, "/gpio-keys"); + qemu_fdt_setprop_string(ms->fdt, "/gpio-keys", "compatible", "gpio-keys"); + qemu_fdt_setprop_cell(ms->fdt, "/gpio-keys", "#size-cells", 0); + qemu_fdt_setprop_cell(ms->fdt, "/gpio-keys", "#address-cells", 1);
- qemu_fdt_add_subnode(vms->fdt, "/gpio-keys/poweroff"); - qemu_fdt_setprop_string(vms->fdt, "/gpio-keys/poweroff", + qemu_fdt_add_subnode(ms->fdt, "/gpio-keys/poweroff"); + qemu_fdt_setprop_string(ms->fdt, "/gpio-keys/poweroff", "label", "GPIO Key Poweroff"); - qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys/poweroff", "linux,code", + qemu_fdt_setprop_cell(ms->fdt, "/gpio-keys/poweroff", "linux,code", KEY_POWER); - qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff", + qemu_fdt_setprop_cells(ms->fdt, "/gpio-keys/poweroff", "gpios", phandle, 3, 0); g_free(nodename); } @@ -867,6 +875,7 @@ static void create_virtio_devices(const VirtMachineState *vms) { int i; hwaddr size = vms->memmap[VIRT_MMIO].size; + MachineState *ms = MACHINE(vms);
/* We create the transports in forwards order. Since qbus_realize() * prepends (not appends) new child buses, the incrementing loop below will @@ -916,15 +925,15 @@ static void create_virtio_devices(const VirtMachineState *vms) hwaddr base = vms->memmap[VIRT_MMIO].base + i * size;
nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, base); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_string(vms->fdt, nodename, + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "virtio,mmio"); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); - qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts", + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", GIC_FDT_IRQ_TYPE_SPI, irq, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI); - qemu_fdt_setprop(vms->fdt, nodename, "dma-coherent", NULL, 0); + qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0); g_free(nodename); } } @@ -1005,17 +1014,18 @@ static void virt_flash_fdt(VirtMachineState *vms, { hwaddr flashsize = vms->memmap[VIRT_FLASH].size / 2; hwaddr flashbase = vms->memmap[VIRT_FLASH].base; + MachineState *ms = MACHINE(vms); char *nodename;
if (sysmem == secure_sysmem) { /* Report both flash devices as a single node in the DT */ nodename = g_strdup_printf("/flash@%" PRIx64, flashbase); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "cfi-flash"); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cfi-flash"); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, flashbase, 2, flashsize, 2, flashbase + flashsize, 2, flashsize); - qemu_fdt_setprop_cell(vms->fdt, nodename, "bank-width", 4); + qemu_fdt_setprop_cell(ms->fdt, nodename, "bank-width", 4); g_free(nodename); } else { /* @@ -1023,21 +1033,21 @@ static void virt_flash_fdt(VirtMachineState *vms, * only visible to the secure world. */ nodename = g_strdup_printf("/secflash@%" PRIx64, flashbase); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "cfi-flash"); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cfi-flash"); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, flashbase, 2, flashsize); - qemu_fdt_setprop_cell(vms->fdt, nodename, "bank-width", 4); - qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled"); - qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay"); + qemu_fdt_setprop_cell(ms->fdt, nodename, "bank-width", 4); + qemu_fdt_setprop_string(ms->fdt, nodename, "status", "disabled"); + qemu_fdt_setprop_string(ms->fdt, nodename, "secure-status", "okay"); g_free(nodename);
nodename = g_strdup_printf("/flash@%" PRIx64, flashbase); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "cfi-flash"); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cfi-flash"); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, flashbase + flashsize, 2, flashsize); - qemu_fdt_setprop_cell(vms->fdt, nodename, "bank-width", 4); + qemu_fdt_setprop_cell(ms->fdt, nodename, "bank-width", 4); g_free(nodename); } } @@ -1102,17 +1112,17 @@ static FWCfgState *create_fw_cfg(const VirtMachineState *vms, AddressSpace *as) fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)ms->smp.cpus);
nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_string(vms->fdt, nodename, + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "qemu,fw-cfg-mmio"); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); - qemu_fdt_setprop(vms->fdt, nodename, "dma-coherent", NULL, 0); + qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0); g_free(nodename); return fw_cfg; }
-static void create_pcie_irq_map(const VirtMachineState *vms, +static void create_pcie_irq_map(const MachineState *ms, uint32_t gic_phandle, int first_irq, const char *nodename) { @@ -1140,10 +1150,10 @@ static void create_pcie_irq_map(const VirtMachineState *vms, } }
- qemu_fdt_setprop(vms->fdt, nodename, "interrupt-map", + qemu_fdt_setprop(ms->fdt, nodename, "interrupt-map", full_irq_map, sizeof(full_irq_map));
- qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupt-map-mask", + qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupt-map-mask", 0x1800, 0, 0, /* devfn (PCI_SLOT(3)) */ 0x7 /* PCI irq */); } @@ -1159,6 +1169,7 @@ static void create_smmu(const VirtMachineState *vms, hwaddr size = vms->memmap[VIRT_SMMU].size; const char irq_names[] = "eventq\0priq\0cmdq-sync\0gerror"; DeviceState *dev; + MachineState *ms = MACHINE(vms);
if (vms->iommu != VIRT_IOMMU_SMMUV3 || !vms->iommu_phandle) { return; @@ -1176,26 +1187,26 @@ static void create_smmu(const VirtMachineState *vms, }
node = g_strdup_printf("/smmuv3@%" PRIx64, base); - qemu_fdt_add_subnode(vms->fdt, node); - qemu_fdt_setprop(vms->fdt, node, "compatible", compat, sizeof(compat)); - qemu_fdt_setprop_sized_cells(vms->fdt, node, "reg", 2, base, 2, size); + qemu_fdt_add_subnode(ms->fdt, node); + qemu_fdt_setprop(ms->fdt, node, "compatible", compat, sizeof(compat)); + qemu_fdt_setprop_sized_cells(ms->fdt, node, "reg", 2, base, 2, size);
- qemu_fdt_setprop_cells(vms->fdt, node, "interrupts", + qemu_fdt_setprop_cells(ms->fdt, node, "interrupts", GIC_FDT_IRQ_TYPE_SPI, irq , GIC_FDT_IRQ_FLAGS_EDGE_LO_HI, GIC_FDT_IRQ_TYPE_SPI, irq + 1, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI, GIC_FDT_IRQ_TYPE_SPI, irq + 2, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI, GIC_FDT_IRQ_TYPE_SPI, irq + 3, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
- qemu_fdt_setprop(vms->fdt, node, "interrupt-names", irq_names, + qemu_fdt_setprop(ms->fdt, node, "interrupt-names", irq_names, sizeof(irq_names));
- qemu_fdt_setprop_cell(vms->fdt, node, "clocks", vms->clock_phandle); - qemu_fdt_setprop_string(vms->fdt, node, "clock-names", "apb_pclk"); - qemu_fdt_setprop(vms->fdt, node, "dma-coherent", NULL, 0); + qemu_fdt_setprop_cell(ms->fdt, node, "clocks", vms->clock_phandle); + qemu_fdt_setprop_string(ms->fdt, node, "clock-names", "apb_pclk"); + qemu_fdt_setprop(ms->fdt, node, "dma-coherent", NULL, 0);
- qemu_fdt_setprop_cell(vms->fdt, node, "#iommu-cells", 1); + qemu_fdt_setprop_cell(ms->fdt, node, "#iommu-cells", 1);
- qemu_fdt_setprop_cell(vms->fdt, node, "phandle", vms->iommu_phandle); + qemu_fdt_setprop_cell(ms->fdt, node, "phandle", vms->iommu_phandle); g_free(node); }
@@ -1203,22 +1214,23 @@ static void create_virtio_iommu_dt_bindings(VirtMachineState *vms) { const char compat[] = "virtio,pci-iommu"; uint16_t bdf = vms->virtio_iommu_bdf; + MachineState *ms = MACHINE(vms); char *node;
- vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt); + vms->iommu_phandle = qemu_fdt_alloc_phandle(ms->fdt);
node = g_strdup_printf("%s/virtio_iommu@%d", vms->pciehb_nodename, bdf); - qemu_fdt_add_subnode(vms->fdt, node); - qemu_fdt_setprop(vms->fdt, node, "compatible", compat, sizeof(compat)); - qemu_fdt_setprop_sized_cells(vms->fdt, node, "reg", + qemu_fdt_add_subnode(ms->fdt, node); + qemu_fdt_setprop(ms->fdt, node, "compatible", compat, sizeof(compat)); + qemu_fdt_setprop_sized_cells(ms->fdt, node, "reg", 1, bdf << 8, 1, 0, 1, 0, 1, 0, 1, 0);
- qemu_fdt_setprop_cell(vms->fdt, node, "#iommu-cells", 1); - qemu_fdt_setprop_cell(vms->fdt, node, "phandle", vms->iommu_phandle); + qemu_fdt_setprop_cell(ms->fdt, node, "#iommu-cells", 1); + qemu_fdt_setprop_cell(ms->fdt, node, "phandle", vms->iommu_phandle); g_free(node);
- qemu_fdt_setprop_cells(vms->fdt, vms->pciehb_nodename, "iommu-map", + qemu_fdt_setprop_cells(ms->fdt, vms->pciehb_nodename, "iommu-map", 0x0, vms->iommu_phandle, 0x0, bdf, bdf + 1, vms->iommu_phandle, bdf + 1, 0xffff - bdf); } @@ -1243,6 +1255,7 @@ static void create_pcie(VirtMachineState *vms) char *nodename; int i, ecam_id; PCIHostState *pci; + MachineState *ms = MACHINE(vms);
dev = qdev_new(TYPE_GPEX_HOST); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); @@ -1302,27 +1315,27 @@ static void create_pcie(VirtMachineState *vms) }
nodename = vms->pciehb_nodename = g_strdup_printf("/pcie@%" PRIx64, base); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_string(vms->fdt, nodename, + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "pci-host-ecam-generic"); - qemu_fdt_setprop_string(vms->fdt, nodename, "device_type", "pci"); - qemu_fdt_setprop_cell(vms->fdt, nodename, "#address-cells", 3); - qemu_fdt_setprop_cell(vms->fdt, nodename, "#size-cells", 2); - qemu_fdt_setprop_cell(vms->fdt, nodename, "linux,pci-domain", 0); - qemu_fdt_setprop_cells(vms->fdt, nodename, "bus-range", 0, + qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "pci"); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 3); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 2); + qemu_fdt_setprop_cell(ms->fdt, nodename, "linux,pci-domain", 0); + qemu_fdt_setprop_cells(ms->fdt, nodename, "bus-range", 0, nr_pcie_buses - 1); - qemu_fdt_setprop(vms->fdt, nodename, "dma-coherent", NULL, 0); + qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0);
if (vms->msi_phandle) { - qemu_fdt_setprop_cells(vms->fdt, nodename, "msi-parent", + qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-parent", vms->msi_phandle); }
- qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base_ecam, 2, size_ecam);
if (vms->highmem) { - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "ranges", + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "ranges", 1, FDT_PCI_RANGE_IOPORT, 2, 0, 2, base_pio, 2, size_pio, 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, @@ -1331,23 +1344,23 @@ static void create_pcie(VirtMachineState *vms) 2, base_mmio_high, 2, base_mmio_high, 2, size_mmio_high); } else { - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "ranges", + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "ranges", 1, FDT_PCI_RANGE_IOPORT, 2, 0, 2, base_pio, 2, size_pio, 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, 2, base_mmio, 2, size_mmio); }
- qemu_fdt_setprop_cell(vms->fdt, nodename, "#interrupt-cells", 1); - create_pcie_irq_map(vms, vms->gic_phandle, irq, nodename); + qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 1); + create_pcie_irq_map(ms, vms->gic_phandle, irq, nodename);
if (vms->iommu) { - vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt); + vms->iommu_phandle = qemu_fdt_alloc_phandle(ms->fdt);
switch (vms->iommu) { case VIRT_IOMMU_SMMUV3: create_smmu(vms, pci->bus); - qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map", + qemu_fdt_setprop_cells(ms->fdt, nodename, "iommu-map", 0x0, vms->iommu_phandle, 0x0, 0x10000); break; default: @@ -1399,17 +1412,18 @@ static void create_secure_ram(VirtMachineState *vms, char *nodename; hwaddr base = vms->memmap[VIRT_SECURE_MEM].base; hwaddr size = vms->memmap[VIRT_SECURE_MEM].size; + MachineState *ms = MACHINE(vms);
memory_region_init_ram(secram, NULL, "virt.secure-ram", size, &error_fatal); memory_region_add_subregion(secure_sysmem, base, secram);
nodename = g_strdup_printf("/secram@%" PRIx64, base); - qemu_fdt_add_subnode(vms->fdt, nodename); - qemu_fdt_setprop_string(vms->fdt, nodename, "device_type", "memory"); - qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", 2, base, 2, size); - qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled"); - qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay"); + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "memory"); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size); + qemu_fdt_setprop_string(ms->fdt, nodename, "status", "disabled"); + qemu_fdt_setprop_string(ms->fdt, nodename, "secure-status", "okay");
if (secure_tag_sysmem) { create_tag_ram(secure_tag_sysmem, base, size, "mach-virt.secure-tag"); @@ -1422,9 +1436,11 @@ static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size) { const VirtMachineState *board = container_of(binfo, VirtMachineState, bootinfo); + MachineState *ms = MACHINE(board); +
*fdt_size = board->fdt_size; - return board->fdt; + return ms->fdt; }
static void virt_build_smbios(VirtMachineState *vms) @@ -1472,7 +1488,7 @@ void virt_machine_done(Notifier *notifier, void *data) * while qemu takes charge of the qom stuff. */ if (info->dtb_filename == NULL) { - platform_bus_add_all_fdt_nodes(vms->fdt, "/intc", + platform_bus_add_all_fdt_nodes(ms->fdt, "/intc", vms->memmap[VIRT_PLATFORM_BUS].base, vms->memmap[VIRT_PLATFORM_BUS].size, vms->irqmap[VIRT_PLATFORM_BUS]);
This is a mechanical change to make the fdt available through MachineState.
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- include/hw/riscv/virt.h | 1 - hw/riscv/virt.c | 18 +++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index b4ed9a32eb..6505ae8d23 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -41,7 +41,6 @@ struct RISCVVirtState { DeviceState *plic[VIRT_SOCKETS_MAX]; PFlashCFI01 *flash[2];
- void *fdt; int fdt_size; };
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 41bd2f38ba..17c0706156 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -194,7 +194,7 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap, hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2; hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
- fdt = s->fdt = create_device_tree(&s->fdt_size); + fdt = mc->fdt = create_device_tree(&s->fdt_size); if (!fdt) { error_report("create_device_tree() failed"); exit(1); @@ -434,12 +434,12 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap, g_free(name);
name = g_strdup_printf("/soc/flash@%" PRIx64, flashbase); - qemu_fdt_add_subnode(s->fdt, name); - qemu_fdt_setprop_string(s->fdt, name, "compatible", "cfi-flash"); - qemu_fdt_setprop_sized_cells(s->fdt, name, "reg", + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", "cfi-flash"); + qemu_fdt_setprop_sized_cells(mc->fdt, name, "reg", 2, flashbase, 2, flashsize, 2, flashbase + flashsize, 2, flashsize); - qemu_fdt_setprop_cell(s->fdt, name, "bank-width", 4); + qemu_fdt_setprop_cell(mc->fdt, name, "bank-width", 4); g_free(name); }
@@ -613,9 +613,9 @@ static void virt_machine_init(MachineState *machine) hwaddr end = riscv_load_initrd(machine->initrd_filename, machine->ram_size, kernel_entry, &start); - qemu_fdt_setprop_cell(s->fdt, "/chosen", + qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-start", start); - qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end", + qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end", end); } } else { @@ -636,11 +636,11 @@ static void virt_machine_init(MachineState *machine)
/* Compute the fdt load address in dram */ fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base, - machine->ram_size, s->fdt); + machine->ram_size, machine->fdt); /* load the reset vector */ riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base, virt_memmap[VIRT_MROM].size, kernel_entry, - fdt_load_addr, s->fdt); + fdt_load_addr, machine->fdt);
/* SiFive Test MMIO device */ sifive_test_create(memmap[VIRT_TEST].base);
On Wed, Oct 21, 2020 at 10:13 AM Alex Bennée alex.bennee@linaro.org wrote:
This is a mechanical change to make the fdt available through MachineState.
Signed-off-by: Alex Bennée alex.bennee@linaro.org
Reviewed-by: Alistair Francis alistair.francis@wdc.com
Alistair
include/hw/riscv/virt.h | 1 - hw/riscv/virt.c | 18 +++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index b4ed9a32eb..6505ae8d23 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -41,7 +41,6 @@ struct RISCVVirtState { DeviceState *plic[VIRT_SOCKETS_MAX]; PFlashCFI01 *flash[2];
- void *fdt; int fdt_size;
};
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 41bd2f38ba..17c0706156 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -194,7 +194,7 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap, hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2; hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
- fdt = s->fdt = create_device_tree(&s->fdt_size);
- fdt = mc->fdt = create_device_tree(&s->fdt_size); if (!fdt) { error_report("create_device_tree() failed"); exit(1);
@@ -434,12 +434,12 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap, g_free(name);
name = g_strdup_printf("/soc/flash@%" PRIx64, flashbase);
- qemu_fdt_add_subnode(s->fdt, name);
- qemu_fdt_setprop_string(s->fdt, name, "compatible", "cfi-flash");
- qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
- qemu_fdt_add_subnode(mc->fdt, name);
- qemu_fdt_setprop_string(mc->fdt, name, "compatible", "cfi-flash");
- qemu_fdt_setprop_sized_cells(mc->fdt, name, "reg", 2, flashbase, 2, flashsize, 2, flashbase + flashsize, 2, flashsize);
- qemu_fdt_setprop_cell(s->fdt, name, "bank-width", 4);
- qemu_fdt_setprop_cell(mc->fdt, name, "bank-width", 4); g_free(name);
}
@@ -613,9 +613,9 @@ static void virt_machine_init(MachineState *machine) hwaddr end = riscv_load_initrd(machine->initrd_filename, machine->ram_size, kernel_entry, &start);
qemu_fdt_setprop_cell(s->fdt, "/chosen",
qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-start", start);
qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
} else {qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end", end); }
@@ -636,11 +636,11 @@ static void virt_machine_init(MachineState *machine)
/* Compute the fdt load address in dram */ fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
machine->ram_size, s->fdt);
/* load the reset vector */ riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base, virt_memmap[VIRT_MROM].size, kernel_entry,machine->ram_size, machine->fdt);
fdt_load_addr, s->fdt);
fdt_load_addr, machine->fdt);
/* SiFive Test MMIO device */ sifive_test_create(memmap[VIRT_TEST].base);
-- 2.20.1
A string array in device tree is simply a series of \0 terminated strings next to each other. As libfdt doesn't support that directly we need to build it ourselves.
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- include/sysemu/device_tree.h | 17 +++++++++++++++++ softmmu/device_tree.c | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+)
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h index 982c89345f..8a2fe55622 100644 --- a/include/sysemu/device_tree.h +++ b/include/sysemu/device_tree.h @@ -70,6 +70,23 @@ int qemu_fdt_setprop_u64(void *fdt, const char *node_path, const char *property, uint64_t val); int qemu_fdt_setprop_string(void *fdt, const char *node_path, const char *property, const char *string); + +/** + * qemu_fdt_setprop_string_array: set a string array property + * + * @fdt: pointer to the dt blob + * @name: node name + * @prop: property array + * @array: pointer to an array of string pointers + * @len: length of array + * + * assigns a string array to a property. This function converts and + * array of strings to a sequential string with \0 separators before + * setting the property. + */ +int qemu_fdt_setprop_string_array(void *fdt, const char *node_path, + const char *prop, char **array, int len); + int qemu_fdt_setprop_phandle(void *fdt, const char *node_path, const char *property, const char *target_node_path); diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c index b335dae707..a19873316a 100644 --- a/softmmu/device_tree.c +++ b/softmmu/device_tree.c @@ -21,6 +21,7 @@ #include "qemu/error-report.h" #include "qemu/option.h" #include "qemu/bswap.h" +#include "qemu/cutils.h" #include "sysemu/device_tree.h" #include "sysemu/sysemu.h" #include "hw/loader.h" @@ -397,6 +398,31 @@ int qemu_fdt_setprop_string(void *fdt, const char *node_path, return r; }
+/* + * libfdt doesn't allow us to add string arrays directly but they are + * test a series of null terminated strings with a length. We build + * the string up here so we can calculate the final length. + */ +int qemu_fdt_setprop_string_array(void *fdt, const char *node_path, const char *prop, + char **array, int len) +{ + int ret, i, total_len = 0; + char *str, *p; + for (i = 0; i < len; i++) { + total_len += strlen(array[i]) + 1; + } + p = str = g_malloc0(total_len); + for (i = 0; i < len; i++) { + int len = strlen(array[i]) + 1; + pstrcpy(p, len, array[i]); + p += len; + } + + ret = qemu_fdt_setprop(fdt, node_path, prop, str, total_len); + g_free(str); + return ret; +} + const void *qemu_fdt_getprop(void *fdt, const char *node_path, const char *property, int *lenp, Error **errp) {
On Wed, Oct 21, 2020 at 10:11 AM Alex Bennée alex.bennee@linaro.org wrote:
A string array in device tree is simply a series of \0 terminated strings next to each other. As libfdt doesn't support that directly we need to build it ourselves.
Signed-off-by: Alex Bennée alex.bennee@linaro.org
Reviewed-by: Alistair Francis alistair.francis@wdc.com
Alistair
include/sysemu/device_tree.h | 17 +++++++++++++++++ softmmu/device_tree.c | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+)
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h index 982c89345f..8a2fe55622 100644 --- a/include/sysemu/device_tree.h +++ b/include/sysemu/device_tree.h @@ -70,6 +70,23 @@ int qemu_fdt_setprop_u64(void *fdt, const char *node_path, const char *property, uint64_t val); int qemu_fdt_setprop_string(void *fdt, const char *node_path, const char *property, const char *string);
+/**
- qemu_fdt_setprop_string_array: set a string array property
- @fdt: pointer to the dt blob
- @name: node name
- @prop: property array
- @array: pointer to an array of string pointers
- @len: length of array
- assigns a string array to a property. This function converts and
- array of strings to a sequential string with \0 separators before
- setting the property.
- */
+int qemu_fdt_setprop_string_array(void *fdt, const char *node_path,
const char *prop, char **array, int len);
int qemu_fdt_setprop_phandle(void *fdt, const char *node_path, const char *property, const char *target_node_path); diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c index b335dae707..a19873316a 100644 --- a/softmmu/device_tree.c +++ b/softmmu/device_tree.c @@ -21,6 +21,7 @@ #include "qemu/error-report.h" #include "qemu/option.h" #include "qemu/bswap.h" +#include "qemu/cutils.h" #include "sysemu/device_tree.h" #include "sysemu/sysemu.h" #include "hw/loader.h" @@ -397,6 +398,31 @@ int qemu_fdt_setprop_string(void *fdt, const char *node_path, return r; }
+/*
- libfdt doesn't allow us to add string arrays directly but they are
- test a series of null terminated strings with a length. We build
- the string up here so we can calculate the final length.
- */
+int qemu_fdt_setprop_string_array(void *fdt, const char *node_path, const char *prop,
char **array, int len)
+{
- int ret, i, total_len = 0;
- char *str, *p;
- for (i = 0; i < len; i++) {
total_len += strlen(array[i]) + 1;
- }
- p = str = g_malloc0(total_len);
- for (i = 0; i < len; i++) {
int len = strlen(array[i]) + 1;
pstrcpy(p, len, array[i]);
p += len;
- }
- ret = qemu_fdt_setprop(fdt, node_path, prop, str, total_len);
- g_free(str);
- return ret;
+}
const void *qemu_fdt_getprop(void *fdt, const char *node_path, const char *property, int *lenp, Error **errp) { -- 2.20.1
Hypervisors, especially type-1 ones, need the firmware/bootcode to put their initial guest somewhere in memory and pass the information to it via platform data. The guest-loader is modelled after the generic loader for exactly this sort of purpose:
$QEMU $ARGS -kernel ~/xen.git/xen/xen \ -append "dom0_mem=1G,max:1G loglvl=all guest_loglvl=all" \ -device guest-loader,addr=0x42000000,kernel=Image,bootargs="root=/dev/sda2 ro console=hvc0 earlyprintk=xen" \ -device guest-loader,addr=0x47000000,initrd=rootfs.cpio
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- hw/core/guest-loader.h | 34 ++++++++++ hw/core/guest-loader.c | 140 +++++++++++++++++++++++++++++++++++++++++ hw/core/meson.build | 2 + 3 files changed, 176 insertions(+) create mode 100644 hw/core/guest-loader.h create mode 100644 hw/core/guest-loader.c
diff --git a/hw/core/guest-loader.h b/hw/core/guest-loader.h new file mode 100644 index 0000000000..07f4b4884b --- /dev/null +++ b/hw/core/guest-loader.h @@ -0,0 +1,34 @@ +/* + * Guest Loader + * + * Copyright (C) 2020 Linaro + * Written by Alex Bennée alex.bennee@linaro.org + * (based on the generic-loader by Li Guang lig.fnst@cn.fujitsu.com) + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef GUEST_LOADER_H +#define GUEST_LOADER_H + +#include "hw/qdev-core.h" +#include "qom/object.h" + +struct GuestLoaderState { + /* <private> */ + DeviceState parent_obj; + + /* <public> */ + uint64_t addr; + char *kernel; + char *args; + char *initrd; +}; + +#define TYPE_GUEST_LOADER "guest-loader" +OBJECT_DECLARE_SIMPLE_TYPE(GuestLoaderState, GUEST_LOADER) + +#endif diff --git a/hw/core/guest-loader.c b/hw/core/guest-loader.c new file mode 100644 index 0000000000..1ce39842be --- /dev/null +++ b/hw/core/guest-loader.c @@ -0,0 +1,140 @@ +/* + * Guest Loader + * + * Copyright (C) 2020 Linaro + * Written by Alex Bennée alex.bennee@linaro.org + * (based on the generic-loader by Li Guang lig.fnst@cn.fujitsu.com) + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +/* + * Much like the generic-loader this is treated as a special device + * inside QEMU. However unlike the generic-loader this device is used + * to load guest images for hypervisors. As part of that process the + * hypervisor needs to have platform information passed to it by the + * lower levels of the stack (e.g. firmware/bootloader). If you boot + * the hypervisor directly you use the guest-loader to load the Dom0 + * or equivalent guest images in the right place in the same way a + * boot loader would. + * + * This is only relevant for full system emulation. + */ + +#include "qemu/osdep.h" +#include "hw/core/cpu.h" +#include "hw/sysbus.h" +#include "sysemu/dma.h" +#include "hw/loader.h" +#include "hw/qdev-properties.h" +#include "qapi/error.h" +#include "qemu/module.h" +#include "guest-loader.h" +#include "sysemu/device_tree.h" +#include "hw/boards.h" + +/* + * Insert some FDT nodes for the loaded blob. + */ +static void loader_insert_platform_data(GuestLoaderState *s, int size, Error **errp) +{ + MachineState *machine = MACHINE(qdev_get_machine()); + void *fdt = machine->fdt; + g_autofree char *node = g_strdup_printf("/chosen/module@%#08lx", s->addr); + uint64_t reg_attr[2] = {cpu_to_be64(s->addr), cpu_to_be64(size)}; + + if (!fdt) { + error_setg(errp, "Cannot modify FDT fields if the machine has none"); + return; + } + + qemu_fdt_add_subnode(fdt, node); + qemu_fdt_setprop(fdt, node, "reg", ®_attr, sizeof(reg_attr)); + + if (s->kernel) { + const char *compat[2] = { "multiboot,module", "multiboot,kernel" }; + if (qemu_fdt_setprop_string_array + (fdt, node, "compatible", (char **) &compat, ARRAY_SIZE(compat)) < 0) { + error_setg(errp, "couldn't set %s/compatible", node); + return; + } + if (s->args) { + if (qemu_fdt_setprop_string(fdt, node, "bootargs", s->args) < 0) { + error_setg(errp, "couldn't set %s/bootargs", node); + } + } + } else if (s->initrd) { + const char * compat[2] = { "multiboot,module", "multiboot,ramdisk" }; + if (qemu_fdt_setprop_string_array + (fdt, node, "compatible", (char **) &compat, ARRAY_SIZE(compat)) < 0) { + error_setg(errp, "couldn't set %s/compatible", node); + return; + } + } +} + +static void guest_loader_realize(DeviceState *dev, Error **errp) +{ + GuestLoaderState *s = GUEST_LOADER(dev); + char *file = s->kernel ? s->kernel : s->initrd; + int size = 0; + + /* Perform some error checking on the user's options */ + if (s->kernel && s->initrd) { + error_setg(errp, "Cannot specify a kernel and initrd in the same stanza"); + return; + } else if (!s->kernel && !s->initrd) { + error_setg(errp, "Need to specify a kernel or initrd image"); + return; + } else if (!s->addr) { + error_setg(errp, "Need to specify the address of guest blob"); + return; + } else if (s->args && !s->kernel) { + error_setg(errp, "Boot args only relevant to kernel blobs"); + } + + /* Default to the maximum size being the machine's ram size */ + size = load_image_targphys_as(file, s->addr, ram_size, NULL); + if (size < 0) { + error_setg(errp, "Cannot load specified image %s", file); + return; + } + + /* Now the image is loaded we need to update the platform data */ + loader_insert_platform_data(s, size, errp); +} + +static Property guest_loader_props[] = { + DEFINE_PROP_UINT64("addr", GuestLoaderState, addr, 0), + DEFINE_PROP_STRING("kernel", GuestLoaderState, kernel), + DEFINE_PROP_STRING("bootargs", GuestLoaderState, args), + DEFINE_PROP_STRING("initrd", GuestLoaderState, initrd), + DEFINE_PROP_END_OF_LIST(), +}; + +static void guest_loader_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = guest_loader_realize; + device_class_set_props(dc, guest_loader_props); + dc->desc = "Guest Loader"; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); +} + +static TypeInfo guest_loader_info = { + .name = TYPE_GUEST_LOADER, + .parent = TYPE_DEVICE, + .instance_size = sizeof(GuestLoaderState), + .class_init = guest_loader_class_init, +}; + +static void guest_loader_register_type(void) +{ + type_register_static(&guest_loader_info); +} + +type_init(guest_loader_register_type) diff --git a/hw/core/meson.build b/hw/core/meson.build index 4a744f3b5e..27a69fc578 100644 --- a/hw/core/meson.build +++ b/hw/core/meson.build @@ -37,6 +37,8 @@ softmmu_ss.add(files( 'clock-vmstate.c', ))
+softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('guest-loader.c')) + specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files( 'machine-qmp-cmds.c', 'numa.c',
On Wed, Oct 21, 2020 at 10:09 AM Alex Bennée alex.bennee@linaro.org wrote:
Hypervisors, especially type-1 ones, need the firmware/bootcode to put their initial guest somewhere in memory and pass the information to it via platform data. The guest-loader is modelled after the generic loader for exactly this sort of purpose:
guest as in Hypervisor guest and QEMU guest is a little confusing, but I can't think of a better name
$QEMU $ARGS -kernel ~/xen.git/xen/xen \ -append "dom0_mem=1G,max:1G loglvl=all guest_loglvl=all" \ -device guest-loader,addr=0x42000000,kernel=Image,bootargs="root=/dev/sda2 ro console=hvc0 earlyprintk=xen" \ -device guest-loader,addr=0x47000000,initrd=rootfs.cpio
This seems fine to me.
Do you mind writing some documentation though? The generic-loader documentation should be a good place to start.
Signed-off-by: Alex Bennée alex.bennee@linaro.org
hw/core/guest-loader.h | 34 ++++++++++ hw/core/guest-loader.c | 140 +++++++++++++++++++++++++++++++++++++++++ hw/core/meson.build | 2 + 3 files changed, 176 insertions(+) create mode 100644 hw/core/guest-loader.h create mode 100644 hw/core/guest-loader.c
diff --git a/hw/core/guest-loader.h b/hw/core/guest-loader.h new file mode 100644 index 0000000000..07f4b4884b --- /dev/null +++ b/hw/core/guest-loader.h @@ -0,0 +1,34 @@ +/*
- Guest Loader
- Copyright (C) 2020 Linaro
- Written by Alex Bennée alex.bennee@linaro.org
- (based on the generic-loader by Li Guang lig.fnst@cn.fujitsu.com)
- SPDX-License-Identifier: GPL-2.0-or-later
- This work is licensed under the terms of the GNU GPL, version 2 or later.
- See the COPYING file in the top-level directory.
- */
+#ifndef GUEST_LOADER_H +#define GUEST_LOADER_H
+#include "hw/qdev-core.h" +#include "qom/object.h"
+struct GuestLoaderState {
- /* <private> */
- DeviceState parent_obj;
- /* <public> */
- uint64_t addr;
- char *kernel;
- char *args;
- char *initrd;
+};
+#define TYPE_GUEST_LOADER "guest-loader" +OBJECT_DECLARE_SIMPLE_TYPE(GuestLoaderState, GUEST_LOADER)
+#endif diff --git a/hw/core/guest-loader.c b/hw/core/guest-loader.c new file mode 100644 index 0000000000..1ce39842be --- /dev/null +++ b/hw/core/guest-loader.c @@ -0,0 +1,140 @@ +/*
- Guest Loader
- Copyright (C) 2020 Linaro
- Written by Alex Bennée alex.bennee@linaro.org
- (based on the generic-loader by Li Guang lig.fnst@cn.fujitsu.com)
- SPDX-License-Identifier: GPL-2.0-or-later
- This work is licensed under the terms of the GNU GPL, version 2 or later.
- See the COPYING file in the top-level directory.
- */
+/*
- Much like the generic-loader this is treated as a special device
- inside QEMU. However unlike the generic-loader this device is used
- to load guest images for hypervisors. As part of that process the
- hypervisor needs to have platform information passed to it by the
- lower levels of the stack (e.g. firmware/bootloader). If you boot
- the hypervisor directly you use the guest-loader to load the Dom0
- or equivalent guest images in the right place in the same way a
- boot loader would.
- This is only relevant for full system emulation.
- */
+#include "qemu/osdep.h" +#include "hw/core/cpu.h" +#include "hw/sysbus.h" +#include "sysemu/dma.h" +#include "hw/loader.h" +#include "hw/qdev-properties.h" +#include "qapi/error.h" +#include "qemu/module.h" +#include "guest-loader.h" +#include "sysemu/device_tree.h" +#include "hw/boards.h"
+/*
- Insert some FDT nodes for the loaded blob.
- */
+static void loader_insert_platform_data(GuestLoaderState *s, int size, Error **errp) +{
- MachineState *machine = MACHINE(qdev_get_machine());
- void *fdt = machine->fdt;
- g_autofree char *node = g_strdup_printf("/chosen/module@%#08lx", s->addr);
- uint64_t reg_attr[2] = {cpu_to_be64(s->addr), cpu_to_be64(size)};
- if (!fdt) {
error_setg(errp, "Cannot modify FDT fields if the machine has none");
return;
- }
- qemu_fdt_add_subnode(fdt, node);
- qemu_fdt_setprop(fdt, node, "reg", ®_attr, sizeof(reg_attr));
- if (s->kernel) {
const char *compat[2] = { "multiboot,module", "multiboot,kernel" };
if (qemu_fdt_setprop_string_array
(fdt, node, "compatible", (char **) &compat, ARRAY_SIZE(compat)) < 0) {
error_setg(errp, "couldn't set %s/compatible", node);
return;
}
if (s->args) {
if (qemu_fdt_setprop_string(fdt, node, "bootargs", s->args) < 0) {
error_setg(errp, "couldn't set %s/bootargs", node);
}
}
- } else if (s->initrd) {
const char * compat[2] = { "multiboot,module", "multiboot,ramdisk" };
if (qemu_fdt_setprop_string_array
(fdt, node, "compatible", (char **) &compat, ARRAY_SIZE(compat)) < 0) {
The ( bracket should be on the previous line right?
Alistair
error_setg(errp, "couldn't set %s/compatible", node);
return;
}
- }
+}
+static void guest_loader_realize(DeviceState *dev, Error **errp) +{
- GuestLoaderState *s = GUEST_LOADER(dev);
- char *file = s->kernel ? s->kernel : s->initrd;
- int size = 0;
- /* Perform some error checking on the user's options */
- if (s->kernel && s->initrd) {
error_setg(errp, "Cannot specify a kernel and initrd in the same stanza");
return;
- } else if (!s->kernel && !s->initrd) {
error_setg(errp, "Need to specify a kernel or initrd image");
return;
- } else if (!s->addr) {
error_setg(errp, "Need to specify the address of guest blob");
return;
- } else if (s->args && !s->kernel) {
error_setg(errp, "Boot args only relevant to kernel blobs");
- }
- /* Default to the maximum size being the machine's ram size */
- size = load_image_targphys_as(file, s->addr, ram_size, NULL);
- if (size < 0) {
error_setg(errp, "Cannot load specified image %s", file);
return;
- }
- /* Now the image is loaded we need to update the platform data */
- loader_insert_platform_data(s, size, errp);
+}
+static Property guest_loader_props[] = {
- DEFINE_PROP_UINT64("addr", GuestLoaderState, addr, 0),
- DEFINE_PROP_STRING("kernel", GuestLoaderState, kernel),
- DEFINE_PROP_STRING("bootargs", GuestLoaderState, args),
- DEFINE_PROP_STRING("initrd", GuestLoaderState, initrd),
- DEFINE_PROP_END_OF_LIST(),
+};
+static void guest_loader_class_init(ObjectClass *klass, void *data) +{
- DeviceClass *dc = DEVICE_CLASS(klass);
- dc->realize = guest_loader_realize;
- device_class_set_props(dc, guest_loader_props);
- dc->desc = "Guest Loader";
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+static TypeInfo guest_loader_info = {
- .name = TYPE_GUEST_LOADER,
- .parent = TYPE_DEVICE,
- .instance_size = sizeof(GuestLoaderState),
- .class_init = guest_loader_class_init,
+};
+static void guest_loader_register_type(void) +{
- type_register_static(&guest_loader_info);
+}
+type_init(guest_loader_register_type) diff --git a/hw/core/meson.build b/hw/core/meson.build index 4a744f3b5e..27a69fc578 100644 --- a/hw/core/meson.build +++ b/hw/core/meson.build @@ -37,6 +37,8 @@ softmmu_ss.add(files( 'clock-vmstate.c', ))
+softmmu_ss.add(when: 'CONFIG_TCG', if_true: files('guest-loader.c'))
specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files( 'machine-qmp-cmds.c', 'numa.c', -- 2.20.1
Patchew URL: https://patchew.org/QEMU/20201021170842.25762-1-alex.bennee@linaro.org/
Hi,
This series seems to have some coding style problems. See output below for more information:
Type: series Message-id: 20201021170842.25762-1-alex.bennee@linaro.org Subject: [PATCH v1 0/4] add guest-loader (for direct Xen boot)
=== TEST SCRIPT BEGIN === #!/bin/bash git rev-parse base > /dev/null || exit 0 git config --local diff.renamelimit 0 git config --local diff.renames True git config --local diff.algorithm histogram ./scripts/checkpatch.pl --mailback base.. === TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 From https://github.com/patchew-project/qemu - [tag update] patchew/20201020153935.54315-1-thuth@redhat.com -> patchew/20201020153935.54315-1-thuth@redhat.com - [tag update] patchew/20201021045149.1582203-1-richard.henderson@linaro.org -> patchew/20201021045149.1582203-1-richard.henderson@linaro.org * [new tag] patchew/20201021170842.25762-1-alex.bennee@linaro.org -> patchew/20201021170842.25762-1-alex.bennee@linaro.org Switched to a new branch 'test' a5415a9 hw/core: implement a guest-loader to support static hypervisor guests 7bb03f4 device_tree: add qemu_fdt_setprop_string_array helper 017ee63 hw/riscv: migrate fdt field to generic MachineState 72e9417 hw/board: promote fdt from ARM VirtMachineState to MachineState
=== OUTPUT BEGIN === 1/4 Checking commit 72e941735a6d (hw/board: promote fdt from ARM VirtMachineState to MachineState) 2/4 Checking commit 017ee63de267 (hw/riscv: migrate fdt field to generic MachineState) 3/4 Checking commit 7bb03f4d1faf (device_tree: add qemu_fdt_setprop_string_array helper) WARNING: line over 80 characters #63: FILE: softmmu/device_tree.c:406: +int qemu_fdt_setprop_string_array(void *fdt, const char *node_path, const char *prop,
total: 0 errors, 1 warnings, 61 lines checked
Patch 3/4 has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. 4/4 Checking commit a5415a96f77f (hw/core: implement a guest-loader to support static hypervisor guests) WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? #21: new file mode 100644
WARNING: line over 80 characters #67: FILE: hw/core/guest-loader.c:42: +static void loader_insert_platform_data(GuestLoaderState *s, int size, Error **errp)
ERROR: Don't use '#' flag of printf format ('%#') in format strings, use '0x' prefix instead #71: FILE: hw/core/guest-loader.c:46: + g_autofree char *node = g_strdup_printf("/chosen/module@%#08lx", s->addr);
WARNING: line over 80 characters #85: FILE: hw/core/guest-loader.c:60: + (fdt, node, "compatible", (char **) &compat, ARRAY_SIZE(compat)) < 0) {
ERROR: "foo * bar" should be "foo *bar" #95: FILE: hw/core/guest-loader.c:70: + const char * compat[2] = { "multiboot,module", "multiboot,ramdisk" };
WARNING: line over 80 characters #97: FILE: hw/core/guest-loader.c:72: + (fdt, node, "compatible", (char **) &compat, ARRAY_SIZE(compat)) < 0) {
WARNING: line over 80 characters #112: FILE: hw/core/guest-loader.c:87: + error_setg(errp, "Cannot specify a kernel and initrd in the same stanza");
total: 2 errors, 5 warnings, 182 lines checked
Patch 4/4 has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===
Test command exited with code: 1
The full log is available at http://patchew.org/logs/20201021170842.25762-1-alex.bennee@linaro.org/testin.... --- Email generated automatically by Patchew [https://patchew.org/]. Please send your feedback to patchew-devel@redhat.com
stratos-dev@op-lists.linaro.org