From 8a2bbcc7bdb912845ac544c3f5a31f7b64ff387c Mon Sep 17 00:00:00 2001 From: kettenis Date: Tue, 15 Jul 2008 22:49:01 +0000 Subject: [PATCH] Add a timecounter based on the $sys_tick register, and use it on machines that have it. Initial diff from art@. --- sys/arch/sparc64/sparc64/clock.c | 38 +++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/sys/arch/sparc64/sparc64/clock.c b/sys/arch/sparc64/sparc64/clock.c index be2b1904b6d..f60899ccba0 100644 --- a/sys/arch/sparc64/sparc64/clock.c +++ b/sys/arch/sparc64/sparc64/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.43 2008/06/11 04:44:19 kettenis Exp $ */ +/* $OpenBSD: clock.c,v 1.44 2008/07/15 22:49:01 kettenis Exp $ */ /* $NetBSD: clock.c,v 1.41 2001/07/24 19:29:25 eeh Exp $ */ /* @@ -113,6 +113,12 @@ struct timecounter tick_timecounter = { tick_get_timecount, NULL, ~0u, 0, "tick", 0, NULL }; +u_int sys_tick_get_timecount(struct timecounter *); + +struct timecounter sys_tick_timecounter = { + sys_tick_get_timecount, NULL, ~0u, 0, "sys_tick", 1000, NULL +}; + /* * Statistics clock interval and variance, in usec. Variance must be a * power of two. Since this gives us an even number, not an odd number, @@ -540,12 +546,14 @@ myetheraddr(cp) * The frequencies of these clocks must be an even number of microseconds. */ void -cpu_initclocks() +cpu_initclocks(void) { int statint, minint; #ifdef DEBUG extern int intrdebug; #endif + u_int sys_tick_rate; + int impl = 0; #ifdef DEBUG /* Set a 1s clock */ @@ -569,7 +577,21 @@ cpu_initclocks() tick_timecounter.tc_frequency = cpu_clockrate; tc_init(&tick_timecounter); - + + /* + * UltraSPARC IIe processors do have a STICK register, but it + * lives on the PCI host bridge and isn't accessable through + * ASR24. + */ + if (CPU_ISSUN4U || CPU_ISSUN4US) + impl = (getver() & VER_IMPL) >> VER_IMPL_SHIFT; + + sys_tick_rate = getpropint(findroot(), "stick-frequency", 0); + if (sys_tick_rate > 0 && impl != IMPL_HUMMINGBIRD) { + sys_tick_timecounter.tc_frequency = sys_tick_rate; + tc_init(&sys_tick_timecounter); + } + /* * Now handle machines w/o counter-timers. */ @@ -910,3 +932,13 @@ tick_get_timecount(struct timecounter *tc) return (tick & ~0u); } + +u_int +sys_tick_get_timecount(struct timecounter *tc) +{ + u_int64_t tick; + + __asm __volatile("rd %%sys_tick, %0" : "=r" (tick) :); + + return (tick & ~0u); +} -- 2.20.1