git: 4ba4cfaf9f29 - stable/14 - acpi: Narrow workaround for broken interrupt settings on x86
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 22 Jul 2024 20:59:19 UTC
The branch stable/14 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=4ba4cfaf9f2991fea0d438e915df8b681a47facf commit 4ba4cfaf9f2991fea0d438e915df8b681a47facf Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2024-07-15 19:13:08 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2024-07-22 19:54:14 +0000 acpi: Narrow workaround for broken interrupt settings on x86 Commit 9a7bf07ccdc1 from 2016 introduced a workaround for some broken BIOSes that specified active-lo instead of active-hi polarity for ISA IRQs for UARTs. The workaround assumed that edge-sensitive ISA IRQs on x86 should always be active-hi. However, some recent AMD systems actually use active-lo edge-sensitive ISA IRQs (and not just for UARTs, but also for the keyboard and PS/2 mouse devices) and the override causes interrupts to be dropped resulting in boot time hangs, non-working keyboards, etc. Add a hw.acpi.override_isa_irq_polarity tunable (readable as a sysctl post-boot) to control this quirk. It can be set to 1 to force enable the override and 0 to disable it. The log of original message mentions an Intel motherboard as the sample case, so default the tunable to 1 on systems with an Intel CPU and 0 otherwise. Special thanks to Matthias Lanter <freebsd@lanter-it.ch> for tracking down boot time issues on recent AMD systems to mismatched interrupt polarity. PR: 270707 Reported by: aixdroix_OSS@protonmail.com, Michael Dexter Reported by: mfw_burn@pm.me, Hannes Hfauswedell <h2+fbsdports@fsfe.org> Reported by: Matthias Lanter <freebsd@lanter-it.ch> Reported by: William Bulley <web@umich.edu> Reviewed by: imp, emaste MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D45554 (cherry picked from commit 0a34d050ae8ea14feddd3d2a62fd2f612613b2c5) --- share/man/man4/acpi.4 | 8 +++++++- sys/dev/acpica/acpi.c | 19 +++++++++++++++++++ sys/dev/acpica/acpi_resource.c | 11 ++++------- sys/dev/acpica/acpivar.h | 12 ++++++++++++ 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/share/man/man4/acpi.4 b/share/man/man4/acpi.4 index 434e97d529f5..cdad3ceeedfc 100644 --- a/share/man/man4/acpi.4 +++ b/share/man/man4/acpi.4 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd October 12, 2021 +.Dd July 15, 2024 .Dt ACPI 4 .Os .Sh NAME @@ -256,6 +256,12 @@ is a valid list of two interfaces .Qq Li FreeBSD and .Qq Li Linux . +.It Va hw.acpi.hw.acpi.override_isa_irq_polarity (x86) +Forces active-lo polarity for edge-triggered ISA interrupts. +Some older systems incorrectly specify active-lo polarity for ISA +interrupts and this override fixes those systems. +This override is enabled by default on systems with Intel CPUs, +but can be enabled or disabled by setting the tunable explicitly. .It Va hw.acpi.reset_video Enables calling the VESA reset BIOS vector on the resume path. This can fix some graphics cards that have problems such as LCD white-out diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 0894f4464162..71b19067707b 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -55,6 +55,8 @@ #if defined(__i386__) || defined(__amd64__) #include <machine/clock.h> #include <machine/pci_cfgreg.h> +#include <x86/cputypes.h> +#include <x86/x86_var.h> #endif #include <machine/resource.h> #include <machine/bus.h> @@ -289,6 +291,10 @@ int acpi_susp_bounce; SYSCTL_INT(_debug_acpi, OID_AUTO, suspend_bounce, CTLFLAG_RW, &acpi_susp_bounce, 0, "Don't actually suspend, just test devices."); +#if defined(__amd64__) || defined(__i386__) +int acpi_override_isa_irq_polarity; +#endif + /* * ACPI standard UUID for Device Specific Data Package * "Device Properties UUID for _DSD" Rev. 2.0 @@ -601,6 +607,19 @@ acpi_attach(device_t dev) OID_AUTO, "handle_reboot", CTLFLAG_RW, &sc->acpi_handle_reboot, 0, "Use ACPI Reset Register to reboot"); +#if defined(__amd64__) || defined(__i386__) + /* + * Enable workaround for incorrect ISA IRQ polarity by default on + * systems with Intel CPUs. + */ + if (cpu_vendor_id == CPU_VENDOR_INTEL) + acpi_override_isa_irq_polarity = 1; + SYSCTL_ADD_INT(&sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(sc->acpi_sysctl_tree), + OID_AUTO, "override_isa_irq_polarity", CTLFLAG_RDTUN, + &acpi_override_isa_irq_polarity, 0, + "Force active-hi polarity for edge-triggered ISA IRQs"); +#endif + /* * Default to 1 second before sleeping to give some machines time to * stabilize. diff --git a/sys/dev/acpica/acpi_resource.c b/sys/dev/acpica/acpi_resource.c index e17b891d7974..8d81d61989a8 100644 --- a/sys/dev/acpica/acpi_resource.c +++ b/sys/dev/acpica/acpi_resource.c @@ -159,14 +159,11 @@ acpi_config_intr(device_t dev, ACPI_RESOURCE *res) } #if defined(__amd64__) || defined(__i386__) - /* - * XXX: Certain BIOSes have buggy AML that specify an IRQ that is - * edge-sensitive and active-lo. However, edge-sensitive IRQs - * should be active-hi. Force IRQs with an ISA IRQ value to be - * active-hi instead. - */ - if (irq < 16 && trig == ACPI_EDGE_SENSITIVE && pol == ACPI_ACTIVE_LOW) + if (irq < 16 && trig == ACPI_EDGE_SENSITIVE && pol == ACPI_ACTIVE_LOW && + acpi_override_isa_irq_polarity) { + device_printf(dev, "forcing active-hi polarity for IRQ %u\n", irq); pol = ACPI_ACTIVE_HIGH; + } #endif BUS_CONFIG_INTR(dev, irq, (trig == ACPI_EDGE_SENSITIVE) ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, (pol == ACPI_ACTIVE_HIGH) ? diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index bb969821b945..afb0a6909e1a 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -231,6 +231,18 @@ extern int acpi_quirks; #define ACPI_Q_TIMER (1 << 1) #define ACPI_Q_MADT_IRQ0 (1 << 2) +#if defined(__amd64__) || defined(__i386__) +/* + * Certain Intel BIOSes have buggy AML that specify an IRQ that is + * edge-sensitive and active-lo. Normally, edge-sensitive IRQs should + * be active-hi. If this value is non-zero, edge-sensitive ISA IRQs + * are forced to be active-hi instead. At least some AMD systems use + * active-lo edge-sensitive ISA IRQs, so this setting is only enabled + * by default on systems with Intel CPUs. + */ +extern int acpi_override_isa_irq_polarity; +#endif + /* * Plug and play information for device matching. Matching table format * is compatible with ids parameter of ACPI_ID_PROBE bus method.