diff options
Diffstat (limited to 'sys/arch/i386/i386/machdep.c')
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 91 |
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"); +} |