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