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