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

Generated on Wed Dec 21 2022 10:22:40 for gem5 by doxygen 1.9.1