Subject: patch to convert ews4800mips to timecounters
To: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: port-ews4800mips
Date: 09/07/2006 10:34:23
This is a multi-part message in MIME format.
--------------090402030700070107040401
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Attached is the following patch, which borrows code from
mips/mips/mips3_clock.c, to use a cp0 based timecounter  for ews4800mips.

I have _not_ converted the clock code to just use
mips/mips/mips3_clock.c directly.  I think that would be a good idea,
but I saw some possible issue with cpu_initclocks(), and enabling the
PICNIC interrupt.

Someone else can do that cleanup.  (And I highly recommend it be done.)

Anyway, if someone could test, and then either commit or let me know it
works, and I can commit, I'd be grateful.

-- 
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


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

Index: sys/arch/ews4800mips/ews4800mips/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/ews4800mips/ews4800mips/clock.c,v
retrieving revision 1.3
diff -d -p -u -r1.3 clock.c
--- sys/arch/ews4800mips/ews4800mips/clock.c	4 Sep 2006 20:31:30 -0000	1.3
+++ sys/arch/ews4800mips/ews4800mips/clock.c	7 Sep 2006 17:34:12 -0000
@@ -39,11 +39,14 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>		/* time */
+#include <sys/timetc.h>
 
 #include <mips/locore.h>	/* mips3_cp0_count_read */
 
 #include <machine/sbdvar.h>
 
+static void init_mips3_tc(void);
+
 void
 cpu_initclocks(void)
 {
@@ -51,6 +54,8 @@ cpu_initclocks(void)
 	KASSERT(platform.initclocks);
 
 	(*platform.initclocks)();
+
+	init_mips3_tc();
 }
 
 void
@@ -60,33 +65,26 @@ setstatclockrate(int arg)
 	/* not yet */
 }
 
-/*
- * Return the best possible estimate of the time in the timeval to
- * which tv points.
- */
 void
-microtime(struct timeval *tvp)
+init_mips3_tc(void)
 {
-	int s = splclock();
-	static struct timeval lasttime;
-
-	*tvp = time;
-	if (platform.readclock)
-		tvp->tv_usec += (*platform.readclock)();
+#if !defined(MULTIPROCESSOR)
+	static struct timecounter tc =  {
+		(timecounter_get_t *)mips3_cp0_count_read, /* get_timecount */
+		0,				/* no poll_pps */
+		~0u,				/* counter_mask */
+		0,				/* frequency */
+		"mips3_cp0_counter",		/* name */
+		0,				/* quality */
+	};
 
-	while (tvp->tv_usec >= 1000000) {
-		tvp->tv_sec++;
-		tvp->tv_usec -= 1000000;
+	tc.tc_frequency = curcpu()->ci_cpu_freq;
+	if (mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) {
+		tc.tc_frequency /= 2;
 	}
 
-	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);
+	tc_init(&tc);
+#endif
 }
 
 /*
Index: sys/arch/ews4800mips/ews4800mips/tr2_intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/ews4800mips/ews4800mips/tr2_intr.c,v
retrieving revision 1.1
diff -d -p -u -r1.1 tr2_intr.c
--- sys/arch/ews4800mips/ews4800mips/tr2_intr.c	29 Dec 2005 15:20:08 -0000	1.1
+++ sys/arch/ews4800mips/ews4800mips/tr2_intr.c	7 Sep 2006 17:34:12 -0000
@@ -310,32 +310,6 @@ tr2_initclocks(void)
 
 	last_clock_intr = mips3_cp0_count_read();
 
-	/* number of microseconds between interrupts */
-	tick = 1000000 / hz;
-	tickfix = 1000000 - (hz * tick);
-#ifdef NTP
-	fixtick = tickfix;
-#endif
-	if (tickfix) {
-		int ftp;
-
-		ftp = min(ffs(tickfix), ffs(hz));
-		tickfix >>= ftp - 1;
-		tickfixinterval = hz >> (ftp - 1);
-	}
-
 	/* Enable clock interrupt */
 	*PICNIC_INT5_MASK_REG |= PICNIC_INT_CLOCK;
 }
-
-u_long
-tr2_readclock(void)
-{
-	uint32_t res, count;
-
-	/* 32bit wrap-around during subtruction ok here. */
-	count = mips3_cp0_count_read() - last_clock_intr;
-	MIPS_COUNT_TO_MHZ(curcpu(), count, res);
-
-	return res;
-}
Index: sys/arch/ews4800mips/ews4800mips/tr2a_intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/ews4800mips/ews4800mips/tr2a_intr.c,v
retrieving revision 1.2
diff -d -p -u -r1.2 tr2a_intr.c
--- sys/arch/ews4800mips/ews4800mips/tr2a_intr.c	10 Jun 2006 12:42:37 -0000	1.2
+++ sys/arch/ews4800mips/ews4800mips/tr2a_intr.c	7 Sep 2006 17:34:12 -0000
@@ -363,33 +363,7 @@ tr2a_initclocks(void)
 
 	last_clock_intr = mips3_cp0_count_read();
 
-	/* number of microseconds between interrupts */
-	tick = 1000000 / hz;
-	tickfix = 1000000 - (hz * tick);
-#ifdef NTP
-	fixtick = tickfix;
-#endif
-	if (tickfix) {
-		int ftp;
-
-		ftp = min(ffs(tickfix), ffs(hz));
-		tickfix >>= ftp - 1;
-		tickfixinterval = hz >> (ftp - 1);
-	}
-
 	/* Enable INT5 */
 	*INTC_MASK_REG |= INTC_INT5;
 	tr2a_wbflush();
 }
-
-u_long
-tr2a_readclock(void)
-{
-	uint32_t res, count;
-
-	/* 32bit wrap-around during subtruction ok here. */
-	count = mips3_cp0_count_read() - last_clock_intr;
-	MIPS_COUNT_TO_MHZ(curcpu(), count, res);
-
-	return res;
-}
Index: sys/arch/ews4800mips/include/sbdvar.h
===================================================================
RCS file: /cvsroot/src/sys/arch/ews4800mips/include/sbdvar.h,v
retrieving revision 1.1
diff -d -p -u -r1.1 sbdvar.h
--- sys/arch/ews4800mips/include/sbdvar.h	29 Dec 2005 15:20:09 -0000	1.1
+++ sys/arch/ews4800mips/include/sbdvar.h	7 Sep 2006 17:34:12 -0000
@@ -79,7 +79,6 @@ struct sbd {
 
 	/* Interval timer helper routines */
 	void (*initclocks)(void);
-	u_long (*readclock)(void);
 
 	/* Miscellaneous */
 	void (*consinit)(void);
@@ -98,7 +97,6 @@ void * x ## _intr_establish(int, int (*)
 void x ## _intr_disestablish(void *);					\
 void x ## _intr(uint32_t, uint32_t, uint32_t, uint32_t);		\
 void x ## _initclocks(void);						\
-u_long x ## _readclock(void);						\
 void x ## _consinit(void);						\
 int x ## _ipl_bootdev(void);						\
 void x ## _reboot(void);						\
@@ -117,7 +115,6 @@ extern const uint32_t x ## _sr_bits[]
 	_SBD_OPS_SET(m, intr_disestablish);				\
 	_SBD_OPS_SET(m, intr);						\
 	_SBD_OPS_SET(m, initclocks);					\
-	_SBD_OPS_SET(m, readclock);					\
 	_SBD_OPS_SET(m, consinit);				       	\
 	_SBD_OPS_SET(m, ipl_bootdev);					\
 	_SBD_OPS_SET(m, reboot);					\
Index: sys/arch/ews4800mips/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/ews4800mips/include/types.h,v
retrieving revision 1.3
diff -d -p -u -r1.3 types.h
--- sys/arch/ews4800mips/include/types.h	4 Sep 2006 20:31:30 -0000	1.3
+++ sys/arch/ews4800mips/include/types.h	7 Sep 2006 17:34:12 -0000
@@ -4,6 +4,7 @@
 
 #define	__HAVE_GENERIC_SOFT_INTERRUPTS
 #define	__HAVE_GENERIC_TODR
+#define	__HAVE_TIMECOUNTER
 
 /* MIPS specific options */
 #define	__HAVE_MIPS_MACHDEP_CACHE_CONFIG

--------------090402030700070107040401--