git: 0efa0fe26b9d - main - arm: Use the Self-Synchronized counter registers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 23 Sep 2025 17:09:37 UTC
The branch main has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=0efa0fe26b9d980b2862bb58f8484f0123cff19f
commit 0efa0fe26b9d980b2862bb58f8484f0123cff19f
Author: Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2025-09-22 17:08:47 +0000
Commit: Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2025-09-23 17:08:37 +0000
arm: Use the Self-Synchronized counter registers
When FEAT_ECV is implemented on arm64 a Self-Synchronized view of the
counter registers are available. These don't need an isb before reading
the count as they are not able to be speculatively executed.
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D51820
---
sys/arm/arm/generic_timer.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index c4a1f44a0079..e3ba56a6f6ac 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -231,6 +231,25 @@ get_cntxct(bool physical)
return (val);
}
+#ifdef __aarch64__
+/*
+ * Read the self-syncronized counter. These cannot be read speculatively so
+ * don't need an isb before them.
+ */
+static uint64_t
+get_cntxctss(bool physical)
+{
+ uint64_t val;
+
+ if (physical)
+ val = READ_SPECIALREG(CNTPCTSS_EL0_REG);
+ else
+ val = READ_SPECIALREG(CNTVCTSS_EL0_REG);
+
+ return (val);
+}
+#endif
+
static int
set_ctrl(uint32_t val, bool physical)
{
@@ -631,6 +650,7 @@ arm_tmr_attach(device_t dev)
pcell_t clock;
#endif
#ifdef __aarch64__
+ uint64_t id_aa64mmfr0_el1;
int user_phys;
#endif
int error;
@@ -641,6 +661,11 @@ arm_tmr_attach(device_t dev)
return (ENXIO);
sc->get_cntxct = &get_cntxct;
+#ifdef __aarch64__
+ if (get_kernel_reg(ID_AA64MMFR0_EL1, &id_aa64mmfr0_el1) &&
+ ID_AA64MMFR0_ECV_VAL(id_aa64mmfr0_el1) >= ID_AA64MMFR0_ECV_IMPL)
+ sc->get_cntxct = &get_cntxctss;
+#endif
#ifdef FDT
/* Get the base clock frequency */
node = ofw_bus_get_node(dev);