Module Name: src
Committed By: jmcneill
Date: Mon Aug 30 22:53:37 UTC 2021
Modified Files:
src/sys/arch/arm/cortex: gtmr.c
Log Message:
- Add an isb before cnt[pv]_ctl read
- cntk_ctl is 64-bits
- Do not toggle CNTCTL_IMASK in intr handler, as this may be needed
elsewhere.
To generate a diff of this commit:
cvs rdiff -u -r1.43 -r1.44 src/sys/arch/arm/cortex/gtmr.c
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.43 src/sys/arch/arm/cortex/gtmr.c:1.44
--- src/sys/arch/arm/cortex/gtmr.c:1.43 Mon Jan 18 23:43:34 2021
+++ src/sys/arch/arm/cortex/gtmr.c Mon Aug 30 22:53:37 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: gtmr.c,v 1.43 2021/01/18 23:43:34 jmcneill Exp $ */
+/* $NetBSD: gtmr.c,v 1.44 2021/08/30 22:53:37 jmcneill Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.43 2021/01/18 23:43:34 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.44 2021/08/30 22:53:37 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.4
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/timetc.h>
+#include <sys/cpu.h>
#include <prop/proplib.h>
@@ -195,6 +196,8 @@ gtmr_read_cntct(struct gtmr_softc *sc)
static uint32_t
gtmr_read_ctl(struct gtmr_softc *sc)
{
+ isb();
+
if (sc->sc_physical)
return gtmr_cntp_ctl_read();
else
@@ -239,7 +242,8 @@ void
gtmr_init_cpu_clock(struct cpu_info *ci)
{
struct gtmr_softc * const sc = >mr_sc;
- uint32_t val;
+ uint32_t cntk;
+ uint64_t ctl;
KASSERT(ci == curcpu());
@@ -249,29 +253,34 @@ gtmr_init_cpu_clock(struct cpu_info *ci)
* Allow the virtual and physical counters to be accessed from
* usermode. (PL0)
*/
- val = gtmr_cntk_ctl_read();
- val &= ~(CNTKCTL_PL0PTEN | CNTKCTL_PL0VTEN | CNTKCTL_EVNTEN);
+ cntk = gtmr_cntk_ctl_read();
+ cntk &= ~(CNTKCTL_PL0PTEN | CNTKCTL_PL0VTEN | CNTKCTL_EVNTEN);
if (sc->sc_physical) {
- val |= CNTKCTL_PL0PCTEN;
- val &= ~CNTKCTL_PL0VCTEN;
+ cntk |= CNTKCTL_PL0PCTEN;
+ cntk &= ~CNTKCTL_PL0VCTEN;
} else {
- val |= CNTKCTL_PL0VCTEN;
- val &= ~CNTKCTL_PL0PCTEN;
+ cntk |= CNTKCTL_PL0VCTEN;
+ cntk &= ~CNTKCTL_PL0PCTEN;
}
- gtmr_cntk_ctl_write(val);
+ gtmr_cntk_ctl_write(cntk);
isb();
/*
* enable timer and stop masking the timer.
*/
- gtmr_write_ctl(sc, CNTCTL_ENABLE);
+ ctl = gtmr_read_ctl(sc);
+ ctl &= ~CNTCTL_IMASK;
+ ctl |= CNTCTL_ENABLE;
+ gtmr_write_ctl(sc, ctl);
/*
* Get now and update the compare timer.
*/
ci->ci_lastintr = gtmr_read_cntct(sc);
gtmr_write_tval(sc, sc->sc_autoinc);
+
splx(s);
+
KASSERT(gtmr_read_cntct(sc) != 0);
}
@@ -324,14 +333,6 @@ gtmr_intr(void *arg)
struct cpu_info * const ci = curcpu();
struct clockframe * const cf = arg;
struct gtmr_softc * const sc = >mr_sc;
- uint32_t ctl;
-
- ctl = gtmr_read_ctl(sc);
- if ((ctl & CNTCTL_ISTATUS) == 0)
- return 0;
-
- ctl |= CNTCTL_IMASK;
- gtmr_write_ctl(sc, ctl);
const uint64_t now = gtmr_read_cntct(sc);
uint64_t delta = now - ci->ci_lastintr;
@@ -371,11 +372,6 @@ gtmr_intr(void *arg)
gtmr_write_tval(sc, sc->sc_autoinc - delta);
}
- ctl = gtmr_read_ctl(sc);
- ctl &= ~CNTCTL_IMASK;
- ctl |= CNTCTL_ENABLE;
- gtmr_write_ctl(sc, ctl);
-
ci->ci_lastintr = now;
#ifdef DIAGNOSTIC