Subject: generic todr support for pmax
To: None <port-pmax@netbsd.org>
From: Garrett D'Amore <garrett@damore.org>
List: port-pmax
Date: 09/15/2006 17:51:56
This is a multi-part message in MIME format.
--------------060202010003040503040603
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Here's my swag at generic TODR support for pmax. Kinda ugly, but
hopefully it will work. Compile tested only.
-- Garrett
--------------060202010003040503040603
Content-Type: text/x-patch;
name="pmax.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="pmax.diff"
Index: dev/dec/clockvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/dec/clockvar.h,v
retrieving revision 1.8
diff -d -p -u -r1.8 clockvar.h
--- dev/dec/clockvar.h 11 Dec 2005 12:21:20 -0000 1.8
+++ dev/dec/clockvar.h 16 Sep 2006 00:21:47 -0000
@@ -32,22 +32,6 @@
*/
/*
- * clocktime structure:
- *
- * structure passed to TOY clocks when setting them. broken out this
- * way, so that the time_t -> field conversion can be shared.
- */
-struct clocktime {
- int year; /* year - 1900 */
- int mon; /* month (1 - 12) */
- int day; /* day (1 - 31) */
- int hour; /* hour (0 - 23) */
- int min; /* minute (0 - 59) */
- int sec; /* second (0 - 59) */
- int dow; /* day of week (0 - 6; 0 = Sunday) */
-};
-
-/*
* clockfns structure:
*
* function switch used by chip-independent clock code, to access
@@ -55,8 +39,6 @@ struct clocktime {
*/
struct clockfns {
void (*cf_init)(struct device *);
- void (*cf_get)(struct device *, time_t, struct clocktime *);
- void (*cf_set)(struct device *, struct clocktime *);
};
void clockattach(struct device *, const struct clockfns *);
Index: dev/dec/mcclock.c
===================================================================
RCS file: /cvsroot/src/sys/dev/dec/mcclock.c,v
retrieving revision 1.17
diff -d -p -u -r1.17 mcclock.c
--- dev/dec/mcclock.c 11 Dec 2005 12:21:20 -0000 1.17
+++ dev/dec/mcclock.c 16 Sep 2006 00:21:47 -0000
@@ -34,6 +34,7 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock.c,v
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <dev/clock_subr.h>
#include <dev/dec/clockvar.h>
#include <dev/dec/mcclockvar.h>
@@ -51,11 +52,11 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock.c,v
void mcclock_init(struct device *);
-void mcclock_get(struct device *, time_t, struct clocktime *);
-void mcclock_set(struct device *, struct clocktime *);
+int mcclock_get(todr_chip_handle_t, volatile struct timeval *);
+int mcclock_set(todr_chip_handle_t, volatile struct timeval *);
const struct clockfns mcclock_clockfns = {
- mcclock_init, mcclock_get, mcclock_set,
+ mcclock_init,
};
#define mc146818_write(dev, reg, datum) \
@@ -76,7 +77,10 @@ mcclock_attach(sc, busfns)
/* Turn interrupts off, just in case. */
mc146818_write(sc, MC_REGB, MC_REGB_BINARY | MC_REGB_24HR);
- clockattach(&sc->sc_dev, &mcclock_clockfns);
+ sc->sc_todr.todr_gettime = mcclock_get;
+ sc->sc_todr.todr_settime = mcclock_set;
+ sc->sc_todr.cookie = sc;
+ todr_attach(&sc->sc_todr);
}
void
@@ -133,56 +137,107 @@ again:
}
/*
+ * Experiments (and passing years) show that Decstation PROMS
+ * assume the kernel uses the clock chip as a time-of-year clock.
+ * The PROM assumes the clock is always set to 1972 or 1973, and contains
+ * time-of-year in seconds. The PROM checks the clock at boot time,
+ * and if it's outside that range, sets it to 1972-01-01.
+ *
+ * XXX should be at the mc146818 layer?
+*/
+
+/*
* Get the time of day, based on the clock's value and/or the base value.
*/
-void
-mcclock_get(dev, base, ct)
- struct device *dev;
- time_t base;
- struct clocktime *ct;
+int
+mcclock_get(todr_chip_handle_t tch, volatile struct timeval *tvp)
{
- struct mcclock_softc *sc = (struct mcclock_softc *)dev;
+ struct mcclock_softc *sc = (struct mcclock_softc *)tch->cookie;
+ uint32_t yearsecs;
mc_todregs regs;
int s;
+ struct clock_ymdhms dt;
s = splclock();
MC146818_GETTOD(sc, ®s)
splx(s);
- ct->sec = regs[MC_SEC];
- ct->min = regs[MC_MIN];
- ct->hour = regs[MC_HOUR];
- ct->dow = regs[MC_DOW];
- ct->day = regs[MC_DOM];
- ct->mon = regs[MC_MONTH];
- ct->year = regs[MC_YEAR];
+ dt.dt_sec = regs[MC_SEC];
+ dt.dt_min = regs[MC_MIN];
+ dt.dt_hour = regs[MC_HOUR];
+ dt.dt_day = regs[MC_DOM];
+ dt.dt_mon = regs[MC_MONTH];
+ dt.dt_year = 1972;
+
+ yearsecs = clock_ymdhms_to_secs(&dt) - (72 - 70) * SECYR;
+
+ /*
+ * Take the actual year from the filesystem if possible;
+ * allow for 2 days of clock loss and 363 days of clock gain.
+ */
+ dt.dt_year = 1972; /* or MINYEAR or base/SECYR+1970 ... */
+ dt.dt_mon = 1;
+ dt.dt_day = 1;
+ dt.dt_hour = 0;
+ dt.dt_min = 0;
+ dt.dt_sec = 0;
+ for(;;) {
+ tvp->tv_sec = yearsecs + clock_ymdhms_to_secs(&dt);
+ if (tvp->tv_sec > tch->base_time - 2 * SECDAY)
+ break;
+ dt.dt_year++;
+ }
+
+ tvp->tv_usec = 0;
+ return 0;
}
/*
* Reset the TODR based on the time value.
*/
-void
-mcclock_set(dev, ct)
- struct device *dev;
- struct clocktime *ct;
+int
+mcclock_set(todr_chip_handle_t tch, volatile struct timeval *tvp)
{
- struct mcclock_softc *sc = (struct mcclock_softc *)dev;
+ struct mcclock_softc *sc = (struct mcclock_softc *)tch->cookie;
+ struct clock_ymdhms dt;
+ uint32_t yearsecs;
mc_todregs regs;
int s;
+ /*
+ * calculate seconds relative to this year
+ */
+ clock_secs_to_ymdhms(tvp->tv_sec, &dt); /* get the year */
+ dt.dt_mon = 1;
+ dt.dt_day = 1;
+ dt.dt_hour = 0;
+ dt.dt_min = 0;
+ dt.dt_sec = 0;
+ yearsecs = tvp->tv_sec - clock_ymdhms_to_secs(&dt);
+
+#define first72 ((72 - 70) * SECYR)
+ clock_secs_to_ymdhms(first72 + yearsecs, &dt);
+
+#ifdef DEBUG
+ if (dt.dt_year != 1972)
+ printf("resettodr: botch (%ld, %ld)\n", yearsecs, time.tv_sec);
+#endif
+
s = splclock();
MC146818_GETTOD(sc, ®s);
splx(s);
- regs[MC_SEC] = ct->sec;
- regs[MC_MIN] = ct->min;
- regs[MC_HOUR] = ct->hour;
- regs[MC_DOW] = ct->dow;
- regs[MC_DOM] = ct->day;
- regs[MC_MONTH] = ct->mon;
- regs[MC_YEAR] = ct->year;
+ regs[MC_SEC] = dt.dt_sec;
+ regs[MC_MIN] = dt.dt_min;
+ regs[MC_HOUR] = dt.dt_hour;
+ regs[MC_DOW] = dt.dt_wday;
+ regs[MC_DOM] = dt.dt_day;
+ regs[MC_MONTH] = dt.dt_mon;
+ regs[MC_YEAR] = dt.dt_year;
s = splclock();
MC146818_PUTTOD(sc, ®s);
splx(s);
+
+ return 0;
}
Index: dev/dec/mcclock_pad32.c
===================================================================
RCS file: /cvsroot/src/sys/dev/dec/mcclock_pad32.c,v
retrieving revision 1.13
diff -d -p -u -r1.13 mcclock_pad32.c
--- dev/dec/mcclock_pad32.c 11 Dec 2005 12:21:20 -0000 1.13
+++ dev/dec/mcclock_pad32.c 16 Sep 2006 00:21:47 -0000
@@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock_pad3
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <dev/clock_subr.h>
#include <machine/autoconf.h>
#include <dev/dec/clockvar.h>
Index: dev/dec/mcclockvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/dec/mcclockvar.h,v
retrieving revision 1.6
diff -d -p -u -r1.6 mcclockvar.h
--- dev/dec/mcclockvar.h 11 Dec 2005 12:21:20 -0000 1.6
+++ dev/dec/mcclockvar.h 16 Sep 2006 00:21:47 -0000
@@ -30,6 +30,7 @@
struct mcclock_softc {
struct device sc_dev;
const struct mcclock_busfns *sc_busfns;
+ struct todr_chip_handle sc_todr;
};
struct mcclock_busfns {
Index: arch/pmax/ibus/mcclock_ibus.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pmax/ibus/mcclock_ibus.c,v
retrieving revision 1.12
diff -d -p -u -r1.12 mcclock_ibus.c
--- arch/pmax/ibus/mcclock_ibus.c 2 Oct 2002 04:15:09 -0000 1.12
+++ arch/pmax/ibus/mcclock_ibus.c 16 Sep 2006 00:21:47 -0000
@@ -34,6 +34,7 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock_ibus
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/systm.h>
+#include <dev/clock_subr.h>
#include <dev/dec/mcclockvar.h>
#include <dev/dec/mcclock_pad32.h>
Index: arch/pmax/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/pmax/include/types.h,v
retrieving revision 1.21
diff -d -p -u -r1.21 types.h
--- arch/pmax/include/types.h 5 Aug 2002 02:13:15 -0000 1.21
+++ arch/pmax/include/types.h 16 Sep 2006 00:21:47 -0000
@@ -4,6 +4,7 @@
#define __HAVE_DEVICE_REGISTER
#define __HAVE_GENERIC_SOFT_INTERRUPTS
+#define __HAVE_GENERIC_TODR
/* MIPS specific options */
#define __HAVE_BOOTINFO_H
Index: arch/pmax/pmax/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pmax/pmax/clock.c,v
retrieving revision 1.34
diff -d -p -u -r1.34 clock.c
--- arch/pmax/pmax/clock.c 11 Dec 2005 12:18:39 -0000 1.34
+++ arch/pmax/pmax/clock.c 16 Sep 2006 00:21:47 -0000
@@ -194,160 +194,3 @@ setstatclockrate(newhz)
/* nothing we can do */
}
-/*
- * Experiments (and passing years) show that Decstation PROMS
- * assume the kernel uses the clock chip as a time-of-year clock.
- * The PROM assumes the clock is always set to 1972 or 1973, and contains
- * time-of-year in seconds. The PROM checks the clock at boot time,
- * and if it's outside that range, sets it to 1972-01-01.
- *
- * XXX should be at the mc146818 layer?
-*/
-
-/*
- * Initialze the time of day register, based on the time base which is, e.g.
- * from a filesystem. Base provides the time to within six months,
- * and the time of year clock (if any) provides the rest.
- */
-void
-inittodr(base)
- time_t base;
-{
- struct clocktime ct;
- struct clock_ymdhms dt;
- time_t yearsecs;
- time_t deltat;
- int badbase;
-
- if (base < (MINYEAR-1970)*SECYR) {
- printf("WARNING: preposterous time in file system");
- /* read the system clock anyway */
- base = (MINYEAR-1970)*SECYR;
- badbase = 1;
- } else
- badbase = 0;
-
- (*clockfns->cf_get)(clockdev, base, &ct);
-#ifdef DEBUG
- printf("readclock: %d/%d/%d/%d/%d/%d", ct.year, ct.mon, ct.day,
- ct.hour, ct.min, ct.sec);
-#endif
- clockinitted = 1;
-
- /* simple sanity checks */
- if (ct.year < 70 || ct.mon < 1 || ct.mon > 12 || ct.day < 1 ||
- ct.day > 31 || ct.hour > 23 || ct.min > 59 || ct.sec > 59) {
- /*
- * Believe the time in the file system for lack of
- * anything better, resetting the TODR.
- */
- time.tv_sec = base;
- if (!badbase) {
- printf("WARNING: preposterous clock chip time\n");
- resettodr();
- }
- goto bad;
- }
-
- /*
- * The clock lives in 1972 (leapyear!);
- * calculate seconds relative to this year.
- */
- dt.dt_year = 1972;
- dt.dt_mon = ct.mon;
- dt.dt_day = ct.day;
- dt.dt_hour = ct.hour;
- dt.dt_min = ct.min;
- dt.dt_sec = ct.sec;
- yearsecs = clock_ymdhms_to_secs(&dt) - (72 - 70) * SECYR;
-
- /*
- * Take the actual year from the filesystem if possible;
- * allow for 2 days of clock loss and 363 days of clock gain.
- */
- dt.dt_year = 1972; /* or MINYEAR or base/SECYR+1970 ... */
- dt.dt_mon = 1;
- dt.dt_day = 1;
- dt.dt_hour = 0;
- dt.dt_min = 0;
- dt.dt_sec = 0;
- for(;;) {
- time.tv_sec = yearsecs + clock_ymdhms_to_secs(&dt);
- if (badbase || (time.tv_sec > base - 2 * SECDAY))
- break;
- dt.dt_year++;
- }
-#ifdef DEBUG
- printf("=>%ld (%ld)\n", time.tv_sec, base);
-#endif
-
- if (!badbase) {
- /*
- * See if we gained/lost two or more days;
- * if so, assume something is amiss.
- */
- deltat = time.tv_sec - base;
- if (deltat < 0)
- deltat = -deltat;
- if (deltat < 2 * SECDAY)
- return;
- printf("WARNING: clock %s %d days",
- time.tv_sec < base ? "lost" : "gained",
- (int) (deltat / SECDAY));
- }
-bad:
- printf(" -- CHECK AND RESET THE DATE!\n");
-}
-
-/*
- * Reset the TODR based on the time value; used when the TODR
- * has a preposterous value and also when the time is reset
- * by the stime system call. Also called when the TODR goes past
- * TODRZERO + 100*(SECYEAR+2*SECDAY) (e.g. on Jan 2 just after midnight)
- * to wrap the TODR around.
- */
-void
-resettodr()
-{
- time_t yearsecs;
- struct clock_ymdhms dt;
- struct clocktime ct;
-
- if (!clockinitted)
- return;
-
- /*
- * calculate seconds relative to this year
- */
- clock_secs_to_ymdhms(time.tv_sec, &dt); /* get the year */
- dt.dt_mon = 1;
- dt.dt_day = 1;
- dt.dt_hour = 0;
- dt.dt_min = 0;
- dt.dt_sec = 0;
- yearsecs = time.tv_sec - clock_ymdhms_to_secs(&dt);
-
- /*
- * The clock lives in 1972 (leapyear!); calc fictious date.
- */
-#define first72 ((72 - 70) * SECYR)
- clock_secs_to_ymdhms(first72 + yearsecs, &dt);
-
-#ifdef DEBUG
- if (dt.dt_year != 1972)
- printf("resettodr: botch (%ld, %ld)\n", yearsecs, time.tv_sec);
-#endif
- ct.year = dt.dt_year % 100; /* rt clock wants 2 digits */
- ct.mon = dt.dt_mon;
- ct.day = dt.dt_day;
- ct.hour = dt.dt_hour;
- ct.min = dt.dt_min;
- ct.sec = dt.dt_sec;
- ct.dow = dt.dt_wday;
-#ifdef DEBUG
- printf("setclock: %d/%d/%d/%d/%d/%d\n", ct.year, ct.mon, ct.day,
- ct.hour, ct.min, ct.sec);
-#endif
-
- (*clockfns->cf_set)(clockdev, &ct);
-}
Index: arch/pmax/tc/mcclock_ioasic.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pmax/tc/mcclock_ioasic.c,v
retrieving revision 1.18
diff -d -p -u -r1.18 mcclock_ioasic.c
--- arch/pmax/tc/mcclock_ioasic.c 2 Oct 2002 04:15:10 -0000 1.18
+++ arch/pmax/tc/mcclock_ioasic.c 16 Sep 2006 00:21:47 -0000
@@ -33,6 +33,7 @@ __KERNEL_RCSID(0, "$NetBSD: mcclock_ioas
#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
+#include <dev/clock_subr.h>
#include <dev/dec/mcclockvar.h>
#include <dev/dec/mcclock_pad32.h>
Index: arch/mips/mips/mips_mcclock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mips_mcclock.c,v
retrieving revision 1.15
diff -d -p -u -r1.15 mips_mcclock.c
--- arch/mips/mips/mips_mcclock.c 8 Mar 2006 23:46:23 -0000 1.15
+++ arch/mips/mips/mips_mcclock.c 16 Sep 2006 00:21:47 -0000
@@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: mips_mcclock
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <dev/clock_subr.h>
#include <dev/ic/mc146818reg.h>
#include <dev/dec/mcclockvar.h>
--------------060202010003040503040603--