diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-05-01 19:56:12 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-05-01 19:56:12 +0000 |
commit | 0c0b18ee9dfb67f89b29c080f9dbca0945ea8bd9 (patch) | |
tree | 84f95cc64a14a441de0a75c87730d402f191d41a /sys/arch | |
parent | 0fecffa9dd431154ee67185814131de2b0ef417c (diff) |
Use the same inittodr()/resettodr() implementation as on
amd64/arm64/armv7/i386/sparc64 and move it to the end of machdep.c. Rework the
actual implementation for the MC14818 compatible RTC into something that can
be used as a todr_handle just like on amd64.
ok mpi@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/hppa/dev/clock.c | 103 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/machdep.c | 91 |
2 files changed, 129 insertions, 65 deletions
diff --git a/sys/arch/hppa/dev/clock.c b/sys/arch/hppa/dev/clock.c index 9c8002f840b..4c594ab5ec7 100644 --- a/sys/arch/hppa/dev/clock.c +++ b/sys/arch/hppa/dev/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.29 2014/03/29 18:09:29 guenther Exp $ */ +/* $OpenBSD: clock.c,v 1.30 2020/05/01 19:56:11 kettenis Exp $ */ /* * Copyright (c) 1998-2003 Michael Shalayeff @@ -42,7 +42,6 @@ #include <machine/autoconf.h> u_long cpu_hzticks; -int timeset; int cpu_hardclock(void *); u_int itmr_get_timecount(struct timecounter *); @@ -51,12 +50,50 @@ struct timecounter itmr_timecounter = { itmr_get_timecount, NULL, 0xffffffff, 0, "itmr", 0, NULL }; +extern todr_chip_handle_t todr_handle; +struct todr_chip_handle pdc_todr; + +int +pdc_gettime(struct todr_chip_handle *handle, struct timeval *tv) +{ + struct pdc_tod tod PDC_ALIGNMENT; + int error; + + if ((error = pdc_call((iodcio_t)pdc, 1, PDC_TOD, PDC_TOD_READ, + &tod, 0, 0, 0, 0, 0))) { + printf("clock: failed to fetch (%d)\n", error); + return EIO; + } + + tv->tv_sec = tod.sec; + tv->tv_usec = tod.usec; + return 0; +} + +int +pdc_settime(struct todr_chip_handle *handle, struct timeval *tv) +{ + int error; + + if ((error = pdc_call((iodcio_t)pdc, 1, PDC_TOD, PDC_TOD_WRITE, + tv->tv_sec, tv->tv_usec))) { + printf("clock: failed to save (%d)\n", error); + return EIO; + } + + return 0; +} + void cpu_initclocks(void) { struct cpu_info *ci = curcpu(); u_long __itmr; + pdc_todr.todr_gettime = pdc_gettime; + pdc_todr.todr_settime = pdc_settime; + todr_handle = &pdc_todr; + cpu_hzticks = (PAGE0->mem_10msec * 100) / hz; itmr_timecounter.tc_frequency = PAGE0->mem_10msec * 100; @@ -128,68 +165,6 @@ cpu_hardclock(void *v) return (1); } -/* - * initialize the system time from the time of day clock - */ -void -inittodr(time_t t) -{ - struct pdc_tod tod PDC_ALIGNMENT; - int error, tbad = 0; - struct timespec ts; - - if (t < 12*SECYR) { - printf ("WARNING: preposterous time in file system"); - t = 6*SECYR + 186*SECDAY + SECDAY/2; - tbad = 1; - } - - if ((error = pdc_call((iodcio_t)pdc, - 1, PDC_TOD, PDC_TOD_READ, &tod, 0, 0, 0, 0, 0))) - printf("clock: failed to fetch (%d)\n", error); - - ts.tv_sec = tod.sec; - ts.tv_nsec = tod.usec * 1000; - tc_setclock(&ts); - timeset = 1; - - if (!tbad) { - u_long dt; - - dt = (tod.sec < t)? t - tod.sec : tod.sec - t; - - if (dt < 2 * SECDAY) - return; - printf("WARNING: clock %s %ld days", - tod.sec < t? "lost" : "gained", dt / SECDAY); - } - - printf (" -- CHECK AND RESET THE DATE!\n"); -} - -/* - * reset the time of day clock to the value in time - */ -void -resettodr() -{ - struct timeval tv; - int error; - - /* - * We might have been called by boot() due to a crash early - * on. Don't reset the clock chip in this case. - */ - if (!timeset) - return; - - microtime(&tv); - - if ((error = pdc_call((iodcio_t)pdc, 1, PDC_TOD, PDC_TOD_WRITE, - tv.tv_sec, tv.tv_usec))) - printf("clock: failed to save (%d)\n", error); -} - void setstatclockrate(int newhz) { diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index 8d90b560c11..75e3247e79c 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.255 2019/04/01 07:00:51 tedu Exp $ */ +/* $OpenBSD: machdep.c,v 1.256 2020/05/01 19:56:11 kettenis Exp $ */ /* * Copyright (c) 1999-2003 Michael Shalayeff @@ -1496,3 +1496,92 @@ blink_led_timeout(void *vsc) t = (((averunnable.ldavg[0] + FSCALE) * hz) >> (FSHIFT + 1)); timeout_add(&sc->bls_to, t); } + +#include <sys/timetc.h> +#include <dev/clock_subr.h> + +todr_chip_handle_t todr_handle; + +#define MINYEAR ((OpenBSD / 100) - 1) /* minimum plausible year */ + +/* + * inittodr: + * + * Initialize time from the time-of-day register. + */ +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 < (MINYEAR - 1970) * SECYR) { + /* + * 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: bad clock chip time\n"); + ts.tv_sec = rtctime.tv_sec; + ts.tv_nsec = rtctime.tv_usec * 1000; + tc_setclock(&ts); + 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 */ +#ifndef SMALL_KERNEL + printf("WARNING: clock %s %lld days\n", + rtctime.tv_sec < base ? "lost" : "gained", + (long long)(deltat / SECDAY)); +#endif + } + 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 (time_second == 1) + return; + + microtime(&rtctime); + + if (todr_handle != NULL && + todr_settime(todr_handle, &rtctime) != 0) + printf("WARNING: can't update clock chip time\n"); +} |