summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/acpi/acpi.c20
-rw-r--r--src/include/acpi/acpi.h1
2 files changed, 21 insertions, 0 deletions
diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c
index e211558f62..3ddb1d02ed 100644
--- a/src/acpi/acpi.c
+++ b/src/acpi/acpi.c
@@ -30,6 +30,10 @@
#include <types.h>
#include <version.h>
+#if ENV_X86
+#include <arch/ioapic.h>
+#endif
+
static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp);
u8 acpi_checksum(u8 *table, u32 length)
@@ -180,6 +184,22 @@ int acpi_create_madt_ioapic(acpi_madt_ioapic_t *ioapic, u8 id, u32 addr,
return ioapic->length;
}
+#if ENV_X86
+/* For a system with multiple I/O APICs it's required that the one potentially
+ routing i8259 via ExtNMI delivery calls this first to get GSI #0. */
+int acpi_create_madt_ioapic_from_hw(acpi_madt_ioapic_t *ioapic, u32 addr)
+{
+ static u32 gsi_base;
+ u32 my_base;
+ u8 id = get_ioapic_id((void *)(uintptr_t)addr);
+ u8 count = ioapic_get_max_vectors((void *)(uintptr_t)addr);
+
+ my_base = gsi_base;
+ gsi_base += count;
+ return acpi_create_madt_ioapic(ioapic, id, addr, my_base);
+}
+#endif
+
int acpi_create_madt_irqoverride(acpi_madt_irqoverride_t *irqoverride,
u8 bus, u8 source, u32 gsirq, u16 flags)
{
diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h
index 286ebface8..d7fc243c11 100644
--- a/src/include/acpi/acpi.h
+++ b/src/include/acpi/acpi.h
@@ -1263,6 +1263,7 @@ void acpi_add_table(acpi_rsdp_t *rsdp, void *table);
int acpi_create_madt_lapic(acpi_madt_lapic_t *lapic, u8 cpu, u8 apic);
int acpi_create_madt_ioapic(acpi_madt_ioapic_t *ioapic, u8 id, u32 addr,
u32 gsi_base);
+int acpi_create_madt_ioapic_from_hw(acpi_madt_ioapic_t *ioapic, u32 addr);
int acpi_create_madt_irqoverride(acpi_madt_irqoverride_t *irqoverride,
u8 bus, u8 source, u32 gsirq, u16 flags);
int acpi_create_madt_lapic_nmi(acpi_madt_lapic_nmi_t *lapic_nmi, u8 cpu,