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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user