Module Name:    src
Committed By:   matt
Date:           Tue Mar 24 08:58:41 UTC 2015

Modified Files:
        src/sys/arch/arm/cortex: gtmr.c

Log Message:
Sprinkle some arm_isb() to force execution of the mcrr instructions to get
more accurate values.  (Given that the generic timer is usually running at
a 64th or less of the cpu clock, this only settle to a tick or so.)


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 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.10 src/sys/arch/arm/cortex/gtmr.c:1.11
--- src/sys/arch/arm/cortex/gtmr.c:1.10	Mon Mar 23 23:33:22 2015
+++ src/sys/arch/arm/cortex/gtmr.c	Tue Mar 24 08:58:41 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: gtmr.c,v 1.10 2015/03/23 23:33:22 jmcneill Exp $	*/
+/*	$NetBSD: gtmr.c,v 1.11 2015/03/24 08:58:41 matt Exp $	*/
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.10 2015/03/23 23:33:22 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.11 2015/03/24 08:58:41 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -44,6 +44,8 @@ __KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.1
 
 #include <prop/proplib.h>
 
+#include <arm/locore.h>
+
 #include <arm/cortex/gtmr_var.h>
 
 #include <arm/cortex/mpcore_var.h>
@@ -169,6 +171,7 @@ gtmr_init_cpu_clock(struct cpu_info *ci)
 	 * Get now and update the compare timer.
 	 */
 	ci->ci_lastintr = armreg_cntv_ct_read();
+	arm_isb();
 	armreg_cntv_tval_write(sc->sc_autoinc);
 #if 0
 	printf("%s: %s: delta cval = %"PRIu64"\n",
@@ -186,14 +189,17 @@ gtmr_init_cpu_clock(struct cpu_info *ci)
 
 	uint64_t now64;
 	uint64_t start64 = armreg_cntv_ct_read();
+	arm_isb();
 	do {
 		now64 = armreg_cntv_ct_read();
+		arm_isb();
 	} while (start64 == now64);
 	start64 = now64;
 	uint64_t end64 = start64 + 64;
 	uint32_t start32 = armreg_pmccntr_read();
 	do {
 		now64 = armreg_cntv_ct_read();
+		arm_isb();
 	} while (end64 != now64);
 	uint32_t end32 = armreg_pmccntr_read();
 
@@ -241,10 +247,11 @@ gtmr_delay(unsigned int n)
 
 	const uint64_t delta = n * incr_per_us;
 	const uint64_t base = armreg_cntv_ct_read();
+	arm_isb();
 	const uint64_t finish = base + delta;
 
 	while (armreg_cntv_ct_read() < finish) {
-		/* spin */
+		arm_isb();	/* spin */
 	}
 }
 
@@ -273,12 +280,16 @@ gtmr_bootdelay(unsigned int ticks)
 int
 gtmr_intr(void *arg)
 {
-	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 = &gtmr_sc;
 
+	const uint64_t now = armreg_cntv_ct_read();
+
+	arm_isb();
+
+	uint64_t delta = now - ci->ci_lastintr;
+
 #ifdef DIAGNOSTIC
 	const uint64_t then = armreg_cntv_cval_read();
 	struct gtmr_percpu * const pc = percpu_getref(sc->sc_percpu);
@@ -329,6 +340,9 @@ setstatclockrate(int newhz)
 static u_int
 gtmr_get_timecount(struct timecounter *tc)
 {
+	u_int now = (u_int) armreg_cntp_ct_read();
+
+	arm_isb();	// we want the time NOW, not some instructions later.
 
-	return (u_int) (armreg_cntp_ct_read());
+	return now;
 }

Reply via email to