Add basic amd64 support for VIA Nano processors.

This commit is contained in:
Jung-uk Kim 2009-01-12 19:17:35 +00:00
parent b7c4c1f7b9
commit 92df0bda99
6 changed files with 200 additions and 15 deletions

View File

@ -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);

View File

@ -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 */
);
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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;

View File

@ -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_ */