Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/cortex port-arm/49737: armgtmr0 timer broken



details:   https://anonhg.NetBSD.org/src/rev/b5735038e59e
branches:  trunk
changeset: 336861:b5735038e59e
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Mon Mar 23 23:33:22 2015 +0000

description:
port-arm/49737: armgtmr0 timer broken

Use physical timer instead of virtual timer for timecounter. For platforms
that implement virtualization extensions, the CNTVOFF register defines a
virtual offset between the physical count and virtual count. Unfortunately,
the CNTVOFF register is only accessible in secure mode and the value is
per-CPU, so we may end up in a scenario where virtual count reads from
CPU A -> B -> A are not monotonic. No offset applied to physical timer,
so physical count reads are guaranteed to be monotonic.

diffstat:

 sys/arch/arm/cortex/gtmr.c |  10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diffs (43 lines):

diff -r cd262c589e0e -r b5735038e59e sys/arch/arm/cortex/gtmr.c
--- a/sys/arch/arm/cortex/gtmr.c        Mon Mar 23 23:28:55 2015 +0000
+++ b/sys/arch/arm/cortex/gtmr.c        Mon Mar 23 23:33:22 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gtmr.c,v 1.9 2015/02/28 09:34:35 skrll Exp $   */
+/*     $NetBSD: gtmr.c,v 1.10 2015/03/23 23:33:22 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.9 2015/02/28 09:34:35 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.10 2015/03/23 23:33:22 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -112,7 +112,8 @@
        /*
         * Enable the virtual counter to be accessed from usermode.
         */
-       armreg_cntk_ctl_write(armreg_cntk_ctl_read() | ARM_CNTKCTL_PL0VCTEN);
+       armreg_cntk_ctl_write(armreg_cntk_ctl_read() |
+           ARM_CNTKCTL_PL0VCTEN | ARM_CNTKCTL_PL0PCTEN);
 
        self->dv_private = sc;
        sc->sc_dev = self;
@@ -159,6 +160,7 @@
         * enable timer and stop masking the timer.
         */
        armreg_cntv_ctl_write(ARM_CNTCTL_ENABLE);
+       armreg_cntp_ctl_write(ARM_CNTCTL_ENABLE);
 #if 0
        printf("%s: cntctl=%#x\n", __func__, armreg_cntv_ctl_read());
 #endif
@@ -328,5 +330,5 @@
 gtmr_get_timecount(struct timecounter *tc)
 {
 
-       return (u_int) (armreg_cntv_ct_read());
+       return (u_int) (armreg_cntp_ct_read());
 }



Home | Main Index | Thread Index | Old Index