Module Name: src Committed By: martin Date: Thu Jun 4 08:57:03 UTC 2015
Modified Files: src/sys/arch/x86/x86 [netbsd-5-2]: intel_busclock.c Log Message: Pull up the following revisions, requested by sborrill in #1963: sys/arch/x86/x86/intel_busclock.c 1.10, 1.13-23 Update p[34]_get_bus_clock() to avoid panic in est(4). Return correct bus clock on some CPUs. Use rdmsr_safe() to access MSRs safely. To generate a diff of this commit: cvs rdiff -u -r1.5.10.5 -r1.5.10.5.2.1 src/sys/arch/x86/x86/intel_busclock.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/x86/intel_busclock.c diff -u src/sys/arch/x86/x86/intel_busclock.c:1.5.10.5 src/sys/arch/x86/x86/intel_busclock.c:1.5.10.5.2.1 --- src/sys/arch/x86/x86/intel_busclock.c:1.5.10.5 Wed Aug 22 21:18:19 2012 +++ src/sys/arch/x86/x86/intel_busclock.c Thu Jun 4 08:57:03 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: intel_busclock.c,v 1.5.10.5 2012/08/22 21:18:19 bouyer Exp $ */ +/* $NetBSD: intel_busclock.c,v 1.5.10.5.2.1 2015/06/04 08:57:03 martin Exp $ */ /*- * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: intel_busclock.c,v 1.5.10.5 2012/08/22 21:18:19 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intel_busclock.c,v 1.5.10.5.2.1 2015/06/04 08:57:03 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -91,25 +91,24 @@ p3_get_bus_clock(struct cpu_info *ci) { uint64_t msr; int bus, bus_clock = 0; + uint32_t model; - switch (CPUID2MODEL(ci->ci_signature)) { + model = CPUID_TO_MODEL(ci->ci_signature); + + switch (model) { case 0x9: /* Pentium M (130 nm, Banias) */ bus_clock = 10000; break; case 0xc: /* Core i7, Atom, model 1 */ /* - * XXX (See also case 0xe and 0xd) - * Some core i7 CPUs can report model 0xc. * Newer CPUs will GP when attemping to access MSR_FSB_FREQ. * In the long-term, use ACPI instead of all this. */ - switch (CPUID2EXTMODEL(ci->ci_signature)) { - case 0x2: - aprint_debug("%s: unable to determine bus speed", - device_xname(ci->ci_dev)); + if (rdmsr_safe(MSR_FSB_FREQ, &msr) == EFAULT) { + aprint_debug_dev(ci->ci_dev, + "unable to determine bus speed"); goto print_msr; } - msr = rdmsr(MSR_FSB_FREQ); bus = (msr >> 0) & 0x7; switch (bus) { case 1: @@ -121,20 +120,12 @@ p3_get_bus_clock(struct cpu_info *ci) goto print_msr; } break; - case 0xd: /* Pentium M (90 nm, Dothan), some Xeons */ - /* - * XXX (See also case 0xc and 0xd) - * Some Xeons can report model 0xd, e.g. E5-2630 - * Newer CPUs will GP when attemping to access MSR_FSB_FREQ. - * In the long-term, use ACPI instead of all this. - */ - switch (CPUID2EXTMODEL(ci->ci_signature)) { - case 0x2: - aprint_debug("%s: unable to determine bus speed", - device_xname(ci->ci_dev)); + case 0xd: /* Pentium M (90 nm, Dothan) */ + if (rdmsr_safe(MSR_FSB_FREQ, &msr) == EFAULT) { + aprint_debug_dev(ci->ci_dev, + "unable to determine bus speed"); goto print_msr; } - msr = rdmsr(MSR_FSB_FREQ); bus = (msr >> 0) & 0x7; switch (bus) { case 0: @@ -150,20 +141,13 @@ p3_get_bus_clock(struct cpu_info *ci) } break; case 0xe: /* Core Duo/Solo */ - /* - * XXX (See also case 0xc) - * Newer CPUs will GP when attemping to access MSR_FSB_FREQ. - * In the long-term, use ACPI instead of all this. - */ - switch (CPUID2EXTMODEL(ci->ci_signature)) { - case 0x1: - aprint_debug("%s: unable to determine bus speed", - device_xname(ci->ci_dev)); + case 0xf: /* Core Xeon */ + case 0x17: /* Xeon [35]000, Core 2 Quad [89]00 */ + if (rdmsr_safe(MSR_FSB_FREQ, &msr) == EFAULT) { + aprint_debug_dev(ci->ci_dev, + "unable to determine bus speed"); goto print_msr; } - /* FALLTHROUGH */ - case 0xf: /* Core Xeon */ - msr = rdmsr(MSR_FSB_FREQ); bus = (msr >> 0) & 0x7; switch (bus) { case 5: @@ -184,6 +168,9 @@ p3_get_bus_clock(struct cpu_info *ci) case 4: bus_clock = 33333; break; + case 6: + bus_clock = 40000; + break; default: aprint_debug("%s: unknown Core FSB_FREQ value %d", device_xname(ci->ci_dev), bus); @@ -210,16 +197,135 @@ p3_get_bus_clock(struct cpu_info *ci) case 2: bus_clock = 10000; break; + case 3: + bus_clock = 10666; + break; default: aprint_debug("%s: unknown i686 EBL_CR_POWERON " "value %d ", device_xname(ci->ci_dev), bus); goto print_msr; } break; + case 0x1c: /* Atom */ + case 0x26: + case 0x27: + case 0x35: + case 0x36: + if (rdmsr_safe(MSR_FSB_FREQ, &msr) == EFAULT) { + aprint_debug_dev(ci->ci_dev, + "unable to determine bus speed"); + goto print_msr; + } + bus = (msr >> 0) & 0x7; + switch (bus) { + case 7: + bus_clock = 8333; + break; + case 5: + bus_clock = 10000; + break; + case 1: + bus_clock = 13333; + break; + case 3: + bus_clock = 16667; + break; + default: + aprint_debug("%s: unknown Atom FSB_FREQ value %d", + device_xname(ci->ci_dev), bus); + goto print_msr; + } + break; + case 0x37: /* Silvermont */ + case 0x4a: + case 0x4d: + case 0x5a: + case 0x5d: + if (rdmsr_safe(MSR_FSB_FREQ, &msr) == EFAULT) { + aprint_debug_dev(ci->ci_dev, + "unable to determine bus speed"); + goto print_msr; + } + bus = (msr >> 0) & 0x7; + switch (bus) { + case 4: + bus_clock = 8000; + break; + case 0: + bus_clock = 8333; + break; + case 1: + bus_clock = 10000; + break; + case 2: + bus_clock = 13333; + break; + case 3: + bus_clock = 11667; + break; + default: + aprint_debug("%s: unknown Silvermont FSB_FREQ value %d", + device_xname(ci->ci_dev), bus); + goto print_msr; + } + break; + case 0x4c: /* Airmont */ + if (rdmsr_safe(MSR_FSB_FREQ, &msr) == EFAULT) { + aprint_debug_dev(ci->ci_dev, + "unable to determine bus speed"); + goto print_msr; + } + bus = (msr >> 0) & 0x1f; + switch (bus) { + case 0: + bus_clock = 8333; + break; + case 1: + bus_clock = 10000; + break; + case 2: + bus_clock = 13333; + break; + case 3: + bus_clock = 11650; + break; + case 4: + bus_clock = 8333; + break; + case 5: + bus_clock = 10000; + break; + case 6: + bus_clock = 13333; + break; + case 7: + bus_clock = 11666; + break; + case 12: + bus_clock = 8000; + break; + case 13: + bus_clock = 9333; + break; + case 14: + bus_clock = 9000; + break; + case 15: + bus_clock = 8888; + break; + case 20: + bus_clock = 8750; + break; + default: + aprint_debug("%s: unknown Airmont FSB_FREQ value %d", + device_xname(ci->ci_dev), bus); + goto print_msr; + } + break; default: - aprint_debug("%s: unknown i686 model %d, can't get bus clock", + aprint_debug("%s: unknown i686 model %02x, can't get bus clock", device_xname(ci->ci_dev), - CPUID2MODEL(ci->ci_signature)); + CPUID_TO_MODEL(ci->ci_signature)); print_msr: /* * Show the EBL_CR_POWERON MSR, so we'll at least have @@ -239,7 +345,7 @@ p4_get_bus_clock(struct cpu_info *ci) int bus, bus_clock = 0; msr = rdmsr(MSR_EBC_FREQUENCY_ID); - if (CPUID2MODEL(ci->ci_signature) < 2) { + if (CPUID_TO_MODEL(ci->ci_signature) < 2) { bus = (msr >> 21) & 0x7; switch (bus) { case 0: @@ -252,15 +358,15 @@ p4_get_bus_clock(struct cpu_info *ci) aprint_debug("%s: unknown Pentium 4 (model %d) " "EBC_FREQUENCY_ID value %d\n", device_xname(ci->ci_dev), - CPUID2MODEL(ci->ci_signature), bus); + CPUID_TO_MODEL(ci->ci_signature), bus); break; } } else { bus = (msr >> 16) & 0x7; switch (bus) { case 0: - bus_clock = (CPUID2MODEL(ci->ci_signature) == 2) ? - 10000 : 26666; + bus_clock = (CPUID_TO_MODEL(ci->ci_signature) == 2) ? + 10000 : 26667; break; case 1: bus_clock = 13333; @@ -269,13 +375,16 @@ p4_get_bus_clock(struct cpu_info *ci) bus_clock = 20000; break; case 3: - bus_clock = 16666; + bus_clock = 16667; + break; + case 4: + bus_clock = 33333; break; default: aprint_debug("%s: unknown Pentium 4 (model %d) " "EBC_FREQUENCY_ID value %d\n", device_xname(ci->ci_dev), - CPUID2MODEL(ci->ci_signature), bus); + CPUID_TO_MODEL(ci->ci_signature), bus); break; } }