[coreboot-gerrit] Patch set updated for coreboot: f64c6a7 x86: add TSC_CONSTANT_RATE option

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Fri May 3 23:21:32 CEST 2013


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3168

-gerrit

commit f64c6a715c716adc9236c2157141b3259fca5e5a
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Wed May 1 15:27:09 2013 -0500

    x86: add TSC_CONSTANT_RATE option
    
    Some boards use the local apic for udelay(), but they also provide their
    own implementation of udelay() for SMM. The reason for using the local
    apic for udelay() in ramstage is to not have to pay the penalty of
    calibrating the TSC frequency. Therefore provide a TSC_CONSTANT_RATE
    option to indicate that TSC calibration is not needed. Instead it relies
    on the presence of a tsc_freq_mhz() function provided by the cpu/board.
    Additionally, assume that if TSC_CONSTANT_RATE is selected the udelay()
    function in SMM will be the tsc.
    
    Change-Id: I1629c2fbe3431772b4e80495160584fb6f599e9e
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/cpu/x86/Kconfig          |  7 +++++++
 src/cpu/x86/tsc/Makefile.inc |  4 ++++
 src/cpu/x86/tsc/delay_tsc.c  | 27 ++++++++++++++++++++++++---
 src/include/cpu/x86/tsc.h    |  4 ++++
 4 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index 5cf40fa..c64a8e4 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -25,6 +25,13 @@ config UDELAY_TSC
 	bool
 	default n
 
+config TSC_CONSTANT_RATE
+	def_bool n
+	depends on UDELAY_TSC
+	help
+	  This option asserts that the TSC ticks at a known constant rate.
+	  Therefore, no TSC calibration is required.
+
 config TSC_MONOTONIC_TIMER
 	def_bool n
 	depends on UDELAY_TSC
diff --git a/src/cpu/x86/tsc/Makefile.inc b/src/cpu/x86/tsc/Makefile.inc
index 44bfe85..3bbae84 100644
--- a/src/cpu/x86/tsc/Makefile.inc
+++ b/src/cpu/x86/tsc/Makefile.inc
@@ -1,2 +1,6 @@
 ramstage-$(CONFIG_UDELAY_TSC) += delay_tsc.c
+romstage-$(CONFIG_TSC_CONSTANT_RATE) += delay_tsc.c
+ifeq ($(CONFIG_HAVE_SMI_HANDLER),y)
+smm-$(CONFIG_TSC_CONSTANT_RATE) += delay_tsc.c
+endif
 
diff --git a/src/cpu/x86/tsc/delay_tsc.c b/src/cpu/x86/tsc/delay_tsc.c
index e4993d0..0540496 100644
--- a/src/cpu/x86/tsc/delay_tsc.c
+++ b/src/cpu/x86/tsc/delay_tsc.c
@@ -5,8 +5,16 @@
 #include <smp/spinlock.h>
 #include <delay.h>
 
+#if !defined(__PRE_RAM__)
+
 static unsigned long clocks_per_usec;
 
+#if CONFIG_TSC_CONSTANT_RATE
+static unsigned long calibrate_tsc(void)
+{
+	return tsc_freq_mhz();
+}
+#else /* CONFIG_TSC_CONSTANT_RATE */
 #if !CONFIG_TSC_CALIBRATE_WITH_IO
 #define CLOCK_TICK_RATE	1193180U /* Underlying HZ */
 
@@ -139,6 +147,7 @@ static unsigned long long calibrate_tsc(void)
 
 
 #endif /* CONFIG_TSC_CALIBRATE_WITH_IO */
+#endif /* CONFIG_TSC_CONSTANT_RATE */
 
 void init_timer(void)
 {
@@ -148,15 +157,27 @@ void init_timer(void)
 	}
 }
 
+static inline unsigned long get_clocks_per_usec(void)
+{
+	init_timer();
+	return clocks_per_usec;
+}
+#else /* !defined(__PRE_RAM__) */
+/* romstage calls into cpu/board specific function every time. */
+static inline unsigned long get_clocks_per_usec(void)
+{
+	return tsc_freq_mhz();
+}
+#endif /* !defined(__PRE_RAM__) */
+
 void udelay(unsigned us)
 {
         unsigned long long count;
         unsigned long long stop;
         unsigned long long clocks;
 
-	init_timer();
 	clocks = us;
-	clocks *= clocks_per_usec;
+	clocks *= get_clocks_per_usec();
         count = rdtscll();
         stop = clocks + count;
         while(stop > count) {
@@ -165,7 +186,7 @@ void udelay(unsigned us)
         }
 }
 
-#if CONFIG_TSC_MONOTONIC_TIMER
+#if CONFIG_TSC_MONOTONIC_TIMER && !defined(__PRE_RAM__) && !defined(__SMM__)
 #include <timer.h>
 
 static struct monotonic_counter {
diff --git a/src/include/cpu/x86/tsc.h b/src/include/cpu/x86/tsc.h
index 6ce7f5f..8e49a66 100644
--- a/src/include/cpu/x86/tsc.h
+++ b/src/include/cpu/x86/tsc.h
@@ -40,4 +40,8 @@ static inline unsigned long long rdtscll(void)
 }
 #endif
 
+#if CONFIG_TSC_CONSTANT_RATE
+unsigned long tsc_freq_mhz(void);
+#endif
+
 #endif /* CPU_X86_TSC_H */



More information about the coreboot-gerrit mailing list