[coreboot] New patch to review for coreboot: 1a50b63 Fix timer frequency detection on Sandybridge

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Thu Apr 5 21:25:56 CEST 2012


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/870

-gerrit

commit 1a50b63b220d62ad987e6c7882e8a83a8f3d680c
Author: Stefan Reinauer <reinauer at chromium.org>
Date:   Tue Apr 3 16:11:02 2012 -0700

    Fix timer frequency detection on Sandybridge
    
    Change-Id: Ide720bd91cde56a0afdd231d93500c371b1ffbe8
    Signed-off-by: Duncan Laurie <dlaurie at google.com>
    Signed-off-by: Stefan Reinauer <reinauer at google.com>
---
 src/cpu/x86/lapic/apic_timer.c |   48 ++++++++++++++++++++++++++++++----------
 1 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/src/cpu/x86/lapic/apic_timer.c b/src/cpu/x86/lapic/apic_timer.c
index 826f5b6..bb6cca7 100644
--- a/src/cpu/x86/lapic/apic_timer.c
+++ b/src/cpu/x86/lapic/apic_timer.c
@@ -20,6 +20,7 @@
 
 #include <stdint.h>
 #include <delay.h>
+#include <arch/cpu.h>
 #include <cpu/x86/msr.h>
 #include <cpu/x86/lapic.h>
 
@@ -27,14 +28,40 @@
  * memory init.
  */
 
-#define FSB_CLOCK_STS 0xcd
+static u32 timer_fsb = 0;
 
-static u32 timer_fsb = 200; // default to 200MHz
+static int set_timer_fsb(void)
+{
+	struct cpuinfo_x86 c;
+	int core_fsb[8] = { -1, 133, -1, 166, -1, 100, -1, -1 };
+	int core2_fsb[8] = { 266, 133, 200, 166, -1, 100, -1, -1 };
+
+	get_fms(&c, cpuid_eax(1));
+	if (c.x86 != 6)
+		return -1;
+
+	switch (c.x86_model) {
+	case 0xe:  /* Core Solo/Duo */
+	case 0x1c: /* Atom */
+		timer_fsb = core_fsb[rdmsr(0xcd).lo & 7];
+		break;
+	case 0xf:  /* Core 2*/
+	case 0x17: /* Enhanced Core */
+		timer_fsb = core2_fsb[rdmsr(0xcd).lo & 7];
+		break;
+	case 0x2a: /* SandyBridge BCLK fixed at 100MHz*/
+		timer_fsb = 100;
+		break;
+	default:
+		timer_fsb = 200;
+		break;
+	}
+
+	return 0;
+}
 
 void init_timer(void)
 {
-	msr_t fsb_clock_sts;
-
 	/* Set the apic timer to no interrupts and periodic mode */
 	lapic_write(LAPIC_LVTT, (LAPIC_LVT_TIMER_PERIODIC | LAPIC_LVT_MASKED));
 
@@ -45,19 +72,16 @@ void init_timer(void)
 	lapic_write(LAPIC_TMICT, 0xffffffff);
 
 	/* Set FSB frequency to a reasonable value */
-	fsb_clock_sts = rdmsr(FSB_CLOCK_STS);
-	switch ((fsb_clock_sts.lo >> 4) & 0x07) {
-	case 0: timer_fsb = 266; break;
-	case 1: timer_fsb = 133; break;
-	case 2: timer_fsb = 200; break;
-	case 3: timer_fsb = 166; break;
-	case 5: timer_fsb = 100; break;
-	}
+	set_timer_fsb();
 }
 
 void udelay(u32 usecs)
 {
 	u32 start, value, ticks;
+
+	if (!timer_fsb)
+		init_timer();
+
 	/* Calculate the number of ticks to run, our FSB runs at timer_fsb Mhz */
 	ticks = usecs * timer_fsb;
 	start = lapic_read(LAPIC_TMCCT);




More information about the coreboot mailing list