gem5  v20.0.0.2
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 "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 
261  ;
264  ;
265 }
266 
268 PowerDomainParams::create()
269 {
270  return new PowerDomain(this);
271 }
#define DPRINTF(x,...)
Definition: trace.hh:222
Enums::PwrState _currState
To keep track of the current power state.
Definition: power_state.hh:123
PowerDomain(const PowerDomainParams *p)
Definition: power_domain.cc:45
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:66
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:998
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:128
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:73
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 Mon Jun 8 2020 15:45:13 for gem5 by doxygen 1.8.13