generic todr support for pmax

Garrett D'Amore <[email protected]>
Newsgroups gmane.os.netbsd.ports.pmax
Message-ID <[email protected]>
Here's my swag at generic TODR support for pmax.  Kinda ugly, but
hopefully it will work.  Compile tested only.

    -- Garrett
pmax.diff (text/x-patch, 13.2 KB)
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, &regs)
 	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, &regs);
 	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, &regs);
 	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>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.