Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/arm/fdt On a system with both global and private ti...



details:   https://anonhg.NetBSD.org/src/rev/9bd54fdcfad4
branches:  trunk
changeset: 372230:9bd54fdcfad4
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Tue Nov 01 11:05:18 2022 +0000

description:
On a system with both global and private timers, we cannot drive hardclock
from both or else time will move too fast.

Check MPIDR and install the global timer interrupt handler on uniprocessor
configs, and the private timer interrupt handler on MPCore configs.

diffstat:

 sys/arch/arm/fdt/a9ptmr_fdt.c |  31 +++++++++++++++++++++----------
 sys/arch/arm/fdt/a9tmr_fdt.c  |  31 +++++++++++++++++++++----------
 2 files changed, 42 insertions(+), 20 deletions(-)

diffs (148 lines):

diff -r 0ac2b0c09f51 -r 9bd54fdcfad4 sys/arch/arm/fdt/a9ptmr_fdt.c
--- a/sys/arch/arm/fdt/a9ptmr_fdt.c     Tue Nov 01 11:03:01 2022 +0000
+++ b/sys/arch/arm/fdt/a9ptmr_fdt.c     Tue Nov 01 11:05:18 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: a9ptmr_fdt.c,v 1.5 2021/08/07 16:18:43 thorpej Exp $ */
+/* $NetBSD: a9ptmr_fdt.c,v 1.6 2022/11/01 11:05:18 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: a9ptmr_fdt.c,v 1.5 2021/08/07 16:18:43 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: a9ptmr_fdt.c,v 1.6 2022/11/01 11:05:18 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -41,6 +41,8 @@
 #include <arm/cortex/mpcore_var.h>
 #include <arm/cortex/a9ptmr_var.h>
 
+#include <arm/armreg.h>
+
 #include <dev/fdt/fdtvar.h>
 #include <arm/fdt/arm_fdtvar.h>
 
@@ -78,6 +80,8 @@
        struct fdt_attach_args * const faa = aux;
        const int phandle = faa->faa_phandle;
        bus_space_handle_t bsh;
+       uint32_t mpidr;
+       bool is_hardclock;
 
        sc->sc_dev = self;
        sc->sc_clk = fdtbus_clock_get_index(phandle, 0);
@@ -103,13 +107,18 @@
        aprint_naive("\n");
        aprint_normal("\n");
 
-       void *ih = fdtbus_intr_establish_xname(phandle, 0, IPL_CLOCK,
-           FDT_INTR_MPSAFE, a9ptmr_intr, NULL, device_xname(self));
-       if (ih == NULL) {
-               aprint_error_dev(self, "couldn't install interrupt handler\n");
-               return;
+       mpidr = armreg_mpidr_read();
+       is_hardclock = (mpidr & MPIDR_U) == 0;  /* Use private timer for SMP */
+
+       if (is_hardclock) {
+               void *ih = fdtbus_intr_establish_xname(phandle, 0, IPL_CLOCK,
+                   FDT_INTR_MPSAFE, a9ptmr_intr, NULL, device_xname(self));
+               if (ih == NULL) {
+                       aprint_error_dev(self, "couldn't install interrupt handler\n");
+                       return;
+               }
+               aprint_normal_dev(self, "interrupting on %s\n", intrstr);
        }
-       aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
        bus_addr_t addr;
        bus_size_t size;
@@ -131,8 +140,10 @@
 
        config_found(self, &mpcaa, NULL, CFARGS_NONE);
 
-       arm_fdt_cpu_hatch_register(self, a9ptmr_fdt_cpu_hatch);
-       arm_fdt_timer_register(a9ptmr_cpu_initclocks);
+       if (is_hardclock) {
+               arm_fdt_cpu_hatch_register(self, a9ptmr_fdt_cpu_hatch);
+               arm_fdt_timer_register(a9ptmr_cpu_initclocks);
+       }
 }
 
 static void
diff -r 0ac2b0c09f51 -r 9bd54fdcfad4 sys/arch/arm/fdt/a9tmr_fdt.c
--- a/sys/arch/arm/fdt/a9tmr_fdt.c      Tue Nov 01 11:03:01 2022 +0000
+++ b/sys/arch/arm/fdt/a9tmr_fdt.c      Tue Nov 01 11:05:18 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: a9tmr_fdt.c,v 1.7 2021/08/07 16:18:43 thorpej Exp $ */
+/* $NetBSD: a9tmr_fdt.c,v 1.8 2022/11/01 11:05:18 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: a9tmr_fdt.c,v 1.7 2021/08/07 16:18:43 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: a9tmr_fdt.c,v 1.8 2022/11/01 11:05:18 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -41,6 +41,8 @@
 #include <arm/cortex/mpcore_var.h>
 #include <arm/cortex/a9tmr_var.h>
 
+#include <arm/armreg.h>
+
 #include <dev/fdt/fdtvar.h>
 #include <arm/fdt/arm_fdtvar.h>
 
@@ -79,6 +81,8 @@
        struct fdt_attach_args * const faa = aux;
        const int phandle = faa->faa_phandle;
        bus_space_handle_t bsh;
+       uint32_t mpidr;
+       bool is_hardclock;
 
        sc->sc_dev = self;
        sc->sc_clk = fdtbus_clock_get_index(phandle, 0);
@@ -104,13 +108,18 @@
        aprint_naive("\n");
        aprint_normal("\n");
 
-       void *ih = fdtbus_intr_establish_xname(phandle, 0, IPL_CLOCK,
-           FDT_INTR_MPSAFE, a9tmr_intr, NULL, device_xname(self));
-       if (ih == NULL) {
-               aprint_error_dev(self, "couldn't install interrupt handler\n");
-               return;
+       mpidr = armreg_mpidr_read();
+       is_hardclock = (mpidr & MPIDR_U) != 0;  /* Global timer for UP */
+
+       if (is_hardclock) {
+               void *ih = fdtbus_intr_establish_xname(phandle, 0, IPL_CLOCK,
+                   FDT_INTR_MPSAFE, a9tmr_intr, NULL, device_xname(self));
+               if (ih == NULL) {
+                       aprint_error_dev(self, "couldn't install interrupt handler\n");
+                       return;
+               }
+               aprint_normal_dev(self, "interrupting on %s\n", intrstr);
        }
-       aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
        bus_addr_t addr;
        bus_size_t size;
@@ -132,8 +141,10 @@
 
        config_found(self, &mpcaa, NULL, CFARGS_NONE);
 
-       arm_fdt_cpu_hatch_register(self, a9tmr_fdt_cpu_hatch);
-       arm_fdt_timer_register(a9tmr_cpu_initclocks);
+       if (is_hardclock) {
+               arm_fdt_cpu_hatch_register(self, a9tmr_fdt_cpu_hatch);
+               arm_fdt_timer_register(a9tmr_cpu_initclocks);
+       }
 
        pmf_event_register(self, PMFE_SPEED_CHANGED, a9tmr_fdt_speed_changed, true);
 }



Home | Main Index | Thread Index | Old Index