gem5  v20.1.0.0
power_domain.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, 2019-2020 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include "sim/power_domain.hh"
39 
40 #include <unordered_map>
41 
42 #include "base/trace.hh"
43 #include "debug/PowerDomain.hh"
44 
45 PowerDomain::PowerDomain(const PowerDomainParams* p) :
46  PowerState(p),
47  leaders(p->leaders),
48  pwrStateUpdateEvent(*this),
49  stats(*this)
50 {
51  // Check if there is at least one leader
52  fatal_if(leaders.empty(), "No leaders registered in %s!)", name());
53 
54  // Go over the leaders and register this power domain with them
55  for (auto leader : leaders) {
56  leader->setControlledDomain(this);
57  }
58 
59  // We will assume a power domain to start in the most performant p-state
60  // This will be corrected during startup()
61  leaderTargetState = Enums::PwrState::ON;
62  _currState = Enums::PwrState::ON;
63 }
64 
65 void
67 {
68  DPRINTF(PowerDomain, "%s is a follower in %s\n", pwr_obj->name(), name());
69  followers.push_back(pwr_obj);
70 }
71 
72 void
74 {
75  DPRINTF(PowerDomain, "Checks at startup\n");
76  // Check if the leaders and followers have the correct power states.
77  DPRINTF(PowerDomain, "Checking power state of leaders & followers\n");
78  for (const auto &objs : { leaders, followers }) {
79  for (const auto &obj : objs) {
80  const auto & states = obj->getPossibleStates();
81  auto it = states.find(Enums::PwrState::ON);
82  fatal_if(it == states.end(),
83  "%s in %s does not have the required power states to be "
84  "part of a PowerDomain i.e. the ON state!", obj->name(),
85  name());
86  }
87  }
88 
89  // Now all objects have been checked for the minimally required power
90  // states, calculate the possible power states for the domain. This is the
91  // intersection between the possible power states of the followers and
92  // leaders.
94 
95  // Check that there is no objects which is both a leader and a
96  // follower.
97  DPRINTF(PowerDomain, "Checking for double entries\n");
98  for (auto follower : followers) {
99  for (auto leader : leaders) {
100  fatal_if(leader == follower, "%s is both a leader and follower"
101  " in %s\n!", leader->name(), name());
102  }
103  }
104  // Record the power states of the leaders and followers
105  DPRINTF(PowerDomain, "Recording the current power states in domain\n");
106  for (auto leader : leaders) {
107  Enums::PwrState pws = leader->get();
108  fatal_if(pws == Enums::PwrState::UNDEFINED,
109  "%s is in the UNDEFINED power state, not acceptable as "
110  "leader!", leader->name());
111  }
112 
113  // Calculate the power state of the domain, only looking at leader
115  // Set the power states of the followers, based upon leaderTargetState.
117 }
118 
119 bool
120 PowerDomain::isPossiblePwrState(Enums::PwrState p_state)
121 {
122  for (const auto &objs : { leaders, followers }) {
123  for (const auto &obj : objs) {
124  const auto &obj_states = obj->getPossibleStates();
125  if (obj_states.find(p_state) == obj_states.end()) {
126  return false;
127  }
128  }
129  }
130  return true;
131 }
132 
133 void
135 {
136  assert(possibleStates.empty());
137  for (auto p_state: leaders[0]->getPossibleStates()) {
138  if (isPossiblePwrState(p_state)) {
139  possibleStates.emplace(p_state);
140  DPRINTF(PowerDomain, "%u/%s is a p-state\n", p_state,
141  Enums::PwrStateStrings[p_state]);
142  }
143  }
144 }
145 
146 Enums::PwrState
148  const std::vector<Enums::PwrState> &f_states)
149 {
150  DPRINTF(PowerDomain, "Calculating the power state\n");
151  Enums::PwrState most_perf_state = Enums::PwrState::Num_PwrState;
152  std::string most_perf_leader;
153  for (auto leader : leaders) {
154  Enums::PwrState pw = leader->get();
155  if (pw < most_perf_state) {
156  most_perf_state = pw;
157  most_perf_leader = leader->name();
158  }
159  }
160  assert(most_perf_state != Enums::PwrState::Num_PwrState);
161  DPRINTF(PowerDomain, "Most performant leader is %s, at %u\n",
162  most_perf_leader, most_perf_state);
163 
164  // If asked to check the power states of the followers (f_states contains
165  // the power states of the followers)
166  if (!f_states.empty()) {
167  for (Enums::PwrState f_pw : f_states ) {
168  // Ignore UNDEFINED state of follower, at startup the followers
169  // might be in the UNDEFINED state, PowerDomain will pull them up
170  if ((f_pw != Enums::PwrState::UNDEFINED) &&
171  (f_pw < most_perf_state)) {
172  most_perf_state = f_pw;
173  }
174  }
175  DPRINTF(PowerDomain, "Most performant state, including followers "
176  "is %u\n", most_perf_state);
177  }
178  return most_perf_state;
179 }
180 
181 void
183 {
184  // Loop over all followers and tell them to change their power state so
185  // they match that of the power domain (or a more performant power state)
186  std::vector<Enums::PwrState> matched_states;
187  for (auto follower : followers) {
188  Enums::PwrState actual_pws =
189  follower->matchPwrState(leaderTargetState);
190  matched_states.push_back(actual_pws);
191  assert(actual_pws <= leaderTargetState);
192  DPRINTF(PowerDomain, "%u matched domain power state (%u) with %u\n",
193  follower->name(), leaderTargetState,
194  actual_pws);
195  }
196  // Now the power states of the follower have been changed recalculate the
197  // power state of the domain as a whole, including followers
198  Enums::PwrState new_power_state =
199  calculatePowerDomainState(matched_states);
200  if (new_power_state != _currState) {
201  // Change in power state of the domain, so update. Updates in power
202  // state need to happen via set() so it can propagate to
203  // overarching power domains (if there are any).
204  DPRINTF(PowerDomain, "Updated power domain state to %u\n",
205  new_power_state);
206  set(new_power_state);
207  }
208 }
209 
210 void
211 PowerDomain::pwrStateChangeCallback(Enums::PwrState new_pwr_state,
212  PowerState* leader)
213 {
214  DPRINTF(PowerDomain, "PwrState update to %u by %s\n", new_pwr_state,
215  leader->name());
216 
217  Enums::PwrState old_target_state = leaderTargetState;
218  // Calculate the power state of the domain, based on the leaders
219  if (new_pwr_state < _currState) {
220  // The power state of the power domain always needs to match that of
221  // the most performant leader so no need to go over the other leaders
222  // The power state need to be changed via a the PwrStateCall() so any
223  // overarching power domains get informed
224  leaderTargetState = new_pwr_state;
225  } else {
226  // Need to calculate the newly required power state, based on the
227  // leaders only and change to that state.
229  }
230  if (old_target_state!= leaderTargetState) {
231  // The followers will try to match that power state requested by the
232  // leaders in in the update event, based upon the actual power state,
233  // we will 'officially' change the power state of the domain by calling
234  // set()
236  DPRINTF(PowerDomain, "TargetState change from %u to %u, followers will"
237  "be updated in %u ticks\n", old_target_state,
240  }
242 }
243 
245  : Stats::Group(&pd),
246  ADD_STAT(numLeaderCalls,
247  "Number of calls by leaders to change power domain state"),
248  ADD_STAT(numLeaderCallsChangingState,
249  "Number of calls by leader to change power domain state "
250  "actually resulting in a power state change")
251 {
252 }
253 
254 void
256 {
258 
259  numLeaderCalls
260  .flags(Stats::nozero)
261  ;
262  numLeaderCallsChangingState
263  .flags(Stats::nozero)
264  ;
265 }
266 
268 PowerDomainParams::create()
269 {
270  return new PowerDomain(this);
271 }
Stats::Group::regStats
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:64
PowerState::possibleStates
std::set< Enums::PwrState > possibleStates
The possible power states this object can be in.
Definition: power_state.hh:126
PowerDomain::PowerDomainStats::PowerDomainStats
PowerDomainStats(PowerDomain &pd)
Definition: power_domain.cc:244
PowerDomain::setFollowerPowerStates
void setFollowerPowerStates()
Update the followers of the newly updated power state.
Definition: power_domain.cc:182
PowerState::set
void set(Enums::PwrState p)
Change the power state of this object to the power state p.
Definition: power_state.cc:89
PowerDomain::PowerDomainStats::numLeaderCalls
Stats::Scalar numLeaderCalls
Definition: power_domain.hh:161
PowerDomain
The PowerDomain groups PowerState objects together to regulate their power states.
Definition: power_domain.hh:56
PowerDomain::PowerDomain
PowerDomain(const PowerDomainParams *p)
Definition: power_domain.cc:45
PowerDomain::PowerDomainStats::regStats
void regStats() override
Callback to set stat parameters.
Definition: power_domain.cc:255
std::vector
STL vector class.
Definition: stl.hh:37
PowerDomain::followers
std::vector< PowerState * > followers
List of all followers in the PowerDomain.
Definition: power_domain.hh:140
PowerDomain::leaders
std::vector< PowerState * > leaders
List of all leaders in the PowerDomain.
Definition: power_domain.hh:126
PowerDomain::stats
PowerDomain::PowerDomainStats stats
power_domain.hh
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1005
PowerDomain::updateLatency
const Tick updateLatency
Latency with which power state changes of the leaders will ripple through to the followers.
Definition: power_domain.hh:146
PowerState::getPossibleStates
std::set< Enums::PwrState > getPossibleStates() const
Return the power states this object can be in.
Definition: power_state.hh:115
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:67
PowerState
Helper class for objects that have power states.
Definition: power_state.hh:61
PowerDomain::pwrStateChangeCallback
void pwrStateChangeCallback(Enums::PwrState new_pwr_state, PowerState *leader)
Register the change in power state in one of the leader.
Definition: power_domain.cc:211
PowerState::_currState
Enums::PwrState _currState
To keep track of the current power state.
Definition: power_state.hh:123
PowerDomain::addFollower
void addFollower(PowerState *pwr_obj) override
Function called by a follower to register itself as a dependant of this power domain.
Definition: power_domain.cc:66
PowerDomain::calculatePossiblePwrStates
void calculatePossiblePwrStates()
Calculate the possible power states of the domain based upon the intersection of the power states of ...
Definition: power_domain.cc:134
PowerDomain::PowerDomainStats::numLeaderCallsChangingState
Stats::Scalar numLeaderCallsChangingState
Definition: power_domain.hh:162
PowerDomain::isPossiblePwrState
bool isPossiblePwrState(Enums::PwrState p_state)
Check if a given p_state is available across all leaders and followers in this domain.
Definition: power_domain.cc:120
Stats::nozero
const FlagsType nozero
Don't print if this is zero.
Definition: info.hh:57
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:133
PowerDomain::leaderTargetState
Enums::PwrState leaderTargetState
Power state requested by the leader.
Definition: power_domain.hh:133
PowerDomain::startup
void startup() override
During startup, the list of possible power states the PowerDomain can be in is populated,...
Definition: power_domain.cc:73
Stats
Definition: statistics.cc:61
trace.hh
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
PowerDomain::calculatePowerDomainState
Enums::PwrState calculatePowerDomainState(const std::vector< Enums::PwrState > &f_states={})
Calculate the power state of the power domain, based upon the power states of the leaders.
Definition: power_domain.cc:147
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
PowerDomain::pwrStateUpdateEvent
EventWrapper< PowerDomain, &PowerDomain::setFollowerPowerStates > pwrStateUpdateEvent
Event to update the power states of the followers.
Definition: power_domain.hh:152

Generated on Wed Sep 30 2020 14:02:14 for gem5 by doxygen 1.8.17