summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2009-01-12 19:17:35 +0000
committerjkim <jkim@FreeBSD.org>2009-01-12 19:17:35 +0000
commit7cdff4176a3e40ec42ba82e4efdd71851bb4b64e (patch)
treeeecbe0e11554a2633c3b731862a1f18dd13b5a77 /sys/amd64
parentb1dd6fa37d9bcc30854719a38a0bc5f4223331cc (diff)
downloadFreeBSD-src-7cdff4176a3e40ec42ba82e4efdd71851bb4b64e.zip
FreeBSD-src-7cdff4176a3e40ec42ba82e4efdd71851bb4b64e.tar.gz
Add basic amd64 support for VIA Nano processors.
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/amd64_mem.c12
-rw-r--r--sys/amd64/amd64/identcpu.c76
-rw-r--r--sys/amd64/amd64/initcpu.c75
-rw-r--r--sys/amd64/amd64/msi.c14
-rw-r--r--sys/amd64/include/md_var.h2
-rw-r--r--sys/amd64/include/specialreg.h36
6 files changed, 200 insertions, 15 deletions
diff --git a/sys/amd64/amd64/amd64_mem.c b/sys/amd64/amd64/amd64_mem.c
index 7f1f428..2b5a73d 100644
--- a/sys/amd64/amd64/amd64_mem.c
+++ b/sys/amd64/amd64/amd64_mem.c
@@ -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);
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
index e7516cc..793c96f 100644
--- a/sys/amd64/amd64/identcpu.c
+++ b/sys/amd64/amd64/identcpu.c
@@ -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, tsc_freq_changed, NULL,
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 */
+ );
+}
diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c
index 23cf082..edf1a98 100644
--- a/sys/amd64/amd64/initcpu.c
+++ b/sys/amd64/amd64/initcpu.c
@@ -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();
}
diff --git a/sys/amd64/amd64/msi.c b/sys/amd64/amd64/msi.c
index f8d92d6..0596c09 100644
--- a/sys/amd64/amd64/msi.c
+++ b/sys/amd64/amd64/msi.c
@@ -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);
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index b0807b3..2125b9f 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -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;
diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h
index c08668c..eb2ff9b 100644
--- a/sys/amd64/include/specialreg.h
+++ b/sys/amd64/include/specialreg.h
@@ -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_ */
OpenPOWER on IntegriCloud