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

Generated on Fri Feb 28 2020 16:27:00 for gem5 by doxygen 1.8.13