mirror of
https://github.com/opnsense/src.git
synced 2026-02-19 02:30:08 -05:00
acpi: Narrow workaround for broken interrupt settings on x86
Commit 9a7bf07ccd 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)
This commit is contained in:
parent
12f2e9525b
commit
4ba4cfaf9f
4 changed files with 42 additions and 8 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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) ?
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue