[coreboot] New patch to review for coreboot: 7ab20fa Synchronize rdtsc instructions

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Wed Aug 8 00:17:02 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/1422

-gerrit

commit 7ab20fad6bcad3f4ec86462c05a58a0aae1f6673
Author: Stefan Reinauer <reinauer at chromium.org>
Date:   Tue Aug 7 14:44:51 2012 -0700

    Synchronize rdtsc instructions
    
    The CPU can arbitrarily reorder calls to rdtsc, significantly
    reducing the precision of timing using the CPUs time stamp counter.
    Unfortunately the method of synchronizing rdtsc is different
    on AMD and Intel CPUs. There is a generic method, using the cpuid
    instruction, but that uses up a lot of registers, and is very slow.
    Hence, use the correct lfence/mfence instructions (for CPUs that
    we know support it)
    
    Change-Id: I17ecb48d283f38f23148c13159aceda704c64ea5
    Signed-off-by: Stefan Reinauer <reinauer at google.com>
---
 src/cpu/amd/agesa/Kconfig         |    1 +
 src/cpu/amd/model_10xxx/Kconfig   |    1 +
 src/cpu/amd/model_fxx/Kconfig     |    1 +
 src/cpu/intel/model_1067x/Kconfig |    1 +
 src/cpu/intel/model_106cx/Kconfig |    2 +-
 src/cpu/intel/model_206ax/Kconfig |    1 +
 src/cpu/intel/model_6ex/Kconfig   |    1 +
 src/cpu/intel/model_6fx/Kconfig   |    1 +
 src/cpu/x86/Kconfig               |   16 ++++++++++++++++
 src/include/cpu/x86/tsc.h         |   21 ++++++++++++++++++---
 10 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/src/cpu/amd/agesa/Kconfig b/src/cpu/amd/agesa/Kconfig
index 5ec5ce8..b7e69e0 100644
--- a/src/cpu/amd/agesa/Kconfig
+++ b/src/cpu/amd/agesa/Kconfig
@@ -25,6 +25,7 @@ config CPU_AMD_AGESA
         default y if CPU_AMD_AGESA_FAMILY15
         default y if CPU_AMD_AGESA_FAMILY15_TN
         default n
+	select TSC_SYNC_LFENCE
 
 if CPU_AMD_AGESA
 
diff --git a/src/cpu/amd/model_10xxx/Kconfig b/src/cpu/amd/model_10xxx/Kconfig
index 221d044..0890771 100644
--- a/src/cpu/amd/model_10xxx/Kconfig
+++ b/src/cpu/amd/model_10xxx/Kconfig
@@ -3,6 +3,7 @@ config CPU_AMD_MODEL_10XXX
 	select SSE
 	select SSE2
 	select MMCONF_SUPPORT_DEFAULT
+	select TSC_SYNC_LFENCE
 
 if CPU_AMD_MODEL_10XXX
 config CPU_ADDR_BITS
diff --git a/src/cpu/amd/model_fxx/Kconfig b/src/cpu/amd/model_fxx/Kconfig
index e04605b..0afc4b0 100644
--- a/src/cpu/amd/model_fxx/Kconfig
+++ b/src/cpu/amd/model_fxx/Kconfig
@@ -3,6 +3,7 @@ config CPU_AMD_MODEL_FXX
 	select MMX
 	select SSE
 	select SSE2
+	select TSC_SYNC_LFENCE
 
 if CPU_AMD_MODEL_FXX
 config UDELAY_IO
diff --git a/src/cpu/intel/model_1067x/Kconfig b/src/cpu/intel/model_1067x/Kconfig
index b079922..852c9cd 100644
--- a/src/cpu/intel/model_1067x/Kconfig
+++ b/src/cpu/intel/model_1067x/Kconfig
@@ -2,3 +2,4 @@ config CPU_INTEL_MODEL_1067X
 	bool
 	select SMP
 	select SSE2
+	select TSC_SYNC_MFENCE
diff --git a/src/cpu/intel/model_106cx/Kconfig b/src/cpu/intel/model_106cx/Kconfig
index 103ed50..7a75ec1 100644
--- a/src/cpu/intel/model_106cx/Kconfig
+++ b/src/cpu/intel/model_106cx/Kconfig
@@ -4,9 +4,9 @@ config CPU_INTEL_MODEL_106CX
 	select SSE2
 	select UDELAY_LAPIC
 	select AP_IN_SIPI_WAIT
+	select TSC_SYNC_MFENCE
 
 config CPU_ADDR_BITS
 	int
 	default 32
 
-
diff --git a/src/cpu/intel/model_206ax/Kconfig b/src/cpu/intel/model_206ax/Kconfig
index 9cc6edd..6635868 100644
--- a/src/cpu/intel/model_206ax/Kconfig
+++ b/src/cpu/intel/model_206ax/Kconfig
@@ -14,6 +14,7 @@ config CPU_SPECIFIC_OPTIONS
 	select SMM_TSEG
 	select MICROCODE_IN_CBFS
 	#select AP_IN_SIPI_WAIT
+	select TSC_SYNC_MFENCE
 
 config BOOTBLOCK_CPU_INIT
 	string
diff --git a/src/cpu/intel/model_6ex/Kconfig b/src/cpu/intel/model_6ex/Kconfig
index 31d24bd..e2b1986 100644
--- a/src/cpu/intel/model_6ex/Kconfig
+++ b/src/cpu/intel/model_6ex/Kconfig
@@ -4,3 +4,4 @@ config CPU_INTEL_MODEL_6EX
 	select SSE2
 	select UDELAY_LAPIC
 	select AP_IN_SIPI_WAIT
+	select TSC_SYNC_MFENCE
diff --git a/src/cpu/intel/model_6fx/Kconfig b/src/cpu/intel/model_6fx/Kconfig
index 851685c..4517f17 100644
--- a/src/cpu/intel/model_6fx/Kconfig
+++ b/src/cpu/intel/model_6fx/Kconfig
@@ -4,3 +4,4 @@ config CPU_INTEL_MODEL_6FX
 	select SSE2
 	select UDELAY_LAPIC
 	select AP_IN_SIPI_WAIT
+	select TSC_SYNC_MFENCE
diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index 07e9d9e..9a96aea 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -23,6 +23,22 @@ config TSC_CALIBRATE_WITH_IO
 	bool
 	default n
 
+config TSC_SYNC_LFENCE
+	bool
+	default n
+	help
+	  The CPU driver should select this if the CPU needs
+	  to execute an lfence instruction in order to synchronize
+	  rdtsc. This is true for all modern AMD CPUs.
+
+config TSC_SYNC_MFENCE
+	bool
+	default n
+	help
+	  The CPU driver should select this if the CPU needs
+	  to execute an mfence instruction in order to synchronize
+	  rdtsc. This is true for all modern Intel CPUs.
+
 config XIP_ROM_SIZE
 	hex
 	default ROM_SIZE if ROMCC
diff --git a/src/include/cpu/x86/tsc.h b/src/include/cpu/x86/tsc.h
index c573627..615aa1c 100644
--- a/src/include/cpu/x86/tsc.h
+++ b/src/include/cpu/x86/tsc.h
@@ -10,10 +10,16 @@ typedef struct tsc_struct tsc_t;
 static inline tsc_t rdtsc(void)
 {
 	tsc_t res;
-	__asm__ __volatile__ (
+	asm volatile (
+#if CONFIG_TSC_SYNC_MFENCE
+		"mfence\n"
+#endif
+#if CONFIG_TSC_SYNC_LFENCE
+		"lfence\n"
+#endif
 		"rdtsc"
 		: "=a" (res.lo), "=d"(res.hi) /* outputs */
-		);
+	);
 	return res;
 }
 
@@ -22,7 +28,16 @@ static inline tsc_t rdtsc(void)
 static inline unsigned long long rdtscll(void)
 {
 	unsigned long long val;
-	asm volatile ("rdtsc" : "=A" (val));
+	asm volatile (
+#if CONFIG_TSC_SYNC_MFENCE
+		"mfence\n"
+#endif
+#if CONFIG_TSC_SYNC_LFENCE
+		"lfence\n"
+#endif
+		"rdtsc"
+		: "=A" (val)
+	);
 	return val;
 }
 #endif




More information about the coreboot mailing list