2 * Copyright (c) 2010,2013,2015 ARM Limited
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.
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.
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.
40 #include "dev/arm/rv_ctrl.hh"
42 #include "base/trace.hh"
43 #include "debug/RVCTRL.hh"
44 #include "mem/packet.hh"
45 #include "mem/packet_access.hh"
46 #include "sim/power/thermal_model.hh"
47 #include "sim/system.hh"
48 #include "sim/voltage_domain.hh"
50 RealViewCtrl::RealViewCtrl(Params
*p
)
51 : BasicPioDevice(p
, 0xD4), flags(0), scData(0)
56 RealViewCtrl::read(PacketPtr pkt
)
58 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
59 assert(pkt
->getSize() == 4);
60 Addr daddr
= pkt
->getAddr() - pioAddr
;
64 pkt
->setLE(params()->proc_id0
);
67 pkt
->setLE(params()->proc_id1
);
71 clk
= SimClock::Float::MHz
* curTick() * 24;
72 pkt
->setLE((uint32_t)(clk
));
76 clk100
= SimClock::Float::MHz
* curTick() * 100;
77 pkt
->setLE((uint32_t)(clk100
));
80 pkt
->setLE
<uint32_t>(0);
83 pkt
->setLE
<uint32_t>(0x00001F00);
86 pkt
->setLE
<uint32_t>(0x00012C5C);
89 pkt
->setLE
<uint32_t>(0x00002CC0);
92 pkt
->setLE
<uint32_t>(0x00002C75);
95 pkt
->setLE
<uint32_t>(0x00020211);
98 pkt
->setLE
<uint32_t>(0x00002C75);
101 pkt
->setLE
<uint32_t>(sysLock
);
104 pkt
->setLE
<uint32_t>(flags
);
107 pkt
->setLE
<uint32_t>(params()->idreg
);
110 pkt
->setLE
<uint32_t>(1);
113 pkt
->setLE
<uint32_t>(scData
);
114 DPRINTF(RVCTRL
, "Read %#x from SCReg\n", scData
);
117 pkt
->setLE
<uint32_t>(0); // not busy
118 DPRINTF(RVCTRL
, "Read 0 from CfgCtrl\n");
121 warn("Tried to read RealView I/O at offset %#x that doesn't exist\n",
123 pkt
->setLE
<uint32_t>(0);
126 pkt
->makeAtomicResponse();
132 RealViewCtrl::write(PacketPtr pkt
)
134 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
136 Addr daddr
= pkt
->getAddr() - pioAddr
;
147 sysLock
.lockVal
= pkt
->getLE
<uint16_t>();
150 // Ignore writes to reset control
151 warn_once("Ignoring write to reset control\n");
154 flags
= pkt
->getLE
<uint32_t>();
160 scData
= pkt
->getLE
<uint32_t>();
163 // A request is being submitted to read/write the system control
165 // http://infocenter.arm.com/help/topic/com.arm.doc.dui0447h/CACDEFGH.html
166 CfgCtrlReg req
= pkt
->getLE
<uint32_t>();
168 DPRINTF(RVCTRL
, "SCReg: write %#x to ctrl but not starting\n",
173 auto it_dev(devices
.find(req
& CFG_CTRL_ADDR_MASK
));
174 if (it_dev
== devices
.end()) {
175 warn_once("SCReg: Access to unknown device "
176 "dcc%d:site%d:pos%d:fn%d:dev%d\n",
177 req
.dcc
, req
.site
, req
.pos
, req
.func
, req
.dev
);
181 // Service the request as a read or write depending on the
182 // wr bit in the control register.
183 Device
&dev(*it_dev
->second
);
185 DPRINTF(RVCTRL
, "SCReg: Writing %#x (ctrlWr %#x)\n",
191 DPRINTF(RVCTRL
, "SCReg: Reading %#x (ctrlRd %#x)\n",
195 case CfgStat
: // Weird to write this
197 warn("Tried to write RVIO at offset %#x (data %#x) that doesn't exist\n",
198 daddr
, pkt
->getLE
<uint32_t>());
201 pkt
->makeAtomicResponse();
206 RealViewCtrl::serialize(CheckpointOut
&cp
) const
208 SERIALIZE_SCALAR(flags
);
212 RealViewCtrl::unserialize(CheckpointIn
&cp
)
214 UNSERIALIZE_SCALAR(flags
);
218 RealViewCtrl::registerDevice(DeviceFunc func
, uint8_t site
, uint8_t pos
,
219 uint8_t dcc
, uint16_t dev
,
229 if (devices
.find(addr
) != devices
.end()) {
230 fatal("Platform device dcc%d:site%d:pos%d:fn%d:dev%d "
231 "already registered.",
232 addr
.dcc
, addr
.site
, addr
.pos
, addr
.func
, addr
.dev
);
235 devices
[addr
] = handler
;
239 RealViewOsc::RealViewOsc(RealViewOscParams
*p
)
240 : ClockDomain(p
, p
->voltage_domain
),
241 RealViewCtrl::Device(*p
->parent
, RealViewCtrl::FUNC_OSC
,
242 p
->site
, p
->position
, p
->dcc
, p
->device
)
244 if (SimClock::Float::s
/ p
->freq
> UINT32_MAX
) {
245 fatal("Oscillator frequency out of range: %f\n",
246 SimClock::Float::s
/ p
->freq
/ 1E6
);
249 _clockPeriod
= p
->freq
;
253 RealViewOsc::startup()
255 // Tell dependent object to set their clock frequency
256 for (auto m
: members
)
257 m
->updateClockPeriod();
261 RealViewOsc::serialize(CheckpointOut
&cp
) const
263 SERIALIZE_SCALAR(_clockPeriod
);
267 RealViewOsc::unserialize(CheckpointIn
&cp
)
269 UNSERIALIZE_SCALAR(_clockPeriod
);
273 RealViewOsc::clockPeriod(Tick clock_period
)
275 panic_if(clock_period
== 0, "%s has a clock period of zero\n", name());
277 // Align all members to the current tick
278 for (auto m
: members
)
279 m
->updateClockPeriod();
281 _clockPeriod
= clock_period
;
283 // inform any derived clocks they need to updated their period
284 for (auto m
: children
)
285 m
->updateClockPeriod();
289 RealViewOsc::read() const
291 const uint32_t freq(SimClock::Float::s
/ _clockPeriod
);
292 DPRINTF(RVCTRL
, "Reading OSC frequency: %f MHz\n", freq
/ 1E6
);
297 RealViewOsc::write(uint32_t freq
)
299 DPRINTF(RVCTRL
, "Setting new OSC frequency: %f MHz\n", freq
/ 1E6
);
300 clockPeriod(SimClock::Float::s
/ freq
);
304 RealViewTemperatureSensor::read() const
306 // Temperature reported in uC
307 ThermalModel
* tm
= system
->getThermalModel();
309 double t
= tm
->getTemp();
311 warn("Temperature below zero!\n");
312 return fmax(0, t
) * 1000000;
315 // Report a dummy 25 degrees temperature
320 RealViewCtrlParams::create()
322 return new RealViewCtrl(this);
326 RealViewOscParams::create()
328 return new RealViewOsc(this);
331 RealViewTemperatureSensor
*
332 RealViewTemperatureSensorParams::create()
334 return new RealViewTemperatureSensor(this);