summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2008-07-15 22:49:02 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2008-07-15 22:49:02 +0000
commit0a9461c1de244904002f70a9dcc56a971248caff (patch)
tree324fed0dba8d103ebf4ddec442bbcf167836ddf8
parent4e9d9cd7c15d5d78eb82bf2c0bc05000bb56ee0a (diff)
Add a timecounter based on the $sys_tick register, and use it on machines
that have it. Initial diff from art@.
-rw-r--r--sys/arch/sparc64/sparc64/clock.c38
1 files 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);
+}