diff --git a/sys/amd64/acpica/madt.c b/sys/amd64/acpica/madt.c index 34ee38720000..a88d183d9746 100644 --- a/sys/amd64/acpica/madt.c +++ b/sys/amd64/acpica/madt.c @@ -367,7 +367,7 @@ madt_setup_io(void) } /* First, we run through adding I/O APIC's. */ - if (madt->PCATCompat) + if (madt->PCATCompat && !(acpi_quirks & ACPI_Q_MADT_IRQ0)) ioapic_enable_mixed_mode(); madt_walk_table(madt_parse_apics, NULL); @@ -596,8 +596,14 @@ madt_parse_interrupt_override(MADT_INTERRUPT_OVERRIDE *intr) enum intr_polarity pol; char buf[64]; + if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->Source == 0 && + intr->Interrupt == 2) { + if (bootverbose) + printf("MADT: Skipping timer override\n"); + return; + } if (bootverbose) - printf("MADT: intr override: source %u, irq %u\n", + printf("MADT: Interrupt override: source %u, irq %u\n", intr->Source, intr->Interrupt); KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero")); if (madt_find_interrupt(intr->Interrupt, &new_ioapic, diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index 4478252b6fd8..fc800e5cdcee 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -160,11 +160,20 @@ extern struct mtx acpi_mutex; #define ACPI_INTR_APIC 1 #define ACPI_INTR_SAPIC 2 -/* Quirk flags. */ +/* + * Quirk flags. + * + * ACPI_Q_BROKEN: Disables all ACPI support. + * ACPI_Q_TIMER: Disables support for the ACPI timer. + * ACPI_Q_MADT_IRQ0: Specifies that ISA IRQ 0 is wired up to pin 0 of the + * first APIC and that the MADT should force that by ignoring the PC-AT + * compatible flag and ignoring overrides that redirect IRQ 0 to pin 2. + */ extern int acpi_quirks; #define ACPI_Q_OK 0 -#define ACPI_Q_BROKEN (1 << 0) /* Disable ACPI completely. */ -#define ACPI_Q_TIMER (1 << 1) /* Disable ACPI timer. */ +#define ACPI_Q_BROKEN (1 << 0) +#define ACPI_Q_TIMER (1 << 1) +#define ACPI_Q_MADT_IRQ0 (1 << 2) /* * Note that the low ivar values are reserved to provide diff --git a/sys/i386/acpica/madt.c b/sys/i386/acpica/madt.c index 43a0a885402a..22598e0f52bd 100644 --- a/sys/i386/acpica/madt.c +++ b/sys/i386/acpica/madt.c @@ -367,7 +367,7 @@ madt_setup_io(void) } /* First, we run through adding I/O APIC's. */ - if (madt->PCATCompat) + if (madt->PCATCompat && !(acpi_quirks & ACPI_Q_MADT_IRQ0)) ioapic_enable_mixed_mode(); madt_walk_table(madt_parse_apics, NULL); @@ -595,8 +595,14 @@ madt_parse_interrupt_override(MADT_INTERRUPT_OVERRIDE *intr) enum intr_polarity pol; char buf[64]; + if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->Source == 0 && + intr->Interrupt == 2) { + if (bootverbose) + printf("MADT: Skipping timer override\n"); + return; + } if (bootverbose) - printf("MADT: intr override: source %u, irq %u\n", + printf("MADT: Interrupt override: source %u, irq %u\n", intr->Source, intr->Interrupt); KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero")); if (madt_find_interrupt(intr->Interrupt, &new_ioapic,