All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Use UEFI Time Service to calibrate TSC
@ 2015-11-09  7:07 Michael Chang
  2015-11-09  7:29 ` Andrei Borzenkov
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Chang @ 2015-11-09  7:07 UTC (permalink / raw)
  To: grub-devel

This patch tries to detect PIT timer is broken and use UEFI Time Service
to calibrate TSC.
---
 grub-core/kern/i386/tsc.c |   33 +++++++++++++++++++++++++++++----
 1 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/grub-core/kern/i386/tsc.c b/grub-core/kern/i386/tsc.c
index bc441d0..bd24cea 100644
--- a/grub-core/kern/i386/tsc.c
+++ b/grub-core/kern/i386/tsc.c
@@ -29,6 +29,10 @@
 #include <grub/xen.h>
 #else
 #include <grub/i386/pit.h>
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/efi.h>
+#include <grub/efi/api.h>
+#endif
 #endif
 #include <grub/cpu/io.h>
 
@@ -72,7 +76,7 @@ grub_cpu_is_tsc_supported (void)
 }
 
 static void
-grub_pit_wait (grub_uint16_t tics)
+grub_pit_wait (grub_uint16_t tics, int *is_started)
 {
   /* Disable timer2 gate and speaker.  */
   grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT)
@@ -90,8 +94,17 @@ grub_pit_wait (grub_uint16_t tics)
 	     | GRUB_PIT_SPK_TMR2,
              GRUB_PIT_SPEAKER_PORT);
 
-  /* Wait.  */
-  while ((grub_inb (GRUB_PIT_SPEAKER_PORT) & GRUB_PIT_SPK_TMR2_LATCH) == 0x00);
+  if ((grub_inb (GRUB_PIT_SPEAKER_PORT) & GRUB_PIT_SPK_TMR2_LATCH))
+    {
+      /* The ticks have expired too fast to know the counting really started or not */
+      *is_started = 0;
+    }
+  else
+    {
+      *is_started = 1;
+      /* Wait.  */
+      while ((grub_inb (GRUB_PIT_SPEAKER_PORT) & GRUB_PIT_SPK_TMR2_LATCH) == 0x00);
+    }
 
   /* Disable timer2 gate and speaker.  */
   grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT)
@@ -117,11 +130,23 @@ calibrate_tsc (void)
 {
   /* First calibrate the TSC rate (relative, not absolute time). */
   grub_uint64_t end_tsc;
+  int is_started;
 
   tsc_boot_time = grub_get_tsc ();
-  grub_pit_wait (0xffff);
+  grub_pit_wait (0xffff, &is_started);
   end_tsc = grub_get_tsc ();
 
+#ifdef GRUB_MACHINE_EFI
+  /* The PIT is broken as 55ms is too sufficent to any cpu to catch it */
+  if (!is_started)
+    {
+      /* Use EFI Time Service to calibrate TSC */
+      tsc_boot_time = grub_get_tsc ();
+      efi_call_1 (grub_efi_system_table->boot_services->stall, 54925);
+      end_tsc = grub_get_tsc ();
+    }
+#endif
+
   grub_tsc_rate = 0;
   if (end_tsc > tsc_boot_time)
     grub_tsc_rate = grub_divmod64 ((55ULL << 32), end_tsc - tsc_boot_time, 0);
-- 
1.7.3.4



^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-11-12  9:33 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-09  7:07 [PATCH] Use UEFI Time Service to calibrate TSC Michael Chang
2015-11-09  7:29 ` Andrei Borzenkov
2015-11-09  8:03   ` Michael Chang
2015-11-09 13:23     ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-11-09 14:21       ` Vladimir 'φ-coder/phcoder' Serbinenko
2015-11-12  7:34         ` Michael Chang
2015-11-12  8:52           ` Andrei Borzenkov
2015-11-12  9:22             ` Michael Chang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.