{
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);
{
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);
}
return freqOpPoints[perf_level];
}
+ void startup();
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string §ion);
// 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
{
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;
#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.
typedef SrcClockDomain::DomainID DomainID;
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 findDomain(domain_id)->clkPeriodAtPerfLevel(perf_level);
}
+ /**
+ * 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.
*
typedef std::map<DomainID, SrcClockDomain*> Domains;
Domains domains;
+ /**
+ * List of IDs avaiable in the domain list
+ */
+ std::vector<DomainID> domainIDList;
+
/**
* Clock domain of the system the handler is instantiated.
*/
// 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
"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",
typedef VoltageDomainParams Params;
VoltageDomain(const Params *p);
+ typedef SrcClockDomain::PerfLevel PerfLevel;
+
/**
* Get the current voltage.
*
*/
double voltage() const { return voltageOpPoints[_perfLevel]; }
- uint32_t numVoltages() const { return (uint32_t)voltageOpPoints.size(); }
+ /**
+ * 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];
+ }
- typedef SrcClockDomain::PerfLevel PerfLevel;
+ uint32_t numVoltages() const { return (uint32_t)voltageOpPoints.size(); }
/**
* Set the voltage point of the domain.