gem5  v21.1.0.2
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
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::PowerDomain
The PowerDomain groups PowerState objects together to regulate their power states.
Definition: power_domain.hh:59
gem5::PowerDomain::stats
gem5::PowerDomain::PowerDomainStats stats
gem5::PowerState::possibleStates
std::set< enums::PwrState > possibleStates
The possible power states this object can be in.
Definition: power_state.hh:125
gem5::PowerDomain::setFollowerPowerStates
void setFollowerPowerStates()
Update the followers of the newly updated power state.
Definition: power_domain.cc:185
gem5::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:123
gem5::statistics::nozero
const FlagsType nozero
Don't print if this is zero.
Definition: info.hh:68
gem5::PowerDomain::leaderTargetState
enums::PwrState leaderTargetState
Power state requested by the leader.
Definition: power_domain.hh:136
gem5::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:69
gem5::EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
std::vector
STL vector class.
Definition: stl.hh:37
gem5::PowerDomain::leaders
std::vector< PowerState * > leaders
List of all leaders in the PowerDomain.
Definition: power_domain.hh:129
gem5::PowerDomain::PowerDomain
PowerDomain(const PowerDomainParams &p)
Definition: power_domain.cc:48
gem5::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:214
power_domain.hh
gem5::PowerDomain::followers
std::vector< PowerState * > followers
List of all followers in the PowerDomain.
Definition: power_domain.hh:143
gem5::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:137
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::PowerDomain::PowerDomainStats::numLeaderCallsChangingState
statistics::Scalar numLeaderCallsChangingState
Definition: power_domain.hh:165
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
gem5::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:150
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::PowerState
Helper class for objects that have power states.
Definition: power_state.hh:64
gem5::PowerDomain::pwrStateUpdateEvent
EventWrapper< PowerDomain, &PowerDomain::setFollowerPowerStates > pwrStateUpdateEvent
Event to update the power states of the followers.
Definition: power_domain.hh:155
gem5::PowerDomain::PowerDomainStats::PowerDomainStats
PowerDomainStats(PowerDomain &pd)
Definition: power_domain.cc:247
gem5::statistics::Group::regStats
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:69
gem5::PowerDomain::startup
void startup() override
During startup, the list of possible power states the PowerDomain can be in is populated,...
Definition: power_domain.cc:76
gem5::PowerDomain::updateLatency
const Tick updateLatency
Latency with which power state changes of the leaders will ripple through to the followers.
Definition: power_domain.hh:149
gem5::statistics::Group
Statistics container.
Definition: group.hh:93
gem5::PowerDomain::PowerDomainStats::numLeaderCalls
statistics::Scalar numLeaderCalls
Definition: power_domain.hh:164
trace.hh
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:225
gem5::PowerState::getPossibleStates
std::set< enums::PwrState > getPossibleStates() const
Return the power states this object can be in.
Definition: power_state.hh:114
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::PowerState::set
void set(enums::PwrState p)
Change the power state of this object to the power state p.
Definition: power_state.cc:96
gem5::PowerDomain::PowerDomainStats::regStats
void regStats() override
Callback to set stat parameters.
Definition: power_domain.cc:258
gem5::PowerState::_currState
enums::PwrState _currState
To keep track of the current power state.
Definition: power_state.hh:122

Generated on Tue Sep 21 2021 12:25:48 for gem5 by doxygen 1.8.17