From b38096892ac5ab54dadd7c1aaa11927ac93ae7f3 Mon Sep 17 00:00:00 2001 From: wdk Date: Wed, 6 Sep 2000 07:52:47 +0000 Subject: [PATCH] Microtime calculation was seriously incorrect when HZ != 100 Give rest of clock interrupt code a revamp. Because we are using an external cycle counter we can now handle loosing several hundred interrupts without the time slipping. --- sys/arch/mipsco/mipsco/machdep.c | 7 ++--- sys/arch/mipsco/obio/rambo.c | 49 ++++++++++++++++++++------------ sys/arch/mipsco/obio/rambo.h | 5 ++-- 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/sys/arch/mipsco/mipsco/machdep.c b/sys/arch/mipsco/mipsco/machdep.c index fa4b0d4382fd..69596549e750 100644 --- a/sys/arch/mipsco/mipsco/machdep.c +++ b/sys/arch/mipsco/mipsco/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.6 2000/08/29 12:12:59 wdk Exp $ */ +/* $NetBSD: machdep.c,v 1.7 2000/09/06 07:52:47 wdk Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -43,7 +43,7 @@ #include /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.6 2000/08/29 12:12:59 wdk Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.7 2000/09/06 07:52:47 wdk Exp $"); /* from: Utah Hdr: machdep.c 1.63 91/04/24 */ @@ -570,13 +570,12 @@ microtime(tvp) { static struct timeval lasttime; int s = splclock(); - long rambo_getutime(); *tvp = time; tvp->tv_usec += (*platform.clkread)(); - if (tvp->tv_usec >= 1000000) { + while (tvp->tv_usec >= 1000000) { tvp->tv_usec -= 1000000; tvp->tv_sec++; } diff --git a/sys/arch/mipsco/obio/rambo.c b/sys/arch/mipsco/obio/rambo.c index e30322cc2628..fa826dd76898 100644 --- a/sys/arch/mipsco/obio/rambo.c +++ b/sys/arch/mipsco/obio/rambo.c @@ -1,4 +1,4 @@ -/* $NetBSD: rambo.c,v 1.2 2000/08/15 04:56:47 wdk Exp $ */ +/* $NetBSD: rambo.c,v 1.3 2000/09/06 07:52:47 wdk Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -104,7 +104,7 @@ rambo_attach(parent, self, aux) /* Setup RAMBO Timer to generate timer interrupts */ sc->sc_hzticks = HZ_TO_TICKS(hz); - sc->sc_tclast = sc->sc_hzticks; + sc->sc_tclast = 0; bus_space_write_4(sc->sc_bst, sc->sc_bsh, RB_TCOUNT, 0); bus_space_write_4(sc->sc_bst, sc->sc_bsh, RB_TBREAK, sc->sc_hzticks); @@ -120,36 +120,49 @@ void rambo_clkintr(cf) struct clockframe *cf; { - register u_int32_t tbreak, tclast; - register int cycles = 0; - + register u_int32_t tbreak, tcount; + register int delta; + rambo->sc_intrcnt.ev_count++; tbreak = bus_space_read_4(rambo->sc_bst, rambo->sc_bsh, RB_TBREAK); - /* This will also clear the interrupt */ - while ((tclast=bus_space_read_4(rambo->sc_bst, rambo->sc_bsh, - RB_TCOUNT)) >= tbreak) { + tcount = bus_space_read_4(rambo->sc_bst, rambo->sc_bsh, RB_TCOUNT); + delta = tcount - tbreak; + + if (delta > (rambo->sc_hzticks>>1)) { + /* + * Either tcount may overtake the updated tbreak value + * or we have missed several interrupt's + */ + int cycles = 10 * hz; + while (cycles && tbreak < tcount) { + hardclock(cf); + rambo->sc_tclast = tbreak; + tbreak += rambo->sc_hzticks; + cycles--; + } + if (cycles == 0) { /* catchup failed - assume we are in sync */ + tcount = bus_space_read_4(rambo->sc_bst, + rambo->sc_bsh, RB_TCOUNT); + rambo->sc_tclast = tbreak = tcount; + } + } else { hardclock(cf); - tbreak += rambo->sc_hzticks; - cycles++; + rambo->sc_tclast = tbreak; } + tbreak += rambo->sc_hzticks; + bus_space_write_4(rambo->sc_bst, rambo->sc_bsh, RB_TBREAK, tbreak); - rambo->sc_tclast = tclast; } /* * Calculate the number of microseconds since the last clock tick */ -unsigned +static unsigned rambo_clkread() { register u_int32_t tcount; - register u_int32_t tusec; - int s = splclock(); tcount = bus_space_read_4(rambo->sc_bst, rambo->sc_bsh, RB_TCOUNT); - tusec = TICKS_TO_USECS(tcount-rambo->sc_tclast, hz); - splx(s); - - return tusec; + return TICKS_TO_USECS(tcount - rambo->sc_tclast); } diff --git a/sys/arch/mipsco/obio/rambo.h b/sys/arch/mipsco/obio/rambo.h index bf6b9496c687..0e32f787f60a 100644 --- a/sys/arch/mipsco/obio/rambo.h +++ b/sys/arch/mipsco/obio/rambo.h @@ -1,4 +1,4 @@ -/* $NetBSD: rambo.h,v 1.1 2000/08/12 22:58:58 wdk Exp $ */ +/* $NetBSD: rambo.h,v 1.2 2000/09/06 07:52:47 wdk Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. * All rights reserved. @@ -115,6 +115,7 @@ struct rambo_ch { #define RB_BMASK ((1<