gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
45namespace gem5
46{
47
48PowerDomain::PowerDomain(const PowerDomainParams &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
68void
70{
71 DPRINTF(PowerDomain, "%s is a follower in %s\n", pwr_obj->name(), name());
72 followers.push_back(pwr_obj);
73}
74
75void
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
122bool
123PowerDomain::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
136void
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
149enums::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
184void
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
213void
214PowerDomain::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
257void
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:210
virtual std::string name() const
Definition named.hh:47
The PowerDomain groups PowerState objects together to regulate their power states.
PowerDomain(const PowerDomainParams &p)
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,...
void addFollower(PowerState *pwr_obj) override
Function called by a follower to register itself as a dependant of this power domain.
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
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.
MemberEventWrapper<&PowerDomain::setFollowerPowerStates > pwrStateUpdateEvent
Event to update the power states of the followers.
Helper class for objects that have power states.
enums::PwrState _currState
To keep track of the current power state.
std::set< enums::PwrState > possibleStates
The possible power states this object can be in.
Statistics container.
Definition group.hh:93
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:1012
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
virtual void regStats()
Callback to set stat parameters.
Definition group.cc:68
Bitfield< 12, 11 > set
Bitfield< 0 > p
const FlagsType nozero
Don't print if this is zero.
Definition info.hh:67
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
void regStats() override
Callback to set stat parameters.
statistics::Scalar numLeaderCallsChangingState

Generated on Tue Jun 18 2024 16:24:06 for gem5 by doxygen 1.11.0