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

Generated on Wed Dec 21 2022 10:22:26 for gem5 by doxygen 1.9.1