[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Use UEFI Time Service to calibrate TSC
From: |
Michael Chang |
Subject: |
[PATCH] Use UEFI Time Service to calibrate TSC |
Date: |
Mon, 9 Nov 2015 15:07:46 +0800 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
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
- [PATCH] Use UEFI Time Service to calibrate TSC,
Michael Chang <=
- Re: [PATCH] Use UEFI Time Service to calibrate TSC, Andrei Borzenkov, 2015/11/09
- Re: [PATCH] Use UEFI Time Service to calibrate TSC, Michael Chang, 2015/11/09
- Re: [PATCH] Use UEFI Time Service to calibrate TSC, Vladimir 'φ-coder/phcoder' Serbinenko, 2015/11/09
- Re: [PATCH] Use UEFI Time Service to calibrate TSC, Vladimir 'φ-coder/phcoder' Serbinenko, 2015/11/09
- Re: [PATCH] Use UEFI Time Service to calibrate TSC, Michael Chang, 2015/11/12
- Re: [PATCH] Use UEFI Time Service to calibrate TSC, Andrei Borzenkov, 2015/11/12
- Re: [PATCH] Use UEFI Time Service to calibrate TSC, Michael Chang, 2015/11/12