mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 19:49:43 +00:00
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->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) {
|
||||
intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);
|
||||
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:
|
||||
qemu_set_irq(s->ioapic_irq[n], level);
|
||||
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 {
|
||||
uint64_t next;
|
||||
uint32_t type;
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
#define IOAPIC_NUM_PINS 24
|
||||
#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_IOAPIC "ioapic"
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "qemu/notify.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define MAX_IOAPICS 1
|
||||
#define MAX_IOAPICS 2
|
||||
|
||||
#define IOAPIC_LVT_DEST_SHIFT 56
|
||||
#define IOAPIC_LVT_DEST_IDX_SHIFT 48
|
||||
|
@ -50,6 +50,7 @@ struct X86MachineState {
|
||||
ISADevice *rtc;
|
||||
FWCfgState *fw_cfg;
|
||||
qemu_irq *gsi;
|
||||
DeviceState *ioapic2;
|
||||
GMappedFile *initrd_mapped_file;
|
||||
HotplugHandler *acpi_dev;
|
||||
|
||||
@ -120,10 +121,12 @@ bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms);
|
||||
typedef struct GSIState {
|
||||
qemu_irq i8259_irq[ISA_NUM_IRQS];
|
||||
qemu_irq ioapic_irq[IOAPIC_NUM_PINS];
|
||||
qemu_irq ioapic2_irq[IOAPIC_NUM_PINS];
|
||||
} GSIState;
|
||||
|
||||
qemu_irq x86_allocate_cpu_irq(void);
|
||||
void gsi_handler(void *opaque, int n, int level);
|
||||
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
|
||||
DeviceState *ioapic_init_secondary(GSIState *gsi_state);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user