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);
 }

Reply via email to