Module Name: src
Committed By: matt
Date: Thu Sep 12 15:38:04 UTC 2013
Modified Files:
src/sys/arch/arm/cortex: gtmr.c gtmr_var.h
Log Message:
Cleanup some diagnostic code.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/cortex/gtmr.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/cortex/gtmr_var.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/cortex/gtmr.c
diff -u src/sys/arch/arm/cortex/gtmr.c:1.3 src/sys/arch/arm/cortex/gtmr.c:1.4
--- src/sys/arch/arm/cortex/gtmr.c:1.3 Sat Sep 7 01:42:44 2013
+++ src/sys/arch/arm/cortex/gtmr.c Thu Sep 12 15:38:04 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: gtmr.c,v 1.3 2013/09/07 01:42:44 matt Exp $ */
+/* $NetBSD: gtmr.c,v 1.4 2013/09/12 15:38:04 matt Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,13 +30,14 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.3 2013/09/07 01:42:44 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.4 2013/09/12 15:38:04 matt Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/kernel.h>
+#include <sys/percpu.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/timetc.h>
@@ -56,6 +57,10 @@ static u_int gtmr_get_timecount(struct t
static struct gtmr_softc gtmr_sc;
+struct gtmr_percpu {
+ uint32_t pc_delta;
+};
+
static struct timecounter gtmr_timecounter = {
.tc_get_timecount = gtmr_get_timecount,
.tc_poll_pps = 0,
@@ -109,10 +114,13 @@ gtmr_attach(device_t parent, device_t se
*/
armreg_cntk_ctl_write(armreg_cntk_ctl_read() | ARM_CNTKCTL_PL0VCTEN);
-
self->dv_private = sc;
sc->sc_dev = self;
+#ifdef DIAGNOSTIC
+ sc->sc_percpu = percpu_alloc(sizeof(struct gtmr_percpu));
+#endif
+
evcnt_attach_dynamic(&sc->sc_ev_missing_ticks, EVCNT_TYPE_MISC, NULL,
device_xname(self), "missing interrupts");
@@ -120,8 +128,17 @@ gtmr_attach(device_t parent, device_t se
IST_EDGE, clockhandler, NULL);
if (sc->sc_global_ih == NULL)
panic("%s: unable to register timer interrupt", __func__);
- aprint_normal_dev(sc->sc_dev, "interrupting on irq %d\n",
+ aprint_normal_dev(self, "interrupting on irq %d\n",
IRQ_GTMR_PPI_VTIMER);
+
+ const uint32_t cnt_frq = armreg_cnt_frq_read();
+ if (cnt_frq == 0) {
+ aprint_verbose_dev(self, "cp15 CNT_FRQ not set\n");
+ } else if (cnt_frq != sc->sc_freq) {
+ aprint_verbose_dev(self,
+ "cp15 CNT_FRQ (%u) differs from supplied frequency\n",
+ cnt_frq);
+ }
}
void
@@ -185,7 +202,7 @@ void
cpu_initclocks(void)
{
struct gtmr_softc * const sc = >mr_sc;
-
+
KASSERT(sc->sc_dev != NULL);
KASSERT(sc->sc_freq != 0);
@@ -206,7 +223,7 @@ gtmr_delay(unsigned int n)
KASSERT(sc != NULL);
- uint32_t freq = sc->sc_freq ? sc->sc_freq : curcpu()->ci_data.cpu_cc_freq / 2;
+ uint32_t freq = sc->sc_freq ? sc->sc_freq : armreg_cnt_frq_read();
KASSERT(freq != 0);
/*
@@ -232,18 +249,18 @@ gtmr_delay(unsigned int n)
static int
clockhandler(void *arg)
{
- struct clockframe * const cf = arg;
- struct gtmr_softc * const sc = >mr_sc;
- struct cpu_info * const ci = curcpu();
-
const uint64_t now = armreg_cntv_ct_read();
+ struct cpu_info * const ci = curcpu();
uint64_t delta = now - ci->ci_lastintr;
+ struct clockframe * const cf = arg;
+ struct gtmr_softc * const sc = >mr_sc;
#ifdef DIAGNOSTIC
const uint64_t then = armreg_cntv_cval_read();
+ struct gtmr_percpu * const pc = percpu_getref(sc->sc_percpu);
KASSERTMSG(then <= now, "%"PRId64, now - then);
- KASSERTMSG(then - ci->ci_lastintr >= sc->sc_autoinc, "%"PRId64,
- then - ci->ci_lastintr - sc->sc_autoinc);
+ KASSERTMSG(then + pc->pc_delta >= ci->ci_lastintr + sc->sc_autoinc,
+ "%"PRId64, then + pc->pc_delta - ci->ci_lastintr - sc->sc_autoinc);
#endif
#if 0
@@ -255,7 +272,7 @@ clockhandler(void *arg)
ci->ci_data.cpu_name, delta, sc->sc_autoinc);
/*
- * If we got interrutped too soon (delta < sc->sc_autoinc) or
+ * If we got interrupted too soon (delta < sc->sc_autoinc) or
* we missed a tick (delta >= 2 * sc->sc_autoinc), don't try to
* adjust for jitter.
*/
@@ -265,12 +282,17 @@ clockhandler(void *arg)
}
armreg_cntv_tval_write(sc->sc_autoinc - delta);
- ci->ci_lastintr = now - delta;
+ ci->ci_lastintr = now;
+
+#ifdef DIAGNOSTIC
+ KASSERT(delta == (uint32_t) delta);
+ pc->pc_delta = delta;
+ percpu_putref(sc->sc_percpu);
+#endif
hardclock(cf);
- if (delta > 2 * sc->sc_autoinc)
- sc->sc_ev_missing_ticks.ev_count += (delta / sc->sc_autoinc) - 1;
+ sc->sc_ev_missing_ticks.ev_count += delta / sc->sc_autoinc;
return 1;
}
Index: src/sys/arch/arm/cortex/gtmr_var.h
diff -u src/sys/arch/arm/cortex/gtmr_var.h:1.2 src/sys/arch/arm/cortex/gtmr_var.h:1.3
--- src/sys/arch/arm/cortex/gtmr_var.h:1.2 Thu Jun 20 05:30:21 2013
+++ src/sys/arch/arm/cortex/gtmr_var.h Thu Sep 12 15:38:04 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: gtmr_var.h,v 1.2 2013/06/20 05:30:21 matt Exp $ */
+/* $NetBSD: gtmr_var.h,v 1.3 2013/09/12 15:38:04 matt Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -37,6 +37,9 @@ struct gtmr_softc {
uint32_t sc_freq;
u_long sc_autoinc;
void *sc_global_ih;
+#ifdef DIAGNOSTIC
+ percpu_t *sc_percpu;
+#endif
};
#ifdef _KERNEL