Port-amd64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

workaround intel apollo lake errata



Hi,

Currently Apollo Lake CPUs fail to boot with SMP enabled.[1]
This is because we use MONITOR/MWAIT with interrupts disabled for
waiting for secondary CPUs to hatch.
Errata means the wakeup doesn't happen.[2]

I've written the attached patch, and tested it by matching my existing
CPU which doesn't have this problem. I see monitor is disabled early
enough.

Due to the first patch failing I know this means that ACPI C FFH won't
be used[3][4]. I suspect this use is safer because it is with interrupts
enabled.

(I'm not sure how to name the MISC_ENABLES register value thing)

Is this diff acceptable?

[1]
https://mail-index.netbsd.org/netbsd-users/2018/06/25/msg021006.html

[2] https://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/pentium-celeron-n-series-j-series-datasheet-spec-update.pdf

APL30   A Store Instruction May Not Wake up MWAIT
Problem :
One use of the MONITOR/MWAIT instruction pair is to allow a logical
processor to wait in a sleep state until a store to the armed address
range occurs. Due to this erratum,
stores to the armed address range may not trigger MWAIT to resume execution.
Implication :
The logical processor that executed the MWAIT instruction may not resume execution
until it receives an interrupt. Software that does not rely on stores to
the armed address range to wake a logical processor from an MWAIT sleep state is
not affected
by this erratum.
Workaround :
Software needs to use interrupts to wake processors from MWAIT-induced
sleep states.

[3] https://nxr.netbsd.org/xref/src/sys/arch/x86/acpi/acpi_cpu_md.c#404
[4] https://nxr.netbsd.org/xref/src/sys/arch/x86/acpi/acpi_cpu_md.c#157
Index: x86/include/specialreg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/specialreg.h,v
retrieving revision 1.126
diff -u -r1.126 specialreg.h
--- x86/include/specialreg.h	31 May 2018 03:29:01 -0000	1.126
+++ x86/include/specialreg.h	1 Jul 2018 08:20:47 -0000
@@ -683,6 +683,7 @@
 #define MSR_THERM_STATUS	0x19c
 #define MSR_THERM2_CTL		0x19d	/* Pentium M */
 #define MSR_MISC_ENABLE		0x1a0
+#define 	IA32_MISC_MWAIT_EN	0x40000
 #define MSR_TEMPERATURE_TARGET	0x1a2
 #define MSR_DEBUGCTLMSR		0x1d9
 #define MSR_LASTBRANCHFROMIP	0x1db
Index: x86/x86/identcpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/identcpu.c,v
retrieving revision 1.77
diff -u -r1.77 identcpu.c
--- x86/x86/identcpu.c	23 Jun 2018 10:30:22 -0000	1.77
+++ x86/x86/identcpu.c	1 Jul 2018 08:20:47 -0000
@@ -190,6 +190,23 @@
 }
 
 static void
+cpu_probe_intel_errata(struct cpu_info *ci)
+{
+        u_int family, model, stepping;
+
+        family = CPUID_TO_FAMILY(ci->ci_signature);
+        model = CPUID_TO_MODEL(ci->ci_signature);
+        stepping = CPUID_TO_STEPPING(ci->ci_signature);
+
+	if (family == 0x6 && model == 0xC && stepping == 0x9) {
+		/* APL30 - A Store Instruction May Not Wake up MWAIT */
+		wrmsr(MSR_MISC_ENABLE, rdmsr(MSR_MISC_ENABLE) & ~IA32_MISC_MWAIT_EN);
+		cpu_feature[1] &= ~CPUID2_MONITOR;
+		ci->ci_feat_val[1] &= ~CPUID2_MONITOR;
+	}
+}
+
+static void
 cpu_probe_intel(struct cpu_info *ci)
 {
 
@@ -197,6 +214,7 @@
 		return;
 
 	cpu_probe_intel_cache(ci);
+	cpu_probe_intel_errata(ci);
 }
 
 static void


Home | Main Index | Thread Index | Old Index