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 &section);
 
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 &section)
 {
+    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

Reply via email to