Subject: timecounter changes for newsmips
To: None <port-newsmips@netbsd.org>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: port-newsmips
Date: 09/12/2006 15:21:44
This is a multi-part message in MIME format.
--------------060702030002090706020609
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

I wrote the following patch which converts newsmips to tc.

In this change:

1) only NWS-5000 has a high resolution timer
2) the timer NEWS5000_FREERUN is assumed to tick once per usec.  That
seems what the current code.
3) I assume it wraps on a 32-bit boundary (i.e counts 0-ffffffff)

If these assumptions are good, then the code should run.  I don't have
news docs, so I'm just interpreting the pre-existing code.  I'd
appreciate it if folks can test, and commit as appropriate.

    -- Garrett

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


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

Index: sys/arch/newsmips/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/include/types.h,v
retrieving revision 1.8
diff -d -p -u -r1.8 types.h
--- sys/arch/newsmips/include/types.h	4 Sep 2006 20:33:24 -0000	1.8
+++ sys/arch/newsmips/include/types.h	12 Sep 2006 22:21:11 -0000
@@ -4,6 +4,7 @@
 
 #define	__HAVE_GENERIC_SOFT_INTERRUPTS
 #define	__HAVE_GENERIC_TODR
+#define	__HAVE_TIMECOUNTER
 
 /* MIPS specific options */
 #define	__HAVE_BOOTINFO_H
Index: sys/arch/newsmips/newsmips/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/newsmips/machdep.c,v
retrieving revision 1.83
diff -d -p -u -r1.83 machdep.c
--- sys/arch/newsmips/newsmips/machdep.c	9 Apr 2006 01:18:14 -0000	1.83
+++ sys/arch/newsmips/newsmips/machdep.c	12 Sep 2006 22:21:11 -0000
@@ -159,7 +159,6 @@ phys_ram_seg_t mem_clusters[VM_PHYSSEG_M
 int mem_cluster_cnt;
 
 struct idrom idrom;
-void (*readmicrotime)(struct timeval *tvp);
 void (*hardware_intr)(uint32_t, uint32_t, uint32_t, uint32_t);
 void (*enable_intr)(void);
 void (*disable_intr)(void);
@@ -622,33 +621,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(struct timeval *tvp)
-{
-	int s = splclock();
-	static struct timeval lasttime;
-
-	if (readmicrotime)
-		readmicrotime(tvp);
-	else
-		*tvp = time;
-
-	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);
-}
-
 void
 delay(int n)
 {
Index: sys/arch/newsmips/newsmips/news5000.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/newsmips/news5000.c,v
retrieving revision 1.15
diff -d -p -u -r1.15 news5000.c
--- sys/arch/newsmips/newsmips/news5000.c	11 Dec 2005 12:18:25 -0000	1.15
+++ sys/arch/newsmips/newsmips/news5000.c	12 Sep 2006 22:21:11 -0000
@@ -32,6 +32,7 @@ __KERNEL_RCSID(0, "$NetBSD: news5000.c,v
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/timetc.h>
 
 #include <machine/adrsmap.h>
 #include <machine/cpu.h>
@@ -40,18 +41,15 @@ __KERNEL_RCSID(0, "$NetBSD: news5000.c,v
 #include <newsmips/apbus/apbusvar.h>
 #include <newsmips/newsmips/machid.h>
 
-extern void (*readmicrotime)(struct timeval *tvp);
-
 static void news5000_level1_intr(void);
 static void news5000_level0_intr(void);
 
 static void news5000_enable_intr(void);
 static void news5000_disable_intr(void);
 static void news5000_enable_timer(void);
-static void news5000_readmicrotime(struct timeval *);
 static void news5000_readidrom(uint8_t *);
-
-static u_int freerun_off;
+static void news5000_tc_init(void);
+static uint32_t news5000_getfreerun(struct timecounter *);
 
 /*
  * Handle news5000 interrupts.
@@ -81,7 +79,6 @@ news5000_intr(uint32_t status, uint32_t 
 
 		if (int2stat & NEWS5000_INT2_TIMER0) {
 			*(volatile uint32_t *)NEWS5000_TIMER0 = 1;
-			freerun_off = *(volatile uint32_t *)NEWS5000_FREERUN;
 
 			cf.pc = pc;
 			cf.sr = status;
@@ -226,22 +223,26 @@ news5000_enable_timer(void)
 	*(volatile uint32_t *)NEWS5000_INTEN2 = NEWS5000_INT2_TIMER0;
 }
 
+static uint32_t
+news5000_getfreerun(struct timecounter *tc)
+{
+	return *(volatile uint32_t *)NEWS5000_FREERUN;
+}
+
 static void
-news5000_readmicrotime(struct timeval *tvp)
+news5000_tc_init(void)
 {
-	uint32_t freerun;
+	static struct timecounter tc = {
+		.tc_get_timecount = news5000_getfreerun,
+		.tc_frequency = 1000000,
+		.tc_counter_mask = ~0,
+		.tc_name = "news5000_freerun",
+		.tc_quality = 100,
+	};
 
-	*tvp = time;
-	freerun = *(volatile uint32_t *)NEWS5000_FREERUN;
-	freerun -= freerun_off;
-	if (freerun > 1000000)
-		freerun = 1000000;
-	tvp->tv_usec += freerun;
-	if (tvp->tv_usec >= 1000000) {
-		tvp->tv_usec -= 1000000;
-		tvp->tv_sec++;
-	}
+	tc_init(&tc);
 }
+	
 
 static void
 news5000_readidrom(uint8_t *rom)
@@ -264,11 +265,12 @@ news5000_init(void)
 	enable_timer = news5000_enable_timer;
 
 	news5000_readidrom((uint8_t *)&idrom);
-	readmicrotime = news5000_readmicrotime;
 	hostid = idrom.id_serial;
 
 	/* XXX reset uPD72067 FDC to avoid spurious interrupts */
 #define NEWS5000_FDC_FDOUT 0xbed20000
 #define FDO_FRST 0x04
 	*(volatile uint8_t *)NEWS5000_FDC_FDOUT = FDO_FRST;
+
+	news5000_tc_init();
 }

--------------060702030002090706020609--