Port-newsmips archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

timecounter changes for newsmips



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

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();
 }


Home | Main Index | Thread Index | Old Index