diff options
author | Jose Marinho <jose.marinho@arm.com> | 2017-06-14 12:29:13 +0100 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2017-07-10 08:36:19 +0000 |
commit | 22e11ea8dbf6ecb6f1788ae30883106c39aa30fa (patch) | |
tree | dc8e360512e3e8e76ea1060a814ccc481caf3060 | |
parent | 457f07c50736ff4ea7fcadc4e766b19e37ffc625 (diff) | |
download | gem5-22e11ea8dbf6ecb6f1788ae30883106c39aa30fa.tar.xz |
arch-arm: Support PMU evens in the 0x4000-0x4040 range
ARMv8.1 added a second architected event range, 0x4000-0x4040. Events
in this range are discovered using the high word of PMCEID{0,1}_EL0
Change-Id: I4cd01264230e5da4c841268a7cf3e6bd307c7180
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/3960
-rw-r--r-- | src/arch/arm/ArmPMU.py | 20 | ||||
-rw-r--r-- | src/arch/arm/pmu.cc | 46 | ||||
-rw-r--r-- | src/arch/arm/pmu.hh | 9 |
3 files changed, 57 insertions, 18 deletions
diff --git a/src/arch/arm/ArmPMU.py b/src/arch/arm/ArmPMU.py index 3802e49bc..4292fd5e8 100644 --- a/src/arch/arm/ArmPMU.py +++ b/src/arch/arm/ArmPMU.py @@ -1,5 +1,5 @@ # -*- mode:python -*- -# Copyright (c) 2009-2014 ARM Limited +# Copyright (c) 2009-2014, 2017 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -97,7 +97,7 @@ class ArmPMU(SimObject): # 0x01: L1I_CACHE_REFILL self.addEventProbe(0x02, itb, "Refills") - # 0x03: L2D_CACHE_REFILL + # 0x03: L1D_CACHE_REFILL # 0x04: L1D_CACHE self.addEventProbe(0x05, dtb, "Refills") self.addEventProbe(0x06, cpu, "RetiredLoads") @@ -127,6 +127,22 @@ class ArmPMU(SimObject): # 0x1E: CHAIN # 0x1F: L1D_CACHE_ALLOCATE # 0x20: L2D_CACHE_ALLOCATE + # 0x21: BR_RETIRED + # 0x22: BR_MIS_PRED_RETIRED + # 0x23: STALL_FRONTEND + # 0x24: STALL_BACKEND + # 0x25: L1D_TLB + # 0x26: L1I_TLB + # 0x27: L2I_CACHE + # 0x28: L2I_CACHE_REFILL + # 0x29: L3D_CACHE_ALLOCATE + # 0x2A: L3D_CACHE_REFILL + # 0x2B: L3D_CACHE + # 0x2C: L3D_CACHE_WB + # 0x2D: L2D_TLB_REFILL + # 0x2E: L2I_TLB_REFILL + # 0x2F: L2D_TLB + # 0x30: L2I_TLB platform = Param.Platform(Parent.any, "Platform this device is part of.") eventCounters = Param.Int(31, "Number of supported PMU counters") diff --git a/src/arch/arm/pmu.cc b/src/arch/arm/pmu.cc index ac2f4759f..14b1b50a0 100644 --- a/src/arch/arm/pmu.cc +++ b/src/arch/arm/pmu.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 ARM Limited + * Copyright (c) 2011-2014, 2017 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -59,7 +59,7 @@ PMU::PMU(const ArmPMUParams *p) : SimObject(p), BaseISADevice(), reg_pmcnten(0), reg_pmcr(0), reg_pmselr(0), reg_pminten(0), reg_pmovsr(0), - reg_pmceid(0), + reg_pmceid0(0),reg_pmceid1(0), clock_remainder(0), counters(p->eventCounters), reg_pmcr_conf(0), @@ -94,10 +94,17 @@ PMU::addEventProbe(unsigned int id, SimObject *obj, const char *probe_name) id, obj->name(), probe_name); pmuEventTypes.insert(std::make_pair(id, EventType(obj, probe_name))); - // Flag the event as available in the PMCEID register if it is an - // architected event. - if (id < 0x40) - reg_pmceid |= (ULL(1) << id); + // Flag the event as available in the corresponding PMCEID register if it + // is an architected event. + if (id < 0x20) { + reg_pmceid0 |= ((uint64_t)1) << id; + } else if (id > 0x20 && id < 0x40) { + reg_pmceid1 |= ((uint64_t)1) << (id - 0x20); + } else if (id >= 0x4000 && id < 0x4020) { + reg_pmceid0 |= ((uint64_t)1) << (id - 0x4000 + 32); + } else if (id >= 0x4020 && id < 0x4040) { + reg_pmceid1 |= ((uint64_t)1) << (id - 0x4020 + 32); + } } void @@ -154,7 +161,7 @@ PMU::setMiscReg(int misc_reg, MiscReg val) case MISCREG_PMSELR: reg_pmselr = val; return; - + //TODO: implement MISCREF_PMCEID{2,3} case MISCREG_PMCEID0_EL0: case MISCREG_PMCEID0: case MISCREG_PMCEID1_EL0: @@ -256,12 +263,17 @@ PMU::readMiscRegInt(int misc_reg) return reg_pmselr; case MISCREG_PMCEID0_EL0: - case MISCREG_PMCEID0: // Common Event ID register - return reg_pmceid & 0xFFFFFFFF; + return reg_pmceid0; case MISCREG_PMCEID1_EL0: + return reg_pmceid1; + + //TODO: implement MISCREF_PMCEID{2,3} + case MISCREG_PMCEID0: // Common Event ID register + return reg_pmceid0 & 0xFFFFFFFF; + case MISCREG_PMCEID1: // Common Event ID register - return (reg_pmceid >> 32) & 0xFFFFFFFF; + return reg_pmceid1 & 0xFFFFFFFF; case MISCREG_PMCCNTR_EL0: return cycleCounter.value; @@ -522,7 +534,8 @@ PMU::serialize(CheckpointOut &cp) const SERIALIZE_SCALAR(reg_pmselr); SERIALIZE_SCALAR(reg_pminten); SERIALIZE_SCALAR(reg_pmovsr); - SERIALIZE_SCALAR(reg_pmceid); + SERIALIZE_SCALAR(reg_pmceid0); + SERIALIZE_SCALAR(reg_pmceid1); SERIALIZE_SCALAR(clock_remainder); for (size_t i = 0; i < counters.size(); ++i) @@ -541,7 +554,16 @@ PMU::unserialize(CheckpointIn &cp) UNSERIALIZE_SCALAR(reg_pmselr); UNSERIALIZE_SCALAR(reg_pminten); UNSERIALIZE_SCALAR(reg_pmovsr); - UNSERIALIZE_SCALAR(reg_pmceid); + + // Old checkpoints used to store the entire PMCEID value in a + // single 64-bit entry (reg_pmceid). The register was extended in + // ARMv8.1, so we now need to store it as two 64-bit registers. + if (!UNSERIALIZE_OPT_SCALAR(reg_pmceid0)) + paramIn(cp, "reg_pmceid", reg_pmceid0); + + if (!UNSERIALIZE_OPT_SCALAR(reg_pmceid1)) + reg_pmceid1 = 0; + UNSERIALIZE_SCALAR(clock_remainder); for (size_t i = 0; i < counters.size(); ++i) diff --git a/src/arch/arm/pmu.hh b/src/arch/arm/pmu.hh index fc5bf74b3..aecdfd84e 100644 --- a/src/arch/arm/pmu.hh +++ b/src/arch/arm/pmu.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014 ARM Limited + * Copyright (c) 2011-2014, 2017 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -148,7 +148,7 @@ class PMU : public SimObject, public ArmISA::BaseISADevice { EndBitUnion(PMSELR_t) BitUnion32(PMEVTYPER_t) - Bitfield<9, 0> evtCount; + Bitfield<15, 0> evtCount; // Secure EL3 filtering Bitfield<26> m; @@ -459,10 +459,11 @@ class PMU : public SimObject, public ArmISA::BaseISADevice { /** * Performance counter ID register * - * This register contains a bitmask of available architected + * These registers contain a bitmask of available architected * counters. */ - uint64_t reg_pmceid; + uint64_t reg_pmceid0; + uint64_t reg_pmceid1; /** Remainder part when the clock counter is divided by 64 */ unsigned clock_remainder; |