diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2011-11-05 18:28:33 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2011-11-05 18:28:33 +0000 |
commit | e26de8845d8eb12463efd49e685847f4a8fa9319 (patch) | |
tree | 4a035f9ba5936afe9df487c3ff20e939e507f5e7 /sys/arch | |
parent | 7702ad293096b08815918cfaeab6a7387a580e42 (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.c | 131 | ||||
-rw-r--r-- | sys/arch/beagle/dev/gptimer.c | 93 | ||||
-rw-r--r-- | sys/arch/beagle/include/intr.h | 5 |
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 |