x86: add support for second ioapic
Add ioapic_init_secondary to initialize it, wire up in gsi handling and acpi apic table creation. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Sergio Lopez <slp@redhat.com> Message-id: 20201203105423.10431-4-kraxel@redhat.com
This commit is contained in:
parent
ceea95cd88
commit
94c5a60637
@ -103,6 +103,16 @@ void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
|
|||||||
io_apic->address = cpu_to_le32(IO_APIC_DEFAULT_ADDRESS);
|
io_apic->address = cpu_to_le32(IO_APIC_DEFAULT_ADDRESS);
|
||||||
io_apic->interrupt = cpu_to_le32(0);
|
io_apic->interrupt = cpu_to_le32(0);
|
||||||
|
|
||||||
|
if (x86ms->ioapic2) {
|
||||||
|
AcpiMadtIoApic *io_apic2;
|
||||||
|
io_apic2 = acpi_data_push(table_data, sizeof *io_apic);
|
||||||
|
io_apic2->type = ACPI_APIC_IO;
|
||||||
|
io_apic2->length = sizeof(*io_apic);
|
||||||
|
io_apic2->io_apic_id = ACPI_BUILD_IOAPIC_ID + 1;
|
||||||
|
io_apic2->address = cpu_to_le32(IO_APIC_SECONDARY_ADDRESS);
|
||||||
|
io_apic2->interrupt = cpu_to_le32(IO_APIC_SECONDARY_IRQBASE);
|
||||||
|
}
|
||||||
|
|
||||||
if (x86ms->apic_xrupt_override) {
|
if (x86ms->apic_xrupt_override) {
|
||||||
intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);
|
intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);
|
||||||
intsrcovr->type = ACPI_APIC_XRUPT_OVERRIDE;
|
intsrcovr->type = ACPI_APIC_XRUPT_OVERRIDE;
|
||||||
|
@ -598,6 +598,10 @@ void gsi_handler(void *opaque, int n, int level)
|
|||||||
case ISA_NUM_IRQS ... IOAPIC_NUM_PINS - 1:
|
case ISA_NUM_IRQS ... IOAPIC_NUM_PINS - 1:
|
||||||
qemu_set_irq(s->ioapic_irq[n], level);
|
qemu_set_irq(s->ioapic_irq[n], level);
|
||||||
break;
|
break;
|
||||||
|
case IO_APIC_SECONDARY_IRQBASE
|
||||||
|
... IO_APIC_SECONDARY_IRQBASE + IOAPIC_NUM_PINS - 1:
|
||||||
|
qemu_set_irq(s->ioapic2_irq[n - IO_APIC_SECONDARY_IRQBASE], level);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,6 +628,23 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeviceState *ioapic_init_secondary(GSIState *gsi_state)
|
||||||
|
{
|
||||||
|
DeviceState *dev;
|
||||||
|
SysBusDevice *d;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
dev = qdev_new(TYPE_IOAPIC);
|
||||||
|
d = SYS_BUS_DEVICE(dev);
|
||||||
|
sysbus_realize_and_unref(d, &error_fatal);
|
||||||
|
sysbus_mmio_map(d, 0, IO_APIC_SECONDARY_ADDRESS);
|
||||||
|
|
||||||
|
for (i = 0; i < IOAPIC_NUM_PINS; i++) {
|
||||||
|
gsi_state->ioapic2_irq[i] = qdev_get_gpio_in(dev, i);
|
||||||
|
}
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
struct setup_data {
|
struct setup_data {
|
||||||
uint64_t next;
|
uint64_t next;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#define IOAPIC_NUM_PINS 24
|
#define IOAPIC_NUM_PINS 24
|
||||||
#define IO_APIC_DEFAULT_ADDRESS 0xfec00000
|
#define IO_APIC_DEFAULT_ADDRESS 0xfec00000
|
||||||
|
#define IO_APIC_SECONDARY_ADDRESS (IO_APIC_DEFAULT_ADDRESS + 0x10000)
|
||||||
|
#define IO_APIC_SECONDARY_IRQBASE 24 /* primary 0 -> 23, secondary 24 -> 47 */
|
||||||
|
|
||||||
#define TYPE_KVM_IOAPIC "kvm-ioapic"
|
#define TYPE_KVM_IOAPIC "kvm-ioapic"
|
||||||
#define TYPE_IOAPIC "ioapic"
|
#define TYPE_IOAPIC "ioapic"
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "qemu/notify.h"
|
#include "qemu/notify.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
|
|
||||||
#define MAX_IOAPICS 1
|
#define MAX_IOAPICS 2
|
||||||
|
|
||||||
#define IOAPIC_LVT_DEST_SHIFT 56
|
#define IOAPIC_LVT_DEST_SHIFT 56
|
||||||
#define IOAPIC_LVT_DEST_IDX_SHIFT 48
|
#define IOAPIC_LVT_DEST_IDX_SHIFT 48
|
||||||
|
@ -50,6 +50,7 @@ struct X86MachineState {
|
|||||||
ISADevice *rtc;
|
ISADevice *rtc;
|
||||||
FWCfgState *fw_cfg;
|
FWCfgState *fw_cfg;
|
||||||
qemu_irq *gsi;
|
qemu_irq *gsi;
|
||||||
|
DeviceState *ioapic2;
|
||||||
GMappedFile *initrd_mapped_file;
|
GMappedFile *initrd_mapped_file;
|
||||||
HotplugHandler *acpi_dev;
|
HotplugHandler *acpi_dev;
|
||||||
|
|
||||||
@ -120,10 +121,12 @@ bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms);
|
|||||||
typedef struct GSIState {
|
typedef struct GSIState {
|
||||||
qemu_irq i8259_irq[ISA_NUM_IRQS];
|
qemu_irq i8259_irq[ISA_NUM_IRQS];
|
||||||
qemu_irq ioapic_irq[IOAPIC_NUM_PINS];
|
qemu_irq ioapic_irq[IOAPIC_NUM_PINS];
|
||||||
|
qemu_irq ioapic2_irq[IOAPIC_NUM_PINS];
|
||||||
} GSIState;
|
} GSIState;
|
||||||
|
|
||||||
qemu_irq x86_allocate_cpu_irq(void);
|
qemu_irq x86_allocate_cpu_irq(void);
|
||||||
void gsi_handler(void *opaque, int n, int level);
|
void gsi_handler(void *opaque, int n, int level);
|
||||||
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
|
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
|
||||||
|
DeviceState *ioapic_init_secondary(GSIState *gsi_state);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user