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

Generated on Fri Feb 28 2020 16:26:57 for gem5 by doxygen 1.8.13