pmu.hh (10461:afeb5cdb3907) pmu.hh (10609:ae5582819481)
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()
326 : eventId(0), value(0), enabled(false),
326 : eventId(0), filter(0), value(0), enabled(false),
327 overflow64(false) {
328
329 listeners.reserve(4);
330 }
331
332 void serialize(std::ostream &os);
333 void unserialize(Checkpoint *cp, const std::string &section);
334
335 /**
336 * Add an event count to the counter and check for overflow.
337 *
338 * @param delta Number of events to add to the counter.
339 * @return true on overflow, false otherwise.
340 */
341 bool add(uint64_t delta);
342
343 public: /* Serializable state */
344 /** Counter event ID */
345 EventTypeId eventId;
346
327 overflow64(false) {
328
329 listeners.reserve(4);
330 }
331
332 void serialize(std::ostream &os);
333 void unserialize(Checkpoint *cp, const std::string &section);
334
335 /**
336 * Add an event count to the counter and check for overflow.
337 *
338 * @param delta Number of events to add to the counter.
339 * @return true on overflow, false otherwise.
340 */
341 bool add(uint64_t delta);
342
343 public: /* Serializable state */
344 /** Counter event ID */
345 EventTypeId eventId;
346
347 /** Filtering settings (evtCount is unused) */
348 PMEVTYPER_t filter;
349
347 /** Current value of the counter */
348 uint64_t value;
349
350 /** Is the counter enabled? */
351 bool enabled;
352
353 /** Is this a 64-bit counter? */
354 bool overflow64;
355
356 public: /* Configuration */
357 /** Probe listeners driving this counter */
358 std::vector<ProbeListenerUPtr> listeners;
359 };
360
361 /**
362 * Handle an counting event triggered by a probe.
363 *
364 * This method is called by the ProbeListener class whenever an
365 * active probe is triggered. Ths method adds the event count from
366 * the probe to the affected counter, checks for overflows, and
367 * delivers an interrupt if needed.
368 *
369 * @param id Counter ID affected by the probe.
370 * @param delta Counter increment
371 */
372 void handleEvent(CounterId id, uint64_t delta);
373
374 /**
375 * Is this a valid counter ID?
376 *
377 * @param id ID of counter within the PMU.
378 *
379 * @return true if counter is within the allowed range or the
380 * cycle counter, false otherwise.
381 */
382 bool isValidCounter(CounterId id) const {
383 return id < counters.size() || id == PMCCNTR;
384 }
385
386 /**
387 * Return the state of a counter.
388 *
389 * @param id ID of counter within the PMU.
390 * @return Reference to a CounterState instance representing the
391 * counter.
392 */
393 CounterState &getCounter(CounterId id) {
394 assert(isValidCounter(id));
395 return id == PMCCNTR ? cycleCounter : counters[id];
396 }
397
398
399 /**
400 * Return the state of a counter.
401 *
402 * @param id ID of counter within the PMU.
403 * @return Reference to a CounterState instance representing the
404 * counter.
405 */
406 const CounterState &getCounter(CounterId id) const {
407 assert(isValidCounter(id));
408 return id == PMCCNTR ? cycleCounter : counters[id];
409 }
410
411 /**
412 * Depending on counter configuration, add or remove the probes
413 * driving the counter.
414 *
415 * Look at the state of a counter and (re-)attach the probes
416 * needed to drive a counter if it is currently active. All probes
417 * for the counter are detached if the counter is inactive.
418 *
419 * @param id ID of counter within the PMU.
420 * @param ctr Reference to the counter's state
421 */
422 void updateCounter(CounterId id, CounterState &ctr);
423
424 /**
350 /** Current value of the counter */
351 uint64_t value;
352
353 /** Is the counter enabled? */
354 bool enabled;
355
356 /** Is this a 64-bit counter? */
357 bool overflow64;
358
359 public: /* Configuration */
360 /** Probe listeners driving this counter */
361 std::vector<ProbeListenerUPtr> listeners;
362 };
363
364 /**
365 * Handle an counting event triggered by a probe.
366 *
367 * This method is called by the ProbeListener class whenever an
368 * active probe is triggered. Ths method adds the event count from
369 * the probe to the affected counter, checks for overflows, and
370 * delivers an interrupt if needed.
371 *
372 * @param id Counter ID affected by the probe.
373 * @param delta Counter increment
374 */
375 void handleEvent(CounterId id, uint64_t delta);
376
377 /**
378 * Is this a valid counter ID?
379 *
380 * @param id ID of counter within the PMU.
381 *
382 * @return true if counter is within the allowed range or the
383 * cycle counter, false otherwise.
384 */
385 bool isValidCounter(CounterId id) const {
386 return id < counters.size() || id == PMCCNTR;
387 }
388
389 /**
390 * Return the state of a counter.
391 *
392 * @param id ID of counter within the PMU.
393 * @return Reference to a CounterState instance representing the
394 * counter.
395 */
396 CounterState &getCounter(CounterId id) {
397 assert(isValidCounter(id));
398 return id == PMCCNTR ? cycleCounter : counters[id];
399 }
400
401
402 /**
403 * Return the state of a counter.
404 *
405 * @param id ID of counter within the PMU.
406 * @return Reference to a CounterState instance representing the
407 * counter.
408 */
409 const CounterState &getCounter(CounterId id) const {
410 assert(isValidCounter(id));
411 return id == PMCCNTR ? cycleCounter : counters[id];
412 }
413
414 /**
415 * Depending on counter configuration, add or remove the probes
416 * driving the counter.
417 *
418 * Look at the state of a counter and (re-)attach the probes
419 * needed to drive a counter if it is currently active. All probes
420 * for the counter are detached if the counter is inactive.
421 *
422 * @param id ID of counter within the PMU.
423 * @param ctr Reference to the counter's state
424 */
425 void updateCounter(CounterId id, CounterState &ctr);
426
427 /**
428 * Check if a counter's settings allow it to be counted.
429 *
430 * @param ctr Counter state instance representing this counter.
431 * @return false if the counter is active, true otherwise.
432 */
433 bool isFiltered(const CounterState &ctr) const;
434
435 /**
425 * Call updateCounter() for each counter in the PMU if the
426 * counter's state has changed..
427 *
428 * @see updateCounter()
429 */
430 void updateAllCounters();
431
432 protected: /* State that needs to be serialized */
433 /** Performance Monitor Count Enable Register */
434 MiscReg reg_pmcnten;
435
436 /** Performance Monitor Control Register */
437 PMCR_t reg_pmcr;
438
439 /** Performance Monitor Selection Register */
440 PMSELR_t reg_pmselr;
441
442 /** Performance Monitor Interrupt Enable Register */
443 MiscReg reg_pminten;
444
445 /** Performance Monitor Overflow Status Register */
446 MiscReg reg_pmovsr;
447
448 /**
449 * Performance counter ID register
450 *
451 * This register contains a bitmask of available architected
452 * counters.
453 */
454 uint64_t reg_pmceid;
455
456 /** Remainder part when the clock counter is divided by 64 */
457 unsigned clock_remainder;
458
459 /** State of all general-purpose counters supported by PMU */
460 std::vector<CounterState> counters;
461 /** State of the cycle counter */
462 CounterState cycleCounter;
463
464 protected: /* Configuration and constants */
465 /** Constant (configuration-dependent) part of the PMCR */
466 PMCR_t reg_pmcr_conf;
467 /** PMCR write mask when accessed from the guest */
468 static const MiscReg reg_pmcr_wr_mask;
469
470 /** Performance monitor interrupt number */
471 const unsigned int pmuInterrupt;
472 /** Platform this device belongs to */
473 Platform *const platform;
474
475 /**
476 * Event types supported by this PMU.
477 *
478 * Each event type ID can map to multiple EventType structures,
479 * which enables the PMU to use multiple probes for a single
480 * event. This can be useful in the following cases:
481 * <ul>
482 * <li>Some events can are increment by multiple different probe
483 * points (e.g., the CPU memory access counter gets
484 * incremented for both loads and stores).
485 *
486 * <li>A system switching between multiple CPU models can
487 * register events for all models that will execute a thread
488 * and tehreby ensure that the PMU continues to work.
489 * </ul>
490 */
491 std::multimap<EventTypeId, EventType> pmuEventTypes;
492};
493
494} // namespace ArmISA
495#endif
436 * Call updateCounter() for each counter in the PMU if the
437 * counter's state has changed..
438 *
439 * @see updateCounter()
440 */
441 void updateAllCounters();
442
443 protected: /* State that needs to be serialized */
444 /** Performance Monitor Count Enable Register */
445 MiscReg reg_pmcnten;
446
447 /** Performance Monitor Control Register */
448 PMCR_t reg_pmcr;
449
450 /** Performance Monitor Selection Register */
451 PMSELR_t reg_pmselr;
452
453 /** Performance Monitor Interrupt Enable Register */
454 MiscReg reg_pminten;
455
456 /** Performance Monitor Overflow Status Register */
457 MiscReg reg_pmovsr;
458
459 /**
460 * Performance counter ID register
461 *
462 * This register contains a bitmask of available architected
463 * counters.
464 */
465 uint64_t reg_pmceid;
466
467 /** Remainder part when the clock counter is divided by 64 */
468 unsigned clock_remainder;
469
470 /** State of all general-purpose counters supported by PMU */
471 std::vector<CounterState> counters;
472 /** State of the cycle counter */
473 CounterState cycleCounter;
474
475 protected: /* Configuration and constants */
476 /** Constant (configuration-dependent) part of the PMCR */
477 PMCR_t reg_pmcr_conf;
478 /** PMCR write mask when accessed from the guest */
479 static const MiscReg reg_pmcr_wr_mask;
480
481 /** Performance monitor interrupt number */
482 const unsigned int pmuInterrupt;
483 /** Platform this device belongs to */
484 Platform *const platform;
485
486 /**
487 * Event types supported by this PMU.
488 *
489 * Each event type ID can map to multiple EventType structures,
490 * which enables the PMU to use multiple probes for a single
491 * event. This can be useful in the following cases:
492 * <ul>
493 * <li>Some events can are increment by multiple different probe
494 * points (e.g., the CPU memory access counter gets
495 * incremented for both loads and stores).
496 *
497 * <li>A system switching between multiple CPU models can
498 * register events for all models that will execute a thread
499 * and tehreby ensure that the PMU continues to work.
500 * </ul>
501 */
502 std::multimap<EventTypeId, EventType> pmuEventTypes;
503};
504
505} // namespace ArmISA
506#endif