Subject: timecounters patch for x68k
To: None <port-x68k@netbsd.org>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: port-x68k
Date: 09/16/2006 01:18:58
This is a multi-part message in MIME format.
--------------070008090507070606020905
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

timecounter patch (untested) attached.

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


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

Index: sys/arch/x68k/dev/kbd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/dev/kbd.c,v
retrieving revision 1.23
diff -d -p -u -r1.23 kbd.c
--- sys/arch/x68k/dev/kbd.c	11 Dec 2005 12:19:37 -0000	1.23
+++ sys/arch/x68k/dev/kbd.c	16 Sep 2006 08:17:03 -0000
@@ -350,7 +350,7 @@ kbdintr(void *arg)
 	}
 	fe->id = KEY_CODE(c);
 	fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN;
-	fe->time = time;
+	getmicrotime(&fe->time);
 	k->sc_events.ev_put = put;
 	EV_WAKEUP(&k->sc_events);
 
Index: sys/arch/x68k/dev/ms.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/dev/ms.c,v
retrieving revision 1.22
diff -d -p -u -r1.22 ms.c
--- sys/arch/x68k/dev/ms.c	29 Mar 2006 04:16:48 -0000	1.22
+++ sys/arch/x68k/dev/ms.c	16 Sep 2006 08:17:03 -0000
@@ -423,7 +423,7 @@ ms_input(struct ms_softc *ms, int c)
 		d = to_one[d - 1];		/* from 1..7 to {1,2,4} */
 		fe->id = to_id[d - 1];		/* from {1,2,4} to ID */
 		fe->value = mb & d ? VKEY_DOWN : VKEY_UP;
-		fe->time = time;
+		getmicrotime(&fe->time);
 		ADVANCE;
 		ub ^= d;
 		any++;
@@ -432,7 +432,7 @@ ms_input(struct ms_softc *ms, int c)
 		NEXT;
 		fe->id = LOC_X_DELTA;
 		fe->value = ms->ms_dx;
-		fe->time = time;
+		getmicrotime(&fe->time);
 		ADVANCE;
 		ms->ms_dx = 0;
 		any++;
@@ -441,7 +441,7 @@ ms_input(struct ms_softc *ms, int c)
 		NEXT;
 		fe->id = LOC_Y_DELTA;
 		fe->value = -ms->ms_dy;	/* XXX? */
-		fe->time = time;
+		getmicrotime(&fe->time);
 		ADVANCE;
 		ms->ms_dy = 0;
 		any++;
Index: sys/arch/x68k/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/include/types.h,v
retrieving revision 1.10
diff -d -p -u -r1.10 types.h
--- sys/arch/x68k/include/types.h	14 Sep 2006 01:18:11 -0000	1.10
+++ sys/arch/x68k/include/types.h	16 Sep 2006 08:17:03 -0000
@@ -7,5 +7,6 @@
 
 #define	__HAVE_DEVICE_REGISTER
 #define	__HAVE_GENERIC_TODR
+#define	__HAVE_TIMECOUNTER
 
 #endif
Index: sys/arch/x68k/x68k/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/x68k/clock.c,v
retrieving revision 1.23
diff -d -p -u -r1.23 clock.c
--- sys/arch/x68k/x68k/clock.c	14 Sep 2006 01:18:11 -0000	1.23
+++ sys/arch/x68k/x68k/clock.c	16 Sep 2006 08:17:03 -0000
@@ -87,6 +87,7 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/device.h>
+#include <sys/timetc.h>
 
 #include <machine/psl.h>
 #include <machine/cpu.h>
@@ -110,6 +111,8 @@ CFATTACH_DECL(clock, sizeof(struct clock
 
 static int clock_attached;
 
+static unsigned mfp_get_timecount(struct timecounter *);
+
 static int
 clock_match(struct device *parent, struct cfdata *cf, void *aux)
 {
@@ -135,25 +138,21 @@ clock_attach(struct device *parent, stru
 /*
  * MFP of X68k uses 4MHz clock always and we use 1/200 prescaler here.
  * Therefore, clock interval is 50 usec.
+ *
+ * Note that for timecounters, we'd like to use a finger grained clock, but
+ * since we only have an 8-bit clock, we can't do that without increasing
+ * the system clock rate.  (Otherwise the counter would roll in less than
+ * a single system clock.)
  */
 #define CLK_RESOLUTION	(50)
 #define CLOCKS_PER_SEC	(1000000 / CLK_RESOLUTION)
 
-static int clkint;		/* clock interval */
-
-static int clkread(void);
-
 /*
  * Machine-dependent clock routines.
  *
  * Startrtclock restarts the real-time clock, which provides
  * hardclock interrupts to kern_clock.c.
  *
- * Inittodr initializes the time of day hardware which provides
- * date functions.
- *
- * Resettodr restores the time of day hardware after a time change.
- *
  * A note on the real-time clock:
  * We actually load the clock with CLK_INTERVAL-1 instead of CLK_INTERVAL.
  * This is because the counter decrements to zero after N+1 enabled clock
@@ -168,18 +167,30 @@ static int clkread(void);
 void
 cpu_initclocks(void)
 {
+	static struct	timecounter tc = {
+		.tc_name = "mfp",
+		.tc_frequency = CLOCKS_PER_SEC,
+		.tc_counter_mask = 0xff,
+		.tc_get_timecount = mfp_get_timecount,
+		.tc_quality = 100,
+	};
+	
 	if (CLOCKS_PER_SEC % hz ||
 	    hz <= (CLOCKS_PER_SEC / 256) || hz > CLOCKS_PER_SEC) {
 		printf("cannot set %d Hz clock. using 100 Hz\n", hz);
 		hz = 100;
 	}
-	clkint = CLOCKS_PER_SEC / hz;
 
-	mfp_set_tcdcr(mfp_get_tcdcr() & 0x0f); /* stop timer C */
+	mfp_set_tcdcr(0);		/* stop timers C and D */
 	mfp_set_tcdcr(mfp_get_tcdcr() | 0x70); /* 1/200 delay mode */
 
-	mfp_set_tcdr(clkint);
+	mfp_set_tcdr(CLOCKS_PER_SEC / hz);
 	mfp_bit_set_ierb(MFP_INTR_TIMER_C);
+
+	mfp_set_tddr(0xff);	/* maximum free run -- only 8 bits wide */
+	mfp_set_tcdcr(mfp_get_tcdcr() | 0x07);	/* 1/200 prescaler */
+
+	tc_init(&tc);
 }
 
 /*
@@ -196,13 +207,14 @@ setstatclockrate(int newhz)
  * Returns number of usec since last recorded clock "tick"
  * (i.e. clock interrupt).
  */
-int
-clkread(void)
+unsigned
+mfp_get_timecount(struct timecounter *tc)
 {
-	return (clkint - mfp_get_tcdr()) * CLK_RESOLUTION;
+	uint8_t	val;
+	val = ~(mfp_get_tddr());
+	return (val);
 }
 
-
 #if 0
 void
 DELAY(mic)
@@ -512,29 +524,6 @@ profclock(caddr_t pc, int ps)
 #endif	/* PROF */
 #endif	/* PROFTIMER */
 
-/*
- * Return the best possible estimate of the current time.
- */
-void
-microtime(struct timeval *tvp)
-{
-	static struct timeval lasttime;
-
-	*tvp = time;
-	tvp->tv_usec += clkread();
-	while (tvp->tv_usec >= 1000000) {
-		tvp->tv_sec++;
-		tvp->tv_usec -= 1000000;
-	}
-	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;
-}
-
 #else	/* NCLOCK */
 #error loose.
 #endif

--------------070008090507070606020905--