From 324ac185c8a3bc7af84fea82aa2b2b08a01a6d58 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Thu, 8 Sep 2022 18:30:14 +0100 Subject: [PATCH] arch-arm: Add an option to use 64-bit PMU counters Add support for 64-bit PMU counter registers (PMEVCNTR_EL0), as specified in Armv8-A. The counter registers are 32-bit by default, but 64-bit counters can be chosen using the `ArmPMU.use64bitCounters` parameter. Change-Id: Idb838a7438c7711438a7e078278bed21710049af Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69683 Reviewed-by: Giacomo Travaglini Tested-by: kokoro Maintainer: Giacomo Travaglini --- src/arch/arm/ArmPMU.py | 10 +++++++++- src/arch/arm/pmu.cc | 9 ++++++--- src/arch/arm/pmu.hh | 10 +++++++--- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/arch/arm/ArmPMU.py b/src/arch/arm/ArmPMU.py index f21aaff634..3eaed077eb 100644 --- a/src/arch/arm/ArmPMU.py +++ b/src/arch/arm/ArmPMU.py @@ -1,5 +1,5 @@ # -*- mode:python -*- -# Copyright (c) 2009-2014, 2017, 2020 ARM Limited +# Copyright (c) 2009-2014, 2017, 2020, 2022 Arm Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -215,3 +215,11 @@ class ArmPMU(SimObject): platform = Param.Platform(Parent.any, "Platform this device is part of.") eventCounters = Param.Int(31, "Number of supported PMU counters") interrupt = Param.ArmInterruptPin("PMU interrupt") + + # 64-bit PMU event counters are officially supported when + # Armv8.5-A FEAT_PMUv3p5 is implemented. This parameter is not a + # full implementation of FEAT_PMUv3p5. + use64bitCounters = Param.Bool( + False, + "Choose whether to use 64-bit or " "32-bit PMEVCNTR_EL0 registers.", + ) diff --git a/src/arch/arm/pmu.cc b/src/arch/arm/pmu.cc index f0ab97836a..89dc2c8412 100644 --- a/src/arch/arm/pmu.cc +++ b/src/arch/arm/pmu.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, 2017-2019 ARM Limited + * Copyright (c) 2011-2014, 2017-2019, 2022 Arm Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -56,12 +56,13 @@ const RegVal PMU::reg_pmcr_wr_mask = 0x39; PMU::PMU(const ArmPMUParams &p) : SimObject(p), BaseISADevice(), + use64bitCounters(p.use64bitCounters), reg_pmcnten(0), reg_pmcr(0), reg_pmselr(0), reg_pminten(0), reg_pmovsr(0), reg_pmceid0(0),reg_pmceid1(0), clock_remainder(0), maximumCounterCount(p.eventCounters), - cycleCounter(*this, maximumCounterCount), + cycleCounter(*this, maximumCounterCount, p.use64bitCounters), cycleCounterEventId(p.cycleEventId), swIncrementEvent(nullptr), reg_pmcr_conf(0), @@ -175,7 +176,7 @@ PMU::regProbeListeners() // at this stage all probe configurations are done // counters can be configured for (uint32_t index = 0; index < maximumCounterCount-1; index++) { - counters.emplace_back(*this, index); + counters.emplace_back(*this, index, use64bitCounters); } std::shared_ptr event = getEvent(cycleCounterEventId); @@ -685,6 +686,7 @@ PMU::serialize(CheckpointOut &cp) const { DPRINTF(Checkpoint, "Serializing Arm PMU\n"); + SERIALIZE_SCALAR(use64bitCounters); SERIALIZE_SCALAR(reg_pmcr); SERIALIZE_SCALAR(reg_pmcnten); SERIALIZE_SCALAR(reg_pmselr); @@ -705,6 +707,7 @@ PMU::unserialize(CheckpointIn &cp) { DPRINTF(Checkpoint, "Unserializing Arm PMU\n"); + UNSERIALIZE_SCALAR(use64bitCounters); UNSERIALIZE_SCALAR(reg_pmcr); UNSERIALIZE_SCALAR(reg_pmcnten); UNSERIALIZE_SCALAR(reg_pmselr); diff --git a/src/arch/arm/pmu.hh b/src/arch/arm/pmu.hh index 46b10d0a8a..ec60c6b7f5 100644 --- a/src/arch/arm/pmu.hh +++ b/src/arch/arm/pmu.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, 2017-2018 ARM Limited + * Copyright (c) 2011-2014, 2017-2018, 2022 Arm Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -413,9 +413,10 @@ class PMU : public SimObject, public ArmISA::BaseISADevice /** State of a counter within the PMU. **/ struct CounterState : public Serializable { - CounterState(PMU &pmuReference, uint64_t counter_id) + CounterState(PMU &pmuReference, uint64_t counter_id, + const bool is_64_bit) : eventId(0), filter(0), enabled(false), - overflow64(false), sourceEvent(nullptr), + overflow64(is_64_bit), sourceEvent(nullptr), counterId(counter_id), value(0), resetValue(false), pmu(pmuReference) {} @@ -572,6 +573,9 @@ class PMU : public SimObject, public ArmISA::BaseISADevice void updateAllCounters(); protected: /* State that needs to be serialized */ + /** Determine whether to use 64-bit or 32-bit counters. */ + bool use64bitCounters; + /** Performance Monitor Count Enable Register */ RegVal reg_pmcnten;