Use ITC on IA64 rather than broken routine based on daytime.
* grub-core/kern/efi/efi.c (grub_rtc_get_time_ms) [__ia64__]: Remove on ia64. (grub_get_rtc) [__ia64__]: Likewise. * grub-core/kern/ia64/efi/init.c (divisor): New variable. (get_itc): New function. (grub_rtc_get_time_ms): Likewise. (grub_machine_init): Calibrate ITC. * include/grub/efi/time.h (grub_get_rtc), (GRUB_TICKS_PER_SECOND): Keep only on non-ia64. Don't export since it's broken and used only if TSC is unavailable.
This commit is contained in:
parent
a176740446
commit
9e5e66d15e
4 changed files with 53 additions and 1 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2012-06-09 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Use ITC on IA64 rather than broken routine based on daytime.
|
||||
|
||||
* grub-core/kern/efi/efi.c (grub_rtc_get_time_ms) [__ia64__]: Remove on
|
||||
ia64.
|
||||
(grub_get_rtc) [__ia64__]: Likewise.
|
||||
* grub-core/kern/ia64/efi/init.c (divisor): New variable.
|
||||
(get_itc): New function.
|
||||
(grub_rtc_get_time_ms): Likewise.
|
||||
(grub_machine_init): Calibrate ITC.
|
||||
* include/grub/efi/time.h (grub_get_rtc), (GRUB_TICKS_PER_SECOND):
|
||||
Keep only on non-ia64. Don't export since it's broken and used only
|
||||
if TSC is unavailable.
|
||||
|
||||
2012-06-09 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/disk/efi/efidisk.c (find_parent_device): Return the parent
|
||||
|
|
|
@ -230,6 +230,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef __ia64__
|
||||
grub_uint64_t
|
||||
grub_rtc_get_time_ms (void)
|
||||
{
|
||||
|
@ -250,6 +251,7 @@ grub_get_rtc (void)
|
|||
{
|
||||
return grub_rtc_get_time_ms ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
|
|
|
@ -27,10 +27,43 @@
|
|||
#include <grub/kernel.h>
|
||||
#include <grub/efi/efi.h>
|
||||
|
||||
static grub_uint64_t divisor = 1;
|
||||
|
||||
static grub_uint64_t
|
||||
get_itc (void)
|
||||
{
|
||||
grub_uint64_t ret;
|
||||
asm volatile ("mov %0=ar.itc" : "=r" (ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
grub_uint64_t
|
||||
grub_rtc_get_time_ms (void)
|
||||
{
|
||||
return get_itc () / divisor;
|
||||
}
|
||||
|
||||
void
|
||||
grub_machine_init (void)
|
||||
{
|
||||
grub_efi_event_t event;
|
||||
grub_uint64_t before, after;
|
||||
grub_efi_uintn_t idx;
|
||||
grub_efi_init ();
|
||||
|
||||
efi_call_5 (grub_efi_system_table->boot_services->create_event,
|
||||
GRUB_EFI_EVT_TIMER, GRUB_EFI_TPL_CALLBACK, 0, 0, &event);
|
||||
|
||||
before = get_itc ();
|
||||
efi_call_3 (grub_efi_system_table->boot_services->set_timer, event,
|
||||
GRUB_EFI_TIMER_RELATIVE, 200000);
|
||||
efi_call_3 (grub_efi_system_table->boot_services->wait_for_event, 1,
|
||||
&event, &idx);
|
||||
after = get_itc ();
|
||||
efi_call_1 (grub_efi_system_table->boot_services->close_event, event);
|
||||
divisor = (after - before + 5) / 20;
|
||||
if (divisor == 0)
|
||||
divisor = 800000;
|
||||
grub_install_get_time_ms (grub_rtc_get_time_ms);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,9 +21,11 @@
|
|||
|
||||
#include <grub/symbol.h>
|
||||
|
||||
#ifndef __ia64__
|
||||
#define GRUB_TICKS_PER_SECOND 1000
|
||||
|
||||
/* Return the real time in ticks. */
|
||||
grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void);
|
||||
grub_uint32_t grub_get_rtc (void);
|
||||
#endif
|
||||
|
||||
#endif /* ! GRUB_EFI_TIME_HEADER */
|
||||
|
|
Loading…
Reference in a new issue