gem5  v20.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 "debug/PowerDomain.hh"
43 
44 PowerDomain::PowerDomain(const PowerDomainParams* p) :
45  PowerState(p),
46  leaders(p->leaders),
47  pwrStateUpdateEvent(*this),
48  stats(*this)
49 {
50  // Check if there is at least one leader
51  fatal_if(leaders.empty(), "No leaders registered in %s!)", name());
52 
53  // Go over the leaders and register this power domain with them
54  for (auto leader : leaders) {
55  leader->setControlledDomain(this);
56  }
57 
58  // We will assume a power domain to start in the most performant p-state
59  // This will be corrected during startup()
60  leaderTargetState = Enums::PwrState::ON;
61  _currState = Enums::PwrState::ON;
62 }
63 
64 void
66 {
67  DPRINTF(PowerDomain, "%s is a follower in %s\n", pwr_obj->name(), name());
68  followers.push_back(pwr_obj);
69 }
70 
71 void
73 {
74  DPRINTF(PowerDomain, "Checks at startup\n");
75  // Check if the leaders and followers have the correct power states.
76  DPRINTF(PowerDomain, "Checking power state of leaders & followers\n");
77  for (const auto &objs : { leaders, followers }) {
78  for (const auto &obj : objs) {
79  const auto & states = obj->getPossibleStates();
80  auto it = states.find(Enums::PwrState::ON);
81  fatal_if(it == states.end(),
82  "%s in %s does not have the required power states to be "
83  "part of a PowerDomain i.e. the ON state!", obj->name(),
84  name());
85  }
86  }
87 
88  // Now all objects have been checked for the minimally required power
89  // states, calculate the possible power states for the domain. This is the
90  // intersection between the possible power states of the followers and
91  // leaders.
93 
94  // Check that there is no objects which is both a leader and a
95  // follower.
96  DPRINTF(PowerDomain, "Checking for double entries\n");
97  for (auto follower : followers) {
98  for (auto leader : leaders) {
99  fatal_if(leader == follower, "%s is both a leader and follower"
100  " in %s\n!", leader->name(), name());
101  }
102  }
103  // Record the power states of the leaders and followers
104  DPRINTF(PowerDomain, "Recording the current power states in domain\n");
105  for (auto leader : leaders) {
106  Enums::PwrState pws = leader->get();
107  fatal_if(pws == Enums::PwrState::UNDEFINED,
108  "%s is in the UNDEFINED power state, not acceptable as "
109  "leader!", leader->name());
110  }
111 
112  // Calculate the power state of the domain, only looking at leader
114  // Set the power states of the followers, based upon leaderTargetState.
116 }
117 
118 bool
119 PowerDomain::isPossiblePwrState(Enums::PwrState p_state)
120 {
121  for (const auto &objs : { leaders, followers }) {
122  for (const auto &obj : objs) {
123  const auto &obj_states = obj->getPossibleStates();
124  if (obj_states.find(p_state) == obj_states.end()) {
125  return false;
126  }
127  }
128  }
129  return true;
130 }
131 
132 void
134 {
135  assert(possibleStates.empty());
136  for (auto p_state: leaders[0]->getPossibleStates()) {
137  if (isPossiblePwrState(p_state)) {
138  possibleStates.emplace(p_state);
139  DPRINTF(PowerDomain, "%u/%s is a p-state\n", p_state,
140  Enums::PwrStateStrings[p_state]);
141  }
142  }
143 }
144 
145 Enums::PwrState
147  const std::vector<Enums::PwrState> &f_states)
148 {
149  DPRINTF(PowerDomain, "Calculating the power state\n");
150  Enums::PwrState most_perf_state = Enums::PwrState::Num_PwrState;
151  std::string most_perf_leader;
152  for (auto leader : leaders) {
153  Enums::PwrState pw = leader->get();
154  if (pw < most_perf_state) {
155  most_perf_state = pw;
156  most_perf_leader = leader->name();
157  }
158  }
159  assert(most_perf_state != Enums::PwrState::Num_PwrState);
160  DPRINTF(PowerDomain, "Most performant leader is %s, at %u\n",
161  most_perf_leader, most_perf_state);
162 
163  // If asked to check the power states of the followers (f_states contains
164  // the power states of the followers)
165  if (!f_states.empty()) {
166  for (Enums::PwrState f_pw : f_states ) {
167  // Ignore UNDEFINED state of follower, at startup the followers
168  // might be in the UNDEFINED state, PowerDomain will pull them up
169  if ((f_pw != Enums::PwrState::UNDEFINED) &&
170  (f_pw < most_perf_state)) {
171  most_perf_state = f_pw;
172  }
173  }
174  DPRINTF(PowerDomain, "Most performant state, including followers "
175  "is %u\n", most_perf_state);
176  }
177  return most_perf_state;
178 }
179 
180 void
182 {
183  // Loop over all followers and tell them to change their power state so
184  // they match that of the power domain (or a more performant power state)
185  std::vector<Enums::PwrState> matched_states;
186  for (auto follower : followers) {
187  Enums::PwrState actual_pws =
188  follower->matchPwrState(leaderTargetState);
189  matched_states.push_back(actual_pws);
190  assert(actual_pws <= leaderTargetState);
191  DPRINTF(PowerDomain, "%u matched domain power state (%u) with %u\n",
192  follower->name(), leaderTargetState,
193  actual_pws);
194  }
195  // Now the power states of the follower have been changed recalculate the
196  // power state of the domain as a whole, including followers
197  Enums::PwrState new_power_state =
198  calculatePowerDomainState(matched_states);
199  if (new_power_state != _currState) {
200  // Change in power state of the domain, so update. Updates in power
201  // state need to happen via set() so it can propagate to
202  // overarching power domains (if there are any).
203  DPRINTF(PowerDomain, "Updated power domain state to %u\n",
204  new_power_state);
205  set(new_power_state);
206  }
207 }
208 
209 void
210 PowerDomain::pwrStateChangeCallback(Enums::PwrState new_pwr_state,
211  PowerState* leader)
212 {
213  DPRINTF(PowerDomain, "PwrState update to %u by %s\n", new_pwr_state,
214  leader->name());
215 
216  Enums::PwrState old_target_state = leaderTargetState;
217  // Calculate the power state of the domain, based on the leaders
218  if (new_pwr_state < _currState) {
219  // The power state of the power domain always needs to match that of
220  // the most performant leader so no need to go over the other leaders
221  // The power state need to be changed via a the PwrStateCall() so any
222  // overarching power domains get informed
223  leaderTargetState = new_pwr_state;
224  } else {
225  // Need to calculate the newly required power state, based on the
226  // leaders only and change to that state.
228  }
229  if (old_target_state!= leaderTargetState) {
230  // The followers will try to match that power state requested by the
231  // leaders in in the update event, based upon the actual power state,
232  // we will 'officially' change the power state of the domain by calling
233  // set()
235  DPRINTF(PowerDomain, "TargetState change from %u to %u, followers will"
236  "be updated in %u ticks\n", old_target_state,
239  }
241 }
242 
244  : Stats::Group(&pd),
245  ADD_STAT(numLeaderCalls,
246  "Number of calls by leaders to change power domain state"),
247  ADD_STAT(numLeaderCallsChangingState,
248  "Number of calls by leader to change power domain state "
249  "actually resulting in a power state change")
250 {
251 }
252 
253 void
255 {
257 
260  ;
263  ;
264 }
265 
267 PowerDomainParams::create()
268 {
269  return new PowerDomain(this);
270 }
#define DPRINTF(x,...)
Definition: trace.hh:225
Enums::PwrState _currState
To keep track of the current power state.
Definition: power_state.hh:123
PowerDomain(const PowerDomainParams *p)
Definition: power_domain.cc:44
std::vector< PowerState * > leaders
List of all leaders in the PowerDomain.
EventWrapper< PowerDomain, &PowerDomain::setFollowerPowerStates > pwrStateUpdateEvent
Event to update the power states of the followers.
std::vector< PowerState * > followers
List of all followers in the PowerDomain.
PowerDomain::PowerDomainStats stats
Helper class for objects that have power states.
Definition: power_state.hh:61
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:333
STL vector class.
Definition: stl.hh:37
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:65
Tick curTick()
The current simulated tick.
Definition: core.hh:44
const Tick updateLatency
Latency with which power state changes of the leaders will ripple through to the followers.
std::set< Enums::PwrState > possibleStates
The possible power states this object can be in.
Definition: power_state.hh:126
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:199
void schedule(Event &event, Tick when)
Definition: eventq.hh:934
void pwrStateChangeCallback(Enums::PwrState new_pwr_state, PowerState *leader)
Register the change in power state in one of the leader.
The PowerDomain groups PowerState objects together to regulate their power states.
Definition: power_domain.hh:56
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:67
virtual const std::string name() const
Definition: sim_object.hh:129
Stats::Scalar numLeaderCallsChangingState
Group()=delete
void calculatePossiblePwrStates()
Calculate the possible power states of the domain based upon the intersection of the power states of ...
void startup() override
During startup, the list of possible power states the PowerDomain can be in is populated, the power state of the PowerDomain is set and some assertions about the PowerState objects in the Domain are checked.
Definition: power_domain.cc:72
Enums::PwrState leaderTargetState
Power state requested by the leader.
bool isPossiblePwrState(Enums::PwrState p_state)
Check if a given p_state is available across all leaders and followers in this domain.
void regStats() override
Callback to set stat parameters.
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:64
std::set< Enums::PwrState > getPossibleStates() const
Return the power states this object can be in.
Definition: power_state.hh:115
const FlagsType nozero
Don&#39;t print if this is zero.
Definition: info.hh:57
Bitfield< 0 > p
void setFollowerPowerStates()
Update the followers of the newly updated power state.
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...
PowerDomainStats(PowerDomain &pd)

Generated on Thu May 28 2020 16:21:35 for gem5 by doxygen 1.8.13