git: 48d41181ee1d - main - hwpmc/arm64: The PMXEVCNTR_EL0 register is 64-bit

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Wed, 28 May 2025 13:35:08 UTC
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=48d41181ee1d43e44cf9aa8332ccb8ad855026a9

commit 48d41181ee1d43e44cf9aa8332ccb8ad855026a9
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2025-05-27 19:55:27 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2025-05-27 19:55:27 +0000

    hwpmc/arm64: The PMXEVCNTR_EL0 register is 64-bit
    
    It may return data in the upper 32-bits when FEAT_PMUv3p5 is
    implemented so mask those bits off.
    
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D50431
---
 sys/dev/hwpmc/hwpmc_arm64.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sys/dev/hwpmc/hwpmc_arm64.c b/sys/dev/hwpmc/hwpmc_arm64.c
index b547ad2fa53e..e51d3fa84828 100644
--- a/sys/dev/hwpmc/hwpmc_arm64.c
+++ b/sys/dev/hwpmc/hwpmc_arm64.c
@@ -135,7 +135,7 @@ arm64_pmcr_write(uint64_t reg)
 /*
  * Performance Count Register N
  */
-static uint32_t
+static uint64_t
 arm64_pmcn_read(unsigned int pmc)
 {
 
@@ -149,7 +149,7 @@ arm64_pmcn_read(unsigned int pmc)
 }
 
 static void
-arm64_pmcn_write(unsigned int pmc, uint32_t reg)
+arm64_pmcn_write(unsigned int pmc, uint64_t reg)
 {
 
 	KASSERT(pmc < arm64_npmcs, ("%s: illegal PMC number %d", __func__, pmc));
@@ -247,6 +247,7 @@ arm64_read_pmc(int cpu, int ri, struct pmc *pm, pmc_value_t *v)
 		/* Reread counter in case we raced. */
 		tmp = arm64_pmcn_read(ri);
 	}
+	tmp &= 0xffffffffu;
 	tmp += 0x100000000llu * pm->pm_pcpu_state[cpu].pps_overflowcnt;
 	intr_restore(s);
 
@@ -282,6 +283,7 @@ arm64_write_pmc(int cpu, int ri, struct pmc *pm, pmc_value_t v)
 	PMCDBG3(MDP, WRI, 1, "arm64-write cpu=%d ri=%d v=%jx", cpu, ri, v);
 
 	pm->pm_pcpu_state[cpu].pps_overflowcnt = v >> 32;
+	v &= 0xffffffffu;
 	arm64_pmcn_write(ri, v);
 
 	return (0);