pmu.cc (10537:47fe87b0cf97) pmu.cc (10609:ae5582819481)
1/*
2 * Copyright (c) 2011-2014 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

--- 27 unchanged lines hidden (view full) ---

36 *
37 * Authors: Dam Sunwoo
38 * Matt Horsnell
39 * Andreas Sandberg
40 */
41
42#include "arch/arm/pmu.hh"
43
1/*
2 * Copyright (c) 2011-2014 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

--- 27 unchanged lines hidden (view full) ---

36 *
37 * Authors: Dam Sunwoo
38 * Matt Horsnell
39 * Andreas Sandberg
40 */
41
42#include "arch/arm/pmu.hh"
43
44#include "arch/arm/isa.hh"
45#include "arch/arm/utility.hh"
44#include "base/trace.hh"
45#include "cpu/base.hh"
46#include "debug/Checkpoint.hh"
47#include "debug/PMUVerbose.hh"
48#include "dev/arm/base_gic.hh"
49#include "dev/arm/realview.hh"
50#include "params/ArmPMU.hh"
51

--- 293 unchanged lines hidden (view full) ---

345
346 const bool ccntr_enable(global_enable && (reg_pmcnten & (1 << PMCCNTR)));
347 if (cycleCounter.enabled != ccntr_enable) {
348 cycleCounter.enabled = ccntr_enable;
349 updateCounter(PMCCNTR, cycleCounter);
350 }
351}
352
46#include "base/trace.hh"
47#include "cpu/base.hh"
48#include "debug/Checkpoint.hh"
49#include "debug/PMUVerbose.hh"
50#include "dev/arm/base_gic.hh"
51#include "dev/arm/realview.hh"
52#include "params/ArmPMU.hh"
53

--- 293 unchanged lines hidden (view full) ---

347
348 const bool ccntr_enable(global_enable && (reg_pmcnten & (1 << PMCCNTR)));
349 if (cycleCounter.enabled != ccntr_enable) {
350 cycleCounter.enabled = ccntr_enable;
351 updateCounter(PMCCNTR, cycleCounter);
352 }
353}
354
355bool
356PMU::isFiltered(const CounterState &ctr) const
357{
358 assert(isa);
359
360 const PMEVTYPER_t filter(ctr.filter);
361 const SCR scr(isa->readMiscRegNoEffect(MISCREG_SCR));
362 const CPSR cpsr(isa->readMiscRegNoEffect(MISCREG_CPSR));
363 const ExceptionLevel el(opModeToEL((OperatingMode)(uint8_t)cpsr.mode));
364 const bool secure(inSecureState(scr, cpsr));
365
366 switch (el) {
367 case EL0:
368 return secure ? filter.u : (filter.u != filter.nsu);
369
370 case EL1:
371 return secure ? filter.p : (filter.p != filter.nsk);
372
373 case EL2:
374 return !filter.nsh;
375
376 case EL3:
377 return filter.p != filter.m;
378
379 default:
380 panic("Unexpected execution level in PMU::isFiltered.\n");
381 }
382}
383
353void
354PMU::handleEvent(CounterId id, uint64_t delta)
355{
356 CounterState &ctr(getCounter(id));
357 const bool overflowed(reg_pmovsr & (1 << id));
358
384void
385PMU::handleEvent(CounterId id, uint64_t delta)
386{
387 CounterState &ctr(getCounter(id));
388 const bool overflowed(reg_pmovsr & (1 << id));
389
390 if (isFiltered(ctr))
391 return;
392
359 // Handle the "count every 64 cycles" mode
360 if (id == PMCCNTR && reg_pmcr.d) {
361 clock_remainder += delta;
362 delta = (clock_remainder >> 6);
363 clock_remainder &= 63;
364 }
365
366 // Add delta and handle (new) overflows

--- 62 unchanged lines hidden (view full) ---

429
430PMU::PMEVTYPER_t
431PMU::getCounterTypeRegister(CounterId id) const
432{
433 if (!isValidCounter(id))
434 return 0;
435
436 const CounterState &cs(getCounter(id));
393 // Handle the "count every 64 cycles" mode
394 if (id == PMCCNTR && reg_pmcr.d) {
395 clock_remainder += delta;
396 delta = (clock_remainder >> 6);
397 clock_remainder &= 63;
398 }
399
400 // Add delta and handle (new) overflows

--- 62 unchanged lines hidden (view full) ---

463
464PMU::PMEVTYPER_t
465PMU::getCounterTypeRegister(CounterId id) const
466{
467 if (!isValidCounter(id))
468 return 0;
469
470 const CounterState &cs(getCounter(id));
437 PMEVTYPER_t type(0);
471 PMEVTYPER_t type(cs.filter);
438
472
439 // TODO: Re-create filtering settings from counter state
440 type.evtCount = cs.eventId;
441
442 return type;
443}
444
445void
446PMU::setCounterTypeRegister(CounterId id, PMEVTYPER_t val)
447{
448 DPRINTF(PMUVerbose, "Set Event [%d] = 0x%08x\n", id, val);
449 if (!isValidCounter(id)) {
450 warn_once("Can't change counter type: Counter %i does not exist.\n",
451 id);
452 return;
453 }
454
455 CounterState &ctr(getCounter(id));
473 type.evtCount = cs.eventId;
474
475 return type;
476}
477
478void
479PMU::setCounterTypeRegister(CounterId id, PMEVTYPER_t val)
480{
481 DPRINTF(PMUVerbose, "Set Event [%d] = 0x%08x\n", id, val);
482 if (!isValidCounter(id)) {
483 warn_once("Can't change counter type: Counter %i does not exist.\n",
484 id);
485 return;
486 }
487
488 CounterState &ctr(getCounter(id));
456 // TODO: Handle filtering (both for general purpose counters and
457 // the cycle counter)
489 const EventTypeId old_event_id(ctr.eventId);
458
490
459 // If PMCCNTR Register, do not change event type. PMCCNTR can count
460 // processor cycles only.
461 if (id != PMCCNTR) {
491 ctr.filter = val;
492
493 // If PMCCNTR Register, do not change event type. PMCCNTR can
494 // count processor cycles only. If we change the event type, we
495 // need to update the probes the counter is using.
496 if (id != PMCCNTR && old_event_id != val.evtCount) {
462 ctr.eventId = val.evtCount;
463 updateCounter(reg_pmselr.sel, ctr);
464 }
465}
466
467void
468PMU::raiseInterrupt()
469{

--- 90 unchanged lines hidden ---
497 ctr.eventId = val.evtCount;
498 updateCounter(reg_pmselr.sel, ctr);
499 }
500}
501
502void
503PMU::raiseInterrupt()
504{

--- 90 unchanged lines hidden ---