diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/macppc/macppc/clock.c | 106 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/machdep.c | 91 |
2 files changed, 114 insertions, 83 deletions
diff --git a/sys/arch/macppc/macppc/clock.c b/sys/arch/macppc/macppc/clock.c index d76cc9c5927..4a44a92cfc0 100644 --- a/sys/arch/macppc/macppc/clock.c +++ b/sys/arch/macppc/macppc/clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clock.c,v 1.42 2019/09/03 17:51:52 deraadt Exp $ */ +/* $OpenBSD: clock.c,v 1.43 2020/05/01 20:00:26 kettenis Exp $ */ /* $NetBSD: clock.c,v 1.1 1996/09/30 16:34:40 ws Exp $ */ /* @@ -42,6 +42,8 @@ #include <machine/pio.h> #include <machine/intr.h> #include <machine/vmparam.h> + +#include <dev/clock_subr.h> #include <dev/ofw/openfirm.h> void decr_intr(struct clockframe *frame); @@ -77,95 +79,31 @@ static struct evcount stat_count; static int clk_irq = PPC_CLK_IRQ; static int stat_irq = PPC_STAT_IRQ; +extern todr_chip_handle_t todr_handle; +struct todr_chip_handle rtc_todr; -/* - * Set up the system's time, given a `reasonable' time value. - */ -void -inittodr(time_t base) +int +rtc_gettime(struct todr_chip_handle *handle, struct timeval *tv) { - int badbase = 0, waszero = base == 0; - char *bad = NULL; - struct timeval tv; - struct timespec ts; - - if (base < 5 * SECYR) { - /* - * If base is 0, assume filesystem time is just unknown - * instead of preposterous. Don't bark. - */ - if (base != 0) - printf("WARNING: preposterous time in file system\n"); - /* not going to use it anyway, if the chip is readable */ - base = 21*SECYR + 186*SECDAY + SECDAY/2; - badbase = 1; - } - - if (time_read != NULL) { - time_t cursec; - (*time_read)(&cursec); - tv.tv_sec = cursec; - tv.tv_usec = 0; - } else { - /* force failure */ - tv.tv_sec = tv.tv_usec = 0; - } - - if (tv.tv_sec == 0) { - /* - * Believe the time in the file system for lack of - * anything better, resetting the clock. - */ - bad = "WARNING: unable to get date/time"; - tv.tv_sec = base; - tv.tv_usec = 0; - if (!badbase) - resettodr(); - } else { - int deltat; - - tv.tv_sec -= utc_offset; - deltat = tv.tv_sec - base; - - if (deltat < 0) - deltat = -deltat; - if (!(waszero || deltat < 2 * SECDAY)) { - printf("WARNING: clock %s %ld days", - tv.tv_sec < base ? "lost" : "gained", deltat / SECDAY); - bad = ""; - - if (tv.tv_sec < base && deltat > 1000 * SECDAY) { - printf(", using FS time"); - tv.tv_sec = base; - } - } - } + time_t sec; - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; - tc_setclock(&ts); + if (time_read == NULL) + return ENXIO; - if (bad) { - printf("%s", bad); - printf(" -- CHECK AND RESET THE DATE!\n"); - } + (*time_read)(&sec); + tv->tv_sec = sec - utc_offset; + tv->tv_usec = 0; + return 0; } -/* - * Similar to the above - */ -void -resettodr(void) +int +rtc_settime(struct todr_chip_handle *handle, struct timeval *tv) { - struct timeval tv; - - if (time_second == 1) - return; + if (time_write == NULL) + return ENXIO; - microtime(&tv); - - if (time_write != NULL) - (*time_write)(tv.tv_sec + utc_offset); + (*time_write)(tv->tv_sec + utc_offset); + return 0; } void @@ -290,6 +228,10 @@ cpu_initclocks(void) #endif } + rtc_todr.todr_gettime = rtc_gettime; + rtc_todr.todr_settime = rtc_settime; + todr_handle = &rtc_todr; + intrstate = ppc_intr_disable(); ticks_per_intr = ticks_per_sec / hz; diff --git a/sys/arch/macppc/macppc/machdep.c b/sys/arch/macppc/macppc/machdep.c index 513d577c724..1443413ee7a 100644 --- a/sys/arch/macppc/macppc/machdep.c +++ b/sys/arch/macppc/macppc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.186 2019/09/03 17:51:52 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.187 2020/05/01 20:00:26 kettenis Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -910,3 +910,92 @@ cpu_switchto(struct proc *oldproc, struct proc *newproc) cpu_switchto_asm(oldproc, newproc); } + +#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"); +} |