Author: jkim
Date: Mon Jan 12 19:17:35 2009
New Revision: 187109
URL: http://svn.freebsd.org/changeset/base/187109

Log:
  Add basic amd64 support for VIA Nano processors.

Modified:
  head/sys/amd64/amd64/amd64_mem.c
  head/sys/amd64/amd64/identcpu.c
  head/sys/amd64/amd64/initcpu.c
  head/sys/amd64/amd64/msi.c
  head/sys/amd64/include/md_var.h
  head/sys/amd64/include/specialreg.h

Modified: head/sys/amd64/amd64/amd64_mem.c
==============================================================================
--- head/sys/amd64/amd64/amd64_mem.c    Mon Jan 12 19:16:00 2009        
(r187108)
+++ head/sys/amd64/amd64/amd64_mem.c    Mon Jan 12 19:17:35 2009        
(r187109)
@@ -678,9 +678,17 @@ amd64_mem_drvinit(void *unused)
                return;
        if ((cpu_id & 0xf00) != 0x600 && (cpu_id & 0xf00) != 0xf00)
                return;
-       if (cpu_vendor_id != CPU_VENDOR_INTEL &&
-           cpu_vendor_id != CPU_VENDOR_AMD)
+       switch (cpu_vendor_id) {
+       case CPU_VENDOR_INTEL:
+       case CPU_VENDOR_AMD:
+               break;
+       case CPU_VENDOR_CENTAUR:
+               if (cpu_exthigh >= 0x80000008)
+                       break;
+               /* FALLTHROUGH */
+       default:
                return;
+       }
        mem_range_softc.mr_op = &amd64_mrops;
 }
 SYSINIT(amd64memdev, SI_SUB_DRIVERS, SI_ORDER_FIRST, amd64_mem_drvinit, NULL);

Modified: head/sys/amd64/amd64/identcpu.c
==============================================================================
--- head/sys/amd64/amd64/identcpu.c     Mon Jan 12 19:16:00 2009        
(r187108)
+++ head/sys/amd64/amd64/identcpu.c     Mon Jan 12 19:17:35 2009        
(r187109)
@@ -72,6 +72,7 @@ void panicifcpuunsupported(void);
 static u_int find_cpu_vendor_id(void);
 static void print_AMD_info(void);
 static void print_AMD_assoc(int i);
+static void print_via_padlock_info(void);
 
 int    cpu_class;
 char machine[] = "amd64";
@@ -132,24 +133,33 @@ printcpuinfo(void)
                }
        }
 
-       if (cpu_vendor_id == CPU_VENDOR_INTEL) {
+       switch (cpu_vendor_id) {
+       case CPU_VENDOR_INTEL:
                /* Please make up your mind folks! */
                strcat(cpu_model, "EM64T");
-       } else if (cpu_vendor_id == CPU_VENDOR_AMD) {
+               break;
+       case CPU_VENDOR_AMD:
                /*
                 * Values taken from AMD Processor Recognition
                 * http://www.amd.com/K6/k6docs/pdf/20734g.pdf
                 * (also describes ``Features'' encodings.
                 */
                strcpy(cpu_model, "AMD ");
-               switch (cpu_id & 0xF00) {
-               case 0xf00:
+               if ((cpu_id & 0xf00) == 0xf00)
                        strcat(cpu_model, "AMD64 Processor");
-                       break;
-               default:
+               else
                        strcat(cpu_model, "Unknown");
-                       break;
-               }
+               break;
+       case CPU_VENDOR_CENTAUR:
+               strcpy(cpu_model, "VIA ");
+               if ((cpu_id & 0xff0) == 0x6f0)
+                       strcat(cpu_model, "Nano Processor");
+               else
+                       strcat(cpu_model, "Unknown");
+               break;
+       default:
+               strcat(cpu_model, "Unknown");
+               break;
        }
 
        /*
@@ -181,7 +191,8 @@ printcpuinfo(void)
                printf("  Id = 0x%x", cpu_id);
 
        if (cpu_vendor_id == CPU_VENDOR_INTEL ||
-           cpu_vendor_id == CPU_VENDOR_AMD) {
+           cpu_vendor_id == CPU_VENDOR_AMD ||
+           cpu_vendor_id == CPU_VENDOR_CENTAUR) {
                printf("  Stepping = %u", cpu_id & 0xf);
                if (cpu_high > 0) {
                        u_int cmp = 1, htt = 1;
@@ -353,6 +364,9 @@ printcpuinfo(void)
                                );
                        }
 
+                       if (cpu_vendor_id == CPU_VENDOR_CENTAUR)
+                               print_via_padlock_info();
+
                        if ((cpu_feature & CPUID_HTT) &&
                            cpu_vendor_id == CPU_VENDOR_AMD)
                                cpu_feature &= ~CPUID_HTT;
@@ -376,6 +390,11 @@ printcpuinfo(void)
                                    AMD64_CPU_MODEL(cpu_id) >= 0x3))
                                        tsc_is_invariant = 1;
                                break;
+                       case CPU_VENDOR_CENTAUR:
+                               if (AMD64_CPU_FAMILY(cpu_id) == 0x6 &&
+                                   AMD64_CPU_MODEL(cpu_id) >= 0xf)
+                                       tsc_is_invariant = 1;
+                               break;
                        }
                        if (tsc_is_invariant)
                                printf("\n  TSC: P-state invariant");
@@ -457,7 +476,7 @@ EVENTHANDLER_DEFINE(cpufreq_post_change,
     EVENTHANDLER_PRI_ANY);
 
 /*
- * Final stage of CPU identification. -- Should I check TI?
+ * Final stage of CPU identification.
  */
 void
 identify_cpu(void)
@@ -479,7 +498,8 @@ identify_cpu(void)
        cpu_feature2 = regs[2];
 
        if (cpu_vendor_id == CPU_VENDOR_INTEL ||
-           cpu_vendor_id == CPU_VENDOR_AMD) {
+           cpu_vendor_id == CPU_VENDOR_AMD ||
+           cpu_vendor_id == CPU_VENDOR_CENTAUR) {
                do_cpuid(0x80000000, regs);
                cpu_exthigh = regs[0];
        }
@@ -600,3 +620,37 @@ print_AMD_info(void)
                print_AMD_l2_assoc((regs[2] >> 12) & 0x0f);     
        }
 }
+
+static void
+print_via_padlock_info(void)
+{
+       u_int regs[4];
+
+       /* Check for supported models. */
+       switch (cpu_id & 0xff0) {
+       case 0x690:
+               if ((cpu_id & 0xf) < 3)
+                       return;
+       case 0x6a0:
+       case 0x6d0:
+       case 0x6f0:
+               break;
+       default:
+               return;
+       }
+       
+       do_cpuid(0xc0000000, regs);
+       if (regs[0] >= 0xc0000001)
+               do_cpuid(0xc0000001, regs);
+       else
+               return;
+
+       printf("\n  VIA Padlock Features=0x%b", regs[3],
+       "\020"
+       "\003RNG"               /* RNG */
+       "\007AES"               /* ACE */
+       "\011AES-CTR"           /* ACE2 */
+       "\013SHA1,SHA256"       /* PHE */
+       "\015RSA"               /* PMM */
+       );
+}

Modified: head/sys/amd64/amd64/initcpu.c
==============================================================================
--- head/sys/amd64/amd64/initcpu.c      Mon Jan 12 19:16:00 2009        
(r187108)
+++ head/sys/amd64/amd64/initcpu.c      Mon Jan 12 19:17:35 2009        
(r187109)
@@ -54,6 +54,8 @@ u_int cpu_feature2;           /* Feature flags */
 u_int  amd_feature;            /* AMD feature flags */
 u_int  amd_feature2;           /* AMD feature flags */
 u_int  amd_pminfo;             /* AMD advanced power management info */
+u_int  via_feature_rng;        /* VIA RNG features */
+u_int  via_feature_xcrypt;     /* VIA ACE features */
 u_int  cpu_high;               /* Highest arg to CPUID */
 u_int  cpu_exthigh;            /* Highest arg to extended CPUID */
 u_int  cpu_id;                 /* Stepping ID */
@@ -64,6 +66,75 @@ u_int        cpu_vendor_id;          /* CPU vendor ID *
 u_int  cpu_fxsr;               /* SSE enabled */
 u_int  cpu_mxcsr_mask;         /* Valid bits in mxcsr */
 
+SYSCTL_UINT(_hw, OID_AUTO, via_feature_rng, CTLFLAG_RD,
+       &via_feature_rng, 0, "VIA C3/C7 RNG feature available in CPU");
+SYSCTL_UINT(_hw, OID_AUTO, via_feature_xcrypt, CTLFLAG_RD,
+       &via_feature_xcrypt, 0, "VIA C3/C7 xcrypt feature available in CPU");
+
+/*
+ * Initialize special VIA C3/C7 features
+ */
+static void
+init_via(void)
+{
+       u_int regs[4], val;
+       u_int64_t msreg;
+
+       do_cpuid(0xc0000000, regs);
+       val = regs[0];
+       if (val >= 0xc0000001) {
+               do_cpuid(0xc0000001, regs);
+               val = regs[3];
+       } else
+               val = 0;
+
+       /* Enable RNG if present and disabled */
+       if (val & VIA_CPUID_HAS_RNG) {
+               if (!(val & VIA_CPUID_DO_RNG)) {
+                       msreg = rdmsr(0x110B);
+                       msreg |= 0x40;
+                       wrmsr(0x110B, msreg);
+               }
+               via_feature_rng = VIA_HAS_RNG;
+       }
+       /* Enable AES engine if present and disabled */
+       if (val & VIA_CPUID_HAS_ACE) {
+               if (!(val & VIA_CPUID_DO_ACE)) {
+                       msreg = rdmsr(0x1107);
+                       msreg |= (0x01 << 28);
+                       wrmsr(0x1107, msreg);
+               }
+               via_feature_xcrypt |= VIA_HAS_AES;
+       }
+       /* Enable ACE2 engine if present and disabled */
+       if (val & VIA_CPUID_HAS_ACE2) {
+               if (!(val & VIA_CPUID_DO_ACE2)) {
+                       msreg = rdmsr(0x1107);
+                       msreg |= (0x01 << 28);
+                       wrmsr(0x1107, msreg);
+               }
+               via_feature_xcrypt |= VIA_HAS_AESCTR;
+       }
+       /* Enable SHA engine if present and disabled */
+       if (val & VIA_CPUID_HAS_PHE) {
+               if (!(val & VIA_CPUID_DO_PHE)) {
+                       msreg = rdmsr(0x1107);
+                       msreg |= (0x01 << 28/**/);
+                       wrmsr(0x1107, msreg);
+               }
+               via_feature_xcrypt |= VIA_HAS_SHA;
+       }
+       /* Enable MM engine if present and disabled */
+       if (val & VIA_CPUID_HAS_PMM) {
+               if (!(val & VIA_CPUID_DO_PMM)) {
+                       msreg = rdmsr(0x1107);
+                       msreg |= (0x01 << 28/**/);
+                       wrmsr(0x1107, msreg);
+               }
+               via_feature_xcrypt |= VIA_HAS_MM;
+       }
+}
+
 /*
  * Initialize CPU control registers
  */
@@ -81,4 +152,8 @@ initializecpu(void)
                wrmsr(MSR_EFER, msr);
                pg_nx = PG_NX;
        }
+       if (cpu_vendor_id == CPU_VENDOR_CENTAUR &&
+           AMD64_CPU_FAMILY(cpu_id) == 0x6 &&
+           AMD64_CPU_MODEL(cpu_id) >= 0xf)
+               init_via();
 }

Modified: head/sys/amd64/amd64/msi.c
==============================================================================
--- head/sys/amd64/amd64/msi.c  Mon Jan 12 19:16:00 2009        (r187108)
+++ head/sys/amd64/amd64/msi.c  Mon Jan 12 19:17:35 2009        (r187109)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/frame.h>
 #include <machine/intr_machdep.h>
 #include <machine/apicvar.h>
+#include <machine/specialreg.h>
 #include <dev/pci/pcivar.h>
 
 /* Fields in address for Intel MSI messages. */
@@ -212,9 +213,18 @@ msi_init(void)
 {
 
        /* Check if we have a supported CPU. */
-       if (!(cpu_vendor_id == CPU_VENDOR_INTEL ||
-           cpu_vendor_id == CPU_VENDOR_AMD))
+       switch (cpu_vendor_id) {
+       case CPU_VENDOR_INTEL:
+       case CPU_VENDOR_AMD:
+               break;
+       case CPU_VENDOR_CENTAUR:
+               if (AMD64_CPU_FAMILY(cpu_id) == 0x6 &&
+                   AMD64_CPU_MODEL(cpu_id) >= 0xf)
+                       break;
+               /* FALLTHROUGH */
+       default:
                return;
+       }
 
        msi_enabled = 1;
        intr_register_pic(&msi_pic);

Modified: head/sys/amd64/include/md_var.h
==============================================================================
--- head/sys/amd64/include/md_var.h     Mon Jan 12 19:16:00 2009        
(r187108)
+++ head/sys/amd64/include/md_var.h     Mon Jan 12 19:17:35 2009        
(r187109)
@@ -45,6 +45,8 @@ extern        u_int   cpu_feature2;
 extern u_int   amd_feature;
 extern u_int   amd_feature2;
 extern u_int   amd_pminfo;
+extern u_int   via_feature_rng;
+extern u_int   via_feature_xcrypt;
 extern u_int   cpu_fxsr;
 extern u_int   cpu_high;
 extern u_int   cpu_id;

Modified: head/sys/amd64/include/specialreg.h
==============================================================================
--- head/sys/amd64/include/specialreg.h Mon Jan 12 19:16:00 2009        
(r187108)
+++ head/sys/amd64/include/specialreg.h Mon Jan 12 19:17:35 2009        
(r187109)
@@ -459,4 +459,40 @@
 #define        MSR_TOP_MEM2    0xc001001d      /* boundary for ram above 4G */
 #define        MSR_K8_UCODE_UPDATE     0xc0010020      /* update microcode */
 
+/* VIA ACE crypto featureset: for via_feature_rng */
+#define        VIA_HAS_RNG             1       /* cpu has RNG */
+
+/* VIA ACE crypto featureset: for via_feature_xcrypt */
+#define        VIA_HAS_AES             1       /* cpu has AES */
+#define        VIA_HAS_SHA             2       /* cpu has SHA1 & SHA256 */
+#define        VIA_HAS_MM              4       /* cpu has RSA instructions */
+#define        VIA_HAS_AESCTR          8       /* cpu has AES-CTR instructions 
*/
+
+/* Centaur Extended Feature flags */
+#define        VIA_CPUID_HAS_RNG       0x000004
+#define        VIA_CPUID_DO_RNG        0x000008
+#define        VIA_CPUID_HAS_ACE       0x000040
+#define        VIA_CPUID_DO_ACE        0x000080
+#define        VIA_CPUID_HAS_ACE2      0x000100
+#define        VIA_CPUID_DO_ACE2       0x000200
+#define        VIA_CPUID_HAS_PHE       0x000400
+#define        VIA_CPUID_DO_PHE        0x000800
+#define        VIA_CPUID_HAS_PMM       0x001000
+#define        VIA_CPUID_DO_PMM        0x002000
+
+/* VIA ACE xcrypt-* instruction context control options */
+#define        VIA_CRYPT_CWLO_ROUND_M          0x0000000f
+#define        VIA_CRYPT_CWLO_ALG_M            0x00000070
+#define        VIA_CRYPT_CWLO_ALG_AES          0x00000000
+#define        VIA_CRYPT_CWLO_KEYGEN_M         0x00000080
+#define        VIA_CRYPT_CWLO_KEYGEN_HW        0x00000000
+#define        VIA_CRYPT_CWLO_KEYGEN_SW        0x00000080
+#define        VIA_CRYPT_CWLO_NORMAL           0x00000000
+#define        VIA_CRYPT_CWLO_INTERMEDIATE     0x00000100
+#define        VIA_CRYPT_CWLO_ENCRYPT          0x00000000
+#define        VIA_CRYPT_CWLO_DECRYPT          0x00000200
+#define        VIA_CRYPT_CWLO_KEY128           0x0000000a      /* 128bit, 10 
rds */
+#define        VIA_CRYPT_CWLO_KEY192           0x0000040c      /* 192bit, 12 
rds */
+#define        VIA_CRYPT_CWLO_KEY256           0x0000080e      /* 256bit, 15 
rds */
+
 #endif /* !_MACHINE_SPECIALREG_H_ */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to