summaryrefslogtreecommitdiff
path: root/sys/arch/i386/i386/machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/i386/i386/machdep.c')
-rw-r--r--sys/arch/i386/i386/machdep.c91
1 files changed, 90 insertions, 1 deletions
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c
index 765d8dd57ab..7600f40c446 100644
--- a/sys/arch/i386/i386/machdep.c
+++ b/sys/arch/i386/i386/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.631 2019/06/14 18:13:55 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.632 2020/04/29 08:53:45 kettenis Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
@@ -378,6 +378,7 @@ cpu_startup(void)
printf("%s", version);
startclocks();
+ rtcinit();
printf("real mem = %llu (%lluMB)\n",
(unsigned long long)ptoa((psize_t)physmem),
@@ -4037,3 +4038,91 @@ intr_barrier(void *ih)
sched_barrier(NULL);
}
+#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");
+}