Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/mvme68k Implement a real microtime() by reading the...



details:   https://anonhg.NetBSD.org/src/rev/7652ed80343d
branches:  trunk
changeset: 508587:7652ed80343d
user:      scw <scw%NetBSD.org@localhost>
date:      Sat Apr 14 13:53:05 2001 +0000

description:
Implement a real microtime() by reading the timer counter register.
On mvme147 this gives 6.25uS resolution, and 1uS on all other boards.

diffstat:

 sys/arch/mvme68k/dev/clock_pcc.c    |  55 +++++++++++++++++++++++++++++++--
 sys/arch/mvme68k/dev/clock_pcctwo.c |  60 +++++++++++++++++++++++++++++++++---
 sys/arch/mvme68k/dev/pccreg.h       |  15 +++++---
 sys/arch/mvme68k/dev/pcctworeg.h    |   3 +-
 sys/arch/mvme68k/mvme68k/clock.c    |   6 ++-
 sys/arch/mvme68k/mvme68k/clockvar.h |   3 +-
 6 files changed, 122 insertions(+), 20 deletions(-)

diffs (truncated from 309 to 300 lines):

diff -r d4fcaffa055f -r 7652ed80343d sys/arch/mvme68k/dev/clock_pcc.c
--- a/sys/arch/mvme68k/dev/clock_pcc.c  Sat Apr 14 13:43:07 2001 +0000
+++ b/sys/arch/mvme68k/dev/clock_pcc.c  Sat Apr 14 13:53:05 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: clock_pcc.c,v 1.6 2000/03/18 22:33:02 scw Exp $        */
+/*     $NetBSD: clock_pcc.c,v 1.7 2001/04/14 13:53:05 scw Exp $        */
 
 /*-
  * Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -73,6 +73,7 @@
 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 struct clock_pcc_softc *clock_pcc_sc;
@@ -125,6 +126,7 @@
 
        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);
@@ -159,15 +161,60 @@
        pcc_reg_write(sys_pcc, PCCREG_TMR2_INTR_CTRL, sc->sc_clock_lvl);
 }
 
+/* ARGSUSED */
+long
+clock_pcc_microtime(arg)
+       void *arg;
+{
+       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;
+
+       /*
+        * There's no way to latch the counter and overflow registers
+        * without pausing the clock, so compensate for the possible
+        * 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().
+        */
+       tc = 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))) {
+               cr = pcc_reg_read(sys_pcc, PCCREG_TMR1_CONTROL);
+               tc = tc2;
+       }
+
+       return ((long) pcc_timer_cnt2us(tc) + ovfl_adj[cr>>PCC_TIMEROVFLSHIFT]);
+}
+
 int
 clock_pcc_profintr(frame)
        void *frame;
 {
+       u_int8_t cr;
+       u_int16_t tc;
+       int s;
 
+       s = splhigh();
+       tc = pcc_reg_read16(sys_pcc, PCCREG_TMR1_COUNT);
+       cr = pcc_reg_read(sys_pcc, PCCREG_TMR1_CONTROL);
+       if (tc > pcc_reg_read16(sys_pcc, PCCREG_TMR1_COUNT))
+               cr = pcc_reg_read(sys_pcc, PCCREG_TMR1_CONTROL);
+       pcc_reg_write(sys_pcc, PCCREG_TMR1_CONTROL, PCC_TIMERSTART);
        pcc_reg_write(sys_pcc, PCCREG_TMR1_INTR_CTRL,
            clock_pcc_sc->sc_clock_lvl);
-       hardclock(frame);
-       clock_profcnt.ev_count++;
+       __asm __volatile("movw %0,%%sr" : : "di" (s));
+
+       for (cr >>= PCC_TIMEROVFLSHIFT; cr; cr--) {
+               hardclock(frame);
+               clock_profcnt.ev_count++;
+       }
+
        return (1);
 }
 
@@ -180,6 +227,7 @@
        pcc_reg_write(sys_pcc, PCCREG_TMR2_INTR_CTRL, 0);
 
        statclock((struct clockframe *) frame);
+       clock_statcnt.ev_count++;
 
        pcc_reg_write16(sys_pcc, PCCREG_TMR2_PRELOAD,
            pcc_timer_us2lim(CLOCK_NEWINT(clock_statvar, clock_statmin)));
@@ -189,7 +237,6 @@
        pcc_reg_write(sys_pcc, PCCREG_TMR2_INTR_CTRL,
            clock_pcc_sc->sc_clock_lvl);
 
-       clock_statcnt.ev_count++;
        return (1);
 }
 
diff -r d4fcaffa055f -r 7652ed80343d sys/arch/mvme68k/dev/clock_pcctwo.c
--- a/sys/arch/mvme68k/dev/clock_pcctwo.c       Sat Apr 14 13:43:07 2001 +0000
+++ b/sys/arch/mvme68k/dev/clock_pcctwo.c       Sat Apr 14 13:53:05 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: clock_pcctwo.c,v 1.4 2000/09/06 19:51:43 scw Exp $ */
+/*     $NetBSD: clock_pcctwo.c,v 1.5 2001/04/14 13:53:06 scw Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -74,6 +74,7 @@
 static int clock_pcctwo_profintr __P((void *));
 static int clock_pcctwo_statintr __P((void *));
 static void clock_pcctwo_initclocks __P((void *, int, int));
+static long clock_pcctwo_microtime __P((void *));
 static void clock_pcctwo_shutdown __P((void *));
 
 static struct clock_pcctwo_softc *clock_pcctwo_sc;
@@ -122,6 +123,7 @@
 
        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);
@@ -154,7 +156,7 @@
        pcc2_reg_write32(sys_pcctwo, PCC2REG_TIMER1_COMPARE,
            PCCTWO_US2LIM(proftick));
        pcc2_reg_write(sys_pcctwo, PCC2REG_TIMER1_CONTROL,
-           PCCTWO_TT_CTRL_CEN | PCCTWO_TT_CTRL_COC);
+           PCCTWO_TT_CTRL_CEN | PCCTWO_TT_CTRL_COC | PCCTWO_TT_CTRL_COVF);
        pcc2_reg_write(sys_pcctwo, PCC2REG_TIMER1_ICSR, sc->sc_clock_lvl);
 
        pcc2_reg_write(sys_pcctwo, PCC2REG_TIMER2_CONTROL, PCCTWO_TT_CTRL_COVF);
@@ -162,19 +164,65 @@
        pcc2_reg_write32(sys_pcctwo, PCC2REG_TIMER2_COMPARE,
            PCCTWO_US2LIM(stattick));
        pcc2_reg_write(sys_pcctwo, PCC2REG_TIMER2_CONTROL,
-           PCCTWO_TT_CTRL_CEN | PCCTWO_TT_CTRL_COC);
+           PCCTWO_TT_CTRL_CEN | PCCTWO_TT_CTRL_COC | PCCTWO_TT_CTRL_COVF);
        pcc2_reg_write(sys_pcctwo, PCC2REG_TIMER2_ICSR, sc->sc_clock_lvl);
 }
 
+/* ARGSUSED */
+long
+clock_pcctwo_microtime(arg)
+       void *arg;
+{
+       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;
+
+       /*
+        * There's no way to latch the counter and overflow registers
+        * without pausing the clock, so compensate for the possible
+        * 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().
+        */
+       tc = 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))) {
+               cr = pcc2_reg_read(sys_pcctwo, PCC2REG_TIMER1_CONTROL);
+               tc = tc2;
+       }
+
+       return ((long) PCCTWO_LIM2US(tc) + ovfl_adj[PCCTWO_TT_CTRL_OVF(cr)]);
+}
+
 int
 clock_pcctwo_profintr(frame)
        void *frame;
 {
+       u_int8_t cr;
+       u_int32_t tc;
+       int s;
 
+       s = splhigh();
+       tc = pcc2_reg_read32(sys_pcctwo, PCC2REG_TIMER1_COUNTER);
+       cr = pcc2_reg_read(sys_pcctwo, PCC2REG_TIMER1_CONTROL);
+       if (tc > pcc2_reg_read32(sys_pcctwo, PCC2REG_TIMER1_COUNTER))
+               cr = pcc2_reg_read(sys_pcctwo, PCC2REG_TIMER1_CONTROL);
+       pcc2_reg_write(sys_pcctwo, PCC2REG_TIMER1_CONTROL,
+           PCCTWO_TT_CTRL_CEN | PCCTWO_TT_CTRL_COC | PCCTWO_TT_CTRL_COVF);
        pcc2_reg_write(sys_pcctwo, PCC2REG_TIMER1_ICSR,
            clock_pcctwo_sc->sc_clock_lvl);
-       hardclock(frame);
-       clock_profcnt.ev_count++;
+       __asm __volatile("movw %0,%%sr" : : "di" (s));
+
+       for (cr = PCCTWO_TT_CTRL_OVF(cr); cr; cr--) {
+               hardclock(frame);
+               clock_profcnt.ev_count++;
+       }
+
        return (1);
 }
 
@@ -193,7 +241,7 @@
        pcc2_reg_write32(sys_pcctwo, PCC2REG_TIMER2_COMPARE,
            PCCTWO_US2LIM(CLOCK_NEWINT(clock_statvar, clock_statmin)));
        pcc2_reg_write(sys_pcctwo, PCC2REG_TIMER2_CONTROL,
-           PCCTWO_TT_CTRL_CEN | PCCTWO_TT_CTRL_COC);
+           PCCTWO_TT_CTRL_CEN | PCCTWO_TT_CTRL_COC | PCCTWO_TT_CTRL_COVF);
 
        pcc2_reg_write(sys_pcctwo, PCC2REG_TIMER2_ICSR,
            clock_pcctwo_sc->sc_clock_lvl);
diff -r d4fcaffa055f -r 7652ed80343d sys/arch/mvme68k/dev/pccreg.h
--- a/sys/arch/mvme68k/dev/pccreg.h     Sat Apr 14 13:43:07 2001 +0000
+++ b/sys/arch/mvme68k/dev/pccreg.h     Sat Apr 14 13:53:05 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pccreg.h,v 1.7 2000/08/20 21:51:31 scw Exp $   */
+/*     $NetBSD: pccreg.h,v 1.8 2001/04/14 13:53:06 scw Exp $   */
 
 /*
  *
@@ -156,14 +156,17 @@
  * clock/timer
  */
 
-#define PCC_TIMERACK 0x80      /* ack intr */
-#define PCC_TIMER100HZ 63936   /* load value for 100Hz */
-#define PCC_TIMERCLEAR 0x0     /* reset and clear timer */
-#define PCC_TIMERSTOP  0x1     /* stop clock, but don't clear it */
-#define PCC_TIMERSTART 0x3      /* start timer */
+#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)
 
 /*
  * serial control
diff -r d4fcaffa055f -r 7652ed80343d sys/arch/mvme68k/dev/pcctworeg.h
--- a/sys/arch/mvme68k/dev/pcctworeg.h  Sat Apr 14 13:43:07 2001 +0000
+++ b/sys/arch/mvme68k/dev/pcctworeg.h  Sat Apr 14 13:53:05 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pcctworeg.h,v 1.7 2000/11/24 09:42:10 scw Exp $ */
+/*     $NetBSD: pcctworeg.h,v 1.8 2001/04/14 13:53:06 scw Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -244,6 +244,7 @@
  * a 1uS period. (PCC2REG_TIMER[12]_COMPARE)
  */
 #define PCCTWO_US2LIM(us)      (us)
+#define PCCTWO_LIM2US(lim)     (lim)
 
 /*
  * The Tick Timer Control Registers (PCC2REG_TIMER[12]_CONTROL)
diff -r d4fcaffa055f -r 7652ed80343d sys/arch/mvme68k/mvme68k/clock.c
--- a/sys/arch/mvme68k/mvme68k/clock.c  Sat Apr 14 13:43:07 2001 +0000
+++ b/sys/arch/mvme68k/mvme68k/clock.c  Sat Apr 14 13:53:05 2001 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: clock.c,v 1.13 2000/06/04 19:14:52 cgd Exp $  */
+/*      $NetBSD: clock.c,v 1.14 2001/04/14 13:53:06 scw Exp $  */
 
 /*
  * Copyright (c) 1992, 1993
@@ -164,7 +164,8 @@
 /*
  * 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 since the last clock interrupt (clock.c:clkread).
+ * 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,
@@ -180,6 +181,7 @@
        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;
diff -r d4fcaffa055f -r 7652ed80343d sys/arch/mvme68k/mvme68k/clockvar.h
--- a/sys/arch/mvme68k/mvme68k/clockvar.h       Sat Apr 14 13:43:07 2001 +0000
+++ b/sys/arch/mvme68k/mvme68k/clockvar.h       Sat Apr 14 13:53:05 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: clockvar.h,v 1.5 2000/03/18 22:33:06 scw Exp $ */
+/*     $NetBSD: clockvar.h,v 1.6 2001/04/14 13:53:06 scw Exp $ */
 
 /*-



Home | Main Index | Thread Index | Old Index