gem5  v20.1.0.0
rtc_pl031.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2012 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/rtc_pl031.hh"
39 
40 #include "base/intmath.hh"
41 #include "base/time.hh"
42 #include "base/trace.hh"
43 #include "debug/Checkpoint.hh"
44 #include "debug/Timer.hh"
45 #include "dev/arm/amba_device.hh"
46 #include "mem/packet.hh"
47 #include "mem/packet_access.hh"
48 
50  : AmbaIntDevice(p, 0x1000), timeVal(mkutctime(&p->time)),
51  lastWrittenTick(0), loadVal(0), matchVal(0),
52  rawInt(false), maskInt(false), pendingInt(false),
53  matchEvent([this]{ counterMatch(); }, name())
54 {
55 }
56 
57 
58 Tick
60 {
61  assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
62  assert(pkt->getSize() == 4);
63  Addr daddr = pkt->getAddr() - pioAddr;
64  uint32_t data;
65 
66  DPRINTF(Timer, "Reading from RTC at offset: %#x\n", daddr);
67 
68  switch (daddr) {
69  case DataReg:
71  break;
72  case MatchReg:
73  data = matchVal;
74  break;
75  case LoadReg:
76  data = loadVal;
77  break;
78  case ControlReg:
79  data = 1; // Always enabled otherwise there is no point
80  break;
81  case IntMask:
82  data = maskInt;
83  break;
84  case RawISR:
85  data = rawInt;
86  break;
87  case MaskedISR:
88  data = pendingInt;
89  break;
90  default:
91  if (readId(pkt, ambaId, pioAddr)) {
92  // Hack for variable sized access
93  data = pkt->getUintX(ByteOrder::little);
94  break;
95  }
96  panic("Tried to read PL031 at offset %#x that doesn't exist\n", daddr);
97  break;
98  }
99 
100  switch(pkt->getSize()) {
101  case 1:
102  pkt->setLE<uint8_t>(data);
103  break;
104  case 2:
105  pkt->setLE<uint16_t>(data);
106  break;
107  case 4:
108  pkt->setLE<uint32_t>(data);
109  break;
110  default:
111  panic("Uart read size too big?\n");
112  break;
113  }
114 
115 
116  pkt->makeAtomicResponse();
117  return pioDelay;
118 }
119 
120 Tick
122 {
123  assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
124  assert(pkt->getSize() == 4);
125  Addr daddr = pkt->getAddr() - pioAddr;
126  DPRINTF(Timer, "Writing to RTC at offset: %#x\n", daddr);
127 
128  switch (daddr) {
129  case DataReg:
130  break;
131  case MatchReg:
132  matchVal = pkt->getLE<uint32_t>();
133  resyncMatch();
134  break;
135  case LoadReg:
137  timeVal = pkt->getLE<uint32_t>();
138  loadVal = timeVal;
139  resyncMatch();
140  break;
141  case ControlReg:
142  break; // Can't stop when started
143  case IntMask:
144  maskInt = pkt->getLE<uint32_t>();
145  break;
146  case IntClear:
147  if (pkt->getLE<uint32_t>()) {
148  rawInt = false;
149  pendingInt = false;
150  }
151  break;
152  default:
153  if (readId(pkt, ambaId, pioAddr))
154  break;
155  panic("Tried to read PL031 at offset %#x that doesn't exist\n", daddr);
156  break;
157  }
158 
159  pkt->makeAtomicResponse();
160  return pioDelay;
161 }
162 
163 void
165 {
166  DPRINTF(Timer, "Setting up new match event match=%d time=%d\n", matchVal,
167  timeVal);
168 
169  uint32_t seconds_until = matchVal - timeVal;
170  Tick ticks_until = SimClock::Int::s * seconds_until;
171 
172  if (matchEvent.scheduled()) {
173  DPRINTF(Timer, "-- Event was already schedule, de-scheduling\n");
175  }
176  schedule(matchEvent, curTick() + ticks_until);
177  DPRINTF(Timer, "-- Scheduling new event for: %d\n", curTick() + ticks_until);
178 }
179 
180 void
182 {
183  DPRINTF(Timer, "Counter reached zero\n");
184 
185  rawInt = true;
186  bool old_pending = pendingInt;
188  if (pendingInt && !old_pending) {
189  DPRINTF(Timer, "-- Causing interrupt\n");
190  interrupt->raise();
191  }
192 }
193 
194 void
196 {
197  DPRINTF(Checkpoint, "Serializing Arm PL031\n");
205 
206  bool is_in_event = matchEvent.scheduled();
207  SERIALIZE_SCALAR(is_in_event);
208 
209  Tick event_time;
210  if (is_in_event){
211  event_time = matchEvent.when();
212  SERIALIZE_SCALAR(event_time);
213  }
214 }
215 
216 void
218 {
219  DPRINTF(Checkpoint, "Unserializing Arm PL031\n");
220 
228 
229  bool is_in_event;
230  UNSERIALIZE_SCALAR(is_in_event);
231 
232  Tick event_time;
233  if (is_in_event){
234  UNSERIALIZE_SCALAR(event_time);
235  schedule(matchEvent, event_time);
236  }
237 }
238 
239 
240 
241 PL031 *
242 PL031Params::create()
243 {
244  return new PL031(this);
245 }
Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:460
Packet::makeAtomicResponse
void makeAtomicResponse()
Definition: packet.hh:1016
PL031::read
Tick read(PacketPtr pkt) override
Handle a read to the device.
Definition: rtc_pl031.cc:59
BasicPioDevice::pioAddr
Addr pioAddr
Address that the device listens to.
Definition: io_device.hh:154
data
const char data[]
Definition: circlebuf.test.cc:42
PL031::write
Tick write(PacketPtr pkt) override
Handle writes to the device.
Definition: rtc_pl031.cc:121
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:754
PL031::ControlReg
@ ControlReg
Definition: rtc_pl031.hh:55
AmbaPioDevice::ambaId
uint64_t ambaId
Definition: amba_device.hh:79
amba_device.hh
mkutctime
time_t mkutctime(struct tm *time)
Definition: time.cc:153
time.hh
PL031::matchVal
uint32_t matchVal
Definition: rtc_pl031.hh:75
ArmInterruptPin::raise
virtual void raise()=0
Signal an interrupt.
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
PL031
Definition: rtc_pl031.hh:48
EventManager::deschedule
void deschedule(Event &event)
Definition: eventq.hh:1014
Packet::getSize
unsigned getSize() const
Definition: packet.hh:764
Event::when
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:503
PL031::matchEvent
EventFunctionWrapper matchEvent
Definition: rtc_pl031.hh:92
packet.hh
PL031::RawISR
@ RawISR
Definition: rtc_pl031.hh:57
PL031::MaskedISR
@ MaskedISR
Definition: rtc_pl031.hh:58
cp
Definition: cprintf.cc:40
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1005
PL031::resyncMatch
void resyncMatch()
Called to update the matchEvent when the load Value or match value are written.
Definition: rtc_pl031.cc:164
AmbaIntDevice::interrupt
ArmInterruptPin *const interrupt
Definition: amba_device.hh:89
Packet::getUintX
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
Definition: packet.cc:350
PL031::maskInt
bool maskInt
If the timer interrupt mask that is anded with the raw interrupt to generate a pending interrupt.
Definition: rtc_pl031.hh:84
PL031::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: rtc_pl031.cc:217
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
PL031::rawInt
bool rawInt
If timer has caused an interrupt.
Definition: rtc_pl031.hh:79
PL031::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: rtc_pl031.cc:195
SimClock::Int::s
Tick s
second
Definition: core.cc:62
rtc_pl031.hh
AmbaDevice::readId
bool readId(PacketPtr pkt, uint64_t amba_id, Addr pio_addr)
Definition: amba_device.cc:72
BasicPioDevice::pioSize
Addr pioSize
Size that the device's address range.
Definition: io_device.hh:157
PL031::LoadReg
@ LoadReg
Definition: rtc_pl031.hh:54
AmbaIntDevice
Definition: amba_device.hh:86
PL031::loadVal
uint32_t loadVal
Definition: rtc_pl031.hh:70
PL031::MatchReg
@ MatchReg
Definition: rtc_pl031.hh:53
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
name
const std::string & name()
Definition: trace.cc:50
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
packet_access.hh
PL031::IntMask
@ IntMask
Definition: rtc_pl031.hh:56
PL031::IntClear
@ IntClear
Definition: rtc_pl031.hh:59
Packet::getLE
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Definition: packet_access.hh:75
AmbaPioDevice::Params
AmbaPioDeviceParams Params
Definition: amba_device.hh:82
PL031::PL031
PL031(Params *p)
The constructor for RealView just registers itself with the MMU.
Definition: rtc_pl031.cc:49
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
PL031::timeVal
uint32_t timeVal
Definition: rtc_pl031.hh:64
PL031::counterMatch
void counterMatch()
Called when the counter reaches matches.
Definition: rtc_pl031.cc:181
BasicPioDevice::pioDelay
Tick pioDelay
Delay that the device experinces on an access.
Definition: io_device.hh:160
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:63
trace.hh
PL031::lastWrittenTick
Tick lastWrittenTick
Definition: rtc_pl031.hh:67
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
intmath.hh
CheckpointIn
Definition: serialize.hh:67
PL031::pendingInt
bool pendingInt
If an interrupt is currently pending.
Definition: rtc_pl031.hh:88
PL031::DataReg
@ DataReg
Definition: rtc_pl031.hh:52
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45

Generated on Wed Sep 30 2020 14:02:10 for gem5 by doxygen 1.8.17