arch-arm: Add support to exit the simloop on PMU control
PMU enables/disables/resets are often used to identify and demark regions of interest in a workload intended for sampled simulation (e.g. fast-forward, warm-up, detailed simulation). This patch adds the option to exit the simulation loop when these events occur so additional simulation control can be effected (e.g. stats dump/reset, CPU switch, etc). Original patch by Nicholas Lindsay <Nicholas.Lindsey@arm.com>. Updated by Richard Cooper <richard.cooper@arm.com>. Change-Id: I19be0def8d52fa036a3eee6bafeb63cc1f41694a Signed-off-by: Richard Cooper <richard.cooper@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/70417 Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Richard Cooper
parent
e90bd5feb9
commit
5fc8188ab3
@@ -1,5 +1,5 @@
|
||||
# -*- mode:python -*-
|
||||
# Copyright (c) 2009-2014, 2017, 2020, 2022 Arm Limited
|
||||
# Copyright (c) 2009-2014, 2017-2018, 2020, 2022-2023 Arm Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
@@ -215,11 +215,14 @@ class ArmPMU(SimObject):
|
||||
platform = Param.Platform(Parent.any, "Platform this device is part of.")
|
||||
eventCounters = Param.Int(31, "Number of supported PMU counters")
|
||||
interrupt = Param.ArmInterruptPin("PMU interrupt")
|
||||
exitOnPMUControl = Param.Bool(
|
||||
False, "Exit on PMU enable, disable, or reset"
|
||||
)
|
||||
|
||||
# 64-bit PMU event counters are officially supported when
|
||||
# Armv8.5-A FEAT_PMUv3p5 is implemented. This parameter is not a
|
||||
# full implementation of FEAT_PMUv3p5.
|
||||
use64bitCounters = Param.Bool(
|
||||
False,
|
||||
"Choose whether to use 64-bit or " "32-bit PMEVCNTR<n>_EL0 registers.",
|
||||
"Choose whether to use 64-bit or 32-bit PMEVCNTR<n>_EL0 registers.",
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2014, 2017-2019, 2022 Arm Limited
|
||||
* Copyright (c) 2011-2014, 2017-2019, 2022-2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "dev/arm/base_gic.hh"
|
||||
#include "dev/arm/generic_timer.hh"
|
||||
#include "params/ArmPMU.hh"
|
||||
#include "sim/sim_exit.hh"
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
@@ -66,7 +67,8 @@ PMU::PMU(const ArmPMUParams &p)
|
||||
cycleCounterEventId(p.cycleEventId),
|
||||
swIncrementEvent(nullptr),
|
||||
reg_pmcr_conf(0),
|
||||
interrupt(nullptr)
|
||||
interrupt(nullptr),
|
||||
exitOnPMUControl(p.exitOnPMUControl)
|
||||
{
|
||||
DPRINTF(PMUVerbose, "Initializing the PMU.\n");
|
||||
|
||||
@@ -412,6 +414,21 @@ PMU::setControlReg(PMCR_t val)
|
||||
if (reg_pmcr.d != val.d)
|
||||
clock_remainder = 0;
|
||||
|
||||
// Optionally exit the simulation on various PMU control events.
|
||||
// Exit on enable/disable takes precedence over exit on reset.
|
||||
if (exitOnPMUControl) {
|
||||
if (!reg_pmcr.e && val.e) {
|
||||
inform("Exiting simulation: PMU enable detected");
|
||||
exitSimLoop("performance counter enabled", 0);
|
||||
} else if (reg_pmcr.e && !val.e) {
|
||||
inform("Exiting simulation: PMU disable detected");
|
||||
exitSimLoop("performance counter disabled", 0);
|
||||
} else if (val.p) {
|
||||
inform("Exiting simulation: PMU reset detected");
|
||||
exitSimLoop("performance counter reset", 0);
|
||||
}
|
||||
}
|
||||
|
||||
reg_pmcr = val & reg_pmcr_wr_mask;
|
||||
updateAllCounters();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2014, 2017-2018, 2022 Arm Limited
|
||||
* Copyright (c) 2011-2014, 2017-2018, 2022-2023 Arm Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -632,6 +632,12 @@ class PMU : public SimObject, public ArmISA::BaseISADevice
|
||||
* List of event types supported by this PMU.
|
||||
*/
|
||||
std::map<EventTypeId, std::shared_ptr<PMUEvent>> eventMap;
|
||||
|
||||
/**
|
||||
* Exit simloop on PMU reset or disable
|
||||
*/
|
||||
const bool exitOnPMUControl;
|
||||
|
||||
};
|
||||
|
||||
} // namespace ArmISA
|
||||
|
||||
@@ -49,6 +49,9 @@ class ExitEvent(Enum):
|
||||
)
|
||||
SIMPOINT_BEGIN = "simpoint begins"
|
||||
MAX_INSTS = "number of instructions reached"
|
||||
PERF_COUNTER_ENABLE = "performance counter enabled"
|
||||
PERF_COUNTER_DISABLE = "performance counter disabled"
|
||||
PERF_COUNTER_RESET = "performance counter reset"
|
||||
|
||||
@classmethod
|
||||
def translate_exit_status(cls, exit_string: str) -> "ExitEvent":
|
||||
@@ -90,6 +93,12 @@ class ExitEvent(Enum):
|
||||
return ExitEvent.SIMPOINT_BEGIN
|
||||
elif exit_string == "a thread reached the max instruction count":
|
||||
return ExitEvent.MAX_INSTS
|
||||
elif exit_string == "performance counter enabled":
|
||||
return ExitEvent.PERF_COUNTER_ENABLE
|
||||
elif exit_string == "performance counter disabled":
|
||||
return ExitEvent.PERF_COUNTER_DISABLE
|
||||
elif exit_string == "performance counter reset":
|
||||
return ExitEvent.PERF_COUNTER_RESET
|
||||
elif exit_string.endswith("will terminate the simulation.\n"):
|
||||
# This is for the traffic generator exit event
|
||||
return ExitEvent.EXIT
|
||||
|
||||
Reference in New Issue
Block a user