gem5  v21.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
energy_ctrl.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2014 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 "dev/arm/energy_ctrl.hh"
39 
40 #include "base/trace.hh"
41 #include "debug/EnergyCtrl.hh"
42 #include "mem/packet.hh"
43 #include "mem/packet_access.hh"
44 #include "params/EnergyCtrl.hh"
45 #include "sim/dvfs_handler.hh"
46 #include "sim/serialize.hh"
47 
49  : BasicPioDevice(p, PIO_NUM_FIELDS * 4), // each field is 32 bit
50  dvfsHandler(p.dvfs_handler),
51  domainID(0),
52  domainIDIndexToRead(0),
53  perfLevelAck(0),
54  perfLevelToRead(0),
55  updateAckEvent([this]{ updatePLAck(); }, name())
56 {
57  fatal_if(!p.dvfs_handler, "EnergyCtrl: Needs a DVFSHandler for a "
58  "functioning system.\n");
59 }
60 
61 Tick
63 {
64  assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
65  assert(pkt->getSize() == 4);
66 
67  Addr daddr = pkt->getAddr() - pioAddr;
68  assert((daddr & 3) == 0);
69  Registers reg = Registers(daddr / 4);
70 
71  if (!dvfsHandler->isEnabled()) {
72  // NB: Zero is a good response if the handler is disabled
73  pkt->setLE<uint32_t>(0);
74  warn_once("EnergyCtrl: Disabled handler, ignoring read from reg %i\n",
75  reg);
76  DPRINTF(EnergyCtrl, "dvfs handler disabled, return 0 for read from "\
77  "reg %i\n", reg);
78  pkt->makeAtomicResponse();
79  return pioDelay;
80  }
81 
82  uint32_t result = 0;
83  Tick period;
84  double voltage;
85 
86  switch(reg) {
88  result = 1;
89  DPRINTF(EnergyCtrl, "dvfs handler enabled\n");
90  break;
91  case DVFS_NUM_DOMAINS:
92  result = dvfsHandler->numDomains();
93  DPRINTF(EnergyCtrl, "reading number of domains %d\n", result);
94  break;
97  DPRINTF(EnergyCtrl, "reading domain id at index %d as %d\n",
98  domainIDIndexToRead, result);
99  break;
101  // Return transition latency in nanoseconds
103  DPRINTF(EnergyCtrl, "reading dvfs handler trans latency %d ns\n",
104  result);
105  break;
106  case DOMAIN_ID:
107  result = domainID;
108  DPRINTF(EnergyCtrl, "reading domain id:%d\n", result);
109  break;
110  case PERF_LEVEL:
111  result = dvfsHandler->perfLevel(domainID);
112  DPRINTF(EnergyCtrl, "reading domain %d perf level: %d\n",
113  domainID, result);
114  break;
115  case PERF_LEVEL_ACK:
116  result = perfLevelAck;
117  DPRINTF(EnergyCtrl, "reading ack:%d\n", result);
118  // Signal is set for a single read only
119  if (result == 1)
120  perfLevelAck = 0;
121  break;
122  case NUM_OF_PERF_LEVELS:
124  DPRINTF(EnergyCtrl, "reading num of perf level:%d\n", result);
125  break;
126  case FREQ_AT_PERF_LEVEL:
128  result = ticksTokHz(period);
129  DPRINTF(EnergyCtrl, "reading freq %d KHz at perf level: %d\n",
130  result, perfLevelToRead);
131  break;
132  case VOLT_AT_PERF_LEVEL:
134  result = toMicroVolt(voltage);
135  DPRINTF(EnergyCtrl, "reading voltage %d u-volt at perf level: %d\n",
136  result, perfLevelToRead);
137  break;
138  default:
139  panic("Tried to read EnergyCtrl at offset %#x / reg %i\n", daddr,
140  reg);
141  }
142  pkt->setLE<uint32_t>(result);
143  pkt->makeAtomicResponse();
144  return pioDelay;
145 }
146 
147 Tick
149 {
150  assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
151  assert(pkt->getSize() == 4);
152 
153  uint32_t data;
154  data = pkt->getLE<uint32_t>();
155 
156  Addr daddr = pkt->getAddr() - pioAddr;
157  assert((daddr & 3) == 0);
158  Registers reg = Registers(daddr / 4);
159 
160  if (!dvfsHandler->isEnabled()) {
161  // Ignore writes to a disabled controller
162  warn_once("EnergyCtrl: Disabled handler, ignoring write %u to "\
163  "reg %i\n", data, reg);
164  DPRINTF(EnergyCtrl, "dvfs handler disabled, ignoring write %u to "\
165  "reg %i\n", data, reg);
166  pkt->makeAtomicResponse();
167  return pioDelay;
168  }
169 
170  switch(reg) {
173  DPRINTF(EnergyCtrl, "writing domain id index:%d\n",
175  break;
176  case DOMAIN_ID:
177  // Extra check to ensure that a valid domain ID is being queried
179  domainID = data;
180  DPRINTF(EnergyCtrl, "writing domain id:%d\n", domainID);
181  } else {
182  DPRINTF(EnergyCtrl, "invalid domain id:%d\n", domainID);
183  }
184  break;
185  case PERF_LEVEL:
187  if (updateAckEvent.scheduled()) {
188  // The OS driver is trying to change the perf level while
189  // another change is in flight. This is fine, but only a
190  // single acknowledgment will be sent.
191  DPRINTF(EnergyCtrl, "descheduling previous pending ack "\
192  "event\n");
194  }
196  DPRINTF(EnergyCtrl, "writing domain %d perf level: %d\n",
197  domainID, data);
198  } else {
199  DPRINTF(EnergyCtrl, "invalid / ineffective perf level:%d for "\
200  "domain:%d\n", data, domainID);
201  }
202  break;
203  case PERF_LEVEL_TO_READ:
205  DPRINTF(EnergyCtrl, "writing perf level to read opp at: %d\n",
206  data);
207  break;
208  default:
209  panic("Tried to write EnergyCtrl at offset %#x\n", daddr);
210  break;
211  }
212 
213  pkt->makeAtomicResponse();
214  return pioDelay;
215 }
216 
217 void
219 {
224 
225  Tick next_event = updateAckEvent.scheduled() ? updateAckEvent.when() : 0;
226  SERIALIZE_SCALAR(next_event);
227 }
228 
229 void
231 {
236  Tick next_event = 0;
237  UNSERIALIZE_SCALAR(next_event);
238 
239  // restore scheduled events
240  if (next_event != 0) {
241  schedule(updateAckEvent, next_event);
242  }
243 }
244 
245 void
247 {
248  if (!dvfsHandler->isEnabled()) {
249  warn("Existing EnergyCtrl, but no enabled DVFSHandler found.\n");
250  }
251 }
252 
253 void
255 {
257 }
EnergyCtrl::FREQ_AT_PERF_LEVEL
@ FREQ_AT_PERF_LEVEL
Definition: energy_ctrl.hh:110
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:462
Packet::makeAtomicResponse
void makeAtomicResponse()
Definition: packet.hh:1017
BasicPioDevice::pioAddr
Addr pioAddr
Address that the device listens to.
Definition: io_device.hh:148
SimClock::Int::ns
Tick ns
nanosecond
Definition: core.cc:62
warn
#define warn(...)
Definition: logging.hh:239
EnergyCtrl::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: energy_ctrl.cc:254
DVFSHandler::numPerfLevels
PerfLevel numPerfLevels(PerfLevel domain_id) const
Get the total number of available performance levels.
Definition: dvfs_handler.hh:165
data
const char data[]
Definition: circlebuf.test.cc:47
serialize.hh
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:591
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:755
PioDevice::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: io_device.cc:56
warn_once
#define warn_once(...)
Definition: logging.hh:243
EnergyCtrl::perfLevelToRead
uint32_t perfLevelToRead
Definition: energy_ctrl.hh:163
EnergyCtrl::DVFS_NUM_DOMAINS
@ DVFS_NUM_DOMAINS
Definition: energy_ctrl.hh:102
EnergyCtrl::EnergyCtrl
EnergyCtrl(const Params &p)
Definition: energy_ctrl.cc:48
Clocked::voltage
double voltage() const
Definition: clocked_object.hh:216
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:59
EnergyCtrl::DVFS_HANDLER_STATUS
@ DVFS_HANDLER_STATUS
Definition: energy_ctrl.hh:101
DVFSHandler::voltageAtPerfLevel
double voltageAtPerfLevel(DomainID domain_id, PerfLevel perf_level) const
Read the voltage of the specified domain at the specified performance level.
Definition: dvfs_handler.cc:170
EnergyCtrl::ticksTokHz
static uint32_t ticksTokHz(Tick period)
Definition: energy_ctrl.hh:165
EventManager::deschedule
void deschedule(Event &event)
Definition: eventq.hh:1025
Packet::getSize
unsigned getSize() const
Definition: packet.hh:765
EnergyCtrl::read
Tick read(PacketPtr pkt) override
Read command sent to the device.
Definition: energy_ctrl.cc:62
DVFSHandler::validDomainID
bool validDomainID(DomainID domain_id) const
Check whether a domain ID is known to the handler or not.
Definition: dvfs_handler.cc:102
EnergyCtrl::DOMAIN_ID
@ DOMAIN_ID
Definition: energy_ctrl.hh:105
DVFSHandler::isEnabled
bool isEnabled() const
Check enable status of the DVFS handler, when the handler is disabled, no request should be sent to t...
Definition: dvfs_handler.hh:175
Event::when
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:505
X86ISA::reg
Bitfield< 5, 3 > reg
Definition: types.hh:88
DVFSHandler::clkPeriodAtPerfLevel
Tick clkPeriodAtPerfLevel(DomainID domain_id, PerfLevel perf_level) const
Read the clock period of the specified domain at the specified performance level.
Definition: dvfs_handler.hh:135
packet.hh
EnergyCtrl::PERF_LEVEL
@ PERF_LEVEL
Definition: energy_ctrl.hh:106
EnergyCtrl::updateAckEvent
EventFunctionWrapper updateAckEvent
Definition: energy_ctrl.hh:181
cp
Definition: cprintf.cc:37
EnergyCtrl::startup
void startup() override
startup() is the final initialization call before simulation.
Definition: energy_ctrl.cc:246
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1016
EnergyCtrl::PERF_LEVEL_TO_READ
@ PERF_LEVEL_TO_READ
Definition: energy_ctrl.hh:109
EnergyCtrl::Params
EnergyCtrlParams Params
Definition: energy_ctrl.hh:115
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
DVFSHandler::numDomains
uint32_t numDomains() const
Get the number of domains assigned to this DVFS handler.
Definition: dvfs_handler.hh:84
DVFSHandler::domainID
DomainID domainID(uint32_t index) const
Get the n-th domain ID, from the domains managed by this handler.
Definition: dvfs_handler.cc:91
EnergyCtrl::NUM_OF_PERF_LEVELS
@ NUM_OF_PERF_LEVELS
Definition: energy_ctrl.hh:108
EnergyCtrl::updatePLAck
void updatePLAck()
Update the acknowledgment that is read back by the software to confirm newly requested performance le...
Definition: energy_ctrl.hh:177
EnergyCtrl
Definition: energy_ctrl.hh:61
BasicPioDevice::pioSize
Addr pioSize
Size that the device's address range.
Definition: io_device.hh:151
EnergyCtrl::perfLevelAck
uint32_t perfLevelAck
Acknowledgment (PERF_LEVEL_ACK) RO register, software polls this register to read back the status of ...
Definition: energy_ctrl.hh:161
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:148
DVFSHandler::transLatency
Tick transLatency() const
Get transition latency to switch between performance levels.
Definition: dvfs_handler.hh:103
name
const std::string & name()
Definition: trace.cc:48
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:584
energy_ctrl.hh
packet_access.hh
EnergyCtrl::toMicroVolt
static uint32_t toMicroVolt(double voltage)
Definition: energy_ctrl.hh:169
Packet::getLE
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Definition: packet_access.hh:75
EnergyCtrl::Registers
Registers
Definition: energy_ctrl.hh:100
EnergyCtrl::write
Tick write(PacketPtr pkt) override
Write command sent to the device.
Definition: energy_ctrl.cc:148
dvfs_handler.hh
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:258
BasicPioDevice
Definition: io_device.hh:144
EnergyCtrl::DVFS_HANDLER_TRANS_LATENCY
@ DVFS_HANDLER_TRANS_LATENCY
Definition: energy_ctrl.hh:104
EnergyCtrl::domainIDIndexToRead
uint32_t domainIDIndexToRead
Index for getting the domain ID from the domain ID list available with the DVFS handler.
Definition: energy_ctrl.hh:150
BasicPioDevice::pioDelay
Tick pioDelay
Delay that the device experinces on an access.
Definition: io_device.hh:154
Packet::setLE
void setLE(T v)
Set the value in the data pointer to v as little endian.
Definition: packet_access.hh:105
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:64
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
trace.hh
EnergyCtrl::domainID
uint32_t domainID
Cluster ID (DOMAIN_ID) R/W register, programmed to ID of the domain for which the set/get performance...
Definition: energy_ctrl.hh:144
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
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:219
CheckpointIn
Definition: serialize.hh:68
EnergyCtrl::VOLT_AT_PERF_LEVEL
@ VOLT_AT_PERF_LEVEL
Definition: energy_ctrl.hh:111
EnergyCtrl::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: energy_ctrl.cc:218
EnergyCtrl::PERF_LEVEL_ACK
@ PERF_LEVEL_ACK
Definition: energy_ctrl.hh:107
EnergyCtrl::dvfsHandler
DVFSHandler * dvfsHandler
Definition: energy_ctrl.hh:138
EnergyCtrl::DVFS_DOMAINID_AT_INDEX
@ DVFS_DOMAINID_AT_INDEX
Definition: energy_ctrl.hh:103
DVFSHandler::perfLevel
bool perfLevel(DomainID domain_id, PerfLevel perf_level)
Set a new performance level for the specified domain.
Definition: dvfs_handler.cc:115
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
EnergyCtrl::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: energy_ctrl.cc:230

Generated on Tue Mar 23 2021 19:41:25 for gem5 by doxygen 1.8.17