summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2011-11-05 18:28:33 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2011-11-05 18:28:33 +0000
commite26de8845d8eb12463efd49e685847f4a8fa9319 (patch)
tree4a035f9ba5936afe9df487c3ff20e939e507f5e7 /sys/arch
parent7702ad293096b08815918cfaeab6a7387a580e42 (diff)
Introduce clock registration code, to deal with having multiple
delay/cpu_initclock operations from different drivers.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/beagle/beagle/intr.c131
-rw-r--r--sys/arch/beagle/dev/gptimer.c93
-rw-r--r--sys/arch/beagle/include/intr.h5
3 files changed, 142 insertions, 87 deletions
diff --git a/sys/arch/beagle/beagle/intr.c b/sys/arch/beagle/beagle/intr.c
index d9379d6c212..ffb3374c459 100644
--- a/sys/arch/beagle/beagle/intr.c
+++ b/sys/arch/beagle/beagle/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.1 2011/10/24 22:49:07 drahn Exp $ */
+/* $OpenBSD: intr.c,v 1.2 2011/11/05 18:28:32 drahn Exp $ */
/*
* Copyright (c) 2011 Dale Rahn <drahn@openbsd.org>
*
@@ -18,7 +18,9 @@
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/param.h>
+#include <sys/timetc.h>
+#include <dev/clock_subr.h>
#include <arm/cpufunc.h>
#include <machine/cpu.h>
#include <machine/intr.h>
@@ -286,3 +288,130 @@ arm_splassert_check(int wantipl, const char *func)
}
}
#endif
+
+void arm_dflt_delay(u_int usecs);
+
+struct {
+ void (*delay)(u_int);
+ void (*initclocks)(void);
+} arm_clock_func = {
+ arm_dflt_delay,
+ NULL
+};
+
+void
+arm_clock_register(void (*initclock)(void), void (*delay)(u_int))
+{
+ arm_clock_func.initclocks = initclock;
+ arm_clock_func.delay = delay;
+}
+
+
+void
+delay(u_int usec)
+{
+ arm_clock_func.delay(usec);
+}
+
+void
+cpu_initclocks(void)
+{
+ if (arm_clock_func.initclocks == NULL)
+ panic("initclocks function not initialized yet");
+
+ arm_clock_func.initclocks();
+}
+
+void
+arm_dflt_delay(u_int usecs)
+{
+ int j;
+ /* BAH - there is no good way to make this close */
+ /* but this isn't supposed to be used after the real clock attaches */
+ for (; usecs > 0; usecs--)
+ for (j = 100; j > 0; j--)
+ ;
+
+}
+
+todr_chip_handle_t todr_handle;
+
+/*
+ * inittodr:
+ *
+ * Initialize time from the time-of-day register.
+ */
+#define MINYEAR 2003 /* minimum plausible year */
+void
+inittodr(time_t base)
+{
+ time_t deltat;
+ struct timeval rtctime;
+ struct timespec ts;
+ int badbase;
+
+ if (base < (MINYEAR - 1970) * SECYR) {
+ printf("WARNING: preposterous time in file system\n");
+ /* read the system clock anyway */
+ base = (MINYEAR - 1970) * SECYR;
+ badbase = 1;
+ } else
+ badbase = 0;
+
+ if (todr_handle == NULL ||
+ todr_gettime(todr_handle, &rtctime) != 0 ||
+ rtctime.tv_sec == 0) {
+ /*
+ * Believe the time in the file system for lack of
+ * anything better, resetting the TODR.
+ */
+ rtctime.tv_sec = base;
+ rtctime.tv_usec = 0;
+ if (todr_handle != NULL && !badbase) {
+ printf("WARNING: preposterous clock chip time\n");
+ resettodr();
+ }
+ goto bad;
+ } else {
+ ts.tv_sec = rtctime.tv_sec;
+ ts.tv_nsec = rtctime.tv_usec * 1000;
+ tc_setclock(&ts);
+ }
+
+ if (!badbase) {
+ /*
+ * See if we gained/lost two or more days; if
+ * so, assume something is amiss.
+ */
+ deltat = rtctime.tv_sec - base;
+ if (deltat < 0)
+ deltat = -deltat;
+ if (deltat < 2 * SECDAY)
+ return; /* all is well */
+ printf("WARNING: clock %s %ld days\n",
+ rtctime.tv_sec < base ? "lost" : "gained",
+ (long)deltat / SECDAY);
+ }
+ bad:
+ printf("WARNING: CHECK AND RESET THE DATE!\n");
+}
+
+/*
+ * resettodr:
+ *
+ * Reset the time-of-day register with the current time.
+ */
+void
+resettodr(void)
+{
+ struct timeval rtctime;
+
+ if (rtctime.tv_sec == 0)
+ return;
+
+ microtime(&rtctime);
+
+ if (todr_handle != NULL &&
+ todr_settime(todr_handle, &rtctime) != 0)
+ printf("resettodr: failed to set time\n");
+}
diff --git a/sys/arch/beagle/dev/gptimer.c b/sys/arch/beagle/dev/gptimer.c
index 6115a6fd2ad..78b41ea3aa2 100644
--- a/sys/arch/beagle/dev/gptimer.c
+++ b/sys/arch/beagle/dev/gptimer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gptimer.c,v 1.8 2011/11/05 17:11:46 drahn Exp $ */
+/* $OpenBSD: gptimer.c,v 1.9 2011/11/05 18:28:32 drahn Exp $ */
/*
* Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
*
@@ -110,6 +110,8 @@ int gptimer_match(struct device *parent, void *v, void *aux);
void gptimer_attach(struct device *parent, struct device *self, void *args);
int gptimer_intr(void *frame);
void gptimer_wait(int reg);
+void gptimer_cpu_initclocks(void);
+void gptimer_delay(u_int);
bus_space_tag_t gptimer_iot;
bus_space_handle_t gptimer_ioh0, gptimer_ioh1;
@@ -185,6 +187,9 @@ gptimer_attach(struct device *parent, struct device *self, void *args)
}
else
panic("attaching too many gptimers at %x", aa->aa_addr);
+
+
+ arm_clock_register(gptimer_cpu_initclocks, gptimer_delay);
}
/*
@@ -289,7 +294,7 @@ gptimer_intr(void *frame)
*/
void
-cpu_initclocks()
+gptimer_cpu_initclocks()
{
// u_int32_t now;
stathz = 128;
@@ -379,7 +384,7 @@ microtime(struct timeval *tvp)
#endif
void
-delay(u_int usecs)
+gptimer_delay(u_int usecs)
{
u_int32_t clock, oclock, delta, delaycnt;
volatile int j;
@@ -442,88 +447,6 @@ setstatclockrate(int newhz)
*/
}
-todr_chip_handle_t todr_handle;
-
-/*
- * inittodr:
- *
- * Initialize time from the time-of-day register.
- */
-#define MINYEAR 2003 /* minimum plausible year */
-void
-inittodr(time_t base)
-{
- time_t deltat;
- struct timeval rtctime;
- struct timespec ts;
- int badbase;
-
- if (base < (MINYEAR - 1970) * SECYR) {
- printf("WARNING: preposterous time in file system\n");
- /* read the system clock anyway */
- base = (MINYEAR - 1970) * SECYR;
- badbase = 1;
- } else
- badbase = 0;
-
- if (todr_handle == NULL ||
- todr_gettime(todr_handle, &rtctime) != 0 ||
- rtctime.tv_sec == 0) {
- /*
- * Believe the time in the file system for lack of
- * anything better, resetting the TODR.
- */
- rtctime.tv_sec = base;
- rtctime.tv_usec = 0;
- if (todr_handle != NULL && !badbase) {
- printf("WARNING: preposterous clock chip time\n");
- resettodr();
- }
- goto bad;
- } else {
- ts.tv_sec = rtctime.tv_sec;
- ts.tv_nsec = rtctime.tv_usec * 1000;
- tc_setclock(&ts);
- }
-
- if (!badbase) {
- /*
- * See if we gained/lost two or more days; if
- * so, assume something is amiss.
- */
- deltat = rtctime.tv_sec - base;
- if (deltat < 0)
- deltat = -deltat;
- if (deltat < 2 * SECDAY)
- return; /* all is well */
- printf("WARNING: clock %s %ld days\n",
- rtctime.tv_sec < base ? "lost" : "gained",
- (long)deltat / SECDAY);
- }
- bad:
- printf("WARNING: CHECK AND RESET THE DATE!\n");
-}
-
-
-/*
- * resettodr:
- *
- * Reset the time-of-day register with the current time.
- */
-void
-resettodr(void)
-{
- struct timeval rtctime;
-
- if (rtctime.tv_sec == 0)
- return;
-
- microtime(&rtctime);
-
- if (todr_handle != NULL &&
- todr_settime(todr_handle, &rtctime) != 0)
- printf("resettodr: failed to set time\n");
-}
u_int
gptimer_get_timecount(struct timecounter *tc)
diff --git a/sys/arch/beagle/include/intr.h b/sys/arch/beagle/include/intr.h
index e1fd6cfee5e..d99a1cc6894 100644
--- a/sys/arch/beagle/include/intr.h
+++ b/sys/arch/beagle/include/intr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.h,v 1.4 2011/10/24 22:49:07 drahn Exp $ */
+/* $OpenBSD: intr.h,v 1.5 2011/11/05 18:28:32 drahn Exp $ */
/* $NetBSD: intr.h,v 1.12 2003/06/16 20:00:59 thorpej Exp $ */
/*
@@ -137,6 +137,9 @@ void *arm_intr_establish(int irqno, int level, int (*func)(void *),
void arm_intr_disestablish(void *cookie);
const char *arm_intr_string(void *cookie);
+/* XXX - this is probably the wrong location for this */
+void arm_clock_register(void (*)(void), void (*)(u_int));
+
#ifdef DIAGNOSTIC
/*
* Although this function is implemented in MI code, it must be in this MD