gem5 v24.1.0.1
Loading...
Searching...
No Matches
pmu.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2014, 2017-2019, 2022-2023 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
38#include "arch/arm/pmu.hh"
39
40#include "arch/arm/isa.hh"
41#include "arch/arm/utility.hh"
42#include "base/trace.hh"
43#include "cpu/base.hh"
44#include "debug/Checkpoint.hh"
45#include "debug/PMUVerbose.hh"
46#include "dev/arm/base_gic.hh"
48#include "params/ArmPMU.hh"
49#include "sim/sim_exit.hh"
50
51namespace gem5
52{
53
54namespace ArmISA {
55
56const RegVal PMU::reg_pmcr_wr_mask = 0x39;
57
58PMU::PMU(const ArmPMUParams &p)
60 use64bitCounters(p.use64bitCounters),
61 reg_pmcnten(0), reg_pmcr(0),
62 reg_pmselr(0), reg_pminten(0), reg_pmovsr(0),
63 reg_pmceid0(0),reg_pmceid1(0),
64 clock_remainder(0),
65 maximumCounterCount(p.eventCounters),
66 cycleCounter(*this, maximumCounterCount, p.use64bitCounters),
67 cycleCounterEventId(p.cycleEventId),
68 swIncrementEvent(nullptr),
69 reg_pmcr_conf(0),
70 interrupt(nullptr),
71 exitOnPMUControl(p.exitOnPMUControl),
72 exitOnPMUInterrupt(p.exitOnPMUInterrupt)
73{
74 DPRINTF(PMUVerbose, "Initializing the PMU.\n");
75
76 if (maximumCounterCount > 31) {
77 fatal("The PMU can only accept 31 counters, %d counters requested.\n",
79 }
80
81 warn_if(!p.interrupt, "ARM PMU: No interrupt specified, interrupt " \
82 "delivery disabled.\n");
83
84 /* Setup the performance counter ID registers */
85 reg_pmcr_conf.imp = 0x41; // ARM Ltd.
86 reg_pmcr_conf.idcode = 0x00;
87 reg_pmcr_conf.n = p.eventCounters;
88
89 // Setup the hard-coded cycle counter, which is equivalent to
90 // architected counter event type 0x11.
91 cycleCounter.eventId = 0x11;
92}
93
95{
96}
97
98void
100{
101 DPRINTF(PMUVerbose, "Assigning PMU to ContextID %i.\n", tc->contextId());
102 const auto &pmu_params = static_cast<const ArmPMUParams &>(params());
103
104 if (pmu_params.interrupt)
105 interrupt = pmu_params.interrupt->get(tc);
106}
107
108void
110{
111 auto old_event = eventMap.find(id);
112 DPRINTF(PMUVerbose, "PMU: Adding SW increment event with id '0x%x'\n", id);
113
114 if (swIncrementEvent) {
115 fatal_if(old_event == eventMap.end() ||
116 old_event->second != swIncrementEvent,
117 "Trying to add a software increment event with multiple"
118 "IDs. This is not supported.\n");
119 return;
120 }
121
122 fatal_if(old_event != eventMap.end(), "An event with id %d has "
123 "been previously defined\n", id);
124
125 swIncrementEvent = std::make_shared<SWIncrementEvent>();
127 registerEvent(id);
128}
129
130void
131PMU::addEventProbe(unsigned int id, SimObject *obj, const char *probe_name)
132{
133
134 DPRINTF(PMUVerbose, "PMU: Adding Probe Driven event with id '0x%x'"
135 "as probe %s:%s\n",id, obj->name(), probe_name);
136
137 std::shared_ptr<RegularEvent> event;
138 auto event_entry = eventMap.find(id);
139 if (event_entry == eventMap.end()) {
140 event = std::make_shared<RegularEvent>();
141 eventMap[id] = event;
142 } else {
143 event = std::dynamic_pointer_cast<RegularEvent>(event_entry->second);
144 fatal_if(!event, "Event with id %d is not probe driven\n", id);
145 }
146 event->addMicroarchitectureProbe(obj, probe_name);
147
148 registerEvent(id);
149
150}
151
152void
154{
155 // Flag the event as available in the corresponding PMCEID register if it
156 // is an architected event.
157 if (id < 0x20) {
158 reg_pmceid0 |= ((uint64_t)1) << id;
159 } else if (id > 0x20 && id < 0x40) {
160 reg_pmceid1 |= ((uint64_t)1) << (id - 0x20);
161 } else if (id >= 0x4000 && id < 0x4020) {
162 reg_pmceid0 |= ((uint64_t)1) << (id - 0x4000 + 32);
163 } else if (id >= 0x4020 && id < 0x4040) {
164 reg_pmceid1 |= ((uint64_t)1) << (id - 0x4020 + 32);
165 }
166}
167
168void
170{
171 // Re-attach enabled counters after a resume in case they changed.
173}
174
175void
177{
178
179 // at this stage all probe configurations are done
180 // counters can be configured
181 for (uint32_t index = 0; index < maximumCounterCount-1; index++) {
182 counters.emplace_back(*this, index, use64bitCounters);
183 }
184
185 std::shared_ptr<PMUEvent> event = getEvent(cycleCounterEventId);
186 panic_if(!event, "core cycle event is not present\n");
187 cycleCounter.enabled = true;
189}
190
191void
193{
194 DPRINTF(PMUVerbose, "setMiscReg(%s, 0x%x)\n",
195 miscRegName[unflattenMiscReg(misc_reg)], val);
196
197 switch (unflattenMiscReg(misc_reg)) {
198 case MISCREG_PMCR_EL0:
199 case MISCREG_PMCR:
201 return;
202
205 reg_pmcnten |= val;
207 return;
208
211 reg_pmcnten &= ~val;
213 return;
214
216 case MISCREG_PMOVSR:
218 return;
219
221 case MISCREG_PMSWINC:
222 if (swIncrementEvent) {
223 swIncrementEvent->write(val);
224 }
225 return;
226
228 case MISCREG_PMCCNTR:
230 return;
231
233 case MISCREG_PMSELR:
234 reg_pmselr = val;
235 return;
236 //TODO: implement MISCREF_PMCEID{2,3}
238 case MISCREG_PMCEID0:
240 case MISCREG_PMCEID1:
241 // Ignore writes
242 return;
243
244 case MISCREG_PMEVTYPER0_EL0...MISCREG_PMEVTYPER5_EL0:
246 return;
247 case MISCREG_PMEVTYPER0...MISCREG_PMEVTYPER5:
249 return;
250
253 DPRINTF(PMUVerbose, "Setting PMCCFILTR: 0x%x\n", val);
255 return;
256
260 DPRINTF(PMUVerbose, "Setting counter type: "
261 "[PMSELR: 0x%x, PMSELER.sel: 0x%x, EVTYPER: 0x%x]\n",
264 return;
265
266 case MISCREG_PMEVCNTR0_EL0...MISCREG_PMEVCNTR5_EL0:
268 return;
269 case MISCREG_PMEVCNTR0...MISCREG_PMEVCNTR5:
271 return;
272
276 return;
277
280 // TODO
281 break;
282
285 reg_pminten |= val;
286 return;
287
290 reg_pminten &= ~val;
291 return;
292
294 case MISCREG_PMOVSSET:
296 return;
297
298 default:
299 panic("Unexpected PMU register: %i\n", miscRegName[misc_reg]);
300 }
301
302 warn("Not doing anything for write to miscreg %s\n",
303 miscRegName[misc_reg]);
304}
305
306RegVal
307PMU::readMiscReg(int misc_reg)
308{
309 RegVal val(readMiscRegInt(misc_reg));
310 DPRINTF(PMUVerbose, "readMiscReg(%s): 0x%x\n",
311 miscRegName[unflattenMiscReg(misc_reg)], val);
312 return val;
313}
314
315RegVal
317{
318 misc_reg = unflattenMiscReg(misc_reg);
319 switch (misc_reg) {
320 case MISCREG_PMCR_EL0:
321 case MISCREG_PMCR:
323
328 return reg_pmcnten;
329
332 case MISCREG_PMOVSR: // Overflow Status Register
333 case MISCREG_PMOVSSET:
334 return reg_pmovsr;
335
337 case MISCREG_PMSWINC: // Software Increment Register (RAZ)
338 return 0;
339
341 case MISCREG_PMSELR:
342 return reg_pmselr;
343
345 return reg_pmceid0;
346
348 return reg_pmceid1;
349
350 //TODO: implement MISCREF_PMCEID{2,3}
351 case MISCREG_PMCEID0: // Common Event ID register
352 return reg_pmceid0 & 0xFFFFFFFF;
353
354 case MISCREG_PMCEID1: // Common Event ID register
355 return reg_pmceid1 & 0xFFFFFFFF;
356
358 case MISCREG_PMCCNTR:
359 return cycleCounter.getValue();
360
361 case MISCREG_PMEVTYPER0_EL0...MISCREG_PMEVTYPER5_EL0:
363 case MISCREG_PMEVTYPER0...MISCREG_PMEVTYPER5:
365
369
374
375 case MISCREG_PMEVCNTR0_EL0...MISCREG_PMEVCNTR5_EL0:
376 return getCounterValue(misc_reg - MISCREG_PMEVCNTR0_EL0) & 0xFFFFFFFF;
377 case MISCREG_PMEVCNTR0...MISCREG_PMEVCNTR5:
378 return getCounterValue(misc_reg - MISCREG_PMEVCNTR0) & 0xFFFFFFFF;
379
382 return getCounterValue(reg_pmselr.sel) & 0xFFFFFFFF;
383
386 // TODO
387 return 0;
388
393 return reg_pminten;
394
395 default:
396 panic("Unexpected PMU register: %i\n", miscRegName[misc_reg]);
397 }
398
399 warn("Not doing anything for read from miscreg %s\n",
400 miscRegName[misc_reg]);
401 return 0;
402}
403
404void
406{
407 DPRINTF(PMUVerbose, "Set Control Reg 0x%08x.\n", val);
408
409 if (val.p) {
410 DPRINTF(PMUVerbose, "PMU reset all events to zero.\n");
412 }
413
414 if (val.c) {
415 DPRINTF(PMUVerbose, "PMU reset cycle counter to zero.\n");
417 }
418
419 // Reset the clock remainder if divide by 64-mode is toggled.
420 if (reg_pmcr.d != val.d)
421 clock_remainder = 0;
422
423 // Optionally exit the simulation on various PMU control events.
424 // Exit on enable/disable takes precedence over exit on reset.
425 if (exitOnPMUControl) {
426 if (!reg_pmcr.e && val.e) {
427 inform("Exiting simulation: PMU enable detected");
428 exitSimLoop("performance counter enabled", 0);
429 } else if (reg_pmcr.e && !val.e) {
430 inform("Exiting simulation: PMU disable detected");
431 exitSimLoop("performance counter disabled", 0);
432 } else if (val.p) {
433 inform("Exiting simulation: PMU reset detected");
434 exitSimLoop("performance counter reset", 0);
435 }
436 }
437
440}
441
442void
444{
445 const bool global_enable(reg_pmcr.e);
446
447 for (int i = 0; i < counters.size(); ++i) {
448 CounterState &ctr(counters[i]);
449 const bool enable(global_enable && (reg_pmcnten & (1 << i)));
450 if (ctr.enabled != enable) {
451 ctr.enabled = enable;
452 updateCounter(ctr);
453 }
454 }
455
456 const bool ccntr_enable(global_enable && (reg_pmcnten & (1 << PMCCNTR)));
457 if (cycleCounter.enabled != ccntr_enable) {
458 cycleCounter.enabled = ccntr_enable;
460 }
461}
462
463void
465{
466 if (userCounters.empty()) {
467 enable();
468 }
469 userCounters.insert(user);
471}
472
473void
475{
476 for (auto& counter: userCounters) {
477 counter->add(val);
478 }
479}
480
481void
483{
484 userCounters.erase(user);
485
486 if (userCounters.empty()) {
487 disable();
488 }
489}
490
491void
493{
494 parentEvent->increment(val);
495}
496
497void
499{
500 for (auto& subEvents: microArchitectureEventSet) {
501 attachedProbePointList.emplace_back(
502 new RegularProbe(this, subEvents.first, subEvents.second));
503 }
504}
505
506void
508{
509 attachedProbePointList.clear();
510}
511
512bool
514{
515 assert(pmu.isa);
516
517 const PMEVTYPER_t filter(this->filter);
518 const ExceptionLevel el(pmu.isa->currEL());
519 const bool secure(pmu.isa->inSecureState());
520
521 switch (el) {
522 case EL0:
523 return secure ? filter.u : (filter.u != filter.nsu);
524
525 case EL1:
526 return secure ? filter.p : (filter.p != filter.nsk);
527
528 case EL2:
529 return !filter.nsh;
530
531 case EL3:
532 return filter.p != filter.m;
533
534 default:
535 panic("Unexpected execution level in PMU::isFiltered.\n");
536 }
537}
538
539void
541{
542 if (sourceEvent) {
543 sourceEvent->detachEvent(this);
544 sourceEvent = nullptr;
545 } else {
546 DPRINTFS(PMUVerbose, &pmu,
547 "detaching event %d not currently attached to any event"
548 " [counterId = %d]\n", eventId, counterId);
549 }
550}
551
552void
553PMU::CounterState::attach(const std::shared_ptr<PMUEvent> &event)
554{
555 if (!resetValue) {
556 value = 0;
557 resetValue = true;
558 }
559 sourceEvent = event;
560 sourceEvent->attachEvent(this);
561}
562
563uint64_t
565{
566 if (sourceEvent) {
567 sourceEvent->updateAttachedCounters();
568 } else {
569 debugCounter("attempted to get value from a counter without"
570 " an associated event\n");
571 }
572 return value;
573}
574
575void
577{
578 value = val;
579 resetValue = true;
580
581 if (sourceEvent) {
582 sourceEvent->updateAttachedCounters();
583 } else {
584 debugCounter("attempted to set value from a counter without"
585 " an associated event\n");
586 }
587}
588
589void
591{
592 if (!ctr.enabled) {
593 DPRINTF(PMUVerbose, "updateCounter(%i): Disabling counter\n",
594 ctr.getCounterId());
595 ctr.detach();
596
597 } else {
598 DPRINTF(PMUVerbose, "updateCounter(%i): Enable event id 0x%x\n",
599 ctr.getCounterId(), ctr.eventId);
600
601 auto sourceEvent = eventMap.find(ctr.eventId);
602 if (sourceEvent == eventMap.end()) {
603 warn("Can't enable PMU counter of type '0x%x': "
604 "No such event type.\n", ctr.eventId);
605 ctr.detach();
606 } else {
607 ctr.attach(sourceEvent->second);
608 }
609 }
610}
611
612
613void
615{
616 for (CounterState &ctr : counters)
617 ctr.setValue(0);
618}
619
620void
621PMU::setCounterValue(CounterId id, uint64_t val)
622{
623 if (!isValidCounter(id)) {
624 warn_once("Can't change counter value: Counter %i does not exist.\n",
625 id);
626 return;
627 }
628
629 CounterState &ctr(getCounter(id));
630 ctr.setValue(val);
631}
632
633PMU::PMEVTYPER_t
635{
636 if (!isValidCounter(id))
637 return 0;
638
639 const CounterState &cs(getCounter(id));
640 PMEVTYPER_t type(cs.filter);
641
642 type.evtCount = cs.eventId;
643
644 return type;
645}
646
647void
648PMU::setCounterTypeRegister(CounterId id, PMEVTYPER_t val)
649{
650 DPRINTF(PMUVerbose, "Set Event [%d] = 0x%08x\n", id, val);
651 if (!isValidCounter(id)) {
652 warn_once("Can't change counter type: Counter %i does not exist.\n",
653 id);
654 return;
655 }
656
657 CounterState &ctr(getCounter(id));
658 const EventTypeId old_event_id(ctr.eventId);
659
660 ctr.filter = val;
661
662 // If PMCCNTR Register, do not change event type. PMCCNTR can
663 // count processor cycles only. If we change the event type, we
664 // need to update the probes the counter is using.
665 if (id != PMCCNTR && old_event_id != val.evtCount) {
666 ctr.eventId = val.evtCount;
667 updateCounter(ctr);
668 }
669}
670
671void
673{
674 const bool int_old = reg_pmovsr != 0;
675 const bool int_new = new_val != 0;
676
677 reg_pmovsr = new_val;
678 if (int_old && !int_new) {
680 } else if (!int_old && int_new && (reg_pminten & reg_pmovsr)) {
682 }
683}
684
685void
687{
688 if (exitOnPMUInterrupt) {
689 inform("Exiting simulation: PMU interrupt detected");
690 exitSimLoop("performance counter interrupt", 0);
691 }
692 if (interrupt) {
693 DPRINTF(PMUVerbose, "Delivering PMU interrupt.\n");
694 interrupt->raise();
695 } else {
696 warn_once("Dropping PMU interrupt as no interrupt has "
697 "been specified\n");
698 }
699}
700
701void
703{
704 if (interrupt) {
705 DPRINTF(PMUVerbose, "Clearing PMU interrupt.\n");
706 interrupt->clear();
707 } else {
708 warn_once("Dropping PMU interrupt as no interrupt has "
709 "been specified\n");
710 }
711}
712
713void
715{
716 DPRINTF(Checkpoint, "Serializing Arm PMU\n");
717
727
728 for (size_t i = 0; i < counters.size(); ++i)
729 counters[i].serializeSection(cp, csprintf("counters.%i", i));
730
731 cycleCounter.serializeSection(cp, "cycleCounter");
732}
733
734void
736{
737 DPRINTF(Checkpoint, "Unserializing Arm PMU\n");
738
745
746 // Old checkpoints used to store the entire PMCEID value in a
747 // single 64-bit entry (reg_pmceid). The register was extended in
748 // ARMv8.1, so we now need to store it as two 64-bit registers.
750 paramIn(cp, "reg_pmceid", reg_pmceid0);
751
753 reg_pmceid1 = 0;
754
756
757 for (size_t i = 0; i < counters.size(); ++i)
758 counters[i].unserializeSection(cp, csprintf("counters.%i", i));
759
760 cycleCounter.unserializeSection(cp, "cycleCounter");
761}
762
763std::shared_ptr<PMU::PMUEvent>
764PMU::getEvent(uint64_t eventId)
765{
766 auto entry = eventMap.find(eventId);
767
768 if (entry == eventMap.end()) {
769 warn("event %d does not exist\n", eventId);
770 return nullptr;
771 } else {
772 return entry->second;
773 }
774}
775
776void
778{
779 SERIALIZE_SCALAR(eventId);
780 SERIALIZE_SCALAR(value);
781 SERIALIZE_SCALAR(overflow64);
782}
783
784void
791
792uint64_t
794{
795 uint64_t value_until_overflow;
796 if (overflow64) {
797 value_until_overflow = UINT64_MAX - value;
798 } else {
799 value_until_overflow = UINT32_MAX - (uint32_t)value;
800 }
801
802 if (isFiltered())
803 return value_until_overflow;
804
805 if (resetValue) {
806 delta = 0;
807 resetValue = false;
808 } else {
809 value += delta;
810 }
811
812 if (delta > value_until_overflow) {
813
814 // overflow situation detected
815 // flag the overflow occurence
816 pmu.reg_pmovsr |= (1 << counterId);
817
818 // Deliver a PMU interrupt if interrupt delivery is enabled
819 // for this counter.
820 if (pmu.reg_pminten & (1 << counterId)) {
821 pmu.raiseInterrupt();
822 }
823 return overflow64 ? UINT64_MAX : UINT32_MAX;
824 }
825 return value_until_overflow - delta + 1;
826}
827
828void
830{
831 for (auto& counter: userCounters) {
832 if (val & (0x1 << counter->getCounterId())) {
833 counter->add(1);
834 }
835 }
836}
837
838} // namespace ArmISA
839} // namespace gem5
#define DPRINTFS(x, s,...)
Definition trace.hh:216
#define DPRINTF(x,...)
Definition trace.hh:209
Base class for ARM GIC implementations.
Base class for devices that use the MiscReg interfaces.
Definition isa_device.hh:62
void write(uint64_t val)
write on the sw increment register inducing an increment of the counters with this event selected acc...
Definition pmu.cc:829
void regProbeListeners() override
Register probe listeners for this object.
Definition pmu.cc:176
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition pmu.cc:735
void setControlReg(PMCR_t val)
PMCR write handling.
Definition pmu.cc:405
void raiseInterrupt()
Deliver a PMU interrupt to the GIC.
Definition pmu.cc:686
PMCR_t reg_pmcr_conf
Constant (configuration-dependent) part of the PMCR.
Definition pmu.hh:623
RegVal readMiscReg(int misc_reg) override
Read a register within the PMU.
Definition pmu.cc:307
RegVal reg_pmcnten
Performance Monitor Count Enable Register.
Definition pmu.hh:580
std::shared_ptr< PMUEvent > getEvent(uint64_t eventId)
Obtain the event of a given id.
Definition pmu.cc:764
void clearInterrupt()
Clear a PMU interrupt.
Definition pmu.cc:702
const uint64_t cycleCounterEventId
The id of the counter hardwired to the cpu cycle counter.
Definition pmu.hh:616
uint64_t maximumCounterCount
The number of regular event counters.
Definition pmu.hh:607
static const RegVal reg_pmcr_wr_mask
PMCR write mask when accessed from the guest.
Definition pmu.hh:626
bool isFiltered(const CounterState &ctr) const
Check if a counter's settings allow it to be counted.
PMEVTYPER_t getCounterTypeRegister(CounterId id) const
Get the type and filter settings of a counter (PMEVTYPER)
Definition pmu.cc:634
unsigned clock_remainder
Remainder part when the clock counter is divided by 64.
Definition pmu.hh:604
uint64_t reg_pmceid1
Definition pmu.hh:601
void updateAllCounters()
Call updateCounter() for each counter in the PMU if the counter's state has changed.
Definition pmu.cc:443
void resetEventCounts()
Reset all event counters excluding the cycle counter to zero.
Definition pmu.cc:614
void registerEvent(uint32_t id)
Definition pmu.cc:153
void setOverflowStatus(RegVal new_val)
Used for writing the Overflow Flag Status Register (SET/CLR)
Definition pmu.cc:672
PMSELR_t reg_pmselr
Performance Monitor Selection Register.
Definition pmu.hh:586
std::map< EventTypeId, std::shared_ptr< PMUEvent > > eventMap
List of event types supported by this PMU.
Definition pmu.hh:634
static const CounterId PMCCNTR
Cycle Count Register Number.
Definition pmu.hh:189
void setThreadContext(ThreadContext *tc) override
Definition pmu.cc:99
std::vector< CounterState > counters
State of all general-purpose counters supported by PMU.
Definition pmu.hh:610
void setCounterTypeRegister(CounterId id, PMEVTYPER_t type)
Set the type and filter settings of a performance counter (PMEVTYPER)
Definition pmu.cc:648
void drainResume() override
Resume execution after a successful drain.
Definition pmu.cc:169
PMU(const ArmPMUParams &p)
Definition pmu.cc:58
RegVal readMiscRegInt(int misc_reg)
Definition pmu.cc:316
void setMiscReg(int misc_reg, RegVal val) override
Set a register within the PMU.
Definition pmu.cc:192
CounterState cycleCounter
State of the cycle counter.
Definition pmu.hh:613
uint64_t reg_pmceid0
Performance counter ID register.
Definition pmu.hh:600
bool isValidCounter(CounterId id) const
Is this a valid counter ID?
Definition pmu.hh:518
PMCR_t reg_pmcr
Performance Monitor Control Register.
Definition pmu.hh:583
Bitfield< 1 > p
Definition pmu.hh:138
RegVal reg_pmovsr
Performance Monitor Overflow Status Register.
Definition pmu.hh:592
ArmInterruptPin * interrupt
Performance monitor interrupt number.
Definition pmu.hh:629
void addSoftwareIncrementEvent(unsigned int id)
Definition pmu.cc:109
CounterState & getCounter(CounterId id)
Return the state of a counter.
Definition pmu.hh:529
bool use64bitCounters
Determine whether to use 64-bit or 32-bit counters.
Definition pmu.hh:577
std::shared_ptr< SWIncrementEvent > swIncrementEvent
The event that implements the software increment.
Definition pmu.hh:619
uint64_t getCounterValue(CounterId id) const
Get the value of a performance counter.
Definition pmu.hh:236
bool exitOnPMUInterrupt
Exit simloop on PMU interrupt.
Definition pmu.hh:644
unsigned int EventTypeId
Event type ID.
Definition pmu.hh:196
void setCounterValue(CounterId id, uint64_t val)
Set the value of a performance counter.
Definition pmu.cc:621
RegVal reg_pminten
Performance Monitor Interrupt Enable Register.
Definition pmu.hh:589
void updateCounter(CounterState &ctr)
Depending on counter configuration, add or remove the probes driving the counter.
Definition pmu.cc:590
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition pmu.cc:714
const bool exitOnPMUControl
Exit simloop on PMU reset or disable.
Definition pmu.hh:639
void addEventProbe(unsigned int id, SimObject *obj, const char *name)
Definition pmu.cc:131
virtual void clear()=0
Clear a signalled interrupt.
virtual void raise()=0
Signal an interrupt.
virtual std::string name() const
Definition named.hh:47
Abstract superclass for simulation objects.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual ContextID contextId() const =0
This module implements the global system counter and the local per-CPU architected timers as specifie...
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
#define UNSERIALIZE_OPT_SCALAR(scalar)
Definition serialize.hh:582
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition serialize.cc:74
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition serialize.cc:81
const Params & params() const
#define warn(...)
Definition logging.hh:256
#define warn_once(...)
Definition logging.hh:260
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition logging.hh:283
#define inform(...)
Definition logging.hh:257
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 33 > id
@ MISCREG_PMXEVTYPER_EL0
Definition misc.hh:805
@ MISCREG_PMEVTYPER0
Definition misc.hh:385
@ MISCREG_PMUSERENR
Definition misc.hh:393
@ MISCREG_PMSELR_EL0
Definition misc.hh:801
@ MISCREG_PMOVSSET
Definition misc.hh:396
@ MISCREG_PMXEVCNTR_EL0
Definition misc.hh:807
@ MISCREG_PMCCNTR_EL0
Definition misc.hh:804
@ MISCREG_PMINTENSET
Definition misc.hh:394
@ MISCREG_PMXEVTYPER
Definition misc.hh:378
@ MISCREG_PMEVTYPER0_EL0
Definition misc.hh:880
@ MISCREG_PMUSERENR_EL0
Definition misc.hh:808
@ MISCREG_PMCR
Definition misc.hh:369
@ MISCREG_PMEVCNTR0_EL0
Definition misc.hh:874
@ MISCREG_PMOVSR
Definition misc.hh:372
@ MISCREG_PMCNTENCLR
Definition misc.hh:371
@ MISCREG_PMCCFILTR_EL0
Definition misc.hh:806
@ MISCREG_PMSWINC_EL0
Definition misc.hh:800
@ MISCREG_PMINTENSET_EL1
Definition misc.hh:794
@ MISCREG_PMINTENCLR_EL1
Definition misc.hh:795
@ MISCREG_PMCCFILTR
Definition misc.hh:391
@ MISCREG_PMCEID1
Definition misc.hh:376
@ MISCREG_PMCNTENSET
Definition misc.hh:370
@ MISCREG_PMCEID0_EL0
Definition misc.hh:802
@ MISCREG_PMSELR
Definition misc.hh:374
@ MISCREG_PMXEVCNTR
Definition misc.hh:392
@ MISCREG_PMCEID0
Definition misc.hh:375
@ MISCREG_PMINTENCLR
Definition misc.hh:395
@ MISCREG_PMCNTENCLR_EL0
Definition misc.hh:798
@ MISCREG_PMSWINC
Definition misc.hh:373
@ MISCREG_PMCNTENSET_EL0
Definition misc.hh:797
@ MISCREG_PMEVCNTR0
Definition misc.hh:379
@ MISCREG_PMOVSCLR_EL0
Definition misc.hh:799
@ MISCREG_PMCCNTR
Definition misc.hh:377
@ MISCREG_PMCR_EL0
Definition misc.hh:796
@ MISCREG_PMCEID1_EL0
Definition misc.hh:803
@ MISCREG_PMXEVTYPER_PMCCFILTR
Definition misc.hh:108
@ MISCREG_PMOVSSET_EL0
Definition misc.hh:809
Bitfield< 3, 2 > el
Definition misc_types.hh:73
int unflattenMiscReg(int reg)
Definition misc.cc:738
const char *const miscRegName[]
Definition misc.hh:1840
Bitfield< 10, 5 > event
Bitfield< 30, 0 > index
Bitfield< 0 > p
Bitfield< 11 > enable
Definition misc.hh:1086
Bitfield< 63 > val
Definition misc.hh:804
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
std::ostream CheckpointOut
Definition serialize.hh:66
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition types.cc:72
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
Definition sim_events.cc:88
uint64_t RegVal
Definition types.hh:173
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
State of a counter within the PMU.
Definition pmu.hh:415
void attach(const std::shared_ptr< PMUEvent > &event)
Attach this counter to an event.
Definition pmu.cc:553
PMEVTYPER_t filter
Filtering settings (evtCount is unused)
Definition pmu.hh:476
void detach()
Detach the counter from its event.
Definition pmu.cc:540
EventTypeId eventId
Counter event ID.
Definition pmu.hh:473
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition pmu.cc:785
uint64_t getCounterId() const
Obtain the counter id.
Definition pmu.hh:453
uint64_t getValue() const
rReturn the counter value
Definition pmu.cc:564
bool enabled
Is the counter enabled?
Definition pmu.hh:479
uint64_t add(uint64_t delta)
Add an event count to the counter and check for overflow.
Definition pmu.cc:793
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition pmu.cc:777
void setValue(uint64_t val)
overwrite the value of the counter
Definition pmu.cc:576
void attachEvent(PMU::CounterState *user)
attach this event to a given counter
Definition pmu.cc:464
virtual void enable()=0
Enable the current event.
std::set< PMU::CounterState * > userCounters
set of counters using this event
Definition pmu.hh:344
virtual void updateAttachedCounters()
Method called immediately before a counter access in order for the associated event to update its sta...
Definition pmu.hh:339
void detachEvent(PMU::CounterState *user)
detach this event from a given counter
Definition pmu.cc:482
virtual void increment(const uint64_t val)
notify an event increment of val units, all the attached counters' value is incremented by val units.
Definition pmu.cc:474
void notify(const uint64_t &val)
Definition pmu.cc:492
void enable() override
Enable the current event.
Definition pmu.cc:498
void disable() override
Disable the current event.
Definition pmu.cc:507

Generated on Mon Jan 13 2025 04:28:20 for gem5 by doxygen 1.9.8