1/* 2 * Copyright (c) 2011-2014, 2017-2018 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 */ 41#ifndef __ARCH_ARM_PMU_HH__ 42#define __ARCH_ARM_PMU_HH__ 43 44#include <map> 45#include <memory> 46#include <vector> 47 48#include "arch/arm/isa_device.hh" 49#include "arch/arm/registers.hh" 50#include "arch/arm/system.hh" 51#include "base/cprintf.hh" 52#include "cpu/base.hh" 53#include "debug/PMUVerbose.hh" 54#include "sim/eventq.hh" 55#include "sim/sim_object.hh" 56#include "sim/system.hh" 57 58class ArmPMUParams; 59class Platform; 60class ThreadContext; 61class ArmInterruptPin; 62 63namespace ArmISA { 64 65 66/** 67 * Model of an ARM PMU version 3 68 * 69 * This class implements a subset of the ARM PMU v3 specification as 70 * described in the ARMv8 reference manual. It supports most of the 71 * features of the PMU, however the following features are known to be 72 * missing: 73 * 74 * <ul> 75 * <li>Event filtering (e.g., from different privilege levels). 76 * <li>Access controls (the PMU currently ignores the execution level). 77 * <li>The chain counter (event no. 0x1E) is unimplemented. 78 * </ul> 79 * 80 * The PMU itself does not implement any events, in merely provides an 81 * interface for the configuration scripts to hook up probes that 82 * drive events. Configuration scripts should call addEventProbe() to 83 * configure custom events or high-level methods to configure 84 * architected events. The Python implementation of addEventProbe() 85 * automatically delays event type registration until after 86 * instantiation. 87 * 88 * In order to support CPU switching and some combined counters (e.g., 89 * memory references synthesized from loads and stores), the PMU 90 * allows multiple probes per event type. When creating a system that 91 * switches between CPU models that share the same PMU, PMU events for 92 * all of the CPU models can be registered with the PMU. 93 * 94 * @see The ARM Architecture Refererence Manual (DDI 0487A) 95 * 96 */ 97class PMU : public SimObject, public ArmISA::BaseISADevice { 98 public: 99 PMU(const ArmPMUParams *p); 100 ~PMU(); 101 102 void addEventProbe(unsigned int id, SimObject *obj, const char *name); 103 void addSoftwareIncrementEvent(unsigned int id); 104 105 void registerEvent(uint32_t id); 106 107 public: // SimObject and related interfaces 108 void serialize(CheckpointOut &cp) const override; 109 void unserialize(CheckpointIn &cp) override; 110 111 void drainResume() override; 112 113 void regProbeListeners() override; 114 115 public: // ISA Device interface 116 void setThreadContext(ThreadContext *tc) override; 117 118 /** 119 * Set a register within the PMU. 120 * 121 * @param misc_reg Register number (see miscregs.hh) 122 * @param val Value to store 123 */ 124 void setMiscReg(int misc_reg, RegVal val) override; 125 /** 126 * Read a register within the PMU. 127 * 128 * @param misc_reg Register number (see miscregs.hh) 129 * @return Register value. 130 */ 131 RegVal readMiscReg(int misc_reg) override; 132 133 protected: // PMU register types and constants 134 BitUnion32(PMCR_t) 135 // PMU Enable 136 Bitfield<0> e; 137 // Event counter reset 138 Bitfield<1> p; 139 // Cycle counter reset 140 Bitfield<2> c; 141 // Cycle counter divider enable 142 Bitfield<3> d; 143 // Export enable 144 Bitfield<4> x; 145 // Disable PMCCNTR when event counting is prohibited 146 Bitfield<5> dp; 147 // Long Cycle counter enable 148 Bitfield<6> lc; 149 // Number of event counters implemented 150 Bitfield<15, 11> n; 151 // Implementation ID 152 Bitfield<23, 16> idcode; 153 // Implementer code 154 Bitfield<31, 24> imp; 155 EndBitUnion(PMCR_t) 156 157 BitUnion32(PMSELR_t) 158 // Performance counter selector 159 Bitfield<4, 0> sel; 160 EndBitUnion(PMSELR_t) 161 162 BitUnion32(PMEVTYPER_t) 163 Bitfield<15, 0> evtCount; 164 165 // Secure EL3 filtering 166 Bitfield<26> m; 167 // Non-secure EL2 mode filtering 168 Bitfield<27> nsh; 169 // Non-secure EL0 mode filtering 170 Bitfield<28> nsu; 171 // Non-secure EL1 mode filtering 172 Bitfield<29> nsk; 173 // EL0 filtering 174 Bitfield<30> u; 175 // EL1 filtering 176 Bitfield<31> p; 177 EndBitUnion(PMEVTYPER_t) 178 179 /** 180 * Counter ID within the PMU. 181 * 182 * This value is typically used to index into various registers 183 * controlling interrupts and overflows. The value normally in the 184 * [0, 31] range, where 31 refers to the cycle counter. 185 */ 186 typedef unsigned int CounterId; 187 188 /** Cycle Count Register Number */ 189 static const CounterId PMCCNTR = 31; 190 191 /** 192 * Event type ID. 193 * 194 * See the PMU documentation for a list of architected IDs. 195 */ 196 typedef unsigned int EventTypeId; 197 198 protected: /* High-level register and interrupt handling */ 199 RegVal readMiscRegInt(int misc_reg); 200 201 /** 202 * PMCR write handling 203 * 204 * The PMCR register needs special handling since writing to it 205 * changes PMU-global state (e.g., resets all counters). 206 * 207 * @param val New PMCR value 208 */ 209 void setControlReg(PMCR_t val); 210 211 /** 212 * Reset all event counters excluding the cycle counter to zero. 213 */ 214 void resetEventCounts(); 215 216 /** 217 * Deliver a PMU interrupt to the GIC 218 */ 219 void raiseInterrupt(); 220 221 /** 222 * Clear a PMU interrupt. 223 */ 224 void clearInterrupt(); 225 226 /** 227 * Get the value of a performance counter. 228 * 229 * This method returns the value of a general purpose performance 230 * counter or the fixed-function cycle counter. Non-existing 231 * counters are treated as constant '0'. 232 * 233 * @return Value of the performance counter, 0 if the counter does 234 * not exist. 235 */ 236 uint64_t getCounterValue(CounterId id) const { 237 return isValidCounter(id) ? getCounter(id).getValue() : 0; 238 } 239 240 /** 241 * Set the value of a performance counter. 242 * 243 * This method sets the value of a general purpose performance 244 * counter or the fixed-function cycle counter. Writes to 245 * non-existing counters are ignored. 246 */ 247 void setCounterValue(CounterId id, uint64_t val); 248 249 /** 250 * Get the type and filter settings of a counter (PMEVTYPER) 251 * 252 * This method implements a read from a PMEVTYPER register. It 253 * returns the type value and filter settings of a general purpose 254 * performance counter or the cycle counter. Non-existing counters 255 * are treated as constant '0'. 256 * 257 * @param id Counter ID within the PMU. 258 * @return Performance counter type ID. 259 */ 260 PMEVTYPER_t getCounterTypeRegister(CounterId id) const; 261 262 /** 263 * Set the type and filter settings of a performance counter 264 * (PMEVTYPER) 265 * 266 * This method implements a write to a PMEVTYPER register. It sets 267 * the type value and filter settings of a general purpose 268 * performance counter or the cycle counter. Writes to 269 * non-existing counters are ignored. The method automatically 270 * updates the probes used by the counter if it is enabled. 271 * 272 * @param id Counter ID within the PMU. 273 * @param type Performance counter type and filter configuration.. 274 */ 275 void setCounterTypeRegister(CounterId id, PMEVTYPER_t type); 276 277 /** 278 * Used for writing the Overflow Flag Status Register (SET/CLR) 279 * 280 * This method implements a write to the PMOVSSET/PMOVSCLR registers. 281 * It is capturing change of state in the register bits so that 282 * the overflow interrupt can be raised/cleared as a side effect 283 * of the write. 284 * 285 * @param new_val New value of the Overflow Status Register 286 */ 287 void setOverflowStatus(RegVal new_val); 288 289 protected: /* Probe handling and counter state */ 290 struct CounterState; 291 292 /** 293 * Event definition base class 294 */ 295 struct PMUEvent { 296 297 PMUEvent() {} 298 299 virtual ~PMUEvent() {} 300 301 /** 302 * attach this event to a given counter 303 * 304 * @param a pointer to the counter where to attach this event 305 */ 306 void attachEvent(PMU::CounterState *user); 307 308 /** 309 * detach this event from a given counter 310 * 311 * @param a pointer to the counter where to detach this event from 312 */ 313 void detachEvent(PMU::CounterState *user); 314 315 /** 316 * notify an event increment of val units, all the attached counters' 317 * value is incremented by val units. 318 * 319 * @param the quantity by which to increment the attached counter 320 * values 321 */ 322 virtual void increment(const uint64_t val); 323 324 /** 325 * Enable the current event 326 */ 327 virtual void enable() = 0; 328 329 /** 330 * Disable the current event 331 */ 332 virtual void disable() = 0; 333 334 /** 335 * Method called immediately before a counter access in order for 336 * the associated event to update its state (if required) 337 */ 338 virtual void updateAttachedCounters() {} 339 340 protected: 341 342 /** set of counters using this event **/ 343 std::set<PMU::CounterState*> userCounters; 344 }; 345 346 struct RegularEvent : public PMUEvent { 347 typedef std::pair<SimObject*, std::string> EventTypeEntry; 348 349 void addMicroarchitectureProbe(SimObject* object, 350 std::string name) { 351 352 panic_if(!object,"malformed probe-point" 353 " definition with name %s\n", name); 354 355 microArchitectureEventSet.emplace(object, name); 356 } 357 358 protected: 359 struct RegularProbe: public ProbeListenerArgBase<uint64_t> 360 { 361 RegularProbe(RegularEvent *parent, SimObject* obj, 362 std::string name) 363 : ProbeListenerArgBase(obj->getProbeManager(), name), 364 parentEvent(parent) {} 365 366 RegularProbe() = delete; 367 368 void notify(const uint64_t &val); 369 370 protected: 371 RegularEvent *parentEvent; 372 }; 373 374 /** The set of events driving the event value **/ 375 std::set<EventTypeEntry> microArchitectureEventSet; 376 377 /** Set of probe listeners tapping onto each of the input micro-arch 378 * events which compose this pmu event 379 */ 380 std::vector<std::unique_ptr<RegularProbe>> attachedProbePointList; 381 382 void enable() override; 383 384 void disable() override; 385 }; 386 387 class SWIncrementEvent : public PMUEvent 388 { 389 void enable() override {} 390 void disable() override {} 391 392 public: 393 394 /** 395 * write on the sw increment register inducing an increment of the 396 * counters with this event selected according to the bitfield written. 397 * 398 * @param the bitfield selecting the counters to increment. 399 */ 400 void write(uint64_t val); 401 }; 402 403 /** 404 * Obtain the event of a given id 405 * 406 * @param the id of the event to obtain 407 * @return a pointer to the event with id eventId 408 */ 409 PMUEvent* getEvent(uint64_t eventId); 410 411 /** State of a counter within the PMU. **/ 412 struct CounterState : public Serializable { 413 CounterState(PMU &pmuReference, uint64_t counter_id) 414 : eventId(0), filter(0), enabled(false), 415 overflow64(false), sourceEvent(nullptr), 416 counterId(counter_id), value(0), resetValue(false), 417 pmu(pmuReference) {} 418 419 void serialize(CheckpointOut &cp) const override; 420 void unserialize(CheckpointIn &cp) override; 421 422 /** 423 * Add an event count to the counter and check for overflow. 424 * 425 * @param delta Number of events to add to the counter. 426 * @return the quantity remaining until a counter overflow occurs. 427 */ 428 uint64_t add(uint64_t delta); 429 430 bool isFiltered() const; 431 432 /** 433 * Detach the counter from its event 434 */ 435 void detach(); 436 437 /** 438 * Attach this counter to an event 439 * 440 * @param the event to attach the counter to 441 */ 442 void attach(PMUEvent* event); 443 444 /** 445 * Obtain the counter id 446 * 447 * @return the pysical counter id 448 */ 449 uint64_t getCounterId() const{ 450 return counterId; 451 } 452 453 /** 454 * rReturn the counter value 455 * 456 * @return the counter value 457 */ 458 uint64_t getValue() const; 459 460 /** 461 * overwrite the value of the counter 462 * 463 * @param the new counter value 464 */ 465 void setValue(uint64_t val); 466 467 public: /* Serializable state */ 468 /** Counter event ID */ 469 EventTypeId eventId; 470 471 /** Filtering settings (evtCount is unused) */ 472 PMEVTYPER_t filter; 473 474 /** Is the counter enabled? */ 475 bool enabled; 476 477 /** Is this a 64-bit counter? */ 478 bool overflow64; 479 480 protected: /* Configuration */ 481 /** PmuEvent currently in use (if any) **/ 482 PMUEvent *sourceEvent; 483 484 /** id of the counter instance **/ 485 uint64_t counterId; 486 487 /** Current value of the counter */ 488 uint64_t value; 489 490 /** Flag keeping track if the counter has been reset **/ 491 bool resetValue; 492 493 PMU &pmu; 494 495 template <typename ...Args> 496 void debugCounter(const char* mainString, Args &...args) const { 497 498 std::string userString = csprintf(mainString, args...); 499 500 warn("[counterId = %d, eventId = %d, sourceEvent = 0x%x] %s", 501 counterId, eventId, sourceEvent, userString.c_str()); 502 503 } 504 }; 505 506 /** 507 * Is this a valid counter ID? 508 * 509 * @param id ID of counter within the PMU. 510 * 511 * @return true if counter is within the allowed range or the 512 * cycle counter, false otherwise. 513 */ 514 bool isValidCounter(CounterId id) const { 515 return id < counters.size() || id == PMCCNTR; 516 } 517 518 /** 519 * Return the state of a counter. 520 * 521 * @param id ID of counter within the PMU. 522 * @return Reference to a CounterState instance representing the 523 * counter. 524 */ 525 CounterState &getCounter(CounterId id) { 526 assert(isValidCounter(id)); 527 return id == PMCCNTR ? cycleCounter : counters[id]; 528 } 529 530 /** 531 * Return the state of a counter. 532 * 533 * @param id ID of counter within the PMU. 534 * @return Reference to a CounterState instance representing the 535 * counter. 536 */ 537 const CounterState &getCounter(CounterId id) const { 538 assert(isValidCounter(id)); 539 return id == PMCCNTR ? cycleCounter : counters[id]; 540 } 541 542 /** 543 * Depending on counter configuration, add or remove the probes 544 * driving the counter. 545 * 546 * Look at the state of a counter and (re-)attach the probes 547 * needed to drive a counter if it is currently active. All probes 548 * for the counter are detached if the counter is inactive. 549 * 550 * @param id ID of counter within the PMU. 551 * @param ctr Reference to the counter's state 552 */ 553 void updateCounter(CounterState &ctr); 554 555 /** 556 * Check if a counter's settings allow it to be counted. 557 * 558 * @param ctr Counter state instance representing this counter. 559 * @return false if the counter is active, true otherwise. 560 */ 561 bool isFiltered(const CounterState &ctr) const; 562 563 /** 564 * Call updateCounter() for each counter in the PMU if the 565 * counter's state has changed.. 566 * 567 * @see updateCounter() 568 */ 569 void updateAllCounters(); 570 571 protected: /* State that needs to be serialized */ 572 /** Performance Monitor Count Enable Register */ 573 RegVal reg_pmcnten; 574 575 /** Performance Monitor Control Register */ 576 PMCR_t reg_pmcr; 577 578 /** Performance Monitor Selection Register */ 579 PMSELR_t reg_pmselr; 580 581 /** Performance Monitor Interrupt Enable Register */ 582 RegVal reg_pminten; 583 584 /** Performance Monitor Overflow Status Register */ 585 RegVal reg_pmovsr; 586 587 /** 588 * Performance counter ID register 589 * 590 * These registers contain a bitmask of available architected 591 * counters. 592 */ 593 uint64_t reg_pmceid0; 594 uint64_t reg_pmceid1; 595 596 /** Remainder part when the clock counter is divided by 64 */ 597 unsigned clock_remainder; 598 599 /** The number of regular event counters **/ 600 uint64_t maximumCounterCount; 601 602 /** State of all general-purpose counters supported by PMU */ 603 std::vector<CounterState> counters; 604 605 /** State of the cycle counter */ 606 CounterState cycleCounter; 607 608 /** The id of the counter hardwired to the cpu cycle counter **/ 609 const uint64_t cycleCounterEventId; 610 611 /** The event that implements the software increment **/ 612 SWIncrementEvent *swIncrementEvent; 613 614 protected: /* Configuration and constants */ 615 /** Constant (configuration-dependent) part of the PMCR */ 616 PMCR_t reg_pmcr_conf; 617 618 /** PMCR write mask when accessed from the guest */ 619 static const RegVal reg_pmcr_wr_mask; 620 621 /** Performance monitor interrupt number */ 622 ArmInterruptPin *interrupt; 623 624 /** 625 * List of event types supported by this PMU. 626 */ 627 std::map<EventTypeId, PMUEvent*> eventMap; 628}; 629 630} // namespace ArmISA 631#endif 632