summaryrefslogtreecommitdiff
path: root/sys/arch/sh
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-05-11 13:27:39 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-05-11 13:27:39 +0000
commit89a04970bbafd86c6989de0dc63c92c05c672d75 (patch)
treea508a28b8d5f8081e93cbf9167d827be979f9a2f /sys/arch/sh
parent9cc9b6c9fc74e84fce54850e733a006d2a3f7fac (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.c95
-rw-r--r--sys/arch/sh/sh/sh_machdep.c95
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");
+}