gem5 [DEVELOP-FOR-25.1]
Loading...
Searching...
No Matches
pmu.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2014, 2017-2019, 2022-2023, 2025 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)
61 reg_pmcnten(0), reg_pmcr(0),
65 maximumCounterCount(p.eventCounters),
67 cycleCounterEventId(p.cycleEventId),
68 swIncrementEvent(nullptr),
70 interrupt(nullptr),
73 stats(this)
74{
75 DPRINTF(PMUVerbose, "Initializing the PMU.\n");
76
77 if (maximumCounterCount > 31) {
78 fatal("The PMU can only accept 31 counters, %d counters requested.\n",
80 }
81
82 for (const auto& [key, value] : p.statCounters) {
83 statCounters.insert(key);
84 }
85
86 warn_if(!p.interrupt, "ARM PMU: No interrupt specified, interrupt " \
87 "delivery disabled.\n");
88
89 /* Setup the performance counter ID registers */
90 reg_pmcr_conf.imp = 0x41; // ARM Ltd.
91 reg_pmcr_conf.idcode = 0x00;
92 reg_pmcr_conf.n = p.eventCounters;
93
94 // Setup the hard-coded cycle counter, which is equivalent to
95 // architected counter event type 0x11.
96 cycleCounter.eventId = enums::EventTypeId::CPU_CYCLES;
97}
98
100{
101}
102
103void
105{
106 DPRINTF(PMUVerbose, "Assigning PMU to ContextID %i.\n", tc->contextId());
107 const auto &pmu_params = static_cast<const ArmPMUParams &>(params());
108
109 if (pmu_params.interrupt)
110 interrupt = pmu_params.interrupt->get(tc);
111}
112
113void
115{
116 auto old_event = eventMap.find(id);
117 DPRINTF(PMUVerbose, "PMU: Adding SW increment event with id '0x%x'\n", id);
118
119 if (swIncrementEvent) {
120 fatal_if(old_event == eventMap.end() ||
121 old_event->second != swIncrementEvent,
122 "Trying to add a software increment event with multiple"
123 "IDs. This is not supported.\n");
124 return;
125 }
126
127 fatal_if(old_event != eventMap.end(), "An event with id %d has "
128 "been previously defined\n", id);
129
130 auto pmu_stats = statCounters.find(id) != statCounters.end() ?
131 &stats : nullptr;
132 swIncrementEvent = std::make_shared<SWIncrementEvent>(id, pmu_stats);
134 registerEvent(id);
135}
136
137void
138PMU::addEventProbe(EventTypeId id, SimObject *obj, const char *probe_name)
139{
140
141 DPRINTF(PMUVerbose, "PMU: Adding Probe Driven event with id '0x%x'"
142 "as probe %s:%s\n", id, obj->name(), probe_name);
143
144 std::shared_ptr<RegularEvent> event;
145 auto event_entry = eventMap.find(id);
146 if (event_entry == eventMap.end()) {
147 auto pmu_stats = statCounters.find(id) != statCounters.end() ?
148 &stats : nullptr;
149 event = std::make_shared<RegularEvent>(id, pmu_stats);
150 eventMap[id] = event;
151 } else {
152 event = std::dynamic_pointer_cast<RegularEvent>(event_entry->second);
153 fatal_if(!event, "Event with id %d is not probe driven\n", id);
154 }
155 event->addMicroarchitectureProbe(obj, probe_name);
156
157 registerEvent(id);
158}
159
160void
162{
163 // Flag the event as available in the corresponding PMCEID register if it
164 // is an architected event.
165 if (id < 0x20) {
166 reg_pmceid0 |= ((uint64_t)1) << id;
167 } else if (id > 0x20 && id < 0x40) {
168 reg_pmceid1 |= ((uint64_t)1) << (id - 0x20);
169 } else if (id >= 0x4000 && id < 0x4020) {
170 reg_pmceid0 |= ((uint64_t)1) << (id - 0x4000 + 32);
171 } else if (id >= 0x4020 && id < 0x4040) {
172 reg_pmceid1 |= ((uint64_t)1) << (id - 0x4020 + 32);
173 }
174}
175
176void
178{
179 // Re-attach enabled counters after a resume in case they changed.
181}
182
183void
185{
186
187 // at this stage all probe configurations are done
188 // counters can be configured
189 for (uint32_t index = 0; index < maximumCounterCount; index++) {
190 counters.emplace_back(*this, index, use64bitCounters);
191 }
192
193 std::shared_ptr<PMUEvent> event = getEvent(cycleCounterEventId);
194 panic_if(!event, "core cycle event is not present\n");
195 cycleCounter.enabled = true;
196 cycleCounter.attach(event);
197
198 // By enabling the event we are actually connecting the
199 // listener (See PMU::RegularEvent::enable)
200 for (auto event_id : statCounters) {
201 if (auto stat_event = getEvent(event_id); stat_event) {
202 stat_event->enable();
203 }
204 }
205}
206
207void
209{
210 DPRINTF(PMUVerbose, "setMiscReg(%s, 0x%x)\n",
212
213 switch (unflattenMiscReg(misc_reg)) {
214 case MISCREG_PMCR_EL0:
215 case MISCREG_PMCR:
217 return;
218
221 reg_pmcnten |= val;
223 pmuExitEvent(false);
224 return;
225
228 reg_pmcnten &= ~val;
230 pmuExitEvent(false);
231 return;
232
234 case MISCREG_PMOVSR:
236 return;
237
239 case MISCREG_PMSWINC:
240 if (swIncrementEvent) {
241 swIncrementEvent->write(val);
242 }
243 return;
244
246 case MISCREG_PMCCNTR:
247 cycleCounter.setValue(val);
248 return;
249
251 case MISCREG_PMSELR:
252 reg_pmselr = val;
253 return;
254 //TODO: implement MISCREF_PMCEID{2,3}
256 case MISCREG_PMCEID0:
258 case MISCREG_PMCEID1:
259 // Ignore writes
260 return;
261
262 case MISCREG_PMEVTYPER0_EL0...MISCREG_PMEVTYPER5_EL0:
264 return;
265 case MISCREG_PMEVTYPER0...MISCREG_PMEVTYPER5:
267 return;
268
271 DPRINTF(PMUVerbose, "Setting PMCCFILTR: 0x%x\n", val);
273 return;
274
278 DPRINTF(PMUVerbose, "Setting counter type: "
279 "[PMSELR: 0x%x, PMSELER.sel: 0x%x, EVTYPER: 0x%x]\n",
282 return;
283
284 case MISCREG_PMEVCNTR0_EL0...MISCREG_PMEVCNTR5_EL0:
286 return;
287 case MISCREG_PMEVCNTR0...MISCREG_PMEVCNTR5:
289 return;
290
294 return;
295
298 // TODO
299 break;
300
303 reg_pminten |= val;
304 return;
305
308 reg_pminten &= ~val;
309 return;
310
312 case MISCREG_PMOVSSET:
314 return;
315
316 default:
317 panic("Unexpected PMU register: %i\n", miscRegName[misc_reg]);
318 }
319
320 warn("Not doing anything for write to miscreg %s\n",
322}
323
324RegVal
326{
328 DPRINTF(PMUVerbose, "readMiscReg(%s): 0x%x\n",
330 return val;
331}
332
333RegVal
335{
337 switch (misc_reg) {
338 case MISCREG_PMCR_EL0:
339 case MISCREG_PMCR:
341
346 return reg_pmcnten;
347
350 case MISCREG_PMOVSR: // Overflow Status Register
351 case MISCREG_PMOVSSET:
352 return reg_pmovsr;
353
355 case MISCREG_PMSWINC: // Software Increment Register (RAZ)
356 return 0;
357
359 case MISCREG_PMSELR:
360 return reg_pmselr;
361
363 return reg_pmceid0;
364
366 return reg_pmceid1;
367
368 //TODO: implement MISCREF_PMCEID{2,3}
369 case MISCREG_PMCEID0: // Common Event ID register
370 return reg_pmceid0 & 0xFFFFFFFF;
371
372 case MISCREG_PMCEID1: // Common Event ID register
373 return reg_pmceid1 & 0xFFFFFFFF;
374
376 case MISCREG_PMCCNTR:
377 return cycleCounter.getValue();
378
379 case MISCREG_PMEVTYPER0_EL0...MISCREG_PMEVTYPER5_EL0:
381 case MISCREG_PMEVTYPER0...MISCREG_PMEVTYPER5:
383
387
392
393 case MISCREG_PMEVCNTR0_EL0...MISCREG_PMEVCNTR5_EL0:
394 return getCounterValue(misc_reg - MISCREG_PMEVCNTR0_EL0) & 0xFFFFFFFF;
395 case MISCREG_PMEVCNTR0...MISCREG_PMEVCNTR5:
396 return getCounterValue(misc_reg - MISCREG_PMEVCNTR0) & 0xFFFFFFFF;
397
400 return getCounterValue(reg_pmselr.sel) & 0xFFFFFFFF;
401
404 // TODO
405 return 0;
406
411 return reg_pminten;
412
413 default:
414 panic("Unexpected PMU register: %i\n", miscRegName[misc_reg]);
415 }
416
417 warn("Not doing anything for read from miscreg %s\n",
419 return 0;
420}
421
422void
424{
425 DPRINTF(PMUVerbose, "Set Control Reg 0x%08x.\n", val);
426
427 if (val.p) {
428 DPRINTF(PMUVerbose, "PMU reset all events to zero.\n");
430 }
431
432 if (val.c) {
433 DPRINTF(PMUVerbose, "PMU reset cycle counter to zero.\n");
434 cycleCounter.setValue(0);
435 }
436
437 // Reset the clock remainder if divide by 64-mode is toggled.
438 if (reg_pmcr.d != val.d)
439 clock_remainder = 0;
440
442
444 pmuExitEvent(true);
445}
446
447void
448PMU::pmuExitEvent(bool check_reset)
449{
450 if (!exitOnPMUControl) {
451 return;
452 }
453
454 // Optionally exit the simulation on various PMU control events.
455 // Exit on enable/disable takes precedence over exit on reset.
456 if (bool any_counter_enabled = reg_pmcr.e && reg_pmcnten;
457 any_counter_enabled != pmuEnabled) {
458
459 pmuEnabled = any_counter_enabled;
460 if (pmuEnabled) {
461 inform("Exiting simulation: PMU enable detected");
462 exitSimLoop("performance counter enabled", 0);
463 } else {
464 inform("Exiting simulation: PMU disable detected");
465 exitSimLoop("performance counter disabled", 0);
466 }
467 } else if (check_reset && reg_pmcr.p) {
468 inform("Exiting simulation: PMU reset detected");
469 exitSimLoop("performance counter reset", 0);
470 }
471}
472
473void
475{
476 const bool global_enable(reg_pmcr.e);
477
478 for (int i = 0; i < counters.size(); ++i) {
479 CounterState &ctr(counters[i]);
480 const bool enable(global_enable && (reg_pmcnten & (1 << i)));
481 if (ctr.enabled != enable) {
482 ctr.enabled = enable;
483 updateCounter(ctr);
484 }
485 }
486
487 const bool ccntr_enable(global_enable && (reg_pmcnten & (1 << PMCCNTR)));
488 if (cycleCounter.enabled != ccntr_enable) {
489 cycleCounter.enabled = ccntr_enable;
491 }
492}
493
494void
496{
497 // Check if there is already a probe (either non-empty
498 // userCounters list, or pmuStats enabled)
499 if (userCounters.empty() && !pmuStats) {
500 enable();
501 }
502 userCounters.insert(user);
504}
505
506void
508{
509 for (auto& counter: userCounters) {
510 counter->add(val);
511 }
512
513 if (pmuStats) {
514 pmuStats->add(id, val);
515 }
516}
517
518void
520{
521 userCounters.erase(user);
522
523 // Do not destroy the probe if pmuStats are listening
524 // to the event
525 if (userCounters.empty() && !pmuStats) {
526 disable();
527 }
528}
529
530void
532{
533 parentEvent->increment(val);
534}
535
536void
538{
539 for (auto& subEvents: microArchitectureEventSet) {
540 ProbeManager *pm = subEvents.first->getProbeManager();
541 ProbePoint *probe = pm->getFirstProbePoint(subEvents.second);
542 // The PMU currently handles explicit PMU probes as well as
543 // cache events. For any further types of events we will need
544 // to handle them in this function.
545 if (dynamic_cast<probing::PMU *>(probe)) {
546 attachedProbePointList.push_back(
547 pm->connect<RegularProbe>(this, subEvents.second));
548 } else if (dynamic_cast<ProbePointArg<CacheAccessProbeArg> *>(probe)) {
549 attachedProbePointList.push_back(
550 pm->connect<CacheProbe>(this, subEvents.second));
551 } else {
552 panic("Unsupported probe kind for event %s", probe->getName());
553 }
554 }
555}
556
557void
562
563bool
565{
566 assert(pmu.isa);
567
568 const PMEVTYPER_t filter(this->filter);
569 const ExceptionLevel el(pmu.isa->currEL());
570 const bool secure(pmu.isa->inSecureState());
571
572 switch (el) {
573 case EL0:
574 return secure ? filter.u : (filter.u != filter.nsu);
575
576 case EL1:
577 return secure ? filter.p : (filter.p != filter.nsk);
578
579 case EL2:
580 return !filter.nsh;
581
582 case EL3:
583 return filter.p != filter.m;
584
585 default:
586 panic("Unexpected execution level in PMU::isFiltered.\n");
587 }
588}
589
590void
592{
593 if (sourceEvent) {
594 sourceEvent->detachEvent(this);
595 sourceEvent = nullptr;
596 } else {
597 DPRINTFS(PMUVerbose, &pmu,
598 "detaching event %d not currently attached to any event"
599 " [counterId = %d]\n", eventId, counterId);
600 }
601}
602
603void
604PMU::CounterState::attach(const std::shared_ptr<PMUEvent> &event)
605{
606 if (!resetValue) {
607 value = 0;
608 resetValue = true;
609 }
611 sourceEvent->attachEvent(this);
612}
613
614uint64_t
616{
617 if (sourceEvent) {
618 sourceEvent->updateAttachedCounters();
619 } else {
620 debugCounter("attempted to get value from a counter without"
621 " an associated event\n");
622 }
623 return value;
624}
625
626void
628{
629 value = val;
630 resetValue = true;
631
632 if (sourceEvent) {
633 sourceEvent->updateAttachedCounters();
634 } else {
635 debugCounter("attempted to set value from a counter without"
636 " an associated event\n");
637 }
638}
639
640void
642{
643 if (!ctr.enabled) {
644 DPRINTF(PMUVerbose, "updateCounter(%i): Disabling counter\n",
645 ctr.getCounterId());
646 ctr.detach();
647
648 } else {
649 DPRINTF(PMUVerbose, "updateCounter(%i): Enable event id 0x%x\n",
650 ctr.getCounterId(), ctr.eventId);
651
652 auto sourceEvent = eventMap.find(ctr.eventId);
653 if (sourceEvent == eventMap.end()) {
654 warn("Can't enable PMU counter of type '0x%x': "
655 "No such event type.\n", ctr.eventId);
656 ctr.detach();
657 } else {
658 ctr.attach(sourceEvent->second);
659 }
660 }
661}
662
663
664void
666{
667 for (CounterState &ctr : counters)
668 ctr.setValue(0);
669}
670
671void
672PMU::setCounterValue(CounterId id, uint64_t val)
673{
674 if (!isValidCounter(id)) {
675 warn_once("Can't change counter value: Counter %i does not exist.\n",
676 id);
677 return;
678 }
679
680 CounterState &ctr(getCounter(id));
681 ctr.setValue(val);
682}
683
684PMU::PMEVTYPER_t
686{
687 if (!isValidCounter(id))
688 return 0;
689
690 const CounterState &cs(getCounter(id));
691 PMEVTYPER_t type(cs.filter);
692
693 type.evtCount = cs.eventId;
694
695 return type;
696}
697
698void
699PMU::setCounterTypeRegister(CounterId id, PMEVTYPER_t val)
700{
701 DPRINTF(PMUVerbose, "Set Event [%d] = 0x%08x\n", id, val);
702 if (!isValidCounter(id)) {
703 warn_once("Can't change counter type: Counter %i does not exist.\n",
704 id);
705 return;
706 }
707
708 CounterState &ctr(getCounter(id));
709 const EventTypeId old_event_id(ctr.eventId);
710
711 ctr.filter = val;
712
713 // If PMCCNTR Register, do not change event type. PMCCNTR can
714 // count processor cycles only. If we change the event type, we
715 // need to update the probes the counter is using.
716 if (id != PMCCNTR && old_event_id != val.evtCount) {
717 ctr.eventId = val.evtCount;
718 updateCounter(ctr);
719 }
720}
721
722void
724{
725 const bool int_old = reg_pmovsr != 0;
726 const bool int_new = new_val != 0;
727
728 reg_pmovsr = new_val;
729 if (int_old && !int_new) {
731 } else if (!int_old && int_new && (reg_pminten & reg_pmovsr)) {
733 }
734}
735
736void
738{
739 if (exitOnPMUInterrupt) {
740 inform("Exiting simulation: PMU interrupt detected");
741 exitSimLoop("performance counter interrupt", 0);
742 }
743 if (interrupt) {
744 DPRINTF(PMUVerbose, "Delivering PMU interrupt.\n");
745 interrupt->raise();
746 } else {
747 warn_once("Dropping PMU interrupt as no interrupt has "
748 "been specified\n");
749 }
750}
751
752void
754{
755 if (interrupt) {
756 DPRINTF(PMUVerbose, "Clearing PMU interrupt.\n");
757 interrupt->clear();
758 } else {
759 warn_once("Dropping PMU interrupt as no interrupt has "
760 "been specified\n");
761 }
762}
763
764void
766{
767 DPRINTF(Checkpoint, "Serializing Arm PMU\n");
768
778
779 for (size_t i = 0; i < counters.size(); ++i)
780 counters[i].serializeSection(cp, csprintf("counters.%i", i));
781
782 cycleCounter.serializeSection(cp, "cycleCounter");
783}
784
785void
787{
788 DPRINTF(Checkpoint, "Unserializing Arm PMU\n");
789
796
798
799 // Old checkpoints used to store the entire PMCEID value in a
800 // single 64-bit entry (reg_pmceid). The register was extended in
801 // ARMv8.1, so we now need to store it as two 64-bit registers.
803 paramIn(cp, "reg_pmceid", reg_pmceid0);
804
806 reg_pmceid1 = 0;
807
809
810 for (size_t i = 0; i < counters.size(); ++i)
811 counters[i].unserializeSection(cp, csprintf("counters.%i", i));
812
813 cycleCounter.unserializeSection(cp, "cycleCounter");
814}
815
816std::shared_ptr<PMU::PMUEvent>
818{
819 auto entry = eventMap.find(eventId);
820
821 if (entry == eventMap.end()) {
822 warn("event %d does not exist\n", eventId);
823 return nullptr;
824 } else {
825 return entry->second;
826 }
827}
828
829void
836
837void
844
845uint64_t
847{
848 uint64_t value_until_overflow;
849 if (overflow64) {
850 value_until_overflow = UINT64_MAX - value;
851 } else {
852 value_until_overflow = UINT32_MAX - (uint32_t)value;
853 }
854
855 if (isFiltered())
856 return value_until_overflow;
857
858 if (resetValue) {
859 delta = 0;
860 resetValue = false;
861 } else {
862 value += delta;
863 }
864
865 if (delta > value_until_overflow) {
866
867 // overflow situation detected
868 // flag the overflow occurence
869 pmu.reg_pmovsr |= (1 << counterId);
870
871 // Deliver a PMU interrupt if interrupt delivery is enabled
872 // for this counter.
873 if (pmu.reg_pminten & (1 << counterId)) {
874 pmu.raiseInterrupt();
875 }
876 return overflow64 ? UINT64_MAX : UINT32_MAX;
877 }
878 return value_until_overflow - delta + 1;
879}
880
881void
883{
884 for (auto& counter: userCounters) {
885 if (val & (0x1 << counter->getCounterId())) {
886 counter->add(1);
887 }
888 }
889}
890
892 : statistics::Group(parent), pmu(parent)
893{
894 auto params = static_cast<const ArmPMUParams&>(pmu->params());
895 for (const auto& [key, val] : params.statCounters) {
896 registerEvent(key, val.c_str());
897 }
898}
899
900void
901PMU::Stats::registerEvent(EventTypeId id, const char *stat_name)
902{
903 map.emplace(std::piecewise_construct,
904 std::forward_as_tuple(id),
905 std::forward_as_tuple(
906 this, stat_name,
908 stat_name));
909 map[id]
910 .precision(0);
911}
912
913void
914PMU::Stats::add(EventTypeId id, uint64_t value)
915{
916 if (auto it = map.find(id); it != map.end()) {
917 it->second += value;
918 } else {
919 panic("Couldn't increment event %d stat counter", id);
920 }
921}
922
923} // namespace ArmISA
924} // namespace gem5
#define DPRINTFS(x, s,...)
Definition trace.hh:216
#define DPRINTF(x,...)
Definition trace.hh:209
Base class for ARM GIC implementations.
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:882
std::shared_ptr< PMUEvent > getEvent(EventTypeId eventId)
Obtain the event of a given id.
Definition pmu.cc:817
void regProbeListeners() override
Register probe listeners for this object.
Definition pmu.cc:184
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition pmu.cc:786
void setControlReg(PMCR_t val)
PMCR write handling.
Definition pmu.cc:423
void raiseInterrupt()
Deliver a PMU interrupt to the GIC.
Definition pmu.cc:737
void addEventProbe(EventTypeId id, SimObject *obj, const char *name)
Definition pmu.cc:138
PMCR_t reg_pmcr_conf
Constant (configuration-dependent) part of the PMCR.
Definition pmu.hh:672
RegVal readMiscReg(int misc_reg) override
Read a register within the PMU.
Definition pmu.cc:325
RegVal reg_pmcnten
Performance Monitor Count Enable Register.
Definition pmu.hh:629
void clearInterrupt()
Clear a PMU interrupt.
Definition pmu.cc:753
uint64_t maximumCounterCount
The number of regular event counters.
Definition pmu.hh:656
static const RegVal reg_pmcr_wr_mask
PMCR write mask when accessed from the guest.
Definition pmu.hh:675
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:685
unsigned clock_remainder
Remainder part when the clock counter is divided by 64.
Definition pmu.hh:653
uint64_t reg_pmceid1
Definition pmu.hh:650
void updateAllCounters()
Call updateCounter() for each counter in the PMU if the counter's state has changed.
Definition pmu.cc:474
void resetEventCounts()
Reset all event counters excluding the cycle counter to zero.
Definition pmu.cc:665
void setOverflowStatus(RegVal new_val)
Used for writing the Overflow Flag Status Register (SET/CLR)
Definition pmu.cc:723
PMSELR_t reg_pmselr
Performance Monitor Selection Register.
Definition pmu.hh:635
std::map< EventTypeId, std::shared_ptr< PMUEvent > > eventMap
List of event types supported by this PMU.
Definition pmu.hh:683
bool pmuEnabled
Is there an enabled counter.
Definition pmu.hh:620
void addSoftwareIncrementEvent(EventTypeId id)
Definition pmu.cc:114
static const CounterId PMCCNTR
Cycle Count Register Number.
Definition pmu.hh:192
void setThreadContext(ThreadContext *tc) override
Definition pmu.cc:104
std::vector< CounterState > counters
State of all general-purpose counters supported by PMU.
Definition pmu.hh:659
void setCounterTypeRegister(CounterId id, PMEVTYPER_t type)
Set the type and filter settings of a performance counter (PMEVTYPER)
Definition pmu.cc:699
void drainResume() override
Resume execution after a successful drain.
Definition pmu.cc:177
PMU(const ArmPMUParams &p)
Definition pmu.cc:58
RegVal readMiscRegInt(int misc_reg)
Definition pmu.cc:334
std::set< EventTypeId > statCounters
Determine whether we merge event counting with the stats framework.
Definition pmu.hh:626
void pmuExitEvent(bool check_reset)
Checks if a PMU exit event needs to be generated.
Definition pmu.cc:448
void setMiscReg(int misc_reg, RegVal val) override
Set a register within the PMU.
Definition pmu.cc:208
CounterState cycleCounter
State of the cycle counter.
Definition pmu.hh:662
uint64_t reg_pmceid0
Performance counter ID register.
Definition pmu.hh:649
const EventTypeId cycleCounterEventId
The id of the counter hardwired to the cpu cycle counter.
Definition pmu.hh:665
bool isValidCounter(CounterId id) const
Is this a valid counter ID?
Definition pmu.hh:548
PMCR_t reg_pmcr
Performance Monitor Control Register.
Definition pmu.hh:632
Bitfield< 1 > p
Definition pmu.hh:141
RegVal reg_pmovsr
Performance Monitor Overflow Status Register.
Definition pmu.hh:641
std::underlying_type_t< enums::EventTypeId > EventTypeId
Definition pmu.hh:101
ArmInterruptPin * interrupt
Performance monitor interrupt number.
Definition pmu.hh:678
void registerEvent(EventTypeId id)
Definition pmu.cc:161
CounterState & getCounter(CounterId id)
Return the state of a counter.
Definition pmu.hh:559
bool use64bitCounters
Determine whether to use 64-bit or 32-bit counters.
Definition pmu.hh:617
std::shared_ptr< SWIncrementEvent > swIncrementEvent
The event that implements the software increment.
Definition pmu.hh:668
uint64_t getCounterValue(CounterId id) const
Get the value of a performance counter.
Definition pmu.hh:232
bool exitOnPMUInterrupt
Exit simloop on PMU interrupt.
Definition pmu.hh:693
gem5::ArmISA::PMU::Stats stats
void setCounterValue(CounterId id, uint64_t val)
Set the value of a performance counter.
Definition pmu.cc:672
RegVal reg_pminten
Performance Monitor Interrupt Enable Register.
Definition pmu.hh:638
void updateCounter(CounterState &ctr)
Depending on counter configuration, add or remove the probes driving the counter.
Definition pmu.cc:641
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition pmu.cc:765
const bool exitOnPMUControl
Exit simloop on PMU reset or disable.
Definition pmu.hh:688
virtual std::string name() const
Definition named.hh:60
ProbeManager is a conduit class that lives on each SimObject, and is used to match up probe listeners...
Definition probe.hh:162
ProbeListenerPtr< Listener > connect(Args &&...args)
Definition probe.hh:198
ProbePoint * getFirstProbePoint(std::string_view point_name) const
Definition probe.cc:110
ProbePointArg generates a point for the class of Arg.
Definition probe.hh:273
ProbePoint base class; again used to simplify use of ProbePoints in containers and used as to define ...
Definition probe.hh:123
const std::string & getName() const
Definition probe.hh:132
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:220
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:268
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:232
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:246
#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
SimObject(const Params &p)
Definition sim_object.cc:58
#define warn(...)
Definition logging.hh:288
#define warn_once(...)
Definition logging.hh:292
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition logging.hh:315
#define inform(...)
Definition logging.hh:289
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:1849
Bitfield< 10, 5 > event
Bitfield< 30, 0 > index
Bitfield< 11 > enable
Definition misc.hh:1086
Bitfield< 63 > val
Definition misc.hh:804
ProbePointArg< uint64_t > PMU
PMU probe point.
Definition pmu.hh:59
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
uint64_t RegVal
Definition types.hh:173
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)
The "old style" exitSimLoop functions.
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:445
bool resetValue
Flag keeping track if the counter has been reset.
Definition pmu.hh:525
void attach(const std::shared_ptr< PMUEvent > &event)
Attach this counter to an event.
Definition pmu.cc:604
PMEVTYPER_t filter
Filtering settings (evtCount is unused)
Definition pmu.hh:506
uint64_t value
Current value of the counter.
Definition pmu.hh:522
bool overflow64
Is this a 64-bit counter?
Definition pmu.hh:512
uint64_t counterId
id of the counter instance
Definition pmu.hh:519
void detach()
Detach the counter from its event.
Definition pmu.cc:591
EventTypeId eventId
Counter event ID.
Definition pmu.hh:503
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition pmu.cc:838
uint64_t getCounterId() const
Obtain the counter id.
Definition pmu.hh:483
uint64_t getValue() const
rReturn the counter value
Definition pmu.cc:615
std::shared_ptr< PMUEvent > sourceEvent
PmuEvent currently in use (if any)
Definition pmu.hh:516
bool enabled
Is the counter enabled?
Definition pmu.hh:509
uint64_t add(uint64_t delta)
Add an event count to the counter and check for overflow.
Definition pmu.cc:846
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition pmu.cc:830
void debugCounter(const char *mainString, Args &...args) const
Definition pmu.hh:530
void setValue(uint64_t val)
overwrite the value of the counter
Definition pmu.cc:627
void attachEvent(PMU::CounterState *user)
attach this event to a given counter
Definition pmu.cc:495
virtual void enable()=0
Enable the current event.
virtual void disable()=0
Disable the current event.
Stats *const pmuStats
True is event is reported as a stat.
Definition pmu.hh:352
std::set< PMU::CounterState * > userCounters
set of counters using this event
Definition pmu.hh:355
virtual void updateAttachedCounters()
Method called immediately before a counter access in order for the associated event to update its sta...
Definition pmu.hh:345
void detachEvent(PMU::CounterState *user)
detach this event from a given counter
Definition pmu.cc:519
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:507
void notify(const uint64_t &val) override
Definition pmu.cc:531
std::set< EventTypeEntry > microArchitectureEventSet
The set of events driving the event value.
Definition pmu.hh:404
void enable() override
Enable the current event.
Definition pmu.cc:537
void disable() override
Disable the current event.
Definition pmu.cc:558
std::vector< ProbeListenerPtr<> > attachedProbePointList
Set of probe listeners tapping onto each of the input micro-arch events which compose this pmu event.
Definition pmu.hh:409
void registerEvent(EventTypeId id, const char *stat_name)
Definition pmu.cc:901
void add(EventTypeId id, uint64_t value)
Increment the map[id] stat by value.
Definition pmu.cc:914
Stats(PMU *parent)
Definition pmu.cc:891
std::unordered_map< EventTypeId, statistics::Scalar > map
Definition pmu.hh:708

Generated on Mon Oct 27 2025 04:12:55 for gem5 by doxygen 1.14.0