aboutsummaryrefslogtreecommitdiff
path: root/hw/i386
diff options
context:
space:
mode:
Diffstat (limited to 'hw/i386')
-rw-r--r--hw/i386/microvm.c56
1 files changed, 51 insertions, 5 deletions
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 829b376a12..5688608613 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -145,32 +145,53 @@ static void create_gpex(MicrovmMachineState *mms)
}
}
+static int microvm_ioapics(MicrovmMachineState *mms)
+{
+ if (!x86_machine_is_acpi_enabled(X86_MACHINE(mms))) {
+ return 1;
+ }
+ if (mms->ioapic2 == ON_OFF_AUTO_OFF) {
+ return 1;
+ }
+ return 2;
+}
+
static void microvm_devices_init(MicrovmMachineState *mms)
{
X86MachineState *x86ms = X86_MACHINE(mms);
ISABus *isa_bus;
ISADevice *rtc_state;
GSIState *gsi_state;
+ int ioapics;
int i;
/* Core components */
-
+ ioapics = microvm_ioapics(mms);
gsi_state = g_malloc0(sizeof(*gsi_state));
- x86ms->gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
+ x86ms->gsi = qemu_allocate_irqs(gsi_handler, gsi_state,
+ IOAPIC_NUM_PINS * ioapics);
isa_bus = isa_bus_new(NULL, get_system_memory(), get_system_io(),
&error_abort);
isa_bus_irqs(isa_bus, x86ms->gsi);
ioapic_init_gsi(gsi_state, "machine");
+ if (ioapics > 1) {
+ x86ms->ioapic2 = ioapic_init_secondary(gsi_state);
+ }
kvmclock_create(true);
mms->virtio_irq_base = 5;
mms->virtio_num_transports = 8;
- if (x86_machine_is_acpi_enabled(x86ms)) {
- mms->pcie_irq_base = 12;
- mms->virtio_irq_base = 16;
+ if (x86ms->ioapic2) {
+ mms->pcie_irq_base = 16; /* 16 -> 19 */
+ /* use second ioapic (24 -> 47) for virtio-mmio irq lines */
+ mms->virtio_irq_base = IO_APIC_SECONDARY_IRQBASE;
+ mms->virtio_num_transports = IOAPIC_NUM_PINS;
+ } else if (x86_machine_is_acpi_enabled(x86ms)) {
+ mms->pcie_irq_base = 12; /* 12 -> 15 */
+ mms->virtio_irq_base = 16; /* 16 -> 23 */
}
for (i = 0; i < mms->virtio_num_transports; i++) {
@@ -544,6 +565,23 @@ static void microvm_machine_set_pcie(Object *obj, Visitor *v, const char *name,
visit_type_OnOffAuto(v, name, &mms->pcie, errp);
}
+static void microvm_machine_get_ioapic2(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ MicrovmMachineState *mms = MICROVM_MACHINE(obj);
+ OnOffAuto ioapic2 = mms->ioapic2;
+
+ visit_type_OnOffAuto(v, name, &ioapic2, errp);
+}
+
+static void microvm_machine_set_ioapic2(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ MicrovmMachineState *mms = MICROVM_MACHINE(obj);
+
+ visit_type_OnOffAuto(v, name, &mms->ioapic2, errp);
+}
+
static bool microvm_machine_get_isa_serial(Object *obj, Error **errp)
{
MicrovmMachineState *mms = MICROVM_MACHINE(obj);
@@ -620,6 +658,7 @@ static void microvm_machine_initfn(Object *obj)
mms->pit = ON_OFF_AUTO_AUTO;
mms->rtc = ON_OFF_AUTO_AUTO;
mms->pcie = ON_OFF_AUTO_AUTO;
+ mms->ioapic2 = ON_OFF_AUTO_AUTO;
mms->isa_serial = true;
mms->option_roms = true;
mms->auto_kernel_cmdline = true;
@@ -693,6 +732,13 @@ static void microvm_class_init(ObjectClass *oc, void *data)
object_class_property_set_description(oc, MICROVM_MACHINE_PCIE,
"Enable PCIe");
+ object_class_property_add(oc, MICROVM_MACHINE_IOAPIC2, "OnOffAuto",
+ microvm_machine_get_ioapic2,
+ microvm_machine_set_ioapic2,
+ NULL, NULL);
+ object_class_property_set_description(oc, MICROVM_MACHINE_IOAPIC2,
+ "Enable second IO-APIC");
+
object_class_property_add_bool(oc, MICROVM_MACHINE_ISA_SERIAL,
microvm_machine_get_isa_serial,
microvm_machine_set_isa_serial);