1/* 2 * Copyright (c) 2011-2014 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Dam Sunwoo 38 * Matt Horsnell 39 * Andreas Sandberg 40 */ 41#ifndef __ARCH_ARM_PMU_HH__ 42#define __ARCH_ARM_PMU_HH__ 43 44#include <map> 45#include <memory> 46#include <vector> 47 48#include "arch/arm/isa_device.hh" 49#include "arch/arm/registers.hh" 50#include "sim/probe/probe.hh" 51#include "sim/sim_object.hh" 52 53class ArmPMUParams; 54class Platform; 55class ThreadContext; 56 57namespace ArmISA { 58 59 60/** 61 * Model of an ARM PMU version 3 62 * 63 * This class implements a subset of the ARM PMU v3 specification as 64 * described in the ARMv8 reference manual. It supports most of the 65 * features of the PMU, however the following features are known to be 66 * missing: 67 * 68 * <ul> 69 * <li>Event filtering (e.g., from different privilege levels). 70 * <li>Access controls (the PMU currently ignores the execution level). 71 * <li>The chain counter (event no. 0x1E) is unimplemented. 72 * </ul> 73 * 74 * The PMU itself does not implement any events, in merely provides an 75 * interface for the configuration scripts to hook up probes that 76 * drive events. Configuration scripts should call addEventProbe() to 77 * configure custom events or high-level methods to configure 78 * architected events. The Python implementation of addEventProbe() 79 * automatically delays event type registration until after 80 * instantiation. 81 * 82 * In order to support CPU switching and some combined counters (e.g., 83 * memory references synthesized from loads and stores), the PMU 84 * allows multiple probes per event type. When creating a system that 85 * switches between CPU models that share the same PMU, PMU events for 86 * all of the CPU models can be registered with the PMU. 87 * 88 * @see The ARM Architecture Refererence Manual (DDI 0487A) 89 * 90 */ 91class PMU : public SimObject, public ArmISA::BaseISADevice { 92 public: 93 PMU(const ArmPMUParams *p); 94 ~PMU(); 95 96 void addEventProbe(unsigned int id, SimObject *obj, const char *name); 97 98 public: // SimObject and related interfaces 99 void serialize(std::ostream &os) M5_ATTR_OVERRIDE; 100 void unserialize(Checkpoint *cp, const std::string &sec) M5_ATTR_OVERRIDE; 101 102 void drainResume() M5_ATTR_OVERRIDE; 103 104 105 public: // ISA Device interface 106 /** 107 * Set a register within the PMU. 108 * 109 * @param misc_reg Register number (see miscregs.hh) 110 * @param val Value to store 111 */ 112 void setMiscReg(int misc_reg, MiscReg val) M5_ATTR_OVERRIDE; 113 /** 114 * Read a register within the PMU. 115 * 116 * @param misc_reg Register number (see miscregs.hh) 117 * @return Register value. 118 */ 119 MiscReg readMiscReg(int misc_reg) M5_ATTR_OVERRIDE; 120 121 protected: // PMU register types and constants 122 BitUnion32(PMCR_t) 123 // PMU Enable 124 Bitfield<0> e; 125 // Event counter reset 126 Bitfield<1> p; 127 // Cycle counter reset 128 Bitfield<2> c; 129 // Cycle counter divider enable 130 Bitfield<3> d; 131 // Export enable 132 Bitfield<4> x; 133 // Disable PMCCNTR when event counting is prohibited 134 Bitfield<5> dp; 135 // Long Cycle counter enable 136 Bitfield<6> lc; 137 // Number of event counters implemented 138 Bitfield<15, 11> n; 139 // Implementation ID 140 Bitfield<23, 16> idcode; 141 // Implementer code 142 Bitfield<31, 24> imp; 143 EndBitUnion(PMCR_t) 144 145 BitUnion32(PMSELR_t) 146 // Performance counter selector 147 Bitfield<4, 0> sel; 148 EndBitUnion(PMSELR_t) 149 150 BitUnion32(PMEVTYPER_t) 151 Bitfield<9, 0> evtCount; 152 153 // Secure EL3 filtering 154 Bitfield<26> m; 155 // Non-secure EL2 mode filtering 156 Bitfield<27> nsh; 157 // Non-secure EL0 mode filtering 158 Bitfield<28> nsu; 159 // Non-secure EL1 mode filtering 160 Bitfield<29> nsk; 161 // EL0 filtering 162 Bitfield<30> u; 163 // EL1 filtering 164 Bitfield<31> p; 165 EndBitUnion(PMEVTYPER_t) 166 167 /** 168 * Counter ID within the PMU. 169 * 170 * This value is typically used to index into various registers 171 * controlling interrupts and overflows. The value normally in the 172 * [0, 31] range, where 31 refers to the cycle counter. 173 */ 174 typedef unsigned int CounterId; 175 176 /** Cycle Count Register Number */ 177 static const CounterId PMCCNTR = 31; 178 179 /** 180 * Event type ID. 181 * 182 * See the PMU documentation for a list of architected IDs. 183 */ 184 typedef unsigned int EventTypeId; 185 186 /** ID of the software increment event */ 187 static const EventTypeId ARCH_EVENT_SW_INCR = 0x00; 188 189 protected: /* High-level register and interrupt handling */ 190 MiscReg readMiscRegInt(int misc_reg); 191 192 /** 193 * PMCR write handling 194 * 195 * The PMCR register needs special handling since writing to it 196 * changes PMU-global state (e.g., resets all counters). 197 * 198 * @param val New PMCR value 199 */ 200 void setControlReg(PMCR_t val); 201 202 /** 203 * Reset all event counters excluding the cycle counter to zero. 204 */ 205 void resetEventCounts(); 206 207 /** 208 * Deliver a PMU interrupt to the GIC 209 */ 210 void raiseInterrupt(); 211 212 /** 213 * Get the value of a performance counter. 214 * 215 * This method returns the value of a general purpose performance 216 * counter or the fixed-function cycle counter. Non-existing 217 * counters are treated as constant '0'. 218 * 219 * @return Value of the performance counter, 0 if the counter does 220 * not exist. 221 */ 222 uint64_t getCounterValue(CounterId id) const { 223 return isValidCounter(id) ? getCounter(id).value : 0; 224 } 225 226 /** 227 * Set the value of a performance counter. 228 * 229 * This method sets the value of a general purpose performance 230 * counter or the fixed-function cycle counter. Writes to 231 * non-existing counters are ignored. 232 */ 233 void setCounterValue(CounterId id, uint64_t val); 234 235 /** 236 * Get the type and filter settings of a counter (PMEVTYPER) 237 * 238 * This method implements a read from a PMEVTYPER register. It 239 * returns the type value and filter settings of a general purpose 240 * performance counter or the cycle counter. Non-existing counters 241 * are treated as constant '0'. 242 * 243 * @param id Counter ID within the PMU. 244 * @return Performance counter type ID. 245 */ 246 PMEVTYPER_t getCounterTypeRegister(CounterId id) const; 247 248 /** 249 * Set the type and filter settings of a performance counter 250 * (PMEVTYPER) 251 * 252 * This method implements a write to a PMEVTYPER register. It sets 253 * the type value and filter settings of a general purpose 254 * performance counter or the cycle counter. Writes to 255 * non-existing counters are ignored. The method automatically 256 * updates the probes used by the counter if it is enabled. 257 * 258 * @param id Counter ID within the PMU. 259 * @param type Performance counter type and filter configuration.. 260 */ 261 void setCounterTypeRegister(CounterId id, PMEVTYPER_t type); 262 263 protected: /* Probe handling and counter state */ 264 class ProbeListener : public ProbeListenerArgBase<uint64_t> 265 { 266 public: 267 ProbeListener(PMU &_pmu, CounterId _id, 268 ProbeManager *pm, const std::string &name) 269 : ProbeListenerArgBase(pm, name), 270 pmu(_pmu), id(_id) {} 271 272 void notify(const uint64_t &val) M5_ATTR_OVERRIDE 273 { 274 pmu.handleEvent(id, val); 275 } 276 277 protected: 278 PMU &pmu; 279 const CounterId id; 280 }; 281 typedef std::unique_ptr<ProbeListener> ProbeListenerUPtr; 282 283 /** 284 * Event type configuration 285 * 286 * The main purpose of this class is to describe how a PMU event 287 * type is sampled. It is implemented as a probe factory that 288 * returns a probe attached to the object the event is mointoring. 289 */ 290 struct EventType { 291 /** 292 * @param _obj Target SimObject 293 * @param _name Probe name 294 */ 295 EventType(SimObject *_obj, const std::string &_name) 296 : obj(_obj), name(_name) {} 297 298 /** 299 * Create and attach a probe used to drive this event. 300 * 301 * @param pmu PMU owning the probe. 302 * @param CounterID counter ID within the PMU. 303 * @return Pointer to a probe listener. 304 */ 305 std::unique_ptr<ProbeListener> create(PMU &pmu, CounterId cid) const 306 { 307 std::unique_ptr<ProbeListener> ptr; 308 ptr.reset(new ProbeListener(pmu, cid, 309 obj->getProbeManager(), name)); 310 return ptr; 311 } 312 313 /** SimObject being measured by this probe */ 314 SimObject *const obj; 315 /** Probe name within obj */ 316 const std::string name; 317 318 private: 319 // Disable the default constructor 320 EventType(); 321 }; 322 323 /** State of a counter within the PMU. */ 324 struct CounterState { 325 CounterState()
| 1/* 2 * Copyright (c) 2011-2014 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Dam Sunwoo 38 * Matt Horsnell 39 * Andreas Sandberg 40 */ 41#ifndef __ARCH_ARM_PMU_HH__ 42#define __ARCH_ARM_PMU_HH__ 43 44#include <map> 45#include <memory> 46#include <vector> 47 48#include "arch/arm/isa_device.hh" 49#include "arch/arm/registers.hh" 50#include "sim/probe/probe.hh" 51#include "sim/sim_object.hh" 52 53class ArmPMUParams; 54class Platform; 55class ThreadContext; 56 57namespace ArmISA { 58 59 60/** 61 * Model of an ARM PMU version 3 62 * 63 * This class implements a subset of the ARM PMU v3 specification as 64 * described in the ARMv8 reference manual. It supports most of the 65 * features of the PMU, however the following features are known to be 66 * missing: 67 * 68 * <ul> 69 * <li>Event filtering (e.g., from different privilege levels). 70 * <li>Access controls (the PMU currently ignores the execution level). 71 * <li>The chain counter (event no. 0x1E) is unimplemented. 72 * </ul> 73 * 74 * The PMU itself does not implement any events, in merely provides an 75 * interface for the configuration scripts to hook up probes that 76 * drive events. Configuration scripts should call addEventProbe() to 77 * configure custom events or high-level methods to configure 78 * architected events. The Python implementation of addEventProbe() 79 * automatically delays event type registration until after 80 * instantiation. 81 * 82 * In order to support CPU switching and some combined counters (e.g., 83 * memory references synthesized from loads and stores), the PMU 84 * allows multiple probes per event type. When creating a system that 85 * switches between CPU models that share the same PMU, PMU events for 86 * all of the CPU models can be registered with the PMU. 87 * 88 * @see The ARM Architecture Refererence Manual (DDI 0487A) 89 * 90 */ 91class PMU : public SimObject, public ArmISA::BaseISADevice { 92 public: 93 PMU(const ArmPMUParams *p); 94 ~PMU(); 95 96 void addEventProbe(unsigned int id, SimObject *obj, const char *name); 97 98 public: // SimObject and related interfaces 99 void serialize(std::ostream &os) M5_ATTR_OVERRIDE; 100 void unserialize(Checkpoint *cp, const std::string &sec) M5_ATTR_OVERRIDE; 101 102 void drainResume() M5_ATTR_OVERRIDE; 103 104 105 public: // ISA Device interface 106 /** 107 * Set a register within the PMU. 108 * 109 * @param misc_reg Register number (see miscregs.hh) 110 * @param val Value to store 111 */ 112 void setMiscReg(int misc_reg, MiscReg val) M5_ATTR_OVERRIDE; 113 /** 114 * Read a register within the PMU. 115 * 116 * @param misc_reg Register number (see miscregs.hh) 117 * @return Register value. 118 */ 119 MiscReg readMiscReg(int misc_reg) M5_ATTR_OVERRIDE; 120 121 protected: // PMU register types and constants 122 BitUnion32(PMCR_t) 123 // PMU Enable 124 Bitfield<0> e; 125 // Event counter reset 126 Bitfield<1> p; 127 // Cycle counter reset 128 Bitfield<2> c; 129 // Cycle counter divider enable 130 Bitfield<3> d; 131 // Export enable 132 Bitfield<4> x; 133 // Disable PMCCNTR when event counting is prohibited 134 Bitfield<5> dp; 135 // Long Cycle counter enable 136 Bitfield<6> lc; 137 // Number of event counters implemented 138 Bitfield<15, 11> n; 139 // Implementation ID 140 Bitfield<23, 16> idcode; 141 // Implementer code 142 Bitfield<31, 24> imp; 143 EndBitUnion(PMCR_t) 144 145 BitUnion32(PMSELR_t) 146 // Performance counter selector 147 Bitfield<4, 0> sel; 148 EndBitUnion(PMSELR_t) 149 150 BitUnion32(PMEVTYPER_t) 151 Bitfield<9, 0> evtCount; 152 153 // Secure EL3 filtering 154 Bitfield<26> m; 155 // Non-secure EL2 mode filtering 156 Bitfield<27> nsh; 157 // Non-secure EL0 mode filtering 158 Bitfield<28> nsu; 159 // Non-secure EL1 mode filtering 160 Bitfield<29> nsk; 161 // EL0 filtering 162 Bitfield<30> u; 163 // EL1 filtering 164 Bitfield<31> p; 165 EndBitUnion(PMEVTYPER_t) 166 167 /** 168 * Counter ID within the PMU. 169 * 170 * This value is typically used to index into various registers 171 * controlling interrupts and overflows. The value normally in the 172 * [0, 31] range, where 31 refers to the cycle counter. 173 */ 174 typedef unsigned int CounterId; 175 176 /** Cycle Count Register Number */ 177 static const CounterId PMCCNTR = 31; 178 179 /** 180 * Event type ID. 181 * 182 * See the PMU documentation for a list of architected IDs. 183 */ 184 typedef unsigned int EventTypeId; 185 186 /** ID of the software increment event */ 187 static const EventTypeId ARCH_EVENT_SW_INCR = 0x00; 188 189 protected: /* High-level register and interrupt handling */ 190 MiscReg readMiscRegInt(int misc_reg); 191 192 /** 193 * PMCR write handling 194 * 195 * The PMCR register needs special handling since writing to it 196 * changes PMU-global state (e.g., resets all counters). 197 * 198 * @param val New PMCR value 199 */ 200 void setControlReg(PMCR_t val); 201 202 /** 203 * Reset all event counters excluding the cycle counter to zero. 204 */ 205 void resetEventCounts(); 206 207 /** 208 * Deliver a PMU interrupt to the GIC 209 */ 210 void raiseInterrupt(); 211 212 /** 213 * Get the value of a performance counter. 214 * 215 * This method returns the value of a general purpose performance 216 * counter or the fixed-function cycle counter. Non-existing 217 * counters are treated as constant '0'. 218 * 219 * @return Value of the performance counter, 0 if the counter does 220 * not exist. 221 */ 222 uint64_t getCounterValue(CounterId id) const { 223 return isValidCounter(id) ? getCounter(id).value : 0; 224 } 225 226 /** 227 * Set the value of a performance counter. 228 * 229 * This method sets the value of a general purpose performance 230 * counter or the fixed-function cycle counter. Writes to 231 * non-existing counters are ignored. 232 */ 233 void setCounterValue(CounterId id, uint64_t val); 234 235 /** 236 * Get the type and filter settings of a counter (PMEVTYPER) 237 * 238 * This method implements a read from a PMEVTYPER register. It 239 * returns the type value and filter settings of a general purpose 240 * performance counter or the cycle counter. Non-existing counters 241 * are treated as constant '0'. 242 * 243 * @param id Counter ID within the PMU. 244 * @return Performance counter type ID. 245 */ 246 PMEVTYPER_t getCounterTypeRegister(CounterId id) const; 247 248 /** 249 * Set the type and filter settings of a performance counter 250 * (PMEVTYPER) 251 * 252 * This method implements a write to a PMEVTYPER register. It sets 253 * the type value and filter settings of a general purpose 254 * performance counter or the cycle counter. Writes to 255 * non-existing counters are ignored. The method automatically 256 * updates the probes used by the counter if it is enabled. 257 * 258 * @param id Counter ID within the PMU. 259 * @param type Performance counter type and filter configuration.. 260 */ 261 void setCounterTypeRegister(CounterId id, PMEVTYPER_t type); 262 263 protected: /* Probe handling and counter state */ 264 class ProbeListener : public ProbeListenerArgBase<uint64_t> 265 { 266 public: 267 ProbeListener(PMU &_pmu, CounterId _id, 268 ProbeManager *pm, const std::string &name) 269 : ProbeListenerArgBase(pm, name), 270 pmu(_pmu), id(_id) {} 271 272 void notify(const uint64_t &val) M5_ATTR_OVERRIDE 273 { 274 pmu.handleEvent(id, val); 275 } 276 277 protected: 278 PMU &pmu; 279 const CounterId id; 280 }; 281 typedef std::unique_ptr<ProbeListener> ProbeListenerUPtr; 282 283 /** 284 * Event type configuration 285 * 286 * The main purpose of this class is to describe how a PMU event 287 * type is sampled. It is implemented as a probe factory that 288 * returns a probe attached to the object the event is mointoring. 289 */ 290 struct EventType { 291 /** 292 * @param _obj Target SimObject 293 * @param _name Probe name 294 */ 295 EventType(SimObject *_obj, const std::string &_name) 296 : obj(_obj), name(_name) {} 297 298 /** 299 * Create and attach a probe used to drive this event. 300 * 301 * @param pmu PMU owning the probe. 302 * @param CounterID counter ID within the PMU. 303 * @return Pointer to a probe listener. 304 */ 305 std::unique_ptr<ProbeListener> create(PMU &pmu, CounterId cid) const 306 { 307 std::unique_ptr<ProbeListener> ptr; 308 ptr.reset(new ProbeListener(pmu, cid, 309 obj->getProbeManager(), name)); 310 return ptr; 311 } 312 313 /** SimObject being measured by this probe */ 314 SimObject *const obj; 315 /** Probe name within obj */ 316 const std::string name; 317 318 private: 319 // Disable the default constructor 320 EventType(); 321 }; 322 323 /** State of a counter within the PMU. */ 324 struct CounterState { 325 CounterState()
|