Port-mvme68k archive

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

Re: mvme68k timecounters.... untested



I wrote:

> - we should ask Steve (scw@) first.
> - IIRC some sources for old microtime(9) are shared with mvmeppc port
>   and in sys/dev/mvme so we should handle it too.
> 
> Anyway I'll take a look after I'm back to my home.

I'm still in my hometown, but I played with the sources via ssh:
---

Index: arch/mvme68k/dev/clock_pcc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mvme68k/dev/clock_pcc.c,v
retrieving revision 1.16
diff -u -r1.16 clock_pcc.c
--- arch/mvme68k/dev/clock_pcc.c        11 Dec 2005 12:18:17 -0000      1.16
+++ arch/mvme68k/dev/clock_pcc.c        4 Jan 2008 13:46:42 -0000
@@ -48,6 +48,7 @@
 #include <sys/kernel.h>
 #include <sys/systm.h>
 #include <sys/device.h>
+#include <sys/timetc.h>
 
 #include <machine/psl.h>
 #include <machine/bus.h>
@@ -64,6 +65,7 @@
        struct device sc_dev;
        struct clock_attach_args sc_clock_args;
        u_char sc_clock_lvl;
+       struct timecounter sc_tc;
 };
 
 CFATTACH_DECL(clock_pcc, sizeof(struct clock_pcc_softc),
@@ -75,10 +77,12 @@
 static int clock_pcc_profintr __P((void *));
 static int clock_pcc_statintr __P((void *));
 static void clock_pcc_initclocks __P((void *, int, int));
-static long clock_pcc_microtime __P((void *));
 static void clock_pcc_shutdown __P((void *));
+static uint32_t clock_pcc_getcount(struct timecounter *);
 
 static struct clock_pcc_softc *clock_pcc_sc;
+static uint32_t clock_pcc_count;
+static uint16_t clock_pcc_reload;
 
 /* ARGSUSED */
 int
@@ -122,7 +126,6 @@
        clock_pcc_sc = sc;
        sc->sc_clock_args.ca_arg = sc;
        sc->sc_clock_args.ca_initfunc = clock_pcc_initclocks;
-       sc->sc_clock_args.ca_microtime = clock_pcc_microtime;
 
        /* Do common portions of clock config. */
        clock_config(self, &sc->sc_clock_args, pccintr_evcnt(pa->pa_ipl));
@@ -148,6 +151,7 @@
 
        pcc_reg_write16(sys_pcc, PCCREG_TMR1_PRELOAD,
            pcc_timer_us2lim(prof_us));
+       clock_pcc_reload = pcc_timer_us2lim(prof_us);
        pcc_reg_write(sys_pcc, PCCREG_TMR1_CONTROL, PCC_TIMERCLEAR);
        pcc_reg_write(sys_pcc, PCCREG_TMR1_CONTROL, PCC_TIMERSTART);
        pcc_reg_write(sys_pcc, PCCREG_TMR1_INTR_CTRL, sc->sc_clock_lvl);
@@ -157,20 +161,25 @@
        pcc_reg_write(sys_pcc, PCCREG_TMR2_CONTROL, PCC_TIMERCLEAR);
        pcc_reg_write(sys_pcc, PCCREG_TMR2_CONTROL, PCC_TIMERSTART);
        pcc_reg_write(sys_pcc, PCCREG_TMR2_INTR_CTRL, sc->sc_clock_lvl);
+
+       sc->sc_tc.tc_get_timecount = clock_pcc_getcount;
+       sc->sc_tc.tc_name = "pcc_count";
+       sc->sc_tc.tc_frequency = PCC_TIMERFREQ;
+       sc->sc_tc.tc_quality = 100;
+       sc->sc_tc.tc_counter_mask = ~0;
+       tc_init(&sc->sc_tc);
 }
 
 /* ARGSUSED */
-long
-clock_pcc_microtime(arg)
-       void *arg;
+uint32_t
+clock_pcc_getcount(struct timecounter *tc)
 {
-       static int ovfl_adj[] = {
-               0,       10000,  20000,  30000,
-               40000,   50000,  60000,  70000,
-               80000,   90000, 100000, 110000,
-               120000, 130000, 140000, 150000};
-       u_int8_t cr;
-       u_int16_t tc, tc2;
+       uint32_t cnt;
+       uint16_t tc1, tc2;
+       uint8_t cr;
+       int s;
+
+       s = splhigh();
 
        /*
         * There's no way to latch the counter and overflow registers
@@ -178,16 +187,22 @@
         * race by checking for counter wrap-around and re-reading the
         * overflow counter if necessary.
         *
-        * Note: This only works because we're called at splhigh().
+        * Note: This only works because we're at splhigh().
         */
-       tc = pcc_reg_read16(sys_pcc, PCCREG_TMR1_COUNT);
+       tc1 = pcc_reg_read16(sys_pcc, PCCREG_TMR1_COUNT);
        cr = pcc_reg_read(sys_pcc, PCCREG_TMR1_CONTROL);
-       if (tc > (tc2 = pcc_reg_read16(sys_pcc, PCCREG_TMR1_COUNT))) {
+       tc2 = pcc_reg_read16(sys_pcc, PCCREG_TMR1_COUNT);
+       if (tc1 > tc2) {
                cr = pcc_reg_read(sys_pcc, PCCREG_TMR1_CONTROL);
-               tc = tc2;
+               tc1 = tc2;
        }
+       cnt = clock_pcc_count;
+       splx(s);
+       /* XXX assume HZ = 100 */
+       cnt += (tc1 - clock_pcc_reload) +
+           (PCC_TIMERFREQ / 100) * (cr >> PCC_TIMEROVFLSHIFT);
 
-       return ((long) pcc_timer_cnt2us(tc) + ovfl_adj[cr>>PCC_TIMEROVFLSHIFT]);
+       return cnt;
 }
 
 int
@@ -208,8 +223,11 @@
            clock_pcc_sc->sc_clock_lvl);
        splx(s);
 
-       for (cr >>= PCC_TIMEROVFLSHIFT; cr; cr--)
+       for (cr >>= PCC_TIMEROVFLSHIFT; cr; cr--) {
+               /* XXX assume HZ = 100 */
+               clock_pcc_count += PCC_TIMERFREQ / 100;
                hardclock(frame);
+       }
 
        return (1);
 }
Index: arch/mvme68k/dev/pccreg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mvme68k/dev/pccreg.h,v
retrieving revision 1.9
diff -u -r1.9 pccreg.h
--- arch/mvme68k/dev/pccreg.h   12 Aug 2001 18:33:13 -0000      1.9
+++ arch/mvme68k/dev/pccreg.h   4 Jan 2008 13:46:42 -0000
@@ -154,16 +154,15 @@
  */
 
 #define PCC_TIMERACK           0x80    /* ack intr */
-#define PCC_TIMER100HZ         63936   /* load value for 100Hz */
 #define PCC_TIMERCLEAR         0x0     /* reset and clear timer */
 #define PCC_TIMERENABLE                0x1     /* Enable clock */
 #define PCC_TIMERSTOP          0x3     /* stop clock, but don't clear it */
 #define PCC_TIMERSTART         0x7     /* start timer */
 #define PCC_TIMEROVFLSHIFT     4
 
-#define pcc_timer_hz2lim(hz)   (65536 - (160000/(hz)))
-#define pcc_timer_us2lim(us)   (65536 - (160000/(1000000/(us))))
-#define pcc_timer_cnt2us(cnt)  ((((cnt) - PCC_TIMER100HZ) * 25) / 4)
+#define PCC_TIMERFREQ          160000
+#define pcc_timer_hz2lim(hz)   (0x10000 - (PCC_TIMERFREQ/(hz)))
+#define pcc_timer_us2lim(us)   (0x10000 - (PCC_TIMERFREQ/(1000000/(us))))
 
 /*
  * serial control
Index: arch/mvme68k/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mvme68k/include/types.h,v
retrieving revision 1.12
diff -u -r1.12 types.h
--- arch/mvme68k/include/types.h        17 Oct 2007 19:55:47 -0000      1.12
+++ arch/mvme68k/include/types.h        4 Jan 2008 13:46:42 -0000
@@ -7,5 +7,6 @@
 
 #define        __HAVE_DEVICE_REGISTER
 #define        __HAVE_GENERIC_TODR
+#define        __HAVE_TIMECOUNTER
 
 #endif
Index: arch/mvme68k/mvme68k/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mvme68k/mvme68k/clock.c,v
retrieving revision 1.24
diff -u -r1.24 clock.c
--- arch/mvme68k/mvme68k/clock.c        9 Sep 2006 22:28:27 -0000       1.24
+++ arch/mvme68k/mvme68k/clock.c        4 Jan 2008 13:46:42 -0000
@@ -139,39 +139,3 @@
 
        /* XXX should we do something here? XXX */
 }
-
-/*
- * Return the best possible estimate of the time in the timeval
- * to which tvp points.  We do this by returning the current time
- * plus the amount of time, in uSec, since the last clock interrupt
- * (clock_args->ca_microtime()) was handled.
- *
- * Check that this time is no less than any previously-reported time,
- * which could happen around the time of a clock adjustment.  Just for fun,
- * we guarantee that the time will be greater than the value obtained by a
- * previous call.
- */
-
-void
-microtime(tvp)
-       struct timeval *tvp;
-{
-       int s = splhigh();
-       static struct timeval lasttime;
-
-       *tvp = time;
-       tvp->tv_usec += (*clock_args->ca_microtime)(clock_args->ca_arg);
-       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;
-       splx(s);
-}
-
Index: dev/mvme/clock_pcctwo.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mvme/clock_pcctwo.c,v
retrieving revision 1.11
diff -u -r1.11 clock_pcctwo.c
--- dev/mvme/clock_pcctwo.c     19 Oct 2007 12:00:36 -0000      1.11
+++ dev/mvme/clock_pcctwo.c     4 Jan 2008 13:46:43 -0000
@@ -49,6 +49,7 @@
 #include <sys/kernel.h>
 #include <sys/systm.h>
 #include <sys/device.h>
+#include <sys/timetc.h>
 
 #include <machine/psl.h>
 #include <sys/bus.h>
@@ -65,6 +66,7 @@
        struct device sc_dev;
        struct clock_attach_args sc_clock_args;
        u_char sc_clock_lvl;
+       struct timecounter sc_tc;
 };
 
 CFATTACH_DECL(clock_pcctwo, sizeof(struct clock_pcctwo_softc),
@@ -75,10 +77,11 @@
 static int clock_pcctwo_profintr(void *);
 static int clock_pcctwo_statintr(void *);
 static void clock_pcctwo_initclocks(void *, int, int);
-static long clock_pcctwo_microtime(void *);
 static void clock_pcctwo_shutdown(void *);
+static uint32_t clock_pcctwo_getcount(struct timecounter *);
 
 static struct clock_pcctwo_softc *clock_pcctwo_sc;
+static uint32_t clock_pcctwo_count;
 
 /* ARGSUSED */
 int
@@ -119,7 +122,6 @@
 
        sc->sc_clock_args.ca_arg = sc;
        sc->sc_clock_args.ca_initfunc = clock_pcctwo_initclocks;
-       sc->sc_clock_args.ca_microtime = clock_pcctwo_microtime;
 
        /* Do common portions of clock config. */
        clock_config(self, &sc->sc_clock_args, pcctwointr_evcnt(pa->pa_ipl));
@@ -162,20 +164,25 @@
        pcc2_reg_write(sys_pcctwo, PCC2REG_TIMER2_CONTROL,
            PCCTWO_TT_CTRL_CEN | PCCTWO_TT_CTRL_COC | PCCTWO_TT_CTRL_COVF);
        pcc2_reg_write(sys_pcctwo, PCC2REG_TIMER2_ICSR, sc->sc_clock_lvl);
+
+       sc->sc_tc.tc_get_timecount = clock_pcctwo_getcount;
+       sc->sc_tc.tc_name = "pcctwo_count";
+       sc->sc_tc.tc_frequency = PCCTWO_TIMERFREQ;
+       sc->sc_tc.tc_quality = 100;
+       sc->sc_tc.tc_counter_mask = ~0;
+       tc_init(&sc->sc_tc);
 }
 
 /* ARGSUSED */
-long
-clock_pcctwo_microtime(arg)
-       void *arg;
+uint32_t
+clock_pcctwo_getcount(struct timecounter *tc)
 {
-       static int ovfl_adj[] = {
-               0,       10000,  20000,  30000,
-               40000,   50000,  60000,  70000,
-               80000,   90000, 100000, 110000,
-               120000, 130000, 140000, 150000};
-       u_int8_t cr;
-       u_int32_t tc, tc2;
+       uint32_t cnt;
+       uint32_t tc1, tc2;
+       uint8_t cr;
+       int s;
+
+       s = splhigh();
 
        /*
         * There's no way to latch the counter and overflow registers
@@ -183,16 +190,21 @@
         * race by checking for counter wrap-around and re-reading the
         * overflow counter if necessary.
         *
-        * Note: This only works because we're called at splhigh().
+        * Note: This only works because we're at splhigh().
         */
-       tc = pcc2_reg_read32(sys_pcctwo, PCC2REG_TIMER1_COUNTER);
+       tc1 = pcc2_reg_read32(sys_pcctwo, PCC2REG_TIMER1_COUNTER);
        cr = pcc2_reg_read(sys_pcctwo, PCC2REG_TIMER1_CONTROL);
-       if (tc > (tc2 = pcc2_reg_read32(sys_pcctwo, PCC2REG_TIMER1_COUNTER))) {
+       tc2 = pcc2_reg_read32(sys_pcctwo, PCC2REG_TIMER1_COUNTER);
+       if (tc1 > tc2) {
                cr = pcc2_reg_read(sys_pcctwo, PCC2REG_TIMER1_CONTROL);
-               tc = tc2;
+               tc1 = tc2;
        }
+       cnt = clock_pcctwo_count;
+       splx(s);
+       /* XXX assume HZ = 100 */
+       cnt += tc1 + (PCCTWO_TIMERFREQ / 100) * PCCTWO_TT_CTRL_OVF(cr);
 
-       return ((long) PCCTWO_LIM2US(tc) + ovfl_adj[PCCTWO_TT_CTRL_OVF(cr)]);
+       return cnt;
 }
 
 int
@@ -214,8 +226,11 @@
            clock_pcctwo_sc->sc_clock_lvl);
        splx(s);
 
-       for (cr = PCCTWO_TT_CTRL_OVF(cr); cr; cr--)
+       for (cr = PCCTWO_TT_CTRL_OVF(cr); cr; cr--) {
+               /* XXX assume HZ = 100 */
+               clock_pcctwo_count += PCCTWO_TIMERFREQ / 100;
                hardclock(frame);
+       }
 
        return (1);
 }
Index: dev/mvme/clockvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/mvme/clockvar.h,v
retrieving revision 1.6
diff -u -r1.6 clockvar.h
--- dev/mvme/clockvar.h 11 Dec 2005 12:22:47 -0000      1.6
+++ dev/mvme/clockvar.h 4 Jan 2008 13:46:43 -0000
@@ -53,7 +53,6 @@
 
 struct clock_attach_args {
        void                    (*ca_initfunc)(void *, int, int);
-       long                    (*ca_microtime)(void *);
        void                    *ca_arg;
 };
 
Index: dev/mvme/pcctworeg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/mvme/pcctworeg.h,v
retrieving revision 1.1
diff -u -r1.1 pcctworeg.h
--- dev/mvme/pcctworeg.h        12 Feb 2002 20:38:49 -0000      1.1
+++ dev/mvme/pcctworeg.h        4 Jan 2008 13:46:43 -0000
@@ -239,6 +239,7 @@
  * this is simple since the Tick Counters already have
  * a 1uS period. (PCC2REG_TIMER[12]_COMPARE)
  */
+#define PCCTWO_TIMERFREQ       1000000
 #define PCCTWO_US2LIM(us)      (us)
 #define PCCTWO_LIM2US(lim)     (lim)
 
---

Note in Garrett's patch tc1 value which was read from
TMR1_COUNT was not used for timecounter, but it looks
he just forgot to add it.
---
Izumi Tsutsui



Home | Main Index | Thread Index | Old Index