Split pmtimer wait and tsc measurement from pmtimer tsc calibration.
This commit is contained in:
parent
1933d37371
commit
d9a3bfead8
3 changed files with 69 additions and 17 deletions
|
@ -24,44 +24,35 @@
|
|||
#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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue