From add5e51e498e27aabee0f41b6c2a1573d24b1aa4 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 3 May 2023 18:36:00 +0100 Subject: [PATCH] arch-arm: Add support to exit the simloop on PMU interrupt Add an option `exitOnPMUInterrupt` to ArmPMU. The PMU is often used to identify and demark regions of interest in a workload intended for sampled simulation (e.g. fast-forward, warm-up, detailed simulation). Often the PMU is enabled and disabled to demark these regions, but for some workloads PMU interrupts are used to count committed instructions directly. This patch adds the option to exit the simulation loop when a PMU interrupt is triggered so additional simulation control can be effected (e.g. stats dump/reset, CPU switch, etc). Change-Id: Ife02fe8e467dec91a2d4fda3f7dc9540a092f1ec Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69958 Maintainer: Jason Lowe-Power Tested-by: kokoro Reviewed-by: Jason Lowe-Power --- src/arch/arm/ArmPMU.py | 1 + src/arch/arm/pmu.cc | 7 ++++++- src/arch/arm/pmu.hh | 4 ++++ src/python/gem5/simulate/exit_event.py | 3 +++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/arch/arm/ArmPMU.py b/src/arch/arm/ArmPMU.py index a07239bb29..a4a2ebe843 100644 --- a/src/arch/arm/ArmPMU.py +++ b/src/arch/arm/ArmPMU.py @@ -218,6 +218,7 @@ class ArmPMU(SimObject): exitOnPMUControl = Param.Bool( False, "Exit on PMU enable, disable, or reset" ) + exitOnPMUInterrupt = Param.Bool(False, "Exit on PMU interrupt") # 64-bit PMU event counters are officially supported when # Armv8.5-A FEAT_PMUv3p5 is implemented. This parameter is not a diff --git a/src/arch/arm/pmu.cc b/src/arch/arm/pmu.cc index efd641797f..2cb7085ca2 100644 --- a/src/arch/arm/pmu.cc +++ b/src/arch/arm/pmu.cc @@ -68,7 +68,8 @@ PMU::PMU(const ArmPMUParams &p) swIncrementEvent(nullptr), reg_pmcr_conf(0), interrupt(nullptr), - exitOnPMUControl(p.exitOnPMUControl) + exitOnPMUControl(p.exitOnPMUControl), + exitOnPMUInterrupt(p.exitOnPMUInterrupt) { DPRINTF(PMUVerbose, "Initializing the PMU.\n"); @@ -677,6 +678,10 @@ PMU::setOverflowStatus(RegVal new_val) void PMU::raiseInterrupt() { + if (exitOnPMUInterrupt) { + inform("Exiting simulation: PMU interrupt detected"); + exitSimLoop("performance counter interrupt", 0); + } if (interrupt) { DPRINTF(PMUVerbose, "Delivering PMU interrupt.\n"); interrupt->raise(); diff --git a/src/arch/arm/pmu.hh b/src/arch/arm/pmu.hh index 49990311c0..64f8f133f8 100644 --- a/src/arch/arm/pmu.hh +++ b/src/arch/arm/pmu.hh @@ -638,6 +638,10 @@ class PMU : public SimObject, public ArmISA::BaseISADevice */ const bool exitOnPMUControl; + /** + * Exit simloop on PMU interrupt + */ + bool exitOnPMUInterrupt; }; } // namespace ArmISA diff --git a/src/python/gem5/simulate/exit_event.py b/src/python/gem5/simulate/exit_event.py index 61462e47aa..cffe864f06 100644 --- a/src/python/gem5/simulate/exit_event.py +++ b/src/python/gem5/simulate/exit_event.py @@ -52,6 +52,7 @@ class ExitEvent(Enum): PERF_COUNTER_ENABLE = "performance counter enabled" PERF_COUNTER_DISABLE = "performance counter disabled" PERF_COUNTER_RESET = "performance counter reset" + PERF_COUNTER_INTERRUPT = "performance counter interrupt" @classmethod def translate_exit_status(cls, exit_string: str) -> "ExitEvent": @@ -99,6 +100,8 @@ class ExitEvent(Enum): return ExitEvent.PERF_COUNTER_DISABLE elif exit_string == "performance counter reset": return ExitEvent.PERF_COUNTER_RESET + elif exit_string == "performance counter interrupt": + return ExitEvent.PERF_COUNTER_INTERRUPT elif exit_string.endswith("will terminate the simulation.\n"): # This is for the traffic generator exit event return ExitEvent.EXIT