gem5 v24.0.0.0
Loading...
Searching...
No Matches
timer_sp804.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 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
39
40#include <cassert>
41
42#include "base/intmath.hh"
43#include "base/logging.hh"
44#include "base/trace.hh"
45#include "debug/Checkpoint.hh"
46#include "debug/Timer.hh"
47#include "dev/arm/base_gic.hh"
48#include "mem/packet.hh"
49#include "mem/packet_access.hh"
50
51namespace gem5
52{
53
55 : AmbaPioDevice(p, 0x1000),
56 timer0(name() + ".timer0", this, p.int0->get(), p.clock0),
57 timer1(name() + ".timer1", this, p.int1->get(), p.clock1)
58{
59}
60
61Sp804::Timer::Timer(std::string __name, Sp804 *_parent,
62 ArmInterruptPin *_interrupt, Tick _clock)
63 : _name(__name), parent(_parent), interrupt(_interrupt),
64 clock(_clock), control(0x20),
65 rawInt(false), pendingInt(false), loadValue(0xffffffff),
66 zeroEvent([this]{ counterAtZero(); }, name())
67{
68}
69
70
71Tick
73{
74 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
75 assert(pkt->getSize() == 4);
76 Addr daddr = pkt->getAddr() - pioAddr;
77 DPRINTF(Timer, "Reading from DualTimer at offset: %#x\n", daddr);
78
79 if (daddr < Timer::Size)
80 timer0.read(pkt, daddr);
81 else if ((daddr - Timer::Size) < Timer::Size)
82 timer1.read(pkt, daddr - Timer::Size);
83 else if (!readId(pkt, ambaId, pioAddr))
84 panic("Tried to read SP804 at offset %#x that doesn't exist\n", daddr);
85 pkt->makeAtomicResponse();
86 return pioDelay;
87}
88
89
90void
92{
93 switch(daddr) {
94 case LoadReg:
95 pkt->setLE<uint32_t>(loadValue);
96 break;
97 case CurrentReg:
98 DPRINTF(Timer, "Event schedule for %d, clock=%d, prescale=%d\n",
99 zeroEvent.when(), clock, control.timerPrescale);
100 Tick time;
101 time = zeroEvent.when() - curTick();
102 time = (time / clock) >> (4 * control.timerPrescale);
103 DPRINTF(Timer, "-- returning counter at %d\n", time);
104 pkt->setLE<uint32_t>(time);
105 break;
106 case ControlReg:
107 pkt->setLE<uint32_t>(control);
108 break;
109 case RawISR:
110 pkt->setLE<uint32_t>(rawInt);
111 break;
112 case MaskedISR:
113 pkt->setLE<uint32_t>(pendingInt);
114 break;
115 case BGLoad:
116 pkt->setLE<uint32_t>(loadValue);
117 break;
118 default:
119 panic("Tried to read SP804 timer at offset %#x\n", daddr);
120 break;
121 }
122 DPRINTF(Timer, "Reading %#x from Timer at offset: %#x\n",
123 pkt->getLE<uint32_t>(), daddr);
124}
125
126Tick
128{
129 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
130 assert(pkt->getSize() == 4);
131 Addr daddr = pkt->getAddr() - pioAddr;
132 DPRINTF(Timer, "Writing to DualTimer at offset: %#x\n", daddr);
133
134 if (daddr < Timer::Size)
135 timer0.write(pkt, daddr);
136 else if ((daddr - Timer::Size) < Timer::Size)
137 timer1.write(pkt, daddr - Timer::Size);
138 else if (!readId(pkt, ambaId, pioAddr))
139 panic("Tried to write SP804 at offset %#x that doesn't exist\n", daddr);
140 pkt->makeAtomicResponse();
141 return pioDelay;
142}
143
144void
146{
147 DPRINTF(Timer, "Writing %#x to Timer at offset: %#x\n",
148 pkt->getLE<uint32_t>(), daddr);
149 switch (daddr) {
150 case LoadReg:
151 loadValue = pkt->getLE<uint32_t>();
152 restartCounter(loadValue);
153 break;
154 case CurrentReg:
155 // Spec says this value can't be written, but linux writes it anyway
156 break;
157 case ControlReg:
158 bool old_enable;
159 old_enable = control.timerEnable;
160 control = pkt->getLE<uint32_t>();
161 if ((old_enable == 0) && control.timerEnable)
162 restartCounter(loadValue);
163 break;
164 case IntClear:
165 rawInt = false;
166 if (pendingInt) {
167 pendingInt = false;
168 DPRINTF(Timer, "Clearing interrupt\n");
169 interrupt->clear();
170 }
171 break;
172 case BGLoad:
173 loadValue = pkt->getLE<uint32_t>();
174 break;
175 default:
176 panic("Tried to write SP804 timer at offset %#x\n", daddr);
177 break;
178 }
179}
180
181void
183{
184 DPRINTF(Timer, "Resetting counter with value %#x\n", val);
185 if (!control.timerEnable)
186 return;
187
188 Tick time = clock << (4 * control.timerPrescale);
189 if (control.timerSize)
190 time *= val;
191 else
192 time *= bits(val,15,0);
193
194 if (zeroEvent.scheduled()) {
195 DPRINTF(Timer, "-- Event was already schedule, de-scheduling\n");
196 parent->deschedule(zeroEvent);
197 }
198 parent->schedule(zeroEvent, curTick() + time);
199 DPRINTF(Timer, "-- Scheduling new event for: %d\n", curTick() + time);
200}
201
202void
204{
205 if (!control.timerEnable)
206 return;
207
208 DPRINTF(Timer, "Counter reached zero\n");
209
210 rawInt = true;
211 bool old_pending = pendingInt;
212 if (control.intEnable)
213 pendingInt = true;
214 if (pendingInt && !old_pending) {
215 DPRINTF(Timer, "-- Causing interrupt\n");
216 interrupt->raise();
217 }
218
219 if (control.oneShot)
220 return;
221
222 // Free-running
223 if (control.timerMode == 0)
224 restartCounter(0xffffffff);
225 else
226 restartCounter(loadValue);
227}
228
229void
231{
232 DPRINTF(Checkpoint, "Serializing Arm Sp804\n");
233
234 uint32_t control_serial = control;
235 SERIALIZE_SCALAR(control_serial);
236
237 SERIALIZE_SCALAR(rawInt);
238 SERIALIZE_SCALAR(pendingInt);
239 SERIALIZE_SCALAR(loadValue);
240
241 bool is_in_event = zeroEvent.scheduled();
242 SERIALIZE_SCALAR(is_in_event);
243
244 Tick event_time;
245 if (is_in_event){
246 event_time = zeroEvent.when();
247 SERIALIZE_SCALAR(event_time);
248 }
249}
250
251void
253{
254 DPRINTF(Checkpoint, "Unserializing Arm Sp804\n");
255
256 uint32_t control_serial;
257 UNSERIALIZE_SCALAR(control_serial);
258 control = control_serial;
259
260 UNSERIALIZE_SCALAR(rawInt);
261 UNSERIALIZE_SCALAR(pendingInt);
262 UNSERIALIZE_SCALAR(loadValue);
263
264 bool is_in_event;
265 UNSERIALIZE_SCALAR(is_in_event);
266
267 Tick event_time;
268 if (is_in_event){
269 UNSERIALIZE_SCALAR(event_time);
270 parent->schedule(zeroEvent, event_time);
271 }
272}
273
274
275
276void
278{
279 timer0.serializeSection(cp, "timer0");
280 timer1.serializeSection(cp, "timer1");
281}
282
283void
285{
286 timer0.unserializeSection(cp, "timer0");
287 timer1.unserializeSection(cp, "timer1");
288}
289
290} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
Base class for ARM GIC implementations.
bool readId(PacketPtr pkt, uint64_t amba_id, Addr pio_addr)
Generic representation of an Arm interrupt pin.
Definition base_gic.hh:200
Addr pioAddr
Address that the device listens to.
Definition io_device.hh:151
Tick pioDelay
Delay that the device experinces on an access.
Definition io_device.hh:157
Addr pioSize
Size that the device's address range.
Definition io_device.hh:154
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
Addr getAddr() const
Definition packet.hh:807
void setLE(T v)
Set the value in the data pointer to v as little endian.
unsigned getSize() const
Definition packet.hh:817
void makeAtomicResponse()
Definition packet.hh:1074
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Timer(std::string __name, Sp804 *parent, ArmInterruptPin *_interrupt, Tick clock)
void counterAtZero()
Called when the counter reaches 0.
void restartCounter(uint32_t val)
Restart the counter ticking at val.
void serialize(CheckpointOut &cp) const override
Serialize an object.
void write(PacketPtr pkt, Addr daddr)
Handle write for a single timer.
void read(PacketPtr pkt, Addr daddr)
Handle read for a single timer.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Bitfield< 3, 2 > timerPrescale
Sp804Params Params
void serialize(CheckpointOut &cp) const override
Serialize an object.
Timer timer0
Timers that do the actual work.
Sp804(const Params &p)
The constructor for RealView just registers itself with the MMU.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Tick read(PacketPtr pkt) override
Handle a read to the device.
Tick write(PacketPtr pkt) override
All writes are simply ignored.
bool int1
Definition common.h:43
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition serialize.cc:74
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition serialize.cc:81
Bitfield< 0 > p
Bitfield< 63 > val
Definition misc.hh:804
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
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint64_t Tick
Tick count type.
Definition types.hh:58
Declaration of the Packet class.
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
This implements the dual Sp804 timer block.
const std::string & name()
Definition trace.cc:48

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