changeset 77b9f96786c1 in /z/repo/gem5 details: http://repo.gem5.org/gem5?cmd=changeset;node=77b9f96786c1 description: energy: Small extentions and fixes for DVFS handler
These additions allow easier interoperability with and querying from an additional controller which will be in a separate patch. Also adding warnings for changing the enabled state of the handler across checkpoint / resume and deviating from the state in the configuration. Contributed-by: Akash Bagdia <akash.bag...@arm.com> diffstat: src/sim/clock_domain.cc | 12 ++++++++++++ src/sim/clock_domain.hh | 1 + src/sim/dvfs_handler.cc | 21 +++++++++++++++++++++ src/sim/dvfs_handler.hh | 33 ++++++++++++++++++++++++++++++++- src/sim/voltage_domain.cc | 11 ++++++++--- src/sim/voltage_domain.hh | 15 +++++++++++++-- 6 files changed, 87 insertions(+), 6 deletions(-) diffs (218 lines): diff -r 70cfafa17653 -r 77b9f96786c1 src/sim/clock_domain.cc --- a/src/sim/clock_domain.cc Sat Sep 20 17:18:21 2014 -0400 +++ b/src/sim/clock_domain.cc Mon Jun 16 14:59:44 2014 +0100 @@ -136,6 +136,11 @@ { assert(validPerfLevel(perf_level)); + if (perf_level == _perfLevel) { + // Silently ignore identical overwrites + return; + } + DPRINTF(ClockDomain, "DVFS: Switching performance level of domain %s "\ "(id: %d) from %d to %d\n", name(), domainID(), _perfLevel, perf_level); @@ -162,6 +167,13 @@ { ClockDomain::unserialize(cp, section); UNSERIALIZE_SCALAR(_perfLevel); +} + +void +SrcClockDomain::startup() +{ + // Perform proper clock update when all related components have been + // created (i.e. after unserialization / object creation) perfLevel(_perfLevel); } diff -r 70cfafa17653 -r 77b9f96786c1 src/sim/clock_domain.hh --- a/src/sim/clock_domain.hh Sat Sep 20 17:18:21 2014 -0400 +++ b/src/sim/clock_domain.hh Mon Jun 16 14:59:44 2014 +0100 @@ -237,6 +237,7 @@ return freqOpPoints[perf_level]; } + void startup(); void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); diff -r 70cfafa17653 -r 77b9f96786c1 src/sim/dvfs_handler.cc --- a/src/sim/dvfs_handler.cc Sat Sep 20 17:18:21 2014 -0400 +++ b/src/sim/dvfs_handler.cc Mon Jun 16 14:59:44 2014 +0100 @@ -81,12 +81,26 @@ // Create a dedicated event slot per known domain ID UpdateEvent *event = &updatePerfLevelEvents[domain_id]; event->domainIDToSet = d->domainID(); + + // Add domain ID to the list of domains + domainIDList.push_back(d->domainID()); } UpdateEvent::dvfsHandler = this; } DVFSHandler *DVFSHandler::UpdateEvent::dvfsHandler; +DVFSHandler::DomainID +DVFSHandler::domainID(uint32_t index) const +{ + fatal_if(index >= numDomains(), "DVFS: Requested index out of "\ + "bound, max value %d\n", (domainIDList.size() - 1)); + + assert(domains.find(domainIDList[index]) != domains.end()); + + return domainIDList[index]; +} + bool DVFSHandler::validDomainID(DomainID domain_id) const { @@ -186,8 +200,15 @@ void DVFSHandler::unserialize(Checkpoint *cp, const std::string §ion) { + bool temp = enableHandler; + UNSERIALIZE_SCALAR(enableHandler); + if(temp != enableHandler) { + warn("DVFS: Forcing enable handler status to unserialized value of %d", + enableHandler); + } + // Reconstruct the map of domain IDs and their scheduled events std::vector<DomainID> domain_ids; std::vector<PerfLevel> perf_levels; diff -r 70cfafa17653 -r 77b9f96786c1 src/sim/dvfs_handler.hh --- a/src/sim/dvfs_handler.hh Sat Sep 20 17:18:21 2014 -0400 +++ b/src/sim/dvfs_handler.hh Mon Jun 16 14:59:44 2014 +0100 @@ -52,13 +52,14 @@ #include <vector> +#include "debug/DVFS.hh" #include "params/ClockDomain.hh" #include "params/DVFSHandler.hh" #include "params/VoltageDomain.hh" #include "sim/clock_domain.hh" #include "sim/eventq.hh" #include "sim/sim_object.hh" - +#include "sim/voltage_domain.hh" /** * DVFS Handler class, maintains a list of all the domains it can handle. @@ -80,6 +81,18 @@ typedef SrcClockDomain::PerfLevel PerfLevel; /** + * Get the number of domains assigned to this DVFS handler. + * @return Number of domains + */ + uint32_t numDomains() const { return domainIDList.size(); } + + /** + * Get the n-th domain ID, from the domains managed by this handler. + * @return Domain ID + */ + DomainID domainID(uint32_t index) const; + + /** * Check whether a domain ID is known to the handler or not. * @param domain_id Domain ID to check * @return Domain ID known to handler? @@ -128,6 +141,19 @@ } /** + * Read the voltage of the specified domain at the specified + * performance level. + * @param domain_id Domain ID to query + * @param perf_level Performance level of interest + * @return Voltage for the requested performance level of the respective + * domain + */ + double voltageAtPerfLevel(DomainID domain_id, PerfLevel perf_level) const + { + return findDomain(domain_id)->voltageDomain()->voltage(perf_level); + } + + /** * Get the total number of available performance levels. * * @param domain_id Domain ID to query @@ -154,6 +180,11 @@ Domains domains; /** + * List of IDs avaiable in the domain list + */ + std::vector<DomainID> domainIDList; + + /** * Clock domain of the system the handler is instantiated. */ SrcClockDomain* sysClkDomain; diff -r 70cfafa17653 -r 77b9f96786c1 src/sim/voltage_domain.cc --- a/src/sim/voltage_domain.cc Sat Sep 20 17:18:21 2014 -0400 +++ b/src/sim/voltage_domain.cc Mon Jun 16 14:59:44 2014 +0100 @@ -54,9 +54,9 @@ // Voltages must be sorted in descending order. fatal_if(!std::is_sorted(voltageOpPoints.begin(), voltageOpPoints.end(), - std::greater_equal<Voltages::value_type>()), "DVFS: Voltage "\ - "operation points not in descending order for voltage domain "\ - "%s\n", name()); + std::greater<Voltages::value_type>()), "DVFS: Voltage operation "\ + "points not in descending order for voltage domain %s\n", + name()); } void @@ -66,6 +66,11 @@ "DVFS: Requested voltage ID %d is outside the known "\ "range for domain %s.\n", perf_level, name()); + if (perf_level == _perfLevel) { + // Silently ignore identical overwrites + return; + } + _perfLevel = perf_level; DPRINTF(VoltageDomain, "Setting voltage to %.3fV idx: %d for domain %s\n", diff -r 70cfafa17653 -r 77b9f96786c1 src/sim/voltage_domain.hh --- a/src/sim/voltage_domain.hh Sat Sep 20 17:18:21 2014 -0400 +++ b/src/sim/voltage_domain.hh Mon Jun 16 14:59:44 2014 +0100 @@ -60,6 +60,8 @@ typedef VoltageDomainParams Params; VoltageDomain(const Params *p); + typedef SrcClockDomain::PerfLevel PerfLevel; + /** * Get the current voltage. * @@ -67,10 +69,19 @@ */ double voltage() const { return voltageOpPoints[_perfLevel]; } + /** + * Get the voltage at specified performance level. + * + * @param perf_level Performance level for which the voltage is requested + * @return Voltage of the domain at specified performance level + */ + double voltage(PerfLevel perf_level) const + { + return voltageOpPoints[perf_level]; + } + uint32_t numVoltages() const { return (uint32_t)voltageOpPoints.size(); } - typedef SrcClockDomain::PerfLevel PerfLevel; - /** * Set the voltage point of the domain. * @param Voltage value to be set _______________________________________________ gem5-dev mailing list gem5-dev@gem5.org http://m5sim.org/mailman/listinfo/gem5-dev