]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Split pmtimer wait and tsc measurement from pmtimer tsc calibration.
authorVladimir Serbinenko <phcoder@gmail.com>
Fri, 12 Feb 2016 10:40:51 +0000 (11:40 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Fri, 12 Feb 2016 10:40:51 +0000 (11:40 +0100)
grub-core/Makefile.am
grub-core/kern/i386/tsc_pmtimer.c
include/grub/i386/pmtimer.h [new file with mode: 0644]

index 90502cb1e1f947d223cd4c93f8762ffa15a6f7bf..04e9395fd949460672c1113c3d49c90a5d4471ec 100644 (file)
@@ -107,6 +107,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
 endif
 
 if COND_i386_coreboot
@@ -162,6 +163,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h
 endif
 
 if COND_ia64_efi
index 2495e6fd432366ec4fc93c9db4cd73cca571026d..c9c36169978f2f045cac531bf20909a8e868685d 100644 (file)
 #include <grub/time.h>
 #include <grub/misc.h>
 #include <grub/i386/tsc.h>
+#include <grub/i386/pmtimer.h>
 #include <grub/acpi.h>
 #include <grub/cpu/io.h>
 
-int
-grub_tsc_calibrate_from_pmtimer (void)
+grub_uint64_t
+grub_pmtimer_wait_count_tsc (grub_port_t pmtimer,
+                            grub_uint16_t num_pm_ticks)
 {
   grub_uint32_t start;
   grub_uint32_t last;
   grub_uint32_t cur, end;
-  struct grub_acpi_fadt *fadt;
-  grub_port_t p;
   grub_uint64_t start_tsc;
   grub_uint64_t end_tsc;
   int num_iter = 0;
 
-  fadt = grub_acpi_find_fadt ();
-  if (!fadt)
-    return 0;
-  p = fadt->pmtimer;
-  if (!p)
-    return 0;
-
-  start = grub_inl (p) & 0xffffff;
+  start = grub_inl (pmtimer) & 0xffffff;
   last = start;
-  /* It's 3.579545 MHz clock. Wait 1 ms.  */
-  end = start + 3580;
+  end = start + num_pm_ticks;
   start_tsc = grub_get_tsc ();
   while (1)
     {
-      cur = grub_inl (p) & 0xffffff;
+      cur = grub_inl (pmtimer) & 0xffffff;
       if (cur < last)
        cur |= 0x1000000;
       num_iter++;
       if (cur >= end)
        {
          end_tsc = grub_get_tsc ();
-         grub_tsc_rate = grub_divmod64 ((1ULL << 32), end_tsc - start_tsc, 0);
-         return 1;
+         return end_tsc - start_tsc;
        }
       /* Check for broken PM timer.
         50000000 TSCs is between 5 ms (10GHz) and 200 ms (250 MHz)
@@ -73,3 +64,25 @@ grub_tsc_calibrate_from_pmtimer (void)
       }
     }
 }
+
+int
+grub_tsc_calibrate_from_pmtimer (void)
+{
+  struct grub_acpi_fadt *fadt;
+  grub_port_t pmtimer;
+  grub_uint64_t tsc_diff;
+
+  fadt = grub_acpi_find_fadt ();
+  if (!fadt)
+    return 0;
+  pmtimer = fadt->pmtimer;
+  if (!pmtimer)
+    return 0;
+
+  /* It's 3.579545 MHz clock. Wait 1 ms.  */
+  tsc_diff = grub_pmtimer_wait_count_tsc (pmtimer, 3580);
+  if (tsc_diff == 0)
+    return 0;
+  grub_tsc_rate = grub_divmod64 ((1ULL << 32), tsc_diff, 0);
+  return 1;
+}
diff --git a/include/grub/i386/pmtimer.h b/include/grub/i386/pmtimer.h
new file mode 100644 (file)
index 0000000..ac09180
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KERNEL_CPU_PMTIMER_HEADER
+#define KERNEL_CPU_PMTIMER_HEADER   1
+
+#include <grub/i386/tsc.h>
+#include <grub/i386/io.h>
+
+/*
+  Preconditions:
+  * Caller has ensured that both pmtimer and tsc are supported
+  * 1 <= num_pm_ticks <= 3580
+  Return:
+  * Number of TSC ticks elapsed
+  * 0 on failure.
+*/
+grub_uint64_t
+EXPORT_FUNC(grub_pmtimer_wait_count_tsc) (grub_port_t pmtimer,
+                                         grub_uint16_t num_pm_ticks);
+
+#endif