amd64/187966: Intel Baytrail-M NUC panics because of buggy ACPI table

Takuya ASADA syuu at freebsd.org
Wed Mar 26 18:10:01 UTC 2014


>Number:         187966
>Category:       amd64
>Synopsis:       Intel Baytrail-M NUC panics because of buggy ACPI table
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-amd64
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Mar 26 18:10:01 UTC 2014
>Closed-Date:
>Last-Modified:
>Originator:     Takuya ASADA
>Release:        -CURRENT
>Organization:
Cloudius Systems
>Environment:
FreeBSD nuc 11.0-CURRENT FreeBSD 11.0-CURRENT #5 ff55131(master)-dirty: Thu Mar 27 09:05:10 JST 2014 root at nuc:/usr/obj/usr/home/syuu/freebsd/sys/GENERIC amd64
>Description:
Intel Baytrail-M NUC(DN2820FYKH) does not able to boot FreeBSD-CURRENT/amd64, because of its buggy ACPI table.

It has two incorrect parameters on MADT: 

Type=Local APIC NMI
ACPI CPU=1
LINT Pin=60
Flags={Polarity=active-hi, Trigger=0x2} <-- trigger value is incorrect. 2 is reserved

Type=Local APIC NMI
ACPI CPU=2
LINT Pin=61
Flags={Polarity=0x2, Trigger=level} <-- polarity value is incorrect. 2 is reserved

Because of this, interrupt_trigger() panics with "Bogus Interrupt Trigger Mode".
Also interrupt_polarity() panics with "Bogus Interrupt Polarity".

I think this is BIOS bug, but we can do some workaround for the machine.
>How-To-Repeat:
Boot -CURRENT on NUC.
>Fix:
Linux uses level trigger and low polarity if the value is 0x2(reserved).
http://lxr.linux.no/linux+v3.13.5/arch/x86/kernel/acpi/boot.c#L1094

We can do similar workaround, but with warning message.

Patch attached with submission follows:

diff --git a/sys/x86/acpica/madt.c b/sys/x86/acpica/madt.c
index 9dfb77f..fdc86c0 100644
--- a/sys/x86/acpica/madt.c
+++ b/sys/x86/acpica/madt.c
@@ -308,14 +308,15 @@ interrupt_polarity(UINT16 IntiFlags, UINT8 Source)
 	case ACPI_MADT_POLARITY_ACTIVE_LOW:
 		return (INTR_POLARITY_LOW);
 	default:
-		panic("Bogus Interrupt Polarity");
+		printf("Bogus Interrupt Polarity %x, set to low\n",
+			IntiFlags & ACPI_MADT_POLARITY_MASK);
+		return (INTR_POLARITY_LOW);
 	}
 }
 
 static enum intr_trigger
 interrupt_trigger(UINT16 IntiFlags, UINT8 Source)
 {
-
 	switch (IntiFlags & ACPI_MADT_TRIGGER_MASK) {
 	case ACPI_MADT_TRIGGER_CONFORMS:
 		if (Source == AcpiGbl_FADT.SciInterrupt)
@@ -327,7 +328,9 @@ interrupt_trigger(UINT16 IntiFlags, UINT8 Source)
 	case ACPI_MADT_TRIGGER_LEVEL:
 		return (INTR_TRIGGER_LEVEL);
 	default:
-		panic("Bogus Interrupt Trigger Mode");
+		printf("Bogus Interrupt Trigger Mode %x, set to level\n",
+			IntiFlags & ACPI_MADT_TRIGGER_MASK);
+		return (INTR_TRIGGER_LEVEL);
 	}
 }
 


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-amd64 mailing list