diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-05-11 13:27:39 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-05-11 13:27:39 +0000 |
commit | 89a04970bbafd86c6989de0dc63c92c05c672d75 (patch) | |
tree | a508a28b8d5f8081e93cbf9167d827be979f9a2f /sys/arch/sh | |
parent | 9cc9b6c9fc74e84fce54850e733a006d2a3f7fac (diff) |
Use the same inittodr()/resettodr() implementation as on
amd64/arm64/armv7/hppa/i386/macppc/mips64/sparc64 and move it to the end
of sh_machdep.c. Wrap the existing sh_clock.rtc hooks into something
that can be used as a todr_handle.
ok mpi@
Diffstat (limited to 'sys/arch/sh')
-rw-r--r-- | sys/arch/sh/sh/clock.c | 95 | ||||
-rw-r--r-- | sys/arch/sh/sh/sh_machdep.c | 95 |
2 files changed, 122 insertions, 68 deletions
diff --git a/sys/arch/sh/sh/clock.c b/sys/arch/sh/sh/clock.c index 6fafb457c52..00a66e35d5d 100644 --- a/sys/arch/sh/sh/clock.c +++ b/sys/arch/sh/sh/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.9 2016/03/05 17:16:33 tobiasu Exp $ */ +/* $OpenBSD: clock.c,v 1.10 2020/05/11 13:27:38 kettenis Exp $ */ /* $NetBSD: clock.c,v 1.32 2006/09/05 11:09:36 uwe Exp $ */ /*- @@ -223,6 +223,30 @@ delay(int n) _cpu_spin(sh_clock.cpucycle_1us * n); } +extern todr_chip_handle_t todr_handle; +struct todr_chip_handle rtc_todr; + +int +rtc_gettime(struct todr_chip_handle *handle, struct timeval *tv) +{ + struct clock_ymdhms dt; + + sh_clock.rtc.get(sh_clock.rtc._cookie, tv->tv_sec, &dt); + tv->tv_sec = clock_ymdhms_to_secs(&dt); + tv->tv_usec = 0; + return 0; +} + +int +rtc_settime(struct todr_chip_handle *handle, struct timeval *tv) +{ + struct clock_ymdhms dt; + + clock_secs_to_ymdhms(tv->tv_sec, &dt); + sh_clock.rtc.set(sh_clock.rtc._cookie, &dt); + return 0; +} + /* * Start the clock interrupt. */ @@ -286,73 +310,10 @@ cpu_initclocks(void) /* Make sure to start RTC */ if (sh_clock.rtc.init != NULL) sh_clock.rtc.init(sh_clock.rtc._cookie); -} - -void -inittodr(time_t base) -{ - struct clock_ymdhms dt; - struct timespec ts; - time_t rtc; - if (!sh_clock.rtc_initialized) - sh_clock.rtc_initialized = 1; - - sh_clock.rtc.get(sh_clock.rtc._cookie, base, &dt); - rtc = clock_ymdhms_to_secs(&dt); - -#ifdef DEBUG - printf("inittodr: %d/%d/%d/%d/%d/%d(%d)\n", dt.dt_year, - dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec, - dt.dt_wday); -#endif - - if (!(sh_clock.flags & SH_CLOCK_NOINITTODR) && - (rtc < base || - dt.dt_year < MINYEAR || - dt.dt_mon < 1 || dt.dt_mon > 12 || - dt.dt_wday > 6 || - dt.dt_day < 1 || dt.dt_day > 31 || - dt.dt_hour > 23 || dt.dt_min > 59 || dt.dt_sec > 59)) { - /* - * Believe the time in the file system for lack of - * anything better, resetting the RTC. - */ - ts.tv_sec = base; - ts.tv_nsec = 0; - tc_setclock(&ts); - printf("WARNING: preposterous clock chip time\n"); - resettodr(); - printf(" -- CHECK AND RESET THE DATE!\n"); - return; - } - - ts.tv_sec = rtc; - ts.tv_nsec = 0; - tc_setclock(&ts); - - return; -} - -void -resettodr(void) -{ - struct clock_ymdhms dt; - int s; - - if (!sh_clock.rtc_initialized) - return; - - s = splclock(); - clock_secs_to_ymdhms(time_second, &dt); - splx(s); - - sh_clock.rtc.set(sh_clock.rtc._cookie, &dt); -#ifdef DEBUG - printf("%s: %d/%d/%d/%d/%d/%d(%d)\n", __FUNCTION__, - dt.dt_year, dt.dt_mon, dt.dt_day, dt.dt_hour, dt.dt_min, dt.dt_sec, - dt.dt_wday); -#endif + rtc_todr.todr_gettime = rtc_gettime; + rtc_todr.todr_settime = rtc_settime; + todr_handle = &rtc_todr; } #ifdef SH3 diff --git a/sys/arch/sh/sh/sh_machdep.c b/sys/arch/sh/sh/sh_machdep.c index c6fd88b3a35..d44965a3954 100644 --- a/sys/arch/sh/sh/sh_machdep.c +++ b/sys/arch/sh/sh/sh_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sh_machdep.c,v 1.49 2019/07/07 14:41:55 deraadt Exp $ */ +/* $OpenBSD: sh_machdep.c,v 1.50 2020/05/11 13:27:38 kettenis Exp $ */ /* $NetBSD: sh3_machdep.c,v 1.59 2006/03/04 01:13:36 uwe Exp $ */ /* @@ -625,3 +625,96 @@ cpu_reset(void) #endif /* NOTREACHED */ } + + +#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; + + rtctime.tv_sec = base; + rtctime.tv_usec = 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"); +} |