re-enable AMD Topology extension on certain models if disabled by BIOS

Some BIOSes disable AMD Topology extension on AMD Family 15h notebook
processors.  We re-enable the extension, so that we can properly discover
core and cache topology.  Linux seems to do the same.

Reported by:	Johannes Dieterich <dieterich.joh@gmail.com>
Reviewed by:	jhb, kib
Tested by:	Johannes Dieterich <dieterich.joh@gmail.com>
		(earlier version)
MFC after:	3 weeks
Differential Revision:	https://reviews.freebsd.org/D5883
This commit is contained in:
Andriy Gapon 2016-04-12 13:30:39 +00:00
parent 53791a95a4
commit 0d63fc3ed8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=297857
5 changed files with 31 additions and 15 deletions

View File

@ -247,7 +247,7 @@ init_secondary(void)
wrmsr(MSR_FSBASE, 0); /* User value */
wrmsr(MSR_GSBASE, (u_int64_t)pc);
wrmsr(MSR_KGSBASE, (u_int64_t)pc); /* XXX User value while we're in the kernel */
intel_fix_cpuid();
fix_cpuid();
lidt(&r_idt);

View File

@ -242,7 +242,7 @@ init_secondary(void)
pc->pc_prvspace = pc;
pc->pc_curthread = 0;
intel_fix_cpuid();
fix_cpuid();
gdt_segs[GPRIV_SEL].ssd_base = (int) pc;
gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss;

View File

@ -816,6 +816,7 @@
#define MSR_P_STATE_CONFIG(n) (0xc0010064 + (n)) /* P-state Config */
#define MSR_SMM_ADDR 0xc0010112 /* SMM TSEG base address */
#define MSR_SMM_MASK 0xc0010113 /* SMM TSEG address mask */
#define MSR_EXTFEATURES 0xc0011005 /* Extended CPUID Features override */
#define MSR_IC_CFG 0xc0011021 /* Instruction Cache Configuration */
#define MSR_K8_UCODE_UPDATE 0xc0010020 /* update microcode */
#define MSR_MC0_CTL_MASK 0xc0010044

View File

@ -103,7 +103,7 @@ void dump_drop_page(vm_paddr_t);
void identify_cpu(void);
void initializecpu(void);
void initializecpucache(void);
bool intel_fix_cpuid(void);
bool fix_cpuid(void);
void fillw(int /*u_short*/ pat, void *base, size_t cnt);
int is_physical_memory(vm_paddr_t addr);
int isa_nmi(int cd);

View File

@ -1342,23 +1342,22 @@ identify_hypervisor(void)
}
}
/*
* Clear "Limit CPUID Maxval" bit and return true if the caller should
* get the largest standard CPUID function number again if it is set
* from BIOS. It is necessary for probing correct CPU topology later
* and for the correct operation of the AVX-aware userspace.
*/
bool
intel_fix_cpuid(void)
fix_cpuid(void)
{
uint64_t msr;
if (cpu_vendor_id != CPU_VENDOR_INTEL)
return (false);
if ((CPUID_TO_FAMILY(cpu_id) == 0xf &&
/*
* Clear "Limit CPUID Maxval" bit and return true if the caller should
* get the largest standard CPUID function number again if it is set
* from BIOS. It is necessary for probing correct CPU topology later
* and for the correct operation of the AVX-aware userspace.
*/
if (cpu_vendor_id == CPU_VENDOR_INTEL &&
((CPUID_TO_FAMILY(cpu_id) == 0xf &&
CPUID_TO_MODEL(cpu_id) >= 0x3) ||
(CPUID_TO_FAMILY(cpu_id) == 0x6 &&
CPUID_TO_MODEL(cpu_id) >= 0xe)) {
CPUID_TO_MODEL(cpu_id) >= 0xe))) {
msr = rdmsr(MSR_IA32_MISC_ENABLE);
if ((msr & IA32_MISC_EN_LIMCPUID) != 0) {
msr &= ~IA32_MISC_EN_LIMCPUID;
@ -1366,6 +1365,22 @@ intel_fix_cpuid(void)
return (true);
}
}
/*
* Re-enable AMD Topology Extension that could be disabled by BIOS
* on some notebook processors. Without the extension it's really
* hard to determine the correct CPU cache topology.
* See BIOS and Kernel Developers Guide (BKDG) for AMD Family 15h
* Models 60h-6Fh Processors, Publication # 50742.
*/
if (cpu_vendor_id == CPU_VENDOR_AMD && CPUID_TO_FAMILY(cpu_id) == 0x15) {
msr = rdmsr(MSR_EXTFEATURES);
if ((msr & ((uint64_t)1 << 54)) == 0) {
msr |= (uint64_t)1 << 54;
wrmsr(MSR_EXTFEATURES, msr);
return (true);
}
}
return (false);
}
@ -1403,7 +1418,7 @@ identify_cpu(void)
identify_hypervisor();
cpu_vendor_id = find_cpu_vendor_id();
if (intel_fix_cpuid()) {
if (fix_cpuid()) {
do_cpuid(0, regs);
cpu_high = regs[0];
}