hv: Handle holes in GSI i.e. Global System Interrupt for multiple IO-APICs

MADT is used to specify the GSI base for each IO-APIC and the number of
interrupt pins per IO-APIC is programmed into Max. Redir. Entry register of
that IO-APIC.

On platforms with multiple IO-APICs, there can be holes in the GSI space.
For example, on a platform with 2 IO-APICs, the following configuration has
a hole (from 24 to 31) in the GSI space.

IO-APIC 1: GSI base - 0, number of pins - 24
IO-APIC 2: GSI base - 32, number of pins - 8

This patch also adjusts the size for variables used to represent the total
number of IO-APICs on the system from uint16_t to uint8_t as the ACPI MADT
uses only 8-bits to indicate the unique IO-APIC IDs.

Tracked-On: #4151
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
Sainath Grandhi
2020-02-24 17:02:41 -08:00
committed by wenlingz
parent 85217e362f
commit f67ac09141
7 changed files with 124 additions and 135 deletions

View File

@@ -21,8 +21,8 @@ struct ioapic_info {
void ioapic_setup_irqs(void);
bool ioapic_irq_is_gsi(uint32_t irq);
uint32_t ioapic_irq_to_pin(uint32_t irq);
bool is_ioapic_irq(uint32_t irq);
uint32_t gsi_to_ioapic_pin(uint32_t gsi);
int32_t init_ioapic_id_info(void);
uint8_t ioapic_irq_to_ioapic_id(uint32_t irq);
@@ -88,15 +88,26 @@ void ioapic_gsi_unmask_irq(uint32_t irq);
void ioapic_get_rte_entry(void *ioapic_base, uint32_t pin, union ioapic_rte *rte);
/*
* is_valid is by default false when all the
* static variables, part of .bss, are initialized to 0s
* It is set to true, if the corresponding
* gsi falls in ranges identified by IOAPIC data
* in ACPI MADT in ioapic_setup_irqs.
*/
struct gsi_table {
uint8_t ioapic_id;
uint32_t pin;
void *addr;
bool is_valid;
struct {
uint8_t acpi_id;
uint8_t index;
uint32_t pin;
void *base_addr;
} ioapic_info;
};
void *gsi_to_ioapic_base(uint32_t gsi);
uint32_t ioapic_get_nr_gsi(void);
uint32_t get_max_nr_gsi(void);
uint32_t get_pic_pin_from_ioapic_pin(uint32_t pin_index);
bool ioapic_is_pin_valid(uint32_t pin);
bool is_gsi_valid(uint32_t gsi);
#endif /* IOAPIC_H */