diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-11 04:01:55 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:12:17 -0500 |
commit | 4bdff41464c2954c6f62f849df0e73eb9fa21c65 (patch) | |
tree | 781d3d844f87cf66b780874c367852af20ca9acc /arch/sparc64/kernel/time.c | |
parent | 36a68e77c554f1ef1c206fd618e6daf82d3e38a3 (diff) |
[SPARC64]: Fetch bootup time of day from Hypervisor.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/time.c')
-rw-r--r-- | arch/sparc64/kernel/time.c | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index a22930d62adf..24681b9b4426 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
@@ -683,6 +683,48 @@ static void __init set_system_time(void) | |||
683 | } | 683 | } |
684 | } | 684 | } |
685 | 685 | ||
686 | /* davem suggests we keep this within the 4M locked kernel image */ | ||
687 | static u32 starfire_get_time(void) | ||
688 | { | ||
689 | static char obp_gettod[32]; | ||
690 | static u32 unix_tod; | ||
691 | |||
692 | sprintf(obp_gettod, "h# %08x unix-gettod", | ||
693 | (unsigned int) (long) &unix_tod); | ||
694 | prom_feval(obp_gettod); | ||
695 | |||
696 | return unix_tod; | ||
697 | } | ||
698 | |||
699 | static u32 hypervisor_get_time(void) | ||
700 | { | ||
701 | register unsigned long func asm("%o5"); | ||
702 | register unsigned long arg0 asm("%o0"); | ||
703 | register unsigned long arg1 asm("%o1"); | ||
704 | int retries = 10000; | ||
705 | |||
706 | retry: | ||
707 | func = HV_FAST_TOD_GET; | ||
708 | arg0 = 0; | ||
709 | arg1 = 0; | ||
710 | __asm__ __volatile__("ta %6" | ||
711 | : "=&r" (func), "=&r" (arg0), "=&r" (arg1) | ||
712 | : "0" (func), "1" (arg0), "2" (arg1), | ||
713 | "i" (HV_FAST_TRAP)); | ||
714 | if (arg0 == HV_EOK) | ||
715 | return arg1; | ||
716 | if (arg0 == HV_EWOULDBLOCK) { | ||
717 | if (--retries > 0) { | ||
718 | udelay(100); | ||
719 | goto retry; | ||
720 | } | ||
721 | printk(KERN_WARNING "SUN4V: tod_get() timed out.\n"); | ||
722 | return 0; | ||
723 | } | ||
724 | printk(KERN_WARNING "SUN4V: tod_get() not supported.\n"); | ||
725 | return 0; | ||
726 | } | ||
727 | |||
686 | void __init clock_probe(void) | 728 | void __init clock_probe(void) |
687 | { | 729 | { |
688 | struct linux_prom_registers clk_reg[2]; | 730 | struct linux_prom_registers clk_reg[2]; |
@@ -702,14 +744,14 @@ void __init clock_probe(void) | |||
702 | 744 | ||
703 | 745 | ||
704 | if (this_is_starfire) { | 746 | if (this_is_starfire) { |
705 | /* davem suggests we keep this within the 4M locked kernel image */ | 747 | xtime.tv_sec = starfire_get_time(); |
706 | static char obp_gettod[256]; | 748 | xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); |
707 | static u32 unix_tod; | 749 | set_normalized_timespec(&wall_to_monotonic, |
708 | 750 | -xtime.tv_sec, -xtime.tv_nsec); | |
709 | sprintf(obp_gettod, "h# %08x unix-gettod", | 751 | return; |
710 | (unsigned int) (long) &unix_tod); | 752 | } |
711 | prom_feval(obp_gettod); | 753 | if (tlb_type == hypervisor) { |
712 | xtime.tv_sec = unix_tod; | 754 | xtime.tv_sec = hypervisor_get_time(); |
713 | xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); | 755 | xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); |
714 | set_normalized_timespec(&wall_to_monotonic, | 756 | set_normalized_timespec(&wall_to_monotonic, |
715 | -xtime.tv_sec, -xtime.tv_nsec); | 757 | -xtime.tv_sec, -xtime.tv_nsec); |