Module Name: src Committed By: jmcneill Date: Tue Nov 1 11:05:18 UTC 2022
Modified Files: src/sys/arch/arm/fdt: a9ptmr_fdt.c a9tmr_fdt.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/sys/arch/arm/fdt/a9ptmr_fdt.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/fdt/a9tmr_fdt.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/fdt/a9ptmr_fdt.c diff -u src/sys/arch/arm/fdt/a9ptmr_fdt.c:1.5 src/sys/arch/arm/fdt/a9ptmr_fdt.c:1.6 --- src/sys/arch/arm/fdt/a9ptmr_fdt.c:1.5 Sat Aug 7 16:18:43 2021 +++ src/sys/arch/arm/fdt/a9ptmr_fdt.c Tue Nov 1 11:05:18 2022 @@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: a9ptmr_fdt.c #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 @@ a9ptmr_fdt_attach(device_t parent, devic 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 @@ a9ptmr_fdt_attach(device_t parent, devic 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 @@ a9ptmr_fdt_attach(device_t parent, devic 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 Index: src/sys/arch/arm/fdt/a9tmr_fdt.c diff -u src/sys/arch/arm/fdt/a9tmr_fdt.c:1.7 src/sys/arch/arm/fdt/a9tmr_fdt.c:1.8 --- src/sys/arch/arm/fdt/a9tmr_fdt.c:1.7 Sat Aug 7 16:18:43 2021 +++ src/sys/arch/arm/fdt/a9tmr_fdt.c Tue Nov 1 11:05:18 2022 @@ -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 <jmcne...@invisible.ca> @@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: a9tmr_fdt.c, #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 @@ a9tmr_fdt_attach(device_t parent, device 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 @@ a9tmr_fdt_attach(device_t parent, device 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 @@ a9tmr_fdt_attach(device_t parent, device 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); }