Subject: Re: mvme68k timecounters.... untested
To: Garrett D'Amore <garrett_damore@tadpole.com>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: port-mvme68k
Date: 09/17/2006 00:08:20
This is a multi-part message in MIME format.
--------------020401030005030305080801
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
File attached this time. Doh!
Garrett D'Amore wrote:
> Attached is an untested diff to convert mvme68k to timecounters. Please
> review, test, and commit.
>
>
--
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
--------------020401030005030305080801
Content-Type: text/x-patch;
name="mvme68k.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="mvme68k.diff"
Index: sys/arch/mvme68k/dev/clock_pcc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mvme68k/dev/clock_pcc.c,v
retrieving revision 1.16
diff -d -p -u -r1.16 clock_pcc.c
--- sys/arch/mvme68k/dev/clock_pcc.c 11 Dec 2005 12:18:17 -0000 1.16
+++ sys/arch/mvme68k/dev/clock_pcc.c 17 Sep 2006 07:06:57 -0000
@@ -48,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: clock_pcc.c,
#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 clock_pcc_softc {
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,11 +77,14 @@ extern struct cfdriver clock_cd;
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;
+
/* ARGSUSED */
int
clock_pcc_match(parent, cf, aux)
@@ -122,7 +127,6 @@ clock_pcc_attach(parent, self, aux)
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));
@@ -157,20 +161,26 @@ clock_pcc_initclocks(arg, prof_us, stat_
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 = 160000;
+ 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;
+ uint16_t tc1, tc2;
+ uint8_t cr;
+ int s;
+ uint32_t cnt;
+
+ s = splhigh();
/*
* There's no way to latch the counter and overflow registers
@@ -180,14 +190,23 @@ clock_pcc_microtime(arg)
*
* Note: This only works because we're called 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) {
+ /* wrapped, reload! */
+ tc1 = tc2;
cr = pcc_reg_read(sys_pcc, PCCREG_TMR1_CONTROL);
- tc = tc2;
+ tc2 = pcc_reg_read16(sys_pcc, PCCREG_TMR1_COUNT);
+ }
+ cnt = clock_pcc_count;
+ splx(s);
+ cr >>= PCC_TIMEROVFLSHIFT;
+ while (cr--) {
+ cnt += (0xffff - PCC_TIMER100HZ); /* adds 1600 */
}
- return ((long) pcc_timer_cnt2us(tc) + ovfl_adj[cr>>PCC_TIMEROVFLSHIFT]);
+ return cnt;
}
int
@@ -208,8 +227,11 @@ clock_pcc_profintr(frame)
clock_pcc_sc->sc_clock_lvl);
splx(s);
- for (cr >>= PCC_TIMEROVFLSHIFT; cr; cr--)
+ for (cr >>= PCC_TIMEROVFLSHIFT; cr; cr--) {
+ /* record progress for timecounter */
+ clock_pcc_count += (0xffff - PCC_TIMER100HZ);
hardclock(frame);
+ }
return (1);
}
Index: sys/arch/mvme68k/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mvme68k/include/types.h,v
retrieving revision 1.10
diff -d -p -u -r1.10 types.h
--- sys/arch/mvme68k/include/types.h 9 Sep 2006 22:28:27 -0000 1.10
+++ sys/arch/mvme68k/include/types.h 17 Sep 2006 07:06:57 -0000
@@ -8,5 +8,6 @@
#define __HAVE_DEVICE_REGISTER
#define __HAVE_GENERIC_SOFT_INTERRUPTS
#define __HAVE_GENERIC_TODR
+#define __HAVE_TIMECOUNTER
#endif
Index: sys/arch/mvme68k/mvme68k/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mvme68k/mvme68k/clock.c,v
retrieving revision 1.24
diff -d -p -u -r1.24 clock.c
--- sys/arch/mvme68k/mvme68k/clock.c 9 Sep 2006 22:28:27 -0000 1.24
+++ sys/arch/mvme68k/mvme68k/clock.c 17 Sep 2006 07:06:57 -0000
@@ -139,39 +139,3 @@ setstatclockrate(newhz)
/* 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);
-}
-
--------------020401030005030305080801--