summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/hppa/dev/clock.c103
-rw-r--r--sys/arch/hppa/hppa/machdep.c91
2 files changed, 129 insertions, 65 deletions
diff --git a/sys/arch/hppa/dev/clock.c b/sys/arch/hppa/dev/clock.c
index 9c8002f840b..4c594ab5ec7 100644
--- a/sys/arch/hppa/dev/clock.c
+++ b/sys/arch/hppa/dev/clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clock.c,v 1.29 2014/03/29 18:09:29 guenther Exp $ */
+/* $OpenBSD: clock.c,v 1.30 2020/05/01 19:56:11 kettenis Exp $ */
/*
* Copyright (c) 1998-2003 Michael Shalayeff
@@ -42,7 +42,6 @@
#include <machine/autoconf.h>
u_long cpu_hzticks;
-int timeset;
int cpu_hardclock(void *);
u_int itmr_get_timecount(struct timecounter *);
@@ -51,12 +50,50 @@ struct timecounter itmr_timecounter = {
itmr_get_timecount, NULL, 0xffffffff, 0, "itmr", 0, NULL
};
+extern todr_chip_handle_t todr_handle;
+struct todr_chip_handle pdc_todr;
+
+int
+pdc_gettime(struct todr_chip_handle *handle, struct timeval *tv)
+{
+ struct pdc_tod tod PDC_ALIGNMENT;
+ int error;
+
+ if ((error = pdc_call((iodcio_t)pdc, 1, PDC_TOD, PDC_TOD_READ,
+ &tod, 0, 0, 0, 0, 0))) {
+ printf("clock: failed to fetch (%d)\n", error);
+ return EIO;
+ }
+
+ tv->tv_sec = tod.sec;
+ tv->tv_usec = tod.usec;
+ return 0;
+}
+
+int
+pdc_settime(struct todr_chip_handle *handle, struct timeval *tv)
+{
+ int error;
+
+ if ((error = pdc_call((iodcio_t)pdc, 1, PDC_TOD, PDC_TOD_WRITE,
+ tv->tv_sec, tv->tv_usec))) {
+ printf("clock: failed to save (%d)\n", error);
+ return EIO;
+ }
+
+ return 0;
+}
+
void
cpu_initclocks(void)
{
struct cpu_info *ci = curcpu();
u_long __itmr;
+ pdc_todr.todr_gettime = pdc_gettime;
+ pdc_todr.todr_settime = pdc_settime;
+ todr_handle = &pdc_todr;
+
cpu_hzticks = (PAGE0->mem_10msec * 100) / hz;
itmr_timecounter.tc_frequency = PAGE0->mem_10msec * 100;
@@ -128,68 +165,6 @@ cpu_hardclock(void *v)
return (1);
}
-/*
- * initialize the system time from the time of day clock
- */
-void
-inittodr(time_t t)
-{
- struct pdc_tod tod PDC_ALIGNMENT;
- int error, tbad = 0;
- struct timespec ts;
-
- if (t < 12*SECYR) {
- printf ("WARNING: preposterous time in file system");
- t = 6*SECYR + 186*SECDAY + SECDAY/2;
- tbad = 1;
- }
-
- if ((error = pdc_call((iodcio_t)pdc,
- 1, PDC_TOD, PDC_TOD_READ, &tod, 0, 0, 0, 0, 0)))
- printf("clock: failed to fetch (%d)\n", error);
-
- ts.tv_sec = tod.sec;
- ts.tv_nsec = tod.usec * 1000;
- tc_setclock(&ts);
- timeset = 1;
-
- if (!tbad) {
- u_long dt;
-
- dt = (tod.sec < t)? t - tod.sec : tod.sec - t;
-
- if (dt < 2 * SECDAY)
- return;
- printf("WARNING: clock %s %ld days",
- tod.sec < t? "lost" : "gained", dt / SECDAY);
- }
-
- printf (" -- CHECK AND RESET THE DATE!\n");
-}
-
-/*
- * reset the time of day clock to the value in time
- */
-void
-resettodr()
-{
- struct timeval tv;
- int error;
-
- /*
- * We might have been called by boot() due to a crash early
- * on. Don't reset the clock chip in this case.
- */
- if (!timeset)
- return;
-
- microtime(&tv);
-
- if ((error = pdc_call((iodcio_t)pdc, 1, PDC_TOD, PDC_TOD_WRITE,
- tv.tv_sec, tv.tv_usec)))
- printf("clock: failed to save (%d)\n", error);
-}
-
void
setstatclockrate(int newhz)
{
diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c
index 8d90b560c11..75e3247e79c 100644
--- a/sys/arch/hppa/hppa/machdep.c
+++ b/sys/arch/hppa/hppa/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.255 2019/04/01 07:00:51 tedu Exp $ */
+/* $OpenBSD: machdep.c,v 1.256 2020/05/01 19:56:11 kettenis Exp $ */
/*
* Copyright (c) 1999-2003 Michael Shalayeff
@@ -1496,3 +1496,92 @@ blink_led_timeout(void *vsc)
t = (((averunnable.ldavg[0] + FSCALE) * hz) >> (FSHIFT + 1));
timeout_add(&sc->bls_to, t);
}
+
+#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");
+}