Subject: timecounters and todr for mipsco
To: None <port-mipsco@netbsd.org>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: port-mipsco
Date: 09/13/2006 15:02:59
This is a multi-part message in MIME format.
--------------090701000303070101050507
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

The following patch provides the MI todr for mipsco.
Additionally it converts the port to timecounters, and if the machine
has a rambo bus, then it will get a timecounter based on the rambo tcount.

Compile tested only.  I'd be grateful to anyone who can test this out on
a real kernel.

-- 
Garrett D'Amore, Principal Software Engineer
Tadpole Computer / Computing Technologies Division,
General Dynamics C4 Systems
http://www.tadpolecomputer.com/
Phone: 951 325-2134  Fax: 951 325-2191


--------------090701000303070101050507
Content-Type: text/x-patch;
 name="mipsco.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="mipsco.diff"

Index: sys/arch/mipsco/include/sysconf.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/include/sysconf.h,v
retrieving revision 1.2
diff -d -p -u -r1.2 sysconf.h
--- sys/arch/mipsco/include/sysconf.h	15 Aug 2000 04:56:46 -0000	1.2
+++ sys/arch/mipsco/include/sysconf.h	13 Sep 2006 22:01:18 -0000
@@ -49,17 +49,15 @@ struct platform {
 	 *	cons_init	-	console initialization
 	 *	iointr		-	I/O interrupt handler
 	 *	memsize		-	Size external memory
-	 *	clkread		-	interporate HZ with hi-resolution timer
 	 *	read_todr	-	Read TOD registers
 	 *	write_todr	-	Write TOD registers
+	 *	clkinit		-	Initialize clocks
 	 */
 	void	(*cons_init) __P((void));
 	void	(*iointr) __P((unsigned, unsigned, unsigned, unsigned));
 	int	(*memsize) __P((caddr_t));
-	unsigned (*clkread) __P((void));
-	void	(*read_todr) __P((struct clock_ymdhms *));
-	void	(*write_todr) __P((struct clock_ymdhms *));
 	void	(*intr_establish) __P((int, int (*)__P((void *)), void *)); 
+	void	(*clkinit) __P((void));
 };
 
 extern struct platform platform;
Index: sys/arch/mipsco/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/include/types.h,v
retrieving revision 1.3
diff -d -p -u -r1.3 types.h
--- sys/arch/mipsco/include/types.h	5 Aug 2002 02:13:15 -0000	1.3
+++ sys/arch/mipsco/include/types.h	13 Sep 2006 22:01:18 -0000
@@ -3,6 +3,8 @@
 #include <mips/types.h>
 
 #define	__HAVE_GENERIC_SOFT_INTERRUPTS
+#define	__HAVE_BOOTINFO_H
+#define	__HAVE_TIMECOUNTER
+#define	__HAVE_GENERIC_TODR
 
 /* MIPS specific options */
-#define	__HAVE_BOOTINFO_H
Index: sys/arch/mipsco/mipsco/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/mipsco/clock.c,v
retrieving revision 1.6
diff -d -p -u -r1.6 clock.c
--- sys/arch/mipsco/mipsco/clock.c	11 Dec 2005 12:18:13 -0000	1.6
+++ sys/arch/mipsco/mipsco/clock.c	13 Sep 2006 22:01:18 -0000
@@ -125,79 +125,6 @@ setstatclockrate(newhz)
 void
 cpu_initclocks()
 {
+	if (platform.clkinit)
+		(*platform.clkinit)();
 }
-
-/*
- * 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 clock_ymdhms dt;
-
-	int deltat, badbase = 0;
-
-	if (base < (MINYEAR-1970)*SECYR) {
-		printf("WARNING: preposterous time in file system\n");
-		/* read the system clock anyway */
-		base = 6*SECYR + 186*SECDAY + SECDAY/2;
-		badbase = 1;
-	}
-
-	(*platform.read_todr)(&dt);
-
-	/* simple sanity checks */
-	if (dt.dt_mon < 1 || dt.dt_mon > 12 ||
-	    dt.dt_day < 1 || dt.dt_day > 31 ||
-	    dt.dt_hour > 23 || dt.dt_min > 59 || dt.dt_sec > 59) {
-		printf("WARNING: preposterous clock chip time\n");
-		/*
-		 * Believe the time in the file system for lack of
-		 * anything better, resetting the TODR.
-		 */
-		time.tv_sec = base;
-		if (!badbase)
-			resettodr();
-		return;
-	}
-
-	/* now have days since Jan 1, 1970; the rest is easy... */
-	time.tv_sec = clock_ymdhms_to_secs(&dt);
-
-	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", deltat / SECDAY);
-		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()
-{
-	struct clock_ymdhms dt;
-
-	if (time.tv_sec >= (MINYEAR-1970)*SECYR) {
-		clock_secs_to_ymdhms(time.tv_sec, &dt);
-		(*platform.write_todr)(&dt);
-	}
-}
-
Index: sys/arch/mipsco/mipsco/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/mipsco/machdep.c,v
retrieving revision 1.46
diff -d -p -u -r1.46 machdep.c
--- sys/arch/mipsco/mipsco/machdep.c	9 Apr 2006 01:18:14 -0000	1.46
+++ sys/arch/mipsco/mipsco/machdep.c	13 Sep 2006 22:01:18 -0000
@@ -195,19 +195,15 @@ extern void pizazz_init __P((void));
 static void	unimpl_cons_init __P((void));
 static void	unimpl_iointr __P((unsigned, unsigned, unsigned, unsigned));
 static int	unimpl_memsize __P((caddr_t));
-static unsigned	unimpl_clkread __P((void));
-static void	unimpl_todr __P((struct clock_ymdhms *));
 static void	unimpl_intr_establish __P((int, int (*)__P((void *)), void *));
 
 struct platform platform = {
-	"iobus not set",
-	unimpl_cons_init,
-	unimpl_iointr,
-	unimpl_memsize,
-	unimpl_clkread,
-	unimpl_todr,
-	unimpl_todr,
-	unimpl_intr_establish,
+	.iobus = "iobus not set",
+	.cons_init = unimpl_cons_init,
+	.iointr = unimpl_iointr,
+	.memsize = unimpl_memsize,
+	.intr_establish = unimpl_intr_establish,
+	.clkinit = NULL,
 };
 
 struct consdev *cn_tab = NULL;
@@ -550,38 +546,6 @@ haltsys:
 	/*NOTREACHED*/
 }
 
-/*
- * Return the best possible estimate of the time in the timeval
- * to which tvp points.  Unfortunately, we can't read the hardware registers.
- * We guarantee that the time will be greater than the value obtained by a
- * previous call.
- */
-void
-microtime(tvp)
-	register struct timeval *tvp;
-{
-	static struct timeval lasttime;
-	int s = splclock();
-
-	*tvp = time;
-
-	tvp->tv_usec += (*platform.clkread)();
-
-	while (tvp->tv_usec >= 1000000) {
-		tvp->tv_usec -= 1000000;
-		tvp->tv_sec++;
-	}
-
-	if (tvp->tv_sec == lasttime.tv_sec &&
-	    tvp->tv_usec <= lasttime.tv_usec &&
-	    (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {
-		tvp->tv_sec++;
-		tvp->tv_usec -= 1000000;
-	}
-	lasttime = *tvp;
-	splx(s);
-}
-
 int
 initcpu()
 {
@@ -615,19 +579,6 @@ caddr_t first;
 	panic("sysconf.init didn't set memsize");
 }
 
-static unsigned
-unimpl_clkread()
-{
-	return 0;	/* No microtime available */
-}
-
-static void
-unimpl_todr(dt)
-	struct clock_ymdhms *dt;
-{
-	panic("sysconf.init didn't init TOD");
-}
-
 void
 unimpl_intr_establish(level, func, arg)
 	int level;
Index: sys/arch/mipsco/obio/mkclock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/obio/mkclock.c,v
retrieving revision 1.6
diff -d -p -u -r1.6 mkclock.c
--- sys/arch/mipsco/obio/mkclock.c	11 Dec 2005 12:18:13 -0000	1.6
+++ sys/arch/mipsco/obio/mkclock.c	13 Sep 2006 22:01:18 -0000
@@ -58,6 +58,7 @@ struct	mkclock_softc {
         struct  device dev; 
 	bus_space_tag_t	sc_bst;
 	bus_space_handle_t sc_bsh;
+	struct todr_chip_handle sc_todr;
 };
 
 static int mkclock_match (struct device *, struct cfdata *, void *);
@@ -66,10 +67,8 @@ static void mkclock_attach (struct devic
 CFATTACH_DECL(mkclock, sizeof(struct mkclock_softc),
     mkclock_match, mkclock_attach, NULL, NULL);
 
-static struct mkclock_softc *mk0; 
-
-void mkclock_read (struct clock_ymdhms *);
-void mkclock_write (struct clock_ymdhms *);
+int mkclock_read (todr_chip_handle_t, struct clock_ymdhms *);
+int mkclock_write (todr_chip_handle_t, struct clock_ymdhms *);
 
 static int mk_read (struct mkclock_softc *, int);
 static void mk_write (struct mkclock_softc *, int, int);
@@ -100,9 +99,11 @@ mkclock_attach(parent, self, aux)
 		return;
 	}
 
-	platform.write_todr = mkclock_write;
-	platform.read_todr  = mkclock_read;
-	mk0 = sc;
+	sc->sc_todr.todr_settime_ymdhms = mkclock_write;
+	sc->sc_todr.todr_gettime_ymdhms = mkclock_read;
+	sc->sc_todr.cookie = sc;
+	todr_attach(&sc->sc_todr);
+
 	printf("\n");
 }
 
@@ -126,11 +127,10 @@ mk_write(sc, reg, val)
 			  DATA_PORT + reg*4, TOBCD(val));
 }
 
-void
-mkclock_read(dt)
-	struct clock_ymdhms *dt;
+int
+mkclock_read(todr_chip_handle_t tch, struct clock_ymdhms *dt)
 {
-	struct mkclock_softc *sc = mk0;
+	struct mkclock_softc *sc = tch->cookie;
 	int s = splclock();
 
 	bus_space_write_1(sc->sc_bst, sc->sc_bsh, RTC_PORT, READ_CLOCK); 
@@ -145,13 +145,13 @@ mkclock_read(dt)
 	splx(s);
 
 	dt->dt_year = dt->dt_year + (dt->dt_year >= 70 ? 1900 : 2000);
+	return 0;
 }
 
-void
-mkclock_write(dt)
-	struct clock_ymdhms *dt;
+int
+mkclock_write(todr_chip_handle_t tch, struct clock_ymdhms *dt)
 {
-	struct mkclock_softc *sc = mk0;
+	struct mkclock_softc *sc = tch->cookie;
 	int year, s;
 
 	year = dt->dt_year % 100;
@@ -167,4 +167,5 @@ mkclock_write(dt)
 	mk_write(sc, 6, year);
 	bus_space_write_1(sc->sc_bst, sc->sc_bsh, RTC_PORT, 0); 
 	splx(s);
+	return 0;
 }
Index: sys/arch/mipsco/obio/rambo.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/obio/rambo.c,v
retrieving revision 1.7
diff -d -p -u -r1.7 rambo.c
--- sys/arch/mipsco/obio/rambo.c	11 Dec 2005 12:18:13 -0000	1.7
+++ sys/arch/mipsco/obio/rambo.c	13 Sep 2006 22:01:19 -0000
@@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: rambo.c,v 1.
 #include <sys/kernel.h>
 #include <sys/device.h>
 #include <sys/systm.h>
+#include <sys/timetc.h>
 
 #include <machine/cpu.h>
 #include <machine/mainboard.h>
@@ -58,8 +59,9 @@ __KERNEL_RCSID(0, "$NetBSD: rambo.c,v 1.
 
 static int	rambo_match  __P((struct device *, struct cfdata *, void *));
 static void	rambo_attach __P((struct device *, struct device *, void *));
-static unsigned rambo_clkread __P((void));
+static unsigned rambo_get_timecount(struct timecounter *);
 void rambo_clkintr __P((struct clockframe *));
+static void rambo_tc_init(void);
 
 struct rambo_softc {
         struct device		dev; 
@@ -115,7 +117,7 @@ rambo_attach(parent, self, aux)
 
 	printf(": parity enabled\n");
 	rambo = sc;
-	platform.clkread = rambo_clkread;
+	platform.clkinit = rambo_tc_init;
 }
 
 void
@@ -161,10 +163,22 @@ rambo_clkintr(cf)
  * Calculate the number of microseconds since the last clock tick
  */
 static unsigned
-rambo_clkread()
+rambo_get_timecount(struct timecounter *tc)
 {
-        register u_int32_t tcount;
-	
-	tcount = bus_space_read_4(rambo->sc_bst, rambo->sc_bsh, RB_TCOUNT);
-	return TICKS_TO_USECS(tcount - rambo->sc_tclast);
+
+	return (bus_space_read_4(rambo->sc_bst, rambo->sc_bsh, RB_TCOUNT));
+}
+
+static void
+rambo_tc_init(void)
+{
+	static struct timecounter tc = {
+		.tc_get_timecount = rambo_get_timecount,
+		.tc_frequency = RB_FREQUENCY,
+		.tc_quality = 100,
+		.tc_name = "rambo_tcount",
+		.tc_counter_mask = ~0
+	};
+
+	tc_init(&tc);
 }
Index: sys/arch/mipsco/obio/rambo.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/obio/rambo.h,v
retrieving revision 1.4
diff -d -p -u -r1.4 rambo.h
--- sys/arch/mipsco/obio/rambo.h	16 Sep 2001 16:34:33 -0000	1.4
+++ sys/arch/mipsco/obio/rambo.h	13 Sep 2006 22:01:19 -0000
@@ -116,6 +116,7 @@ struct	rambo_ch {
 #define	RB_BOUNDRY	(1<<RB_BSIZE)
 
 /* Rambo cycle counter is fed by 25MHz clock then divided by 4 */
-#define	HZ_TO_TICKS(hz)		(6250000L/(hz))
+#define	RB_FREQUENCY		625000L
+#define	HZ_TO_TICKS(hz)		(RB_FREQUENCY/(hz))
 #define TICKS_TO_USECS(t)	(((t)*4)/25)
 #endif

--------------090701000303070101050507--