#include "hw/firmware/smbios.h"
#include "qapi/visitor.h"
#include "qapi/qapi-visit-common.h"
+#include "qapi/qmp/qlist.h"
#include "standard-headers/linux/input.h"
#include "hw/arm/smmuv3.h"
#include "hw/acpi/acpi.h"
#include "target/arm/internals.h"
-#include "hw/mem/memory-device.h"
#include "hw/mem/pc-dimm.h"
#include "hw/mem/nvdimm.h"
#include "hw/acpi/generic_event_device.h"
-#include "hw/virtio/virtio-mem-pci.h"
+#include "hw/virtio/virtio-md-pci.h"
#include "hw/virtio/virtio-iommu.h"
#include "hw/char/pl011.h"
#include "qemu/guest-random.h"
ARM_CPU_TYPE_NAME("cortex-a55"),
ARM_CPU_TYPE_NAME("cortex-a72"),
ARM_CPU_TYPE_NAME("cortex-a76"),
+ ARM_CPU_TYPE_NAME("cortex-a710"),
ARM_CPU_TYPE_NAME("a64fx"),
ARM_CPU_TYPE_NAME("neoverse-n1"),
+ ARM_CPU_TYPE_NAME("neoverse-v1"),
+ ARM_CPU_TYPE_NAME("neoverse-n2"),
#endif
ARM_CPU_TYPE_NAME("cortex-a53"),
ARM_CPU_TYPE_NAME("cortex-a57"),
+#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
ARM_CPU_TYPE_NAME("host"),
+#endif
ARM_CPU_TYPE_NAME("max"),
};
}
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,
- GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags);
+ GIC_FDT_IRQ_TYPE_PPI,
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
+ GIC_FDT_IRQ_TYPE_PPI,
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
+ GIC_FDT_IRQ_TYPE_PPI,
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
+ GIC_FDT_IRQ_TYPE_PPI,
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
}
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
if (vms->virt) {
qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
- GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ,
+ GIC_FDT_IRQ_TYPE_PPI,
+ INTID_TO_PPI(ARCH_GIC_MAINT_IRQ),
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
}
} else {
2, vms->memmap[VIRT_GIC_VCPU].base,
2, vms->memmap[VIRT_GIC_VCPU].size);
qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
- GIC_FDT_IRQ_TYPE_PPI, ARCH_GIC_MAINT_IRQ,
+ GIC_FDT_IRQ_TYPE_PPI,
+ INTID_TO_PPI(ARCH_GIC_MAINT_IRQ),
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
}
}
qemu_fdt_setprop(ms->fdt, "/pmu", "compatible",
compat, sizeof(compat));
qemu_fdt_setprop_cells(ms->fdt, "/pmu", "interrupts",
- GIC_FDT_IRQ_TYPE_PPI, VIRTUAL_PMU_IRQ, irqflags);
+ GIC_FDT_IRQ_TYPE_PPI,
+ INTID_TO_PPI(VIRTUAL_PMU_IRQ), irqflags);
}
}
dev = qdev_new(TYPE_ACPI_GED);
qdev_prop_set_uint32(dev, "ged-event", event);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
-
return dev;
}
DeviceState *dev;
dev = qdev_new("arm-gicv2m");
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_V2M].base);
qdev_prop_set_uint32(dev, "base-spi", irq);
qdev_prop_set_uint32(dev, "num-spi", NUM_GICV2M_SPIS);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_V2M].base);
for (i = 0; i < NUM_GICV2M_SPIS; i++) {
sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
}
if (vms->gic_version != VIRT_GIC_VERSION_2) {
+ QList *redist_region_count;
uint32_t redist0_capacity = virt_redist_capacity(vms, VIRT_GIC_REDIST);
uint32_t redist0_count = MIN(smp_cpus, redist0_capacity);
nb_redist_regions = virt_gicv3_redist_region_count(vms);
- qdev_prop_set_uint32(vms->gic, "len-redist-region-count",
- nb_redist_regions);
- qdev_prop_set_uint32(vms->gic, "redist-region-count[0]", redist0_count);
+ redist_region_count = qlist_new();
+ qlist_append_int(redist_region_count, redist0_count);
+ if (nb_redist_regions == 2) {
+ uint32_t redist1_capacity =
+ virt_redist_capacity(vms, VIRT_HIGH_GIC_REDIST2);
+
+ qlist_append_int(redist_region_count,
+ MIN(smp_cpus - redist0_count, redist1_capacity));
+ }
+ qdev_prop_set_array(vms->gic, "redist-region-count",
+ redist_region_count);
if (!kvm_irqchip_in_kernel()) {
if (vms->tcg_its) {
qdev_prop_set_bit(vms->gic, "has-lpi", true);
}
}
-
- if (nb_redist_regions == 2) {
- uint32_t redist1_capacity =
- virt_redist_capacity(vms, VIRT_HIGH_GIC_REDIST2);
-
- qdev_prop_set_uint32(vms->gic, "redist-region-count[1]",
- MIN(smp_cpus - redist0_count, redist1_capacity));
- }
} else {
if (!kvm_irqchip_in_kernel()) {
qdev_prop_set_bit(vms->gic, "has-virtualization-extensions",
*/
for (i = 0; i < smp_cpus; i++) {
DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
- int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
- int irq;
+ int intidbase = NUM_IRQS + i * GIC_INTERNAL;
/* Mapping from the output timer irq lines from the CPU to the
* GIC PPI inputs we use for the virt board.
*/
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
};
- for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
+ for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
qdev_connect_gpio_out(cpudev, irq,
qdev_get_gpio_in(vms->gic,
- ppibase + timer_irq[irq]));
+ intidbase + timer_irq[irq]));
}
if (vms->gic_version != VIRT_GIC_VERSION_2) {
qemu_irq irq = qdev_get_gpio_in(vms->gic,
- ppibase + ARCH_GIC_MAINT_IRQ);
+ intidbase + ARCH_GIC_MAINT_IRQ);
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
0, irq);
} else if (vms->virt) {
qemu_irq irq = qdev_get_gpio_in(vms->gic,
- ppibase + ARCH_GIC_MAINT_IRQ);
+ intidbase + ARCH_GIC_MAINT_IRQ);
sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
}
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
- qdev_get_gpio_in(vms->gic, ppibase
+ qdev_get_gpio_in(vms->gic, intidbase
+ VIRTUAL_PMU_IRQ));
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
vms->bus = pci->bus;
if (vms->bus) {
for (i = 0; i < nb_nics; i++) {
- NICInfo *nd = &nd_table[i];
-
- if (!nd->model) {
- nd->model = g_strdup(mc->default_nic);
- }
-
- pci_nic_init_nofail(nd, pci->bus, nd->model, NULL);
+ pci_nic_init_nofail(&nd_table[i], pci->bus, mc->default_nic, NULL);
}
}
virt_set_high_memmap(vms, base, pa_bits);
if (device_memory_size > 0) {
- ms->device_memory = g_malloc0(sizeof(*ms->device_memory));
- ms->device_memory->base = device_memory_base;
- memory_region_init(&ms->device_memory->mr, OBJECT(vms),
- "device-memory", device_memory_size);
+ machine_memory_devices_init(ms, device_memory_base, device_memory_size);
}
}
if (pmu) {
assert(arm_feature(&ARM_CPU(cpu)->env, ARM_FEATURE_PMU));
if (kvm_irqchip_in_kernel()) {
- kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ));
+ kvm_arm_pmu_set_irq(ARM_CPU(cpu), VIRTUAL_PMU_IRQ);
}
- kvm_arm_pmu_init(cpu);
+ kvm_arm_pmu_init(ARM_CPU(cpu));
}
if (steal_time) {
- kvm_arm_pvtime_init(cpu, pvtime_reg_base +
- cpu->cpu_index * PVTIME_SIZE_PER_CPU);
+ kvm_arm_pvtime_init(ARM_CPU(cpu), pvtime_reg_base
+ + cpu->cpu_index
+ * PVTIME_SIZE_PER_CPU);
}
}
} else {
memory_region_add_subregion(sysmem, vms->memmap[VIRT_MEM].base,
machine->ram);
- if (machine->device_memory) {
- memory_region_add_subregion(sysmem, machine->device_memory->base,
- &machine->device_memory->mr);
- }
virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
dev, &error_abort);
}
-static void virt_virtio_md_pci_pre_plug(HotplugHandler *hotplug_dev,
- DeviceState *dev, Error **errp)
-{
- HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev);
- Error *local_err = NULL;
-
- if (!hotplug_dev2 && dev->hotplugged) {
- /*
- * Without a bus hotplug handler, we cannot control the plug/unplug
- * order. We should never reach this point when hotplugging on ARM.
- * However, it's nice to add a safety net, similar to what we have
- * on x86.
- */
- error_setg(errp, "hotplug of virtio based memory devices not supported"
- " on this bus.");
- return;
- }
- /*
- * First, see if we can plug this memory device at all. If that
- * succeeds, branch of to the actual hotplug handler.
- */
- memory_device_pre_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev), NULL,
- &local_err);
- if (!local_err && hotplug_dev2) {
- hotplug_handler_pre_plug(hotplug_dev2, dev, &local_err);
- }
- error_propagate(errp, local_err);
-}
-
-static void virt_virtio_md_pci_plug(HotplugHandler *hotplug_dev,
- DeviceState *dev, Error **errp)
-{
- HotplugHandler *hotplug_dev2 = qdev_get_bus_hotplug_handler(dev);
- Error *local_err = NULL;
-
- /*
- * Plug the memory device first and then branch off to the actual
- * hotplug handler. If that one fails, we can easily undo the memory
- * device bits.
- */
- memory_device_plug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
- if (hotplug_dev2) {
- hotplug_handler_plug(hotplug_dev2, dev, &local_err);
- if (local_err) {
- memory_device_unplug(MEMORY_DEVICE(dev), MACHINE(hotplug_dev));
- }
- }
- error_propagate(errp, local_err);
-}
-
-static void virt_virtio_md_pci_unplug_request(HotplugHandler *hotplug_dev,
- DeviceState *dev, Error **errp)
-{
- /* We don't support hot unplug of virtio based memory devices */
- error_setg(errp, "virtio based memory devices cannot be unplugged.");
-}
-
-
static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
virt_memory_pre_plug(hotplug_dev, dev, errp);
- } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
- virt_virtio_md_pci_pre_plug(hotplug_dev, dev, errp);
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
+ virtio_md_pci_pre_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
hwaddr db_start = 0, db_end = 0;
+ QList *reserved_regions;
char *resv_prop_str;
if (vms->iommu != VIRT_IOMMU_NONE) {
db_start, db_end,
VIRTIO_IOMMU_RESV_MEM_T_MSI);
- object_property_set_uint(OBJECT(dev), "len-reserved-regions", 1, errp);
- object_property_set_str(OBJECT(dev), "reserved-regions[0]",
- resv_prop_str, errp);
+ reserved_regions = qlist_new();
+ qlist_append_str(reserved_regions, resv_prop_str);
+ qdev_prop_set_array(dev, "reserved-regions", reserved_regions);
g_free(resv_prop_str);
}
}
SYS_BUS_DEVICE(dev));
}
}
+
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
virt_memory_plug(hotplug_dev, dev, errp);
- }
-
- if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
- virt_virtio_md_pci_plug(hotplug_dev, dev, errp);
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
+ virtio_md_pci_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
}
if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
{
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
virt_dimm_unplug_request(hotplug_dev, dev, errp);
- } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI)) {
- virt_virtio_md_pci_unplug_request(hotplug_dev, dev, errp);
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
+ virtio_md_pci_unplug_request(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev),
+ errp);
} else {
error_setg(errp, "device unplug request for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
{
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
virt_dimm_unplug(hotplug_dev, dev, errp);
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
+ virtio_md_pci_unplug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
} else {
error_setg(errp, "virt: device unplug for unsupported device"
" type: %s", object_get_typename(OBJECT(dev)));
if (device_is_dynamic_sysbus(mc, dev) ||
object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
- object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MEM_PCI) ||
+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI) ||
object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
return HOTPLUG_HANDLER(machine);
}
"require an IPA range (%d bits) larger than "
"the one supported by the host (%d bits)",
requested_pa_size, max_vm_pa_size);
- exit(1);
+ return -1;
}
/*
* We return the requested PA log size, unless KVM only supports
}
type_init(machvirt_machine_init);
+static void virt_machine_9_0_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
+
+static void virt_machine_8_2_options(MachineClass *mc)
+{
+ virt_machine_9_0_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
+}
+DEFINE_VIRT_MACHINE(8, 2)
+
static void virt_machine_8_1_options(MachineClass *mc)
{
+ virt_machine_8_2_options(mc);
+ compat_props_add(mc->compat_props, hw_compat_8_1, hw_compat_8_1_len);
}
-DEFINE_VIRT_MACHINE_AS_LATEST(8, 1)
+DEFINE_VIRT_MACHINE(8, 1)
static void virt_machine_8_0_options(MachineClass *mc)
{