Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151084308
D26470.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D26470.id.diff
View Options
Index: head/sys/amd64/amd64/initcpu.c
===================================================================
--- head/sys/amd64/amd64/initcpu.c
+++ head/sys/amd64/amd64/initcpu.c
@@ -69,6 +69,23 @@
uint64_t msr;
/*
+ * C1E renders the local APIC timer dead, so we disable it by
+ * reading the Interrupt Pending Message register and clearing
+ * both C1eOnCmpHalt (bit 28) and SmiOnCmpHalt (bit 27).
+ *
+ * Reference:
+ * "BIOS and Kernel Developer's Guide for AMD NPT Family 0Fh Processors"
+ * #32559 revision 3.00+
+ *
+ * Detect the presence of C1E capability mostly on latest
+ * dual-cores (or future) k8 family. Affected models range is
+ * taken from Linux sources.
+ */
+ if ((CPUID_TO_FAMILY(cpu_id) == 0xf ||
+ CPUID_TO_FAMILY(cpu_id) == 0x10) && (cpu_feature2 & CPUID2_HV) == 0)
+ cpu_amdc1e_bug = 1;
+
+ /*
* Work around Erratum 721 for Family 10h and 12h processors.
* These processors may incorrectly update the stack pointer
* after a long series of push and/or near-call instructions,
Index: head/sys/amd64/amd64/machdep.c
===================================================================
--- head/sys/amd64/amd64/machdep.c
+++ head/sys/amd64/amd64/machdep.c
@@ -1928,8 +1928,6 @@
if (env != NULL)
strlcpy(kernelname, env, sizeof(kernelname));
- cpu_probe_amdc1e();
-
kcsan_cpu_init(0);
#ifdef FDT
Index: head/sys/i386/i386/initcpu.c
===================================================================
--- head/sys/i386/i386/initcpu.c
+++ head/sys/i386/i386/initcpu.c
@@ -720,8 +720,8 @@
break;
}
break;
-#ifdef CPU_ATHLON_SSE_HACK
case CPU_VENDOR_AMD:
+#ifdef CPU_ATHLON_SSE_HACK
/*
* Sometimes the BIOS doesn't enable SSE instructions.
* According to AMD document 20734, the mobile
@@ -738,8 +738,16 @@
do_cpuid(1, regs);
cpu_feature = regs[3];
}
- break;
#endif
+ /*
+ * Detect C1E that breaks APIC. See comment in
+ * amd64/initcpu.c.
+ */
+ if ((CPUID_TO_FAMILY(cpu_id) == 0xf ||
+ CPUID_TO_FAMILY(cpu_id) == 0x10) &&
+ (cpu_feature2 & CPUID2_HV) == 0)
+ cpu_amdc1e_bug = 1;
+ break;
case CPU_VENDOR_CENTAUR:
init_via();
break;
Index: head/sys/i386/i386/machdep.c
===================================================================
--- head/sys/i386/i386/machdep.c
+++ head/sys/i386/i386/machdep.c
@@ -2505,8 +2505,6 @@
thread0.td_pcb->pcb_ext = 0;
thread0.td_frame = &proc0_tf;
- cpu_probe_amdc1e();
-
#ifdef FDT
x86_init_fdt();
#endif
Index: head/sys/x86/include/specialreg.h
===================================================================
--- head/sys/x86/include/specialreg.h
+++ head/sys/x86/include/specialreg.h
@@ -1126,6 +1126,7 @@
#define MSR_NB_CFG1 0xc001001f /* NB configuration 1 */
#define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */
#define MSR_MC0_CTL_MASK 0xc0010044
+#define MSR_AMDK8_IPM 0xc0010055
#define MSR_P_STATE_LIMIT 0xc0010061 /* P-state Current Limit Register */
#define MSR_P_STATE_CONTROL 0xc0010062 /* P-state Control Register */
#define MSR_P_STATE_STATUS 0xc0010063 /* P-state Status Register */
@@ -1142,6 +1143,9 @@
/* MSR_VM_CR related */
#define VM_CR_SVMDIS 0x10 /* SVM: disabled by BIOS */
+
+#define AMDK8_SMIONCMPHALT (1ULL << 27)
+#define AMDK8_C1EONCMPHALT (1ULL << 28)
/* VIA ACE crypto featureset: for via_feature_rng */
#define VIA_HAS_RNG 1 /* cpu has RNG */
Index: head/sys/x86/include/x86_var.h
===================================================================
--- head/sys/x86/include/x86_var.h
+++ head/sys/x86/include/x86_var.h
@@ -94,6 +94,7 @@
extern int x86_taa_enable;
extern int cpu_flush_rsb_ctxsw;
extern int x86_rngds_mitg_enable;
+extern int cpu_amdc1e_bug;
struct pcb;
struct thread;
Index: head/sys/x86/x86/cpu_machdep.c
===================================================================
--- head/sys/x86/x86/cpu_machdep.c
+++ head/sys/x86/x86/cpu_machdep.c
@@ -486,7 +486,9 @@
}
void (*cpu_idle_hook)(sbintime_t) = NULL; /* ACPI idle hook. */
-static int cpu_ident_amdc1e = 0; /* AMD C1E supported. */
+
+int cpu_amdc1e_bug = 0; /* AMD C1E APIC workaround required. */
+
static int idle_mwait = 1; /* Use MONITOR/MWAIT for short idle. */
SYSCTL_INT(_machdep, OID_AUTO, idle_mwait, CTLFLAG_RWTUN, &idle_mwait,
0, "Use MONITOR/MWAIT for short idle");
@@ -587,35 +589,6 @@
}
}
-/*
- * C1E renders the local APIC timer dead, so we disable it by
- * reading the Interrupt Pending Message register and clearing
- * both C1eOnCmpHalt (bit 28) and SmiOnCmpHalt (bit 27).
- *
- * Reference:
- * "BIOS and Kernel Developer's Guide for AMD NPT Family 0Fh Processors"
- * #32559 revision 3.00+
- */
-#define MSR_AMDK8_IPM 0xc0010055
-#define AMDK8_SMIONCMPHALT (1ULL << 27)
-#define AMDK8_C1EONCMPHALT (1ULL << 28)
-#define AMDK8_CMPHALT (AMDK8_SMIONCMPHALT | AMDK8_C1EONCMPHALT)
-
-void
-cpu_probe_amdc1e(void)
-{
-
- /*
- * Detect the presence of C1E capability mostly on latest
- * dual-cores (or future) k8 family.
- */
- if (cpu_vendor_id == CPU_VENDOR_AMD &&
- (cpu_id & 0x00000f00) == 0x00000f00 &&
- (cpu_id & 0x0fff0000) >= 0x00040000) {
- cpu_ident_amdc1e = 1;
- }
-}
-
void (*cpu_idle_fn)(sbintime_t) = cpu_idle_acpi;
void
@@ -645,10 +618,11 @@
}
/* Apply AMD APIC timer C1E workaround. */
- if (cpu_ident_amdc1e && cpu_disable_c3_sleep) {
+ if (cpu_amdc1e_bug && cpu_disable_c3_sleep) {
msr = rdmsr(MSR_AMDK8_IPM);
- if (msr & AMDK8_CMPHALT)
- wrmsr(MSR_AMDK8_IPM, msr & ~AMDK8_CMPHALT);
+ if ((msr & (AMDK8_SMIONCMPHALT | AMDK8_C1EONCMPHALT)) != 0)
+ wrmsr(MSR_AMDK8_IPM, msr & ~(AMDK8_SMIONCMPHALT |
+ AMDK8_C1EONCMPHALT));
}
/* Call main idle method. */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Apr 6, 9:33 PM (1 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30999862
Default Alt Text
D26470.id.diff (5 KB)
Attached To
Mode
D26470: Limit workaround for errata E400 to appropriate AMD cpus.
Attached
Detach File
Event Timeline
Log In to Comment