Author: kib
Date: Wed Oct 21 15:04:12 2020
New Revision: 366909
URL: https://svnweb.freebsd.org/changeset/base/366909

Log:
  MFC r366712:
  Limit workaround for errata E400 to appropriate AMD cpus.

Modified:
  stable/12/sys/amd64/amd64/initcpu.c
  stable/12/sys/amd64/amd64/machdep.c
  stable/12/sys/i386/i386/initcpu.c
  stable/12/sys/i386/i386/machdep.c
  stable/12/sys/x86/include/specialreg.h
  stable/12/sys/x86/include/x86_var.h
  stable/12/sys/x86/x86/cpu_machdep.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/amd64/amd64/initcpu.c
==============================================================================
--- stable/12/sys/amd64/amd64/initcpu.c Wed Oct 21 15:01:33 2020        
(r366908)
+++ stable/12/sys/amd64/amd64/initcpu.c Wed Oct 21 15:04:12 2020        
(r366909)
@@ -69,6 +69,23 @@ init_amd(void)
        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,

Modified: stable/12/sys/amd64/amd64/machdep.c
==============================================================================
--- stable/12/sys/amd64/amd64/machdep.c Wed Oct 21 15:01:33 2020        
(r366908)
+++ stable/12/sys/amd64/amd64/machdep.c Wed Oct 21 15:04:12 2020        
(r366909)
@@ -1910,8 +1910,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
        if (env != NULL)
                strlcpy(kernelname, env, sizeof(kernelname));
 
-       cpu_probe_amdc1e();
-
 #ifdef FDT
        x86_init_fdt();
 #endif

Modified: stable/12/sys/i386/i386/initcpu.c
==============================================================================
--- stable/12/sys/i386/i386/initcpu.c   Wed Oct 21 15:01:33 2020        
(r366908)
+++ stable/12/sys/i386/i386/initcpu.c   Wed Oct 21 15:04:12 2020        
(r366909)
@@ -721,8 +721,8 @@ initializecpu(void)
                                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
@@ -739,8 +739,16 @@ initializecpu(void)
                                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;

Modified: stable/12/sys/i386/i386/machdep.c
==============================================================================
--- stable/12/sys/i386/i386/machdep.c   Wed Oct 21 15:01:33 2020        
(r366908)
+++ stable/12/sys/i386/i386/machdep.c   Wed Oct 21 15:04:12 2020        
(r366909)
@@ -2518,8 +2518,6 @@ init386(int first)
        thread0.td_pcb->pcb_ext = 0;
        thread0.td_frame = &proc0_tf;
 
-       cpu_probe_amdc1e();
-
 #ifdef FDT
        x86_init_fdt();
 #endif

Modified: stable/12/sys/x86/include/specialreg.h
==============================================================================
--- stable/12/sys/x86/include/specialreg.h      Wed Oct 21 15:01:33 2020        
(r366908)
+++ stable/12/sys/x86/include/specialreg.h      Wed Oct 21 15:04:12 2020        
(r366909)
@@ -1078,6 +1078,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 */
@@ -1093,6 +1094,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 */

Modified: stable/12/sys/x86/include/x86_var.h
==============================================================================
--- stable/12/sys/x86/include/x86_var.h Wed Oct 21 15:01:33 2020        
(r366908)
+++ stable/12/sys/x86/include/x86_var.h Wed Oct 21 15:04:12 2020        
(r366909)
@@ -89,6 +89,7 @@ extern        int     hw_ssb_active;
 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;

Modified: stable/12/sys/x86/x86/cpu_machdep.c
==============================================================================
--- stable/12/sys/x86/x86/cpu_machdep.c Wed Oct 21 15:01:33 2020        
(r366908)
+++ stable/12/sys/x86/x86/cpu_machdep.c Wed Oct 21 15:04:12 2020        
(r366909)
@@ -485,7 +485,9 @@ cpu_mwait_usable(void)
 }
 
 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");
@@ -586,35 +588,6 @@ cpu_idle_spin(sbintime_t sbt)
        }
 }
 
-/*
- * 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
@@ -644,10 +617,11 @@ cpu_idle(int busy)
        }
 
        /* 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. */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to