Module Name:    src
Committed By:   martin
Date:           Thu Jun  4 08:55:24 UTC 2015

Modified Files:
        src/sys/arch/x86/x86 [netbsd-5]: 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.6 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.6
--- 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:55:24 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.6 2015/06/04 08:55:24 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.6 2015/06/04 08:55:24 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;
 		}
 	}

Reply via email to