diff options
Diffstat (limited to 'hw/i386/microvm.c')
-rw-r--r-- | hw/i386/microvm.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index 60d3272230..273abe28c9 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -46,6 +46,7 @@ #include "hw/virtio/virtio-mmio.h" #include "hw/acpi/acpi.h" #include "hw/acpi/generic_event_device.h" +#include "hw/pci-host/gpex.h" #include "cpu.h" #include "elf.h" @@ -101,6 +102,55 @@ static void microvm_gsi_handler(void *opaque, int n, int level) qemu_set_irq(s->ioapic_irq[n], level); } +static void create_gpex(MicrovmMachineState *mms) +{ + X86MachineState *x86ms = X86_MACHINE(mms); + MemoryRegion *mmio32_alias; + MemoryRegion *mmio64_alias; + MemoryRegion *mmio_reg; + MemoryRegion *ecam_alias; + MemoryRegion *ecam_reg; + DeviceState *dev; + int i; + + dev = qdev_new(TYPE_GPEX_HOST); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + + /* Map only the first size_ecam bytes of ECAM space */ + ecam_alias = g_new0(MemoryRegion, 1); + ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); + memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam", + ecam_reg, 0, mms->gpex.ecam.size); + memory_region_add_subregion(get_system_memory(), + mms->gpex.ecam.base, ecam_alias); + + /* Map the MMIO window into system address space so as to expose + * the section of PCI MMIO space which starts at the same base address + * (ie 1:1 mapping for that part of PCI MMIO space visible through + * the window). + */ + mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); + if (mms->gpex.mmio32.size) { + mmio32_alias = g_new0(MemoryRegion, 1); + memory_region_init_alias(mmio32_alias, OBJECT(dev), "pcie-mmio32", mmio_reg, + mms->gpex.mmio32.base, mms->gpex.mmio32.size); + memory_region_add_subregion(get_system_memory(), + mms->gpex.mmio32.base, mmio32_alias); + } + if (mms->gpex.mmio64.size) { + mmio64_alias = g_new0(MemoryRegion, 1); + memory_region_init_alias(mmio64_alias, OBJECT(dev), "pcie-mmio64", mmio_reg, + mms->gpex.mmio64.base, mms->gpex.mmio64.size); + memory_region_add_subregion(get_system_memory(), + mms->gpex.mmio64.base, mmio64_alias); + } + + for (i = 0; i < GPEX_NUM_IRQS; i++) { + sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, + x86ms->gsi[mms->gpex.irq + i]); + } +} + static void microvm_devices_init(MicrovmMachineState *mms) { X86MachineState *x86ms = X86_MACHINE(mms); @@ -147,6 +197,15 @@ static void microvm_devices_init(MicrovmMachineState *mms) x86ms->acpi_dev = HOTPLUG_HANDLER(dev); } + if (x86_machine_is_acpi_enabled(x86ms) && mms->pcie == ON_OFF_AUTO_ON) { + mms->gpex.mmio32.base = PCIE_MMIO_BASE; + mms->gpex.mmio32.size = PCIE_MMIO_SIZE; + mms->gpex.ecam.base = PCIE_ECAM_BASE; + mms->gpex.ecam.size = PCIE_ECAM_SIZE; + mms->gpex.irq = PCIE_IRQ_BASE; + create_gpex(mms); + } + if (mms->pic == ON_OFF_AUTO_ON || mms->pic == ON_OFF_AUTO_AUTO) { qemu_irq *i8259; @@ -446,6 +505,23 @@ static void microvm_machine_set_rtc(Object *obj, Visitor *v, const char *name, visit_type_OnOffAuto(v, name, &mms->rtc, errp); } +static void microvm_machine_get_pcie(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + MicrovmMachineState *mms = MICROVM_MACHINE(obj); + OnOffAuto pcie = mms->pcie; + + visit_type_OnOffAuto(v, name, &pcie, errp); +} + +static void microvm_machine_set_pcie(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + MicrovmMachineState *mms = MICROVM_MACHINE(obj); + + visit_type_OnOffAuto(v, name, &mms->pcie, errp); +} + static bool microvm_machine_get_isa_serial(Object *obj, Error **errp) { MicrovmMachineState *mms = MICROVM_MACHINE(obj); @@ -521,6 +597,7 @@ static void microvm_machine_initfn(Object *obj) mms->pic = ON_OFF_AUTO_AUTO; mms->pit = ON_OFF_AUTO_AUTO; mms->rtc = ON_OFF_AUTO_AUTO; + mms->pcie = ON_OFF_AUTO_AUTO; mms->isa_serial = true; mms->option_roms = true; mms->auto_kernel_cmdline = true; @@ -587,6 +664,13 @@ static void microvm_class_init(ObjectClass *oc, void *data) object_class_property_set_description(oc, MICROVM_MACHINE_RTC, "Enable MC146818 RTC"); + object_class_property_add(oc, MICROVM_MACHINE_PCIE, "OnOffAuto", + microvm_machine_get_pcie, + microvm_machine_set_pcie, + NULL, NULL); + object_class_property_set_description(oc, MICROVM_MACHINE_PCIE, + "Enable PCIe"); + object_class_property_add_bool(oc, MICROVM_MACHINE_ISA_SERIAL, microvm_machine_get_isa_serial, microvm_machine_set_isa_serial); |