diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c index c91d507223a..bfb2c16afc8 100644 --- a/sys/amd64/amd64/identcpu.c +++ b/sys/amd64/amd64/identcpu.c @@ -385,7 +385,7 @@ printcpuinfo(void) ); } - if (cpu_vendor_id == CPU_VENDOR_CENTAUR) + if (via_feature_rng != 0 || via_feature_xcrypt != 0) print_via_padlock_info(); if ((cpu_feature & CPUID_HTT) && @@ -643,25 +643,7 @@ 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; - + do_cpuid(0xc0000001, regs); printf("\n VIA Padlock Features=0x%b", regs[3], "\020" "\003RNG" /* RNG */ diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c index 923b28cdf89..5a832a6262b 100644 --- a/sys/amd64/amd64/initcpu.c +++ b/sys/amd64/amd64/initcpu.c @@ -74,72 +74,47 @@ u_int cpu_mxcsr_mask; /* Valid bits in mxcsr */ u_int cpu_clflush_line_size = 32; SYSCTL_UINT(_hw, OID_AUTO, via_feature_rng, CTLFLAG_RD, - &via_feature_rng, 0, "VIA C3/C7 RNG feature available in CPU"); + &via_feature_rng, 0, "VIA 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"); + &via_feature_xcrypt, 0, "VIA xcrypt feature available in CPU"); /* - * Initialize special VIA C3/C7 features + * Initialize special VIA features */ static void init_via(void) { u_int regs[4], val; - u_int64_t msreg; + /* + * Check extended CPUID for PadLock features. + * + * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/programming_guide.pdf + */ do_cpuid(0xc0000000, regs); - val = regs[0]; - if (val >= 0xc0000001) { + if (regs[0] >= 0xc0000001) { do_cpuid(0xc0000001, regs); val = regs[3]; } else - val = 0; + return; - /* 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); - } + /* Enable RNG if present. */ + if ((val & VIA_CPUID_HAS_RNG) != 0) { via_feature_rng = VIA_HAS_RNG; + wrmsr(0x110B, rdmsr(0x110B) | VIA_CPUID_DO_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); - } + + /* Enable PadLock if present. */ + if ((val & VIA_CPUID_HAS_ACE) != 0) 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); - } + if ((val & VIA_CPUID_HAS_ACE2) != 0) 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); - } + if ((val & VIA_CPUID_HAS_PHE) != 0) 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); - } + if ((val & VIA_CPUID_HAS_PMM) != 0) via_feature_xcrypt |= VIA_HAS_MM; - } + if (via_feature_xcrypt != 0) + wrmsr(0x1107, rdmsr(0x1107) | (1 << 28)); } /* @@ -159,9 +134,7 @@ initializecpu(void) wrmsr(MSR_EFER, msr); pg_nx = PG_NX; } - if (cpu_vendor_id == CPU_VENDOR_CENTAUR && - CPUID_TO_FAMILY(cpu_id) == 0x6 && - CPUID_TO_MODEL(cpu_id) >= 0xf) + if (cpu_vendor_id == CPU_VENDOR_CENTAUR) init_via(); } diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c index e1b64765a7c..8760562f832 100644 --- a/sys/i386/i386/identcpu.c +++ b/sys/i386/i386/identcpu.c @@ -560,7 +560,8 @@ printcpuinfo(void) } else if (cpu_vendor_id == CPU_VENDOR_RISE) { strcpy(cpu_model, "Rise "); switch (cpu_id & 0xff0) { - case 0x500: + case 0x500: /* 6401 and 6441 (Kirin) */ + case 0x520: /* 6510 (Lynx) */ strcat(cpu_model, "mP6"); break; default: @@ -570,11 +571,20 @@ printcpuinfo(void) switch (cpu_id & 0xff0) { case 0x540: strcpy(cpu_model, "IDT WinChip C6"); + /* + * http://www.centtech.com/c6_data_sheet.pdf + * + * I-12 RDTSC may return incoherent values in EDX:EAX + * I-13 RDTSC hangs when certain event counters are used + */ tsc_freq = 0; break; case 0x580: strcpy(cpu_model, "IDT WinChip 2"); break; + case 0x590: + strcpy(cpu_model, "IDT WinChip 3"); + break; case 0x660: strcpy(cpu_model, "VIA C3 Samuel"); break; @@ -852,7 +862,7 @@ printcpuinfo(void) ); } - if (cpu_vendor_id == CPU_VENDOR_CENTAUR) + if (via_feature_rng != 0 || via_feature_xcrypt != 0) print_via_padlock_info(); if ((cpu_feature & CPUID_HTT) && @@ -1127,6 +1137,12 @@ finishidentcpu(void) do_cpuid(0x80000008, regs); cpu_procinfo2 = regs[2]; } + } else if (cpu_vendor_id == CPU_VENDOR_CENTAUR) { + init_exthigh(); + if (cpu_exthigh >= 0x80000001) { + do_cpuid(0x80000001, regs); + amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff); + } } else if (cpu_vendor_id == CPU_VENDOR_CYRIX) { if (cpu == CPU_486) { /* @@ -1560,25 +1576,7 @@ 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; - + do_cpuid(0xc0000001, regs); printf("\n VIA Padlock Features=0x%b", regs[3], "\020" "\003RNG" /* RNG */ diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c index b7fa78ce728..c2daf54371f 100644 --- a/sys/i386/i386/initcpu.c +++ b/sys/i386/i386/initcpu.c @@ -100,9 +100,9 @@ u_int cpu_vendor_id = 0; /* CPU vendor ID */ u_int cpu_clflush_line_size = 32; SYSCTL_UINT(_hw, OID_AUTO, via_feature_rng, CTLFLAG_RD, - &via_feature_rng, 0, "VIA C3/C7 RNG feature available in CPU"); + &via_feature_rng, 0, "VIA 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"); + &via_feature_xcrypt, 0, "VIA xcrypt feature available in CPU"); #ifdef CPU_ENABLE_SSE u_int cpu_fxsr; /* SSE enabled */ @@ -420,6 +420,38 @@ init_6x86(void) } #endif /* I486_CPU */ +#ifdef I586_CPU +/* + * IDT WinChip C6/2/2A/2B/3 + * + * http://www.centtech.com/winchip_bios_writers_guide_v4_0.pdf + */ +static void +init_winchip(void) +{ + u_int regs[4]; + uint64_t fcr; + + fcr = rdmsr(0x0107); + + /* + * Set ECX8, DSMC, DTLOCK/EDCTLB, EMMX, and ERETSTK and clear DPDC. + */ + fcr |= (1 << 1) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 16); + fcr &= ~(1ULL << 11); + + /* + * Additioanlly, set EBRPRED, E2MMX and EAMD3D for WinChip 2 and 3. + */ + if (CPUID_TO_MODEL(cpu_id) >= 8) + fcr |= (1 << 12) | (1 << 19) | (1 << 20); + + wrmsr(0x0107, fcr); + do_cpuid(1, regs); + cpu_feature = regs[3]; +} +#endif + #ifdef I686_CPU /* * Cyrix 6x86MX (code-named M2) @@ -538,71 +570,72 @@ init_mendocino(void) } /* - * Initialize special VIA C3/C7 features + * Initialize special VIA features */ static void init_via(void) { u_int regs[4], val; - u_int64_t msreg; + uint64_t fcr; + /* + * Explicitly enable CX8 and PGE on C3. + * + * http://www.via.com.tw/download/mainboards/6/13/VIA_C3_EBGA%20datasheet110.pdf + */ + if (CPUID_TO_MODEL(cpu_id) <= 9) + fcr = (1 << 1) | (1 << 7); + else + fcr = 0; + + /* + * Check extended CPUID for PadLock features. + * + * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/programming_guide.pdf + */ do_cpuid(0xc0000000, regs); - val = regs[0]; - if (val >= 0xc0000001) { + if (regs[0] >= 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); - } + /* Enable RNG if present. */ + if ((val & VIA_CPUID_HAS_RNG) != 0) { via_feature_rng = VIA_HAS_RNG; + wrmsr(0x110B, rdmsr(0x110B) | VIA_CPUID_DO_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); - } + + /* Enable PadLock if present. */ + if ((val & VIA_CPUID_HAS_ACE) != 0) 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); - } + if ((val & VIA_CPUID_HAS_ACE2) != 0) 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); - } + if ((val & VIA_CPUID_HAS_PHE) != 0) 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); - } + if ((val & VIA_CPUID_HAS_PMM) != 0) via_feature_xcrypt |= VIA_HAS_MM; - } + if (via_feature_xcrypt != 0) + fcr |= 1 << 28; + + wrmsr(0x1107, rdmsr(0x1107) | fcr); } #endif /* I686_CPU */ +#if defined(I586_CPU) || defined(I686_CPU) +static void +init_transmeta(void) +{ + u_int regs[0]; + + /* Expose all hidden features. */ + wrmsr(0x80860004, rdmsr(0x80860004) | ~0UL); + do_cpuid(1, regs); + cpu_feature = regs[3]; +} +#endif + /* * Initialize CR4 (Control register 4) to enable SSE instructions. */ @@ -644,12 +677,25 @@ initializecpu(void) init_6x86(); break; #endif /* I486_CPU */ +#ifdef I586_CPU + case CPU_586: + switch (cpu_vendor_id) { + case CPU_VENDOR_CENTAUR: + init_winchip(); + break; + case CPU_VENDOR_TRANSMETA: + init_transmeta(); + break; + } + break; +#endif #ifdef I686_CPU case CPU_M2: init_6x86MX(); break; case CPU_686: - if (cpu_vendor_id == CPU_VENDOR_INTEL) { + switch (cpu_vendor_id) { + case CPU_VENDOR_INTEL: switch (cpu_id & 0xff0) { case 0x610: init_ppro(); @@ -658,8 +704,9 @@ initializecpu(void) init_mendocino(); break; } - } else if (cpu_vendor_id == CPU_VENDOR_AMD) { -#if defined(I686_CPU) && defined(CPU_ATHLON_SSE_HACK) + break; +#ifdef CPU_ATHLON_SSE_HACK + case CPU_VENDOR_AMD: /* * Sometimes the BIOS doesn't enable SSE instructions. * According to AMD document 20734, the mobile @@ -676,21 +723,14 @@ initializecpu(void) do_cpuid(1, regs); cpu_feature = regs[3]; } + break; #endif - } else if (cpu_vendor_id == CPU_VENDOR_CENTAUR) { - switch (cpu_id & 0xff0) { - case 0x690: - if ((cpu_id & 0xf) < 3) - break; - /* fall through. */ - case 0x6a0: - case 0x6d0: - case 0x6f0: - init_via(); - break; - default: - break; - } + case CPU_VENDOR_CENTAUR: + init_via(); + break; + case CPU_VENDOR_TRANSMETA: + init_transmeta(); + break; } #ifdef PAE if ((amd_feature & AMDID_NX) != 0) {