[SeaBIOS] [PATCH] timer: Add CONFIG_TSC_TIMER build option to disable the CPU TSC timer

Kevin O'Connor kevin at koconnor.net
Thu Jul 23 15:01:09 CEST 2015


Allow users to remove the CPU timestamp counter support at compile
time.  The PMTIMER is frequently used instead of the TSC and this
compile time option allows one to strip a few bytes from the final
binary.  This change also defaults the internal timer to use the PIT
based timer until the PMTIMER or TSC is detected.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/Kconfig    | 10 ++++++++--
 src/hw/timer.c | 23 ++++++++---------------
 2 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/src/Kconfig b/src/Kconfig
index 14c38fb..b14e554 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -316,10 +316,16 @@ menu "Hardware support"
         help
             Initialize the Memory Type Range Registers (on emulators).
     config PMTIMER
-        bool "Use ACPI timer"
+        bool "Support ACPI timer"
         default y
         help
-            Use the ACPI timer instead of the TSC for timekeeping (on qemu).
+            Detect and use the ACPI timer for timekeeping.
+    config TSC_TIMER
+        bool "Support CPU timestamp counter as timer"
+        default y
+        help
+            Support for using the CPU timestamp counter as an internal
+            timing source.
 endmenu
 
 menu "BIOS interfaces"
diff --git a/src/hw/timer.c b/src/hw/timer.c
index 5edc9fd..882b772 100644
--- a/src/hw/timer.c
+++ b/src/hw/timer.c
@@ -49,8 +49,8 @@
 #define PMTIMER_HZ 3579545      // Underlying Hz of the PM Timer
 #define PMTIMER_TO_PIT 3        // Ratio of pmtimer rate to pit rate
 
-u32 TimerKHz VARFSEG;
-u16 TimerPort VARFSEG;
+u32 TimerKHz VARFSEG = DIV_ROUND_UP(PMTIMER_HZ, 1000 * PMTIMER_TO_PIT);
+u16 TimerPort VARFSEG = PORT_PIT_COUNTER0;
 u8 ShiftTSC VARFSEG;
 
 
@@ -92,6 +92,7 @@ tsctimer_setup(void)
         t = (t + 1) >> 1;
     }
     TimerKHz = DIV_ROUND_UP((u32)t, 1000 * PMTIMER_TO_PIT);
+    TimerPort = 0;
 
     dprintf(1, "CPU Mhz=%u\n", (TimerKHz << ShiftTSC) / 1000);
 }
@@ -100,24 +101,16 @@ tsctimer_setup(void)
 void
 timer_setup(void)
 {
-    if (CONFIG_PMTIMER && TimerPort) {
-        dprintf(3, "pmtimer already configured; will not calibrate TSC\n");
+    if (!CONFIG_TSC_TIMER || (CONFIG_PMTIMER && TimerPort != PORT_PIT_COUNTER0))
         return;
-    }
 
+    // Check if CPU has a timestamp counter
     u32 eax, ebx, ecx, edx, cpuid_features = 0;
     cpuid(0, &eax, &ebx, &ecx, &edx);
     if (eax > 0)
         cpuid(1, &eax, &ebx, &ecx, &cpuid_features);
-
-    if (!(cpuid_features & CPUID_TSC)) {
-        TimerPort = PORT_PIT_COUNTER0;
-        TimerKHz = DIV_ROUND_UP(PMTIMER_HZ, 1000 * PMTIMER_TO_PIT);
-        dprintf(3, "386/486 class CPU. Using TSC emulation\n");
-        return;
-    }
-
-    tsctimer_setup();
+    if (cpuid_features & CPUID_TSC)
+        tsctimer_setup();
 }
 
 void
@@ -154,7 +147,7 @@ static u32
 timer_read(void)
 {
     u16 port = GET_GLOBAL(TimerPort);
-    if (!port)
+    if (CONFIG_TSC_TIMER && !port)
         // Read from CPU TSC
         return rdtscll() >> GET_GLOBAL(ShiftTSC);
     if (CONFIG_PMTIMER && port != PORT_PIT_COUNTER0)
-- 
1.9.3




More information about the SeaBIOS mailing list