gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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  * Authors: Vasileios Spiliopoulos
38  * Akash Bagdia
39  * Stephan Diestelhorst
40  */
41 
42 #include "dev/arm/energy_ctrl.hh"
43 
44 #include "debug/EnergyCtrl.hh"
45 #include "mem/packet.hh"
46 #include "mem/packet_access.hh"
47 #include "params/EnergyCtrl.hh"
48 #include "sim/dvfs_handler.hh"
49 
51  : BasicPioDevice(p, PIO_NUM_FIELDS * 4), // each field is 32 bit
52  dvfsHandler(p->dvfs_handler),
53  domainID(0),
54  domainIDIndexToRead(0),
55  perfLevelAck(0),
56  perfLevelToRead(0),
57  updateAckEvent(this)
58 {
59  fatal_if(!p->dvfs_handler, "EnergyCtrl: Needs a DVFSHandler for a "
60  "functioning system.\n");
61 }
62 
63 Tick
65 {
66  assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
67  assert(pkt->getSize() == 4);
68 
69  Addr daddr = pkt->getAddr() - pioAddr;
70  assert((daddr & 3) == 0);
71  Registers reg = Registers(daddr / 4);
72 
73  if (!dvfsHandler->isEnabled()) {
74  // NB: Zero is a good response if the handler is disabled
75  pkt->set<uint32_t>(0);
76  warn_once("EnergyCtrl: Disabled handler, ignoring read from reg %i\n",
77  reg);
78  DPRINTF(EnergyCtrl, "dvfs handler disabled, return 0 for read from "\
79  "reg %i\n", reg);
80  pkt->makeAtomicResponse();
81  return pioDelay;
82  }
83 
84  uint32_t result = 0;
85  Tick period;
86  double voltage;
87 
88  switch(reg) {
90  result = 1;
91  DPRINTF(EnergyCtrl, "dvfs handler enabled\n");
92  break;
93  case DVFS_NUM_DOMAINS:
94  result = dvfsHandler->numDomains();
95  DPRINTF(EnergyCtrl, "reading number of domains %d\n", result);
96  break;
99  DPRINTF(EnergyCtrl, "reading domain id at index %d as %d\n",
100  domainIDIndexToRead, result);
101  break;
103  // Return transition latency in nanoseconds
105  DPRINTF(EnergyCtrl, "reading dvfs handler trans latency %d ns\n",
106  result);
107  break;
108  case DOMAIN_ID:
109  result = domainID;
110  DPRINTF(EnergyCtrl, "reading domain id:%d\n", result);
111  break;
112  case PERF_LEVEL:
113  result = dvfsHandler->perfLevel(domainID);
114  DPRINTF(EnergyCtrl, "reading domain %d perf level: %d\n",
115  domainID, result);
116  break;
117  case PERF_LEVEL_ACK:
118  result = perfLevelAck;
119  DPRINTF(EnergyCtrl, "reading ack:%d\n", result);
120  // Signal is set for a single read only
121  if (result == 1)
122  perfLevelAck = 0;
123  break;
124  case NUM_OF_PERF_LEVELS:
126  DPRINTF(EnergyCtrl, "reading num of perf level:%d\n", result);
127  break;
128  case FREQ_AT_PERF_LEVEL:
130  result = ticksTokHz(period);
131  DPRINTF(EnergyCtrl, "reading freq %d KHz at perf level: %d\n",
132  result, perfLevelToRead);
133  break;
134  case VOLT_AT_PERF_LEVEL:
136  result = toMicroVolt(voltage);
137  DPRINTF(EnergyCtrl, "reading voltage %d u-volt at perf level: %d\n",
138  result, perfLevelToRead);
139  break;
140  default:
141  panic("Tried to read EnergyCtrl at offset %#x / reg %i\n", daddr,
142  reg);
143  }
144  pkt->set<uint32_t>(result);
145  pkt->makeAtomicResponse();
146  return pioDelay;
147 }
148 
149 Tick
151 {
152  assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
153  assert(pkt->getSize() == 4);
154 
155  uint32_t data;
156  data = pkt->get<uint32_t>();
157 
158  Addr daddr = pkt->getAddr() - pioAddr;
159  assert((daddr & 3) == 0);
160  Registers reg = Registers(daddr / 4);
161 
162  if (!dvfsHandler->isEnabled()) {
163  // Ignore writes to a disabled controller
164  warn_once("EnergyCtrl: Disabled handler, ignoring write %u to "\
165  "reg %i\n", data, reg);
166  DPRINTF(EnergyCtrl, "dvfs handler disabled, ignoring write %u to "\
167  "reg %i\n", data, reg);
168  pkt->makeAtomicResponse();
169  return pioDelay;
170  }
171 
172  switch(reg) {
175  DPRINTF(EnergyCtrl, "writing domain id index:%d\n",
177  break;
178  case DOMAIN_ID:
179  // Extra check to ensure that a valid domain ID is being queried
180  if (dvfsHandler->validDomainID(data)) {
181  domainID = data;
182  DPRINTF(EnergyCtrl, "writing domain id:%d\n", domainID);
183  } else {
184  DPRINTF(EnergyCtrl, "invalid domain id:%d\n", domainID);
185  }
186  break;
187  case PERF_LEVEL:
188  if (dvfsHandler->perfLevel(domainID, data)) {
189  if (updateAckEvent.scheduled()) {
190  // The OS driver is trying to change the perf level while
191  // another change is in flight. This is fine, but only a
192  // single acknowledgment will be sent.
193  DPRINTF(EnergyCtrl, "descheduling previous pending ack "\
194  "event\n");
196  }
198  DPRINTF(EnergyCtrl, "writing domain %d perf level: %d\n",
199  domainID, data);
200  } else {
201  DPRINTF(EnergyCtrl, "invalid / ineffective perf level:%d for "\
202  "domain:%d\n", data, domainID);
203  }
204  break;
205  case PERF_LEVEL_TO_READ:
207  DPRINTF(EnergyCtrl, "writing perf level to read opp at: %d\n",
208  data);
209  break;
210  default:
211  panic("Tried to write EnergyCtrl at offset %#x\n", daddr);
212  break;
213  }
214 
215  pkt->makeAtomicResponse();
216  return pioDelay;
217 }
218 
219 void
221 {
226 
227  Tick next_event = updateAckEvent.scheduled() ? updateAckEvent.when() : 0;
228  SERIALIZE_SCALAR(next_event);
229 }
230 
231 void
233 {
238  Tick next_event = 0;
239  UNSERIALIZE_SCALAR(next_event);
240 
241  // restore scheduled events
242  if (next_event != 0) {
243  schedule(updateAckEvent, next_event);
244  }
245 }
246 
247 EnergyCtrl * EnergyCtrlParams::create()
248 {
249  return new EnergyCtrl(this);
250 }
251 
252 void
254 {
255  if (!dvfsHandler->isEnabled()) {
256  warn("Existing EnergyCtrl, but no enabled DVFSHandler found.\n");
257  }
258 }
259 
260 void
262 {
264 }
#define DPRINTF(x,...)
Definition: trace.hh:212
bool perfLevel(DomainID domain_id, PerfLevel perf_level)
Set a new performance level for the specified domain.
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
Bitfield< 5, 3 > reg
Definition: types.hh:89
#define panic(...)
Definition: misc.hh:153
uint32_t perfLevelAck
Acknowledgment (PERF_LEVEL_ACK) RO register, software polls this register to read back the status of ...
Definition: energy_ctrl.hh:165
Tick write(PacketPtr pkt) override
Write command sent to the device.
Definition: energy_ctrl.cc:150
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:381
static uint32_t toMicroVolt(double voltage)
Definition: energy_ctrl.hh:173
#define warn_once(...)
Definition: misc.hh:226
bool validDomainID(DomainID domain_id) const
Check whether a domain ID is known to the handler or not.
Tick clkPeriodAtPerfLevel(DomainID domain_id, PerfLevel perf_level) const
Read the clock period of the specified domain at the specified performance level. ...
Registers
Discovery flows:
Definition: energy_ctrl.hh:104
bool isEnabled() const
Check enable status of the DVFS handler, when the handler is disabled, no request should be sent to t...
void deschedule(Event &event)
Definition: eventq.hh:734
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
uint32_t domainIDIndexToRead
Index for getting the domain ID from the domain ID list available with the DVFS handler.
Definition: energy_ctrl.hh:154
const char data[]
Definition: circlebuf.cc:43
#define warn(...)
Definition: misc.hh:219
DVFSHandler * dvfsHandler
Definition: energy_ctrl.hh:142
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
EnergyCtrl(const Params *p)
Definition: energy_ctrl.cc:50
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:148
Tick curTick()
The current simulated tick.
Definition: core.hh:47
EventWrapper< EnergyCtrl,&EnergyCtrl::updatePLAck > updateAckEvent
Definition: energy_ctrl.hh:185
Tick transLatency() const
Get transition latency to switch between performance levels.
Addr pioSize
Size that the device's address range.
Definition: io_device.hh:142
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:397
void makeAtomicResponse()
Definition: packet.hh:857
double voltage() const
uint64_t Tick
Tick count type.
Definition: types.hh:63
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: energy_ctrl.cc:220
PerfLevel numPerfLevels(PerfLevel domain_id) const
Get the total number of available performance levels.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: energy_ctrl.cc:232
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: energy_ctrl.cc:261
DVFSHandler and DomainConfig class declaration used for managing voltage and frequency scaling of the...
double voltageAtPerfLevel(DomainID domain_id, PerfLevel perf_level) const
Read the voltage of the specified domain at the specified performance level.
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
uint32_t numDomains() const
Get the number of domains assigned to this DVFS handler.
Definition: dvfs_handler.hh:84
uint32_t perfLevelToRead
Definition: energy_ctrl.hh:167
static uint32_t ticksTokHz(Tick period)
Definition: energy_ctrl.hh:169
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: io_device.cc:83
Declaration of the Packet class.
std::ostream CheckpointOut
Definition: serialize.hh:67
The energy controller is a device being used to manage power and energy related control operations wi...
Tick pioDelay
Delay that the device experinces on an access.
Definition: io_device.hh:145
void schedule(Event &event, Tick when)
Definition: eventq.hh:728
Tick read(PacketPtr pkt) override
Read command sent to the device.
Definition: energy_ctrl.cc:64
Tick ns
nanosecond
Definition: core.cc:66
void startup() override
startup() is the final initialization call before simulation.
Definition: energy_ctrl.cc:253
DomainID domainID(uint32_t index) const
Get the n-th domain ID, from the domains managed by this handler.
Definition: dvfs_handler.cc:97
unsigned getSize() const
Definition: packet.hh:649
fatal_if(p->js_features.size() > 16,"Too many job slot feature registers specified (%i)\n", p->js_features.size())
EnergyCtrlParams Params
Definition: energy_ctrl.hh:119
Bitfield< 0 > p
Addr pioAddr
Address that the device listens to.
Definition: io_device.hh:139
Addr getAddr() const
Definition: packet.hh:639

Generated on Fri Jun 9 2017 13:03:45 for gem5 by doxygen 1.8.6