diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2012-09-08 19:24:29 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2012-09-08 19:24:29 +0000 |
commit | 65797db56d3ef9be78b5912eebf7c907d701e268 (patch) | |
tree | 82cac422516a413a1b4c19090200d2dcc40a0c35 /sys/arch/hp300 | |
parent | b4d0f3aa21b2a6f7b6944eea7cf9663d443aa0bd (diff) |
Switch hp300 to timecounters. From NetBSD via martin@
Diffstat (limited to 'sys/arch/hp300')
-rw-r--r-- | sys/arch/hp300/dev/dcm.c | 6 | ||||
-rw-r--r-- | sys/arch/hp300/hp300/clock.c | 103 | ||||
-rw-r--r-- | sys/arch/hp300/hp300/locore.s | 4 | ||||
-rw-r--r-- | sys/arch/hp300/include/_types.h | 5 |
4 files changed, 71 insertions, 47 deletions
diff --git a/sys/arch/hp300/dev/dcm.c b/sys/arch/hp300/dev/dcm.c index 3e329fc8ac5..6346eeb1f38 100644 --- a/sys/arch/hp300/dev/dcm.c +++ b/sys/arch/hp300/dev/dcm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dcm.c,v 1.35 2010/07/02 17:27:01 nicm Exp $ */ +/* $OpenBSD: dcm.c,v 1.36 2012/09/08 19:24:28 miod Exp $ */ /* $NetBSD: dcm.c,v 1.41 1997/05/05 20:59:16 thorpej Exp $ */ /* @@ -726,7 +726,7 @@ dcmintr(arg) * See if it is time to check/change the interrupt rate. */ if (dcmistype < 0 && - (i = time.tv_sec - dis->dis_time) >= dcminterval) { + (i = time_second - dis->dis_time) >= dcminterval) { /* * If currently per-character and averaged over 70 interrupts * per-second (66 is threshold of 600 baud) in last interval, @@ -750,7 +750,7 @@ dcmintr(arg) dcmrint(sc); } dis->dis_intr = dis->dis_char = 0; - dis->dis_time = time.tv_sec; + dis->dis_time = time_second; } return (1); } diff --git a/sys/arch/hp300/hp300/clock.c b/sys/arch/hp300/hp300/clock.c index 66b8188ece7..559d2e89090 100644 --- a/sys/arch/hp300/hp300/clock.c +++ b/sys/arch/hp300/hp300/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.14 2010/09/20 06:33:47 matthew Exp $ */ +/* $OpenBSD: clock.c,v 1.15 2012/09/08 19:24:28 miod Exp $ */ /* $NetBSD: clock.c,v 1.20 1997/04/27 20:43:38 thorpej Exp $ */ /* @@ -50,8 +50,8 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/tty.h> #include <sys/evcount.h> +#include <sys/timetc.h> #include <machine/psl.h> #include <machine/cpu.h> @@ -64,9 +64,10 @@ #include <sys/gmon.h> #endif -int clkstd[1]; +int clkstd[1]; +int clkint; /* clock interval, as loaded */ +uint32_t clkcounter; /* for timecounter */ -static int clkint; /* clock interval, as loaded */ /* * 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, @@ -89,6 +90,7 @@ volatile u_int8_t *bbcaddr = NULL; void clockintr(struct clockframe *); void statintr(struct clockframe *); +u_int mc6840_counter(struct timecounter *); void hp300_calibrate_delay(void); struct bbc_tm *gmt_to_bbc(long); @@ -117,6 +119,10 @@ struct evcount statcnt; */ #define COUNTS_PER_SEC (1000000 / CLK_RESOLUTION) +struct timecounter mc6840_tc = { + mc6840_counter, NULL, ~0, COUNTS_PER_SEC, "mc6840", 100, NULL +}; + /* * Calibrate the delay constant, based on Chuck Cranor's * mvme68k delay calibration algorithm. @@ -266,6 +272,8 @@ cpu_initclocks() clk->clk_cr1 = CLK_IENAB; clk->clk_cr2 = CLK_CR3; clk->clk_cr3 = CLK_IENAB; + + tc_init(&mc6840_tc); } /* @@ -329,43 +337,31 @@ statintr(fp) statclock(fp); } -/* - * Return the best possible estimate of the current time. - */ -void -microtime(tvp) - struct timeval *tvp; +u_int +mc6840_counter(struct timecounter *tc) { volatile struct clkreg *clk; - int s, u, t, u2, s2; + uint32_t ccounter, count; + static uint32_t lastcount; + int s; - /* - * Read registers from slowest-changing to fastest-changing, - * then re-read out to slowest. If the values read before the - * innermost match those read after, the innermost value is - * consistent with the outer values. If not, it may not be and - * we must retry. Typically this loop runs only once; occasionally - * it runs twice, and only rarely does it run longer. - * - * (Using this loop avoids the need to block interrupts.) - */ clk = (volatile struct clkreg *)clkstd[0]; - do { - s = time.tv_sec; - u = time.tv_usec; - asm volatile (" clrl %0; movpw %1@(5),%0" - : "=d" (t) : "a" (clk)); - u2 = time.tv_usec; - s2 = time.tv_sec; - } while (u != u2 || s != s2); - - u += (clkint - t) * CLK_RESOLUTION; - if (u >= 1000000) { /* normalize */ - s++; - u -= 1000000; + + s = splclock(); + ccounter = clkcounter; + /* XXX reading counter clears interrupt flag?? */ + __asm__ __volatile__ + ("clrl %0; movpw %1@(5),%0" : "=d" (count) : "a" (clk)); + splx(s); + + count = ccounter + (clkint - count); + if ((int32_t)(count - lastcount) < 0) { + /* XXX wrapped; maybe hardclock() is blocked more than 1/hz */ + count = lastcount + 1; } - tvp->tv_sec = s; - tvp->tv_usec = u; + lastcount = count; + + return count; } /* @@ -378,6 +374,20 @@ inittodr(base) { u_long timbuf = base; /* assume no battery clock exists */ static int bbcinited = 0; + int badbase = 0, waszero = base == 0; + struct timespec ts; + + if (base < (2012 - 1970) * SECYR) { + /* + * If base is 0, assume filesystem time is just unknown + * instead of preposterous. Don't bark. + */ + if (base != 0) + printf("WARNING: preposterous time in file system\n"); + /* not going to use it anyway, if the chip is readable */ + base = (2012 - 1970) * SECYR; + badbase = 1; + } /* XXX */ if (!bbcinited) { @@ -404,14 +414,23 @@ inittodr(base) timbuf = base; } } - if (base < 5*SECYR) { - printf("WARNING: preposterous time in file system"); - timbuf = 6*SECYR + 186*SECDAY + SECDAY/2; - printf(" -- CHECK AND RESET THE DATE!\n"); + + if (timbuf != base) { + int deltat = timbuf - base; + + if (deltat < 0) + deltat = -deltat; + if (!waszero && deltat >= 2 * SECDAY) + printf("WARNING: clock %s %d days" + " -- CHECK AND RESET THE DATE!\n", + timbuf < base ? "lost" : "gained", deltat / SECDAY); } /* Battery clock does not store usec's, so forget about it. */ - time.tv_sec = timbuf; + ts.tv_sec = timbuf; + ts.tv_nsec = 0; + + tc_setclock(&ts); } /* @@ -426,7 +445,7 @@ resettodr() if (bbcaddr == NULL) return; - tmptr = gmt_to_bbc(time.tv_sec); + tmptr = gmt_to_bbc(time_second); decimal_to_bbc(0, 1, tmptr->tm_sec); decimal_to_bbc(2, 3, tmptr->tm_min); diff --git a/sys/arch/hp300/hp300/locore.s b/sys/arch/hp300/hp300/locore.s index d5ba0536fd0..871a1a1d0e9 100644 --- a/sys/arch/hp300/hp300/locore.s +++ b/sys/arch/hp300/hp300/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.69 2012/01/22 13:13:06 miod Exp $ */ +/* $OpenBSD: locore.s,v 1.70 2012/09/08 19:24:28 miod Exp $ */ /* $NetBSD: locore.s,v 1.91 1998/11/11 06:41:25 thorpej Exp $ */ /* @@ -1127,6 +1127,8 @@ Lclkagain: btst #0,d0 | clear timer1 int immediately to jeq Lnotim1 | minimize chance of losing another movpw a0@(CLKMSB1),d1 | due to statintr processing delay + movl _C_LABEL(clkint),d1 | clkcounter += clkint + addl d1,_C_LABEL(clkcounter) Lnotim1: btst #2,d0 | timer3 interrupt? jeq Lnotim3 | no, skip statclock diff --git a/sys/arch/hp300/include/_types.h b/sys/arch/hp300/include/_types.h index c94a2348549..bb22f089bda 100644 --- a/sys/arch/hp300/include/_types.h +++ b/sys/arch/hp300/include/_types.h @@ -1,4 +1,4 @@ -/* $OpenBSD: _types.h,v 1.3 2011/03/23 16:54:34 pirofti Exp $ */ +/* $OpenBSD: _types.h,v 1.4 2012/09/08 19:24:28 miod Exp $ */ /* public domain */ @@ -7,4 +7,7 @@ #include <m68k/_types.h> +/* Feature test macros */ +#define __HAVE_TIMECOUNTER + #endif /* _MACHINE__TYPES_H_ */ |