Hi,
There are two parts to this series, broadly related because they are all to do with Xen. The first half is a re-spin of the guest-loader patches from a few weeks ago. The only changes are to move the generic-loader documentation into the manual and then add some words about the guest-loader.
The second half of the series is an attempt to fix and then clean up the handling of Xen enabled builds. Recent changes to the build system broke the ability to build qemu-system-i386 on arm64 hosts with Xen support enabled. The actual fix for that:
meson.build: fix building of Xen support for aarch64
should probably be rolled into the current release as it fixes a regression. The rest can wait until the tree re-opens. The patches broadly try to:
- clean-up detection and reporting - be more explicit about linking stubs for accel - add an explicit CONFIG_XEN_HVM for x86
and finally allow you to build a qemu-system-aarch64 with Xen support.
This is my first major foray into tweaking meson builds and it seems to occasionally come unstuck and requires a distclean and re-configure to un-wedge itself. The following need review:
- meson.build: build a Xen aware qemu-aarch64-system - xen: only build HVM support under CONFIG_XEN_HVM - accel/stubs: drop unused cpu.h include - stubs/xen-hw-stub: drop xenstore_store_pv_console_info stub - include/hw/xen.h: drop superfluous struct - meson.build: clean-up summary reporting of XEN and it's features - meson.build: introduce CONFIG_XEN_HVM flag - meson.build: fix building of Xen support for aarch64 - accel/meson: you only need accelerator stubs for softmmu builds - docs: add some documentation for the guest-loader - docs: move generic-loader documentation into the main manual
Alex Bennée (15): 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 docs: move generic-loader documentation into the main manual docs: add some documentation for the guest-loader accel/meson: you only need accelerator stubs for softmmu builds meson.build: fix building of Xen support for aarch64 meson.build: introduce CONFIG_XEN_HVM flag meson.build: clean-up summary reporting of XEN and it's features include/hw/xen.h: drop superfluous struct stubs/xen-hw-stub: drop xenstore_store_pv_console_info stub accel/stubs: drop unused cpu.h include xen: only build HVM support under CONFIG_XEN_HVM meson.build: build a Xen aware qemu-aarch64-system
docs/generic-loader.txt | 92 ---------- docs/system/generic-loader.rst | 117 ++++++++++++ docs/system/guest-loader.rst | 54 ++++++ docs/system/index.rst | 2 + meson.build | 24 ++- hw/core/guest-loader.h | 34 ++++ include/hw/arm/virt.h | 1 - include/hw/boards.h | 1 + include/hw/riscv/virt.h | 1 - include/hw/xen/xen.h | 2 +- include/sysemu/device_tree.h | 17 ++ include/sysemu/xen-mapcache.h | 2 +- include/sysemu/xen.h | 9 +- accel/stubs/hax-stub.c | 1 - accel/stubs/xen-all-stub.c | 11 ++ accel/stubs/xen-stub.c | 2 - hw/arm/virt.c | 322 +++++++++++++++++---------------- hw/core/guest-loader.c | 140 ++++++++++++++ hw/riscv/virt.c | 20 +- softmmu/device_tree.c | 26 +++ stubs/xen-hw-stub.c | 4 - accel/Kconfig | 3 + accel/meson.build | 4 +- accel/stubs/meson.build | 13 +- hw/core/meson.build | 2 + hw/i386/xen/meson.build | 2 +- 26 files changed, 627 insertions(+), 279 deletions(-) delete mode 100644 docs/generic-loader.txt create mode 100644 docs/system/generic-loader.rst create mode 100644 docs/system/guest-loader.rst create mode 100644 hw/core/guest-loader.h create mode 100644 accel/stubs/xen-all-stub.c 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 Message-Id: 20201021170842.25762-2-alex.bennee@linaro.org 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 a49e3a6b44..7b835e361c 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 27dbeb549e..14ba077bb0 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]);
On 11/5/20 6:51 PM, Alex Bennée wrote:
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 Message-Id: 20201021170842.25762-2-alex.bennee@linaro.org Signed-off-by: Alex Bennée alex.bennee@linaro.org
Two S-o-b better than one!
include/hw/arm/virt.h | 1 - include/hw/boards.h | 1 + hw/arm/virt.c | 322 ++++++++++++++++++++++-------------------- 3 files changed, 170 insertions(+), 154 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé philmd@redhat.com
Philippe Mathieu-Daudé philmd@redhat.com writes:
On 11/5/20 6:51 PM, Alex Bennée wrote:
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 Message-Id: 20201021170842.25762-2-alex.bennee@linaro.org Signed-off-by: Alex Bennée alex.bennee@linaro.org
Two S-o-b better than one!
Hmm I wonder what happened there? I'm sure b4 applied that patches for me.
include/hw/arm/virt.h | 1 - include/hw/boards.h | 1 + hw/arm/virt.c | 322 ++++++++++++++++++++++-------------------- 3 files changed, 170 insertions(+), 154 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé philmd@redhat.com
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 Message-Id: 20201021170842.25762-3-alex.bennee@linaro.org Signed-off-by: Alex Bennée alex.bennee@linaro.org --- include/hw/riscv/virt.h | 1 - hw/riscv/virt.c | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 11 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 25cea7aa67..377400e02a 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -197,14 +197,14 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb"); if (dtb_filename) { - fdt = s->fdt = load_device_tree(dtb_filename, &s->fdt_size); + fdt = mc->fdt = load_device_tree(dtb_filename, &s->fdt_size); if (!fdt) { error_report("load_device_tree() failed"); exit(1); } goto update_bootargs; } else { - 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); @@ -442,12 +442,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);
update_bootargs: @@ -631,9 +631,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 { @@ -654,11 +654,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 11/5/20 6:51 PM, Alex Bennée 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 Message-Id: 20201021170842.25762-3-alex.bennee@linaro.org Signed-off-by: Alex Bennée alex.bennee@linaro.org
include/hw/riscv/virt.h | 1 - hw/riscv/virt.c | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé philmd@redhat.com
On Fri, Nov 6, 2020 at 1:57 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 Message-Id: 20201021170842.25762-3-alex.bennee@linaro.org Signed-off-by: Alex Bennée alex.bennee@linaro.org
include/hw/riscv/virt.h | 1 - hw/riscv/virt.c | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-)
What about the 'sifive_u' and 'spike' machines?
Regards, Bin
Bin Meng bmeng.cn@gmail.com writes:
On Fri, Nov 6, 2020 at 1:57 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 Message-Id: 20201021170842.25762-3-alex.bennee@linaro.org Signed-off-by: Alex Bennée alex.bennee@linaro.org
include/hw/riscv/virt.h | 1 - hw/riscv/virt.c | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-)
What about the 'sifive_u' and 'spike' machines?
If they support direct -kernel loading then we could certainly do the same for them.
Regards, Bin
On Fri, Nov 6, 2020 at 6:21 PM Alex Bennée alex.bennee@linaro.org wrote:
Bin Meng bmeng.cn@gmail.com writes:
On Fri, Nov 6, 2020 at 1:57 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 Message-Id: 20201021170842.25762-3-alex.bennee@linaro.org Signed-off-by: Alex Bennée alex.bennee@linaro.org
include/hw/riscv/virt.h | 1 - hw/riscv/virt.c | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-)
What about the 'sifive_u' and 'spike' machines?
If they support direct -kernel loading then we could certainly do the same for them.
Yes, they do.
Regards, Bin
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 Message-Id: 20201021170842.25762-4-alex.bennee@linaro.org 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) {
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 Message-Id: 20201021170842.25762-5-alex.bennee@linaro.org 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',
We might as well surface this useful information in the manual so users can find it easily. It is a fairly simple conversion to rst with the only textual fixes being QemuOps to QemuOpts.
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- docs/generic-loader.txt | 92 -------------------------- docs/system/generic-loader.rst | 117 +++++++++++++++++++++++++++++++++ docs/system/index.rst | 1 + 3 files changed, 118 insertions(+), 92 deletions(-) delete mode 100644 docs/generic-loader.txt create mode 100644 docs/system/generic-loader.rst
diff --git a/docs/generic-loader.txt b/docs/generic-loader.txt deleted file mode 100644 index a9603a2af7..0000000000 --- a/docs/generic-loader.txt +++ /dev/null @@ -1,92 +0,0 @@ -Copyright (c) 2016 Xilinx Inc. - -This work is licensed under the terms of the GNU GPL, version 2 or later. See -the COPYING file in the top-level directory. - - -The 'loader' device allows the user to load multiple images or values into -QEMU at startup. - -Loading Data into Memory Values -------------------------------- -The loader device allows memory values to be set from the command line. This -can be done by following the syntax below: - - -device loader,addr=<addr>,data=<data>,data-len=<data-len> - [,data-be=<data-be>][,cpu-num=<cpu-num>] - - <addr> - The address to store the data in. - <data> - The value to be written to the address. The maximum size of - the data is 8 bytes. - <data-len> - The length of the data in bytes. This argument must be - included if the data argument is. - <data-be> - Set to true if the data to be stored on the guest should be - written as big endian data. The default is to write little - endian data. - <cpu-num> - The number of the CPU's address space where the data should - be loaded. If not specified the address space of the first - CPU is used. - -All values are parsed using the standard QemuOps parsing. This allows the user -to specify any values in any format supported. By default the values -will be parsed as decimal. To use hex values the user should prefix the number -with a '0x'. - -An example of loading value 0x8000000e to address 0xfd1a0104 is: - -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4 - -Setting a CPU's Program Counter -------------------------------- -The loader device allows the CPU's PC to be set from the command line. This -can be done by following the syntax below: - - -device loader,addr=<addr>,cpu-num=<cpu-num> - - <addr> - The value to use as the CPU's PC. - <cpu-num> - The number of the CPU whose PC should be set to the - specified value. - -All values are parsed using the standard QemuOps parsing. This allows the user -to specify any values in any format supported. By default the values -will be parsed as decimal. To use hex values the user should prefix the number -with a '0x'. - -An example of setting CPU 0's PC to 0x8000 is: - -device loader,addr=0x8000,cpu-num=0 - -Loading Files -------------- -The loader device also allows files to be loaded into memory. It can load ELF, -U-Boot, and Intel HEX executable formats as well as raw images. The syntax is -shown below: - - -device loader,file=<file>[,addr=<addr>][,cpu-num=<cpu-num>][,force-raw=<raw>] - - <file> - A file to be loaded into memory - <addr> - The memory address where the file should be loaded. This is - required for raw images and ignored for non-raw files. - <cpu-num> - This specifies the CPU that should be used. This is an - optional argument and will cause the CPU's PC to be set to - the memory address where the raw file is loaded or the entry - point specified in the executable format header. This option - should only be used for the boot image. - This will also cause the image to be written to the specified - CPU's address space. If not specified, the default is CPU 0. - <force-raw> - Setting force-raw=on forces the file to be treated as a raw - image. This can be used to load supported executable formats - as if they were raw. - -All values are parsed using the standard QemuOps parsing. This allows the user -to specify any values in any format supported. By default the values -will be parsed as decimal. To use hex values the user should prefix the number -with a '0x'. - -An example of loading an ELF file which CPU0 will boot is shown below: - -device loader,file=./images/boot.elf,cpu-num=0 - -Restrictions and ToDos ----------------------- - - At the moment it is just assumed that if you specify a cpu-num then you - want to set the PC as well. This might not always be the case. In future - the internal state 'set_pc' (which exists in the generic loader now) should - be exposed to the user so that they can choose if the PC is set or not. diff --git a/docs/system/generic-loader.rst b/docs/system/generic-loader.rst new file mode 100644 index 0000000000..59f28d1230 --- /dev/null +++ b/docs/system/generic-loader.rst @@ -0,0 +1,117 @@ +.. + Copyright (c) 2016, Xilinx Inc. + +This work is licensed under the terms of the GNU GPL, version 2 or later. See +the COPYING file in the top-level directory. + +Generic Loader +-------------- + +The 'loader' device allows the user to load multiple images or values into +QEMU at startup. + +Loading Data into Memory Values +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The loader device allows memory values to be set from the command line. This +can be done by following the syntax below:: + + -device loader,addr=<addr>,data=<data>,data-len=<data-len> \ + [,data-be=<data-be>][,cpu-num=<cpu-num>] + +``<addr>`` + The address to store the data in. + +``<data>`` + The value to be written to the address. The maximum size of the data + is 8 bytes. + +``<data-len>`` + The length of the data in bytes. This argument must be included if + the data argument is. + +``<data-be>`` + Set to true if the data to be stored on the guest should be written + as big endian data. The default is to write little endian data. + +``<cpu-num>`` + The number of the CPU's address space where the data should be + loaded. If not specified the address space of the first CPU is used. + +All values are parsed using the standard QemuOps parsing. This allows the user +to specify any values in any format supported. By default the values +will be parsed as decimal. To use hex values the user should prefix the number +with a '0x'. + +An example of loading value 0x8000000e to address 0xfd1a0104 is:: + + -device loader,addr=0xfd1a0104,data=0x8000000e,data-len=4 + +Setting a CPU's Program Counter +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The loader device allows the CPU's PC to be set from the command line. This +can be done by following the syntax below:: + + -device loader,addr=<addr>,cpu-num=<cpu-num> + +``<addr>`` + The value to use as the CPU's PC. + +``<cpu-num>`` + The number of the CPU whose PC should be set to the specified value. + +All values are parsed using the standard QemuOpts parsing. This allows the user +to specify any values in any format supported. By default the values +will be parsed as decimal. To use hex values the user should prefix the number +with a '0x'. + +An example of setting CPU 0's PC to 0x8000 is:: + + -device loader,addr=0x8000,cpu-num=0 + +Loading Files +^^^^^^^^^^^^^ + +The loader device also allows files to be loaded into memory. It can load ELF, +U-Boot, and Intel HEX executable formats as well as raw images. The syntax is +shown below: + + -device loader,file=<file>[,addr=<addr>][,cpu-num=<cpu-num>][,force-raw=<raw>] + +``<file>`` + A file to be loaded into memory + +``<addr>`` + The memory address where the file should be loaded. This is required + for raw images and ignored for non-raw files. + +``<cpu-num>`` + This specifies the CPU that should be used. This is an + optional argument and will cause the CPU's PC to be set to the + memory address where the raw file is loaded or the entry point + specified in the executable format header. This option should only + be used for the boot image. This will also cause the image to be + written to the specified CPU's address space. If not specified, the + default is CPU 0. <force-raw> - Setting force-raw=on forces the file + to be treated as a raw image. This can be used to load supported + executable formats as if they were raw. + +All values are parsed using the standard QemuOpts parsing. This allows the user +to specify any values in any format supported. By default the values +will be parsed as decimal. To use hex values the user should prefix the number +with a '0x'. + +An example of loading an ELF file which CPU0 will boot is shown below:: + + -device loader,file=./images/boot.elf,cpu-num=0 + +Restrictions and ToDos +^^^^^^^^^^^^^^^^^^^^^^ + +At the moment it is just assumed that if you specify a cpu-num then +you want to set the PC as well. This might not always be the case. In +future the internal state 'set_pc' (which exists in the generic loader +now) should be exposed to the user so that they can choose if the PC +is set or not. + + diff --git a/docs/system/index.rst b/docs/system/index.rst index c0f685b818..3cff0ca98f 100644 --- a/docs/system/index.rst +++ b/docs/system/index.rst @@ -24,6 +24,7 @@ Contents: usb ivshmem linuxboot + generic-loader vnc-security tls gdb
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- docs/system/guest-loader.rst | 54 ++++++++++++++++++++++++++++++++++++ docs/system/index.rst | 1 + 2 files changed, 55 insertions(+) create mode 100644 docs/system/guest-loader.rst
diff --git a/docs/system/guest-loader.rst b/docs/system/guest-loader.rst new file mode 100644 index 0000000000..37d03cbd89 --- /dev/null +++ b/docs/system/guest-loader.rst @@ -0,0 +1,54 @@ +.. + Copyright (c) 2020, Linaro + +Guest Loader +------------ + +The guest loader is similar to the `generic-loader` although it is +aimed at a particular use case of loading hypervisor guests. This is +useful for debugging hypervisors without having to jump through the +hoops of firmware and boot-loaders. + +The guest loader does two things: + + - load blobs (kernels and initial ram disks) into memory + - sets platform FDT data so hypervisors can find and boot them + +This is what is typically done by a boot-loader like grub using it's +multi-boot capability. A typical example would look like: + +.. parsed-literal:: + + |qemu_system| -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 + +In the above example the Xen hypervisor is loaded by the -kernel +parameter and passed it's boot arguments via -append. The Dom0 guest +is loaded into the areas of memory. Each blob will get +`/chosen/module@<addr>` entry in the FDT to indicate it's location and +size. Additional information can be passed with by using additional +arguments. + +Currently the only supported machines which use FDT data to boot are +the ARM and RiscV `virt` machines. + +Arguments +^^^^^^^^^ + +The full syntax of the guest-loader is:: + + -device guest-loader,addr=<addr>[,kernel=<file>,[bootargs=<args>]][,initrd=<file>] + +``addr=<addr>`` + This is mandatory and indicates the start address of the blob. + +``kernel|initrd=<file>`` + Indicates the filename of the kernel or initrd blob. Both blobs will + have the "multiboot,module" compatibility string as well as + "multiboot,kernel" or "multiboot,ramdisk" as appropriate. + +``bootargs=<args>`` + This is an optional field for kernel blobs which will pass command + like via the `/chosen/module@<addr>/bootargs` node. diff --git a/docs/system/index.rst b/docs/system/index.rst index 3cff0ca98f..b5cfe8ee93 100644 --- a/docs/system/index.rst +++ b/docs/system/index.rst @@ -25,6 +25,7 @@ Contents: ivshmem linuxboot generic-loader + guest-loader vnc-security tls gdb
On Thu, Nov 5, 2020 at 9:58 AM Alex Bennée alex.bennee@linaro.org wrote:
Signed-off-by: Alex Bennée alex.bennee@linaro.org
docs/system/guest-loader.rst | 54 ++++++++++++++++++++++++++++++++++++ docs/system/index.rst | 1 + 2 files changed, 55 insertions(+) create mode 100644 docs/system/guest-loader.rst
diff --git a/docs/system/guest-loader.rst b/docs/system/guest-loader.rst new file mode 100644 index 0000000000..37d03cbd89 --- /dev/null +++ b/docs/system/guest-loader.rst @@ -0,0 +1,54 @@ +..
- Copyright (c) 2020, Linaro
+Guest Loader +------------
+The guest loader is similar to the `generic-loader` although it is +aimed at a particular use case of loading hypervisor guests. This is +useful for debugging hypervisors without having to jump through the +hoops of firmware and boot-loaders.
+The guest loader does two things:
- load blobs (kernels and initial ram disks) into memory
- sets platform FDT data so hypervisors can find and boot them
+This is what is typically done by a boot-loader like grub using it's +multi-boot capability. A typical example would look like:
+.. parsed-literal::
- |qemu_system| -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
+In the above example the Xen hypervisor is loaded by the -kernel +parameter and passed it's boot arguments via -append. The Dom0 guest +is loaded into the areas of memory. Each blob will get +`/chosen/module@<addr>` entry in the FDT to indicate it's location and +size. Additional information can be passed with by using additional +arguments.
+Currently the only supported machines which use FDT data to boot are +the ARM and RiscV `virt` machines.
RISC-V.
Otherwise:
Reviewed-by: Alistair Francis alistair.francis@wdc.com
Alistair
+Arguments +^^^^^^^^^
+The full syntax of the guest-loader is::
- -device guest-loader,addr=<addr>[,kernel=<file>,[bootargs=<args>]][,initrd=<file>]
+``addr=<addr>``
- This is mandatory and indicates the start address of the blob.
+``kernel|initrd=<file>``
- Indicates the filename of the kernel or initrd blob. Both blobs will
- have the "multiboot,module" compatibility string as well as
- "multiboot,kernel" or "multiboot,ramdisk" as appropriate.
+``bootargs=<args>``
- This is an optional field for kernel blobs which will pass command
- like via the `/chosen/module@<addr>/bootargs` node.
diff --git a/docs/system/index.rst b/docs/system/index.rst index 3cff0ca98f..b5cfe8ee93 100644 --- a/docs/system/index.rst +++ b/docs/system/index.rst @@ -25,6 +25,7 @@ Contents: ivshmem linuxboot generic-loader
- guest-loader vnc-security tls gdb
-- 2.20.1
On Thu, 19 Nov 2020 at 20:30, Alistair Francis alistair23@gmail.com wrote:
On Thu, Nov 5, 2020 at 9:58 AM Alex Bennée alex.bennee@linaro.org wrote:
+Currently the only supported machines which use FDT data to boot are +the ARM and RiscV `virt` machines.
RISC-V.
If we're going to be picky, also "Arm" :-)
-- PMM
This avoids us pulling in Xen headers we don't need. The TCG accelerator will always exist for the *-user builds.
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- accel/meson.build | 4 +++- accel/stubs/meson.build | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/accel/meson.build b/accel/meson.build index b26cca227a..c4936698cd 100644 --- a/accel/meson.build +++ b/accel/meson.build @@ -4,7 +4,9 @@ subdir('qtest') subdir('kvm') subdir('tcg') subdir('xen') -subdir('stubs') +if have_system + subdir('stubs') +endif
dummy_ss = ss.source_set() dummy_ss.add(files( diff --git a/accel/stubs/meson.build b/accel/stubs/meson.build index 12dd1539af..d65cb6a5e1 100644 --- a/accel/stubs/meson.build +++ b/accel/stubs/meson.build @@ -1,4 +1,8 @@ -specific_ss.add(when: 'CONFIG_HAX', if_false: files('hax-stub.c')) -specific_ss.add(when: 'CONFIG_XEN', if_false: files('xen-stub.c')) -specific_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c')) -specific_ss.add(when: 'CONFIG_TCG', if_false: files('tcg-stub.c')) +softmmu_stub_ss = ss.source_set() + +softmmu_stub_ss.add(when: 'CONFIG_HAX', if_false: files('hax-stub.c')) +softmmu_stub_ss.add(when: 'CONFIG_XEN', if_false: files('xen-stub.c')) +softmmu_stub_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c')) +softmmu_stub_ss.add(when: 'CONFIG_TCG', if_false: files('tcg-stub.c')) + +specific_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: softmmu_stub_ss)
On 11/5/20 6:51 PM, Alex Bennée wrote:
This avoids us pulling in Xen headers we don't need. The TCG accelerator will always exist for the *-user builds.
Signed-off-by: Alex Bennée alex.bennee@linaro.org
accel/meson.build | 4 +++- accel/stubs/meson.build | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/accel/meson.build b/accel/meson.build index b26cca227a..c4936698cd 100644 --- a/accel/meson.build +++ b/accel/meson.build @@ -4,7 +4,9 @@ subdir('qtest') subdir('kvm') subdir('tcg') subdir('xen') -subdir('stubs') +if have_system
Do we really need this check ...
- subdir('stubs')
+endif dummy_ss = ss.source_set() dummy_ss.add(files( diff --git a/accel/stubs/meson.build b/accel/stubs/meson.build index 12dd1539af..d65cb6a5e1 100644 --- a/accel/stubs/meson.build +++ b/accel/stubs/meson.build @@ -1,4 +1,8 @@ -specific_ss.add(when: 'CONFIG_HAX', if_false: files('hax-stub.c')) -specific_ss.add(when: 'CONFIG_XEN', if_false: files('xen-stub.c')) -specific_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c')) -specific_ss.add(when: 'CONFIG_TCG', if_false: files('tcg-stub.c')) +softmmu_stub_ss = ss.source_set()
+softmmu_stub_ss.add(when: 'CONFIG_HAX', if_false: files('hax-stub.c')) +softmmu_stub_ss.add(when: 'CONFIG_XEN', if_false: files('xen-stub.c')) +softmmu_stub_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c')) +softmmu_stub_ss.add(when: 'CONFIG_TCG', if_false: files('tcg-stub.c'))
+specific_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: softmmu_stub_ss)
... when we check for CONFIG_SOFTMMU here?
Xen is supported on ARM although weirdly using the i386-softmmu model. Checking based on the host CPU meant we never enabled Xen support. It would be nice to enable CONFIG_XEN for aarch64-softmmu to make it not seem weird but that will require further build surgery.
Suggested-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Alex Bennée alex.bennee@linaro.org Cc: Masami Hiramatsu masami.hiramatsu@linaro.org Cc: Stefano Stabellini sstabellini@kernel.org Cc: Anthony Perard anthony.perard@citrix.com Cc: Paul Durrant paul@xen.org Fixes: 8a19980e3f ("configure: move accelerator logic to meson") --- meson.build | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build index f5175010df..58e95227ea 100644 --- a/meson.build +++ b/meson.build @@ -74,10 +74,15 @@ else endif
accelerator_targets = { 'CONFIG_KVM': kvm_targets } +if cpu in ['x86', 'x86_64', 'arm', 'aarch64'] + # i368 emulator provides xenpv machine type for multiple architectures + accelerator_targets += { + 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'], + } +endif if cpu in ['x86', 'x86_64'] accelerator_targets += { 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'], - 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'], 'CONFIG_HVF': ['x86_64-softmmu'], 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'], }
On 11/5/20 6:51 PM, Alex Bennée wrote:
Xen is supported on ARM although weirdly using the i386-softmmu model. Checking based on the host CPU meant we never enabled Xen support. It would be nice to enable CONFIG_XEN for aarch64-softmmu to make it not seem weird but that will require further build surgery.
Suggested-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Alex Bennée alex.bennee@linaro.org Cc: Masami Hiramatsu masami.hiramatsu@linaro.org Cc: Stefano Stabellini sstabellini@kernel.org Cc: Anthony Perard anthony.perard@citrix.com Cc: Paul Durrant paul@xen.org Fixes: 8a19980e3f ("configure: move accelerator logic to meson")
meson.build | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
Reviewed-by: Philippe Mathieu-Daudé philmd@redhat.com
While Xen traditionally uses i386-softmmu to run it's PV models on all architectures some models are very much x86 only. This includes the full hardware virtualisation (HVM) which is only used on x86 HW. By introducing the symbol we can also fix the inclusion of XEN_PCI_PASSTHROUGH which should only be built for x86 (and Linux) systems.
Suggested-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Alex Bennée alex.bennee@linaro.org --- meson.build | 6 +++++- accel/Kconfig | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build index 58e95227ea..46e4c2fc3a 100644 --- a/meson.build +++ b/meson.build @@ -83,6 +83,7 @@ endif if cpu in ['x86', 'x86_64'] accelerator_targets += { 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'], + 'CONFIG_XEN_HVM': ['i386-softmmu', 'x86_64-softmmu'], 'CONFIG_HVF': ['x86_64-softmmu'], 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'], } @@ -204,6 +205,9 @@ if not get_option('kvm').disabled() and targetos == 'linux' endif if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host accelerators += 'CONFIG_XEN' + if host_machine.cpu() == 'x86_64' + accelerators += 'CONFIG_XEN_HVM' + endif have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux' else have_xen_pci_passthrough = false @@ -916,7 +920,7 @@ foreach target : target_dirs if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) config_target += { sym: 'y' } config_all += { sym: 'y' } - if sym == 'CONFIG_XEN' and have_xen_pci_passthrough + if sym == 'CONFIG_XEN_HVM' and have_xen_pci_passthrough config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' } endif have_accel = true diff --git a/accel/Kconfig b/accel/Kconfig index 2ad94a3839..4cd54029bd 100644 --- a/accel/Kconfig +++ b/accel/Kconfig @@ -7,3 +7,6 @@ config KVM config XEN bool select FSDEV_9P if VIRTFS + +config XEN_HVM + bool
On 11/5/20 6:51 PM, Alex Bennée wrote:
While Xen traditionally uses i386-softmmu to run it's PV models on all architectures some models are very much x86 only. This includes the full hardware virtualisation (HVM) which is only used on x86 HW. By introducing the symbol we can also fix the inclusion of XEN_PCI_PASSTHROUGH which should only be built for x86 (and Linux) systems.
Suggested-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Alex Bennée alex.bennee@linaro.org
meson.build | 6 +++++- accel/Kconfig | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-)
Reviewed-by: Philippe Mathieu-Daudé philmd@redhat.com
On 11/5/20 6:51 PM, Alex Bennée wrote:
While Xen traditionally uses i386-softmmu to run it's PV models on all architectures some models are very much x86 only. This includes the full hardware virtualisation (HVM) which is only used on x86 HW. By introducing the symbol we can also fix the inclusion of XEN_PCI_PASSTHROUGH which should only be built for x86 (and Linux) systems.
Suggested-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Alex Bennée alex.bennee@linaro.org
meson.build | 6 +++++- accel/Kconfig | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build index 58e95227ea..46e4c2fc3a 100644 --- a/meson.build +++ b/meson.build @@ -83,6 +83,7 @@ endif if cpu in ['x86', 'x86_64'] accelerator_targets += { 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
- 'CONFIG_XEN_HVM': ['i386-softmmu', 'x86_64-softmmu'],
I'm confused while looking at https://wiki.xen.org/wiki/Xen_Project_Software_Overview#ARM_Hosts
Maybe it makes sense to add both CONFIG_XEN_PV / CONFIG_XEN_HVM accelerators?
'CONFIG_HVF': ['x86_64-softmmu'], 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
} @@ -204,6 +205,9 @@ if not get_option('kvm').disabled() and targetos == 'linux' endif if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host accelerators += 'CONFIG_XEN'
- if host_machine.cpu() == 'x86_64'
Are you sure it is restricted to 64-bit host? I can't find the reference.
- accelerators += 'CONFIG_XEN_HVM'
- endif have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
Report XEN support along with the rest of the accelerators. Repurposed the existing Xen support line to display details about the control API version and the additional enabled features.
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- meson.build | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build index 46e4c2fc3a..79b74fbda7 100644 --- a/meson.build +++ b/meson.build @@ -2078,8 +2078,15 @@ if vnc.found() summary_info += {'VNC JPEG support': jpeg.found()} summary_info += {'VNC PNG support': png.found()} endif -summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')} if config_host.has_key('CONFIG_XEN_BACKEND') + xen_features = ['backend'] + if config_all.has_key('CONFIG_XEN_HVM') + xen_features += 'HVM' + endif + if config_all.has_key('CONFIG_XEN_PCI_PASSTHROUGH') + xen_features += 'PCI Passthrough' + endif + summary_info += {'xen features': ' '.join(xen_features)} summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']} endif summary_info += {'brlapi support': config_host.has_key('CONFIG_BRLAPI')} @@ -2092,6 +2099,7 @@ summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_ summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')} summary_info += {'Install blobs': get_option('install_blobs')} summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')} +summary_info += {'XEN support': config_all.has_key('CONFIG_XEN')} summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')} summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
On 11/5/20 6:51 PM, Alex Bennée wrote:
Report XEN support along with the rest of the accelerators. Repurposed the existing Xen support line to display details about the control API version and the additional enabled features.
Signed-off-by: Alex Bennée alex.bennee@linaro.org
meson.build | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build index 46e4c2fc3a..79b74fbda7 100644 --- a/meson.build +++ b/meson.build @@ -2078,8 +2078,15 @@ if vnc.found() summary_info += {'VNC JPEG support': jpeg.found()} summary_info += {'VNC PNG support': png.found()} endif -summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')} if config_host.has_key('CONFIG_XEN_BACKEND')
- xen_features = ['backend']
- if config_all.has_key('CONFIG_XEN_HVM')
- xen_features += 'HVM'
- endif
- if config_all.has_key('CONFIG_XEN_PCI_PASSTHROUGH')
- xen_features += 'PCI Passthrough'
- endif
- summary_info += {'xen features': ' '.join(xen_features)}
Maybe ','.join, as ' ' already in 'PCI Passthrough'.
Otherwise: Reviewed-by: Philippe Mathieu-Daudé philmd@redhat.com
summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']} endif summary_info += {'brlapi support': config_host.has_key('CONFIG_BRLAPI')} @@ -2092,6 +2099,7 @@ summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_ summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')} summary_info += {'Install blobs': get_option('install_blobs')} summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')} +summary_info += {'XEN support': config_all.has_key('CONFIG_XEN')} summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')} summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
Chardev is already a typedef'ed struct.
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- include/hw/xen/xen.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index 1406648ca5..0f9962b1c1 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -28,7 +28,7 @@ int xen_is_pirq_msi(uint32_t msi_data);
qemu_irq *xen_interrupt_controller_init(void);
-void xenstore_store_pv_console_info(int i, struct Chardev *chr); +void xenstore_store_pv_console_info(int i, Chardev *chr);
void xen_register_framebuffer(struct MemoryRegion *mr);
On 11/5/20 6:51 PM, Alex Bennée wrote:
Chardev is already a typedef'ed struct.
Signed-off-by: Alex Bennée alex.bennee@linaro.org
include/hw/xen/xen.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Philippe Mathieu-Daudé philmd@redhat.com
We should never build something that calls this without having it.
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- stubs/xen-hw-stub.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/stubs/xen-hw-stub.c b/stubs/xen-hw-stub.c index 2ea8190921..15f3921a76 100644 --- a/stubs/xen-hw-stub.c +++ b/stubs/xen-hw-stub.c @@ -10,10 +10,6 @@ #include "hw/xen/xen.h" #include "hw/xen/xen-x86.h"
-void xenstore_store_pv_console_info(int i, Chardev *chr) -{ -} - int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) { return -1;
On 11/5/20 6:51 PM, Alex Bennée wrote:
We should never build something that calls this without having it.
"because ..."?
Reviewed-by: Philippe Mathieu-Daudé philmd@redhat.com
Signed-off-by: Alex Bennée alex.bennee@linaro.org
stubs/xen-hw-stub.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/stubs/xen-hw-stub.c b/stubs/xen-hw-stub.c index 2ea8190921..15f3921a76 100644 --- a/stubs/xen-hw-stub.c +++ b/stubs/xen-hw-stub.c @@ -10,10 +10,6 @@ #include "hw/xen/xen.h" #include "hw/xen/xen-x86.h" -void xenstore_store_pv_console_info(int i, Chardev *chr) -{ -}
int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) { return -1;
Philippe Mathieu-Daudé philmd@redhat.com writes:
On 11/5/20 6:51 PM, Alex Bennée wrote:
We should never build something that calls this without having it.
"because ..."?
xen-all.c is only built when we have CONFIG_XEN which also gates the only call-site in xen-console.c
Reviewed-by: Philippe Mathieu-Daudé philmd@redhat.com
Signed-off-by: Alex Bennée alex.bennee@linaro.org
stubs/xen-hw-stub.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/stubs/xen-hw-stub.c b/stubs/xen-hw-stub.c index 2ea8190921..15f3921a76 100644 --- a/stubs/xen-hw-stub.c +++ b/stubs/xen-hw-stub.c @@ -10,10 +10,6 @@ #include "hw/xen/xen.h" #include "hw/xen/xen-x86.h" -void xenstore_store_pv_console_info(int i, Chardev *chr) -{ -}
int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) { return -1;
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- accel/stubs/hax-stub.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/accel/stubs/hax-stub.c b/accel/stubs/hax-stub.c index 1a9da83185..49077f88e3 100644 --- a/accel/stubs/hax-stub.c +++ b/accel/stubs/hax-stub.c @@ -14,7 +14,6 @@ */
#include "qemu/osdep.h" -#include "cpu.h" #include "sysemu/hax.h"
int hax_sync_vcpus(void)
On 11/5/20 6:51 PM, Alex Bennée wrote:
Signed-off-by: Alex Bennée alex.bennee@linaro.org
accel/stubs/hax-stub.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/accel/stubs/hax-stub.c b/accel/stubs/hax-stub.c index 1a9da83185..49077f88e3 100644 --- a/accel/stubs/hax-stub.c +++ b/accel/stubs/hax-stub.c @@ -14,7 +14,6 @@ */ #include "qemu/osdep.h" -#include "cpu.h" #include "sysemu/hax.h" int hax_sync_vcpus(void)
Reviewed-by: Philippe Mathieu-Daudé philmd@redhat.com
When running on non-x86 systems there is no point building HVM support because we will never see such things. To achieve this we need to shuffle a little bit of the inline and other stubs about.
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- include/sysemu/xen-mapcache.h | 2 +- include/sysemu/xen.h | 9 +++++---- accel/stubs/xen-all-stub.c | 11 +++++++++++ accel/stubs/xen-stub.c | 2 -- accel/stubs/meson.build | 3 ++- hw/i386/xen/meson.build | 2 +- 6 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 accel/stubs/xen-all-stub.c
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h index c8e7c2f6cf..4bba764745 100644 --- a/include/sysemu/xen-mapcache.h +++ b/include/sysemu/xen-mapcache.h @@ -13,7 +13,7 @@
typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset, ram_addr_t size); -#ifdef CONFIG_XEN +#ifdef CONFIG_XEN_HVM
void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque); diff --git a/include/sysemu/xen.h b/include/sysemu/xen.h index 0ca25697e4..43d2314441 100644 --- a/include/sysemu/xen.h +++ b/include/sysemu/xen.h @@ -24,7 +24,7 @@ extern bool xen_allowed;
#define xen_enabled() (xen_allowed)
-#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_XEN_HVM void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length); void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, struct MemoryRegion *mr, Error **errp); @@ -33,7 +33,10 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, #else /* !CONFIG_XEN_IS_POSSIBLE */
#define xen_enabled() 0 -#ifndef CONFIG_USER_ONLY + +#endif /* CONFIG_XEN_IS_POSSIBLE */ + +#if !defined(CONFIG_XEN_HVM) && !defined(CONFIG_USER_ONLY) static inline void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length) { /* nothing */ @@ -45,6 +48,4 @@ static inline void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, } #endif
-#endif /* CONFIG_XEN_IS_POSSIBLE */ - #endif diff --git a/accel/stubs/xen-all-stub.c b/accel/stubs/xen-all-stub.c new file mode 100644 index 0000000000..597c5789cc --- /dev/null +++ b/accel/stubs/xen-all-stub.c @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2014 Citrix Systems UK Ltd. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "sysemu/xen.h" + +bool xen_allowed; diff --git a/accel/stubs/xen-stub.c b/accel/stubs/xen-stub.c index 7054965c48..6bc9906239 100644 --- a/accel/stubs/xen-stub.c +++ b/accel/stubs/xen-stub.c @@ -9,8 +9,6 @@ #include "sysemu/xen.h" #include "qapi/qapi-commands-migration.h"
-bool xen_allowed; - void qmp_xen_set_global_dirty_log(bool enable, Error **errp) { } diff --git a/accel/stubs/meson.build b/accel/stubs/meson.build index d65cb6a5e1..dca468c82a 100644 --- a/accel/stubs/meson.build +++ b/accel/stubs/meson.build @@ -1,7 +1,8 @@ softmmu_stub_ss = ss.source_set()
softmmu_stub_ss.add(when: 'CONFIG_HAX', if_false: files('hax-stub.c')) -softmmu_stub_ss.add(when: 'CONFIG_XEN', if_false: files('xen-stub.c')) +softmmu_stub_ss.add(when: 'CONFIG_XEN', if_false: files('xen-all-stub.c')) +softmmu_stub_ss.add(when: 'CONFIG_XEN_HVM', if_false: files('xen-stub.c')) softmmu_stub_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c')) softmmu_stub_ss.add(when: 'CONFIG_TCG', if_false: files('tcg-stub.c'))
diff --git a/hw/i386/xen/meson.build b/hw/i386/xen/meson.build index be84130300..576e2cc5dc 100644 --- a/hw/i386/xen/meson.build +++ b/hw/i386/xen/meson.build @@ -1,4 +1,4 @@ -i386_ss.add(when: 'CONFIG_XEN', if_true: files( +i386_ss.add(when: 'CONFIG_XEN_HVM', if_true: files( 'xen-hvm.c', 'xen-mapcache.c', 'xen_apic.c',
The i386-softmmu is a bit of an oddity for running ARM Xen guests so lets allow us to build an aarch64 binary with a reasonable name as well.
Signed-off-by: Alex Bennée alex.bennee@linaro.org --- meson.build | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/meson.build b/meson.build index 79b74fbda7..5280cd9e8f 100644 --- a/meson.build +++ b/meson.build @@ -74,15 +74,16 @@ else endif
accelerator_targets = { 'CONFIG_KVM': kvm_targets } -if cpu in ['x86', 'x86_64', 'arm', 'aarch64'] - # i368 emulator provides xenpv machine type for multiple architectures +if cpu in ['arm', 'aarch64'] + # i386 emulator used to provide xenpv machine type for all + # supported architectures accelerator_targets += { - 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'], + 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu', 'arm-softmmu', 'aarch64-softmmu'], } -endif -if cpu in ['x86', 'x86_64'] +elif cpu in ['x86', 'x86_64'] accelerator_targets += { 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'], + 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'], 'CONFIG_XEN_HVM': ['i386-softmmu', 'x86_64-softmmu'], 'CONFIG_HVF': ['x86_64-softmmu'], 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
Patchew URL: https://patchew.org/QEMU/20201105175153.30489-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: 20201105175153.30489-1-alex.bennee@linaro.org Subject: [RFC PATCH 00/15] Xen guest-loader and arm64 build fixes/enhancements
=== 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 * [new tag] patchew/20201105175153.30489-1-alex.bennee@linaro.org -> patchew/20201105175153.30489-1-alex.bennee@linaro.org Switched to a new branch 'test' 27a1c8e meson.build: build a Xen aware qemu-aarch64-system c2531b0 xen: only build HVM support under CONFIG_XEN_HVM a4e2d49 accel/stubs: drop unused cpu.h include 8e6bdd0 stubs/xen-hw-stub: drop xenstore_store_pv_console_info stub c89ecab include/hw/xen.h: drop superfluous struct f76f5a8 meson.build: clean-up summary reporting of XEN and it's features 739b93f meson.build: introduce CONFIG_XEN_HVM flag e739aac meson.build: fix building of Xen support for aarch64 f28183e accel/meson: you only need accelerator stubs for softmmu builds 8227889 docs: add some documentation for the guest-loader 5d2e6b4 docs: move generic-loader documentation into the main manual 97eabd7 hw/core: implement a guest-loader to support static hypervisor guests d3af3c7 device_tree: add qemu_fdt_setprop_string_array helper 57bb510 hw/riscv: migrate fdt field to generic MachineState 4d28909 hw/board: promote fdt from ARM VirtMachineState to MachineState
=== OUTPUT BEGIN === 1/15 Checking commit 4d289091b31a (hw/board: promote fdt from ARM VirtMachineState to MachineState) 2/15 Checking commit 57bb510cbd7f (hw/riscv: migrate fdt field to generic MachineState) 3/15 Checking commit d3af3c7f5650 (device_tree: add qemu_fdt_setprop_string_array helper) WARNING: line over 80 characters #66: 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/15 has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. 4/15 Checking commit 97eabd73472c (hw/core: implement a guest-loader to support static hypervisor guests) WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? #23: new file mode 100644
WARNING: line over 80 characters #69: 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 #73: FILE: hw/core/guest-loader.c:46: + g_autofree char *node = g_strdup_printf("/chosen/module@%#08lx", s->addr);
WARNING: line over 80 characters #87: FILE: hw/core/guest-loader.c:60: + (fdt, node, "compatible", (char **) &compat, ARRAY_SIZE(compat)) < 0) {
ERROR: "foo * bar" should be "foo *bar" #97: FILE: hw/core/guest-loader.c:70: + const char * compat[2] = { "multiboot,module", "multiboot,ramdisk" };
WARNING: line over 80 characters #99: FILE: hw/core/guest-loader.c:72: + (fdt, node, "compatible", (char **) &compat, ARRAY_SIZE(compat)) < 0) {
WARNING: line over 80 characters #114: 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/15 has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS.
5/15 Checking commit 5d2e6b45a0ff (docs: move generic-loader documentation into the main manual) WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? #15: deleted file mode 100644
ERROR: trailing whitespace #204: FILE: docs/system/generic-loader.rst:87: + $
total: 1 errors, 1 warnings, 124 lines checked
Patch 5/15 has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS.
6/15 Checking commit 82278896e117 (docs: add some documentation for the guest-loader) WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? #11: new file mode 100644
total: 0 errors, 1 warnings, 61 lines checked
Patch 6/15 has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. 7/15 Checking commit f28183e58873 (accel/meson: you only need accelerator stubs for softmmu builds) 8/15 Checking commit e739aac98546 (meson.build: fix building of Xen support for aarch64) 9/15 Checking commit 739b93f74453 (meson.build: introduce CONFIG_XEN_HVM flag) 10/15 Checking commit f76f5a8ae6f4 (meson.build: clean-up summary reporting of XEN and it's features) 11/15 Checking commit c89ecab617c8 (include/hw/xen.h: drop superfluous struct) 12/15 Checking commit 8e6bdd0b268e (stubs/xen-hw-stub: drop xenstore_store_pv_console_info stub) 13/15 Checking commit a4e2d49e005e (accel/stubs: drop unused cpu.h include) 14/15 Checking commit c2531b00f4b8 (xen: only build HVM support under CONFIG_XEN_HVM) WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? #29: new file mode 100644
total: 0 errors, 1 warnings, 66 lines checked
Patch 14/15 has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS. 15/15 Checking commit 27a1c8ef9d5d (meson.build: build a Xen aware qemu-aarch64-system) === OUTPUT END ===
Test command exited with code: 1
The full log is available at http://patchew.org/logs/20201105175153.30489-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