48 #include "debug/Checkpoint.hh"
49 #include "debug/PMUVerbose.hh"
52 #include "params/ArmPMU.hh"
60 reg_pmcnten(0), reg_pmcr(0),
61 reg_pmselr(0), reg_pminten(0), reg_pmovsr(0),
64 counters(p->eventCounters),
66 pmuInterrupt(p->pmuInterrupt),
69 DPRINTF(PMUVerbose,
"Initializing the PMU.\n");
71 if (p->eventCounters > 31) {
72 fatal(
"The PMU can only accept 31 counters, %d counters requested.\n",
93 DPRINTF(PMUVerbose,
"PMU: Adding event type '0x%x' as probe %s:%s\n",
94 id, obj->
name(), probe_name);
113 DPRINTF(PMUVerbose,
"setMiscReg(%s, 0x%x)\n",
143 if (ctr.
enabled && (val & (1 <<
i)))
171 DPRINTF(PMUVerbose,
"Setting PMCCFILTR: 0x%x\n", val);
178 DPRINTF(PMUVerbose,
"Setting counter type: "
179 "[PMSELR: 0x%x, PMSELER.sel: 0x%x, EVTYPER: 0x%x]\n",
217 warn(
"Not doing anything for write to miscreg %s\n",
225 DPRINTF(PMUVerbose,
"readMiscReg(%s): 0x%x\n",
306 warn(
"Not doing anything for read from miscreg %s\n",
314 DPRINTF(PMUVerbose,
"Set Control Reg 0x%08x.\n", val);
317 DPRINTF(PMUVerbose,
"PMU reset all events to zero.\n");
322 DPRINTF(PMUVerbose,
"PMU reset cycle counter to zero.\n");
337 const bool global_enable(
reg_pmcr.e);
360 const PMEVTYPER_t filter(ctr.
filter);
368 return secure ? filter.u : (filter.u != filter.nsu);
371 return secure ? filter.p : (filter.p != filter.nsk);
377 return filter.p != filter.m;
380 panic(
"Unexpected execution level in PMU::isFiltered.\n");
388 const bool overflowed(
reg_pmovsr & (1 <<
id));
401 if (ctr.
add(delta) && !overflowed) {
402 DPRINTF(PMUVerbose,
"PMU counter '%i' overflowed.\n",
id);
416 DPRINTF(PMUVerbose,
"updateCounter(%i): Disabling counter\n",
id);
420 DPRINTF(PMUVerbose,
"updateCounter(%i): Enable event id 0x%x\n",
425 for (
auto it = range.first; it != range.second; ++it) {
437 warn(
"Can't enable PMU counter of type '0x%x': "
438 "No such event type.\n", ctr.
eventId);
455 warn_once(
"Can't change counter value: Counter %i does not exist.\n",
481 DPRINTF(PMUVerbose,
"Set Event [%d] = 0x%08x\n",
id, val);
483 warn_once(
"Can't change counter type: Counter %i does not exist.\n",
496 if (
id !=
PMCCNTR && old_event_id != val.evtCount) {
506 if (!rv || !rv->
gic) {
507 warn_once(
"ARM PMU: GIC missing, can't raise interrupt.\n");
511 DPRINTF(PMUVerbose,
"Delivering PMU interrupt.\n");
518 DPRINTF(Checkpoint,
"Serializing Arm PMU\n");
537 DPRINTF(Checkpoint,
"Unserializing Arm PMU\n");
574 const uint64_t msb(1
ULL << (overflow64 ? 63 : 31));
575 const uint64_t old_value(value);
580 return (old_value & msb) && !(value & msb);
586 ArmPMUParams::create()
const unsigned int pmuInterrupt
Performance monitor interrupt number.
void updateAllCounters()
Call updateCounter() for each counter in the PMU if the counter's state has changed.
void drainResume() override
Resume execution after a successful drain.
void handleEvent(CounterId id, uint64_t delta)
Handle an counting event triggered by a probe.
unsigned clock_remainder
Remainder part when the clock counter is divided by 64.
uint64_t getCounterValue(CounterId id) const
Get the value of a performance counter.
std::unique_ptr< ProbeListener > create(PMU &pmu, CounterId cid) const
Create and attach a probe used to drive this event.
CounterState & getCounter(CounterId id)
Return the state of a counter.
void addEventProbe(unsigned int id, SimObject *obj, const char *name)
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Model of an ARM PMU version 3.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
bool isFiltered(const CounterState &ctr) const
Check if a counter's settings allow it to be counted.
PMSELR_t reg_pmselr
Performance Monitor Selection Register.
PMCR_t reg_pmcr
Performance Monitor Control Register.
Base class for devices that use the MiscReg interfaces.
CounterState cycleCounter
State of the cycle counter.
const char *const miscRegName[]
Declaration of top level class for the RealView platform chips.
MiscReg readMiscReg(int misc_reg) override
Read a register within the PMU.
MiscReg reg_pmovsr
Performance Monitor Overflow Status Register.
MiscReg readMiscRegInt(int misc_reg)
MiscReg reg_pminten
Performance Monitor Interrupt Enable Register.
#define UNSERIALIZE_SCALAR(scalar)
int unflattenMiscReg(int reg)
std::string csprintf(const char *format, const Args &...args)
std::vector< CounterState > counters
State of all general-purpose counters supported by PMU.
SimObject *const obj
SimObject being measured by this probe.
bool isValidCounter(CounterId id) const
Is this a valid counter ID?
Platform *const platform
Platform this device belongs to.
virtual void sendInt(uint32_t num)=0
Post an interrupt from a device that is connected to the GIC.
void raiseInterrupt()
Deliver a PMU interrupt to the GIC.
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
static ExceptionLevel opModeToEL(OperatingMode mode)
uint64_t reg_pmceid
Performance counter ID register.
Event type configuration.
void setControlReg(PMCR_t val)
PMCR write handling.
MiscReg reg_pmcnten
Performance Monitor Count Enable Register.
void resetEventCounts()
Reset all event counters excluding the cycle counter to zero.
#define ULL(N)
uint64_t constant
static const MiscReg reg_pmcr_wr_mask
PMCR write mask when accessed from the guest.
PMEVTYPER_t filter
Filtering settings (evtCount is unused)
void setCounterValue(CounterId id, uint64_t val)
Set the value of a performance counter.
#define SERIALIZE_SCALAR(scalar)
PMCR_t reg_pmcr_conf
Constant (configuration-dependent) part of the PMCR.
PMU(const ArmPMUParams *p)
bool add(uint64_t delta)
Add an event count to the counter and check for overflow.
virtual const std::string name() const
void updateCounter(CounterId id, CounterState &ctr)
Depending on counter configuration, add or remove the probes driving the counter. ...
Base class for ARM GIC implementations.
std::ostream CheckpointOut
const std::string name
Probe name within obj.
void setMiscReg(int misc_reg, MiscReg val) override
Set a register within the PMU.
bool overflow64
Is this a 64-bit counter?
void serialize(CheckpointOut &cp) const override
Serialize an object.
static const CounterId PMCCNTR
Cycle Count Register Number.
unsigned int EventTypeId
Event type ID.
void setCounterTypeRegister(CounterId id, PMEVTYPER_t type)
Set the type and filter settings of a performance counter (PMEVTYPER)
std::vector< ProbeListenerUPtr > listeners
Probe listeners driving this counter.
PMEVTYPER_t getCounterTypeRegister(CounterId id) const
Get the type and filter settings of a counter (PMEVTYPER)
std::multimap< EventTypeId, EventType > pmuEventTypes
Event types supported by this PMU.
EventTypeId eventId
Counter event ID.
bool inSecureState(ThreadContext *tc)
static const EventTypeId ARCH_EVENT_SW_INCR
ID of the software increment event.
ProbePointArg< uint64_t > PMU
PMU probe point.
void serialize(CheckpointOut &cp) const override
Serialize an object.
Abstract superclass for simulation objects.
MiscReg readMiscRegNoEffect(int misc_reg) const
State of a counter within the PMU.
uint64_t value
Current value of the counter.
bool enabled
Is the counter enabled?