gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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, 0xfff), timeVal(mkutctime(&p->time)),
53  lastWrittenTick(0), loadVal(0), matchVal(0),
54  rawInt(false), maskInt(false), pendingInt(false), matchEvent(this)
55 {
56 }
57 
58 
59 Tick
61 {
62  assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
63  assert(pkt->getSize() == 4);
64  Addr daddr = pkt->getAddr() - pioAddr;
65  uint32_t data;
66 
67  DPRINTF(Timer, "Reading from RTC at offset: %#x\n", daddr);
68 
69  switch (daddr) {
70  case DataReg:
72  break;
73  case MatchReg:
74  data = matchVal;
75  break;
76  case LoadReg:
77  data = loadVal;
78  break;
79  case ControlReg:
80  data = 1; // Always enabled otherwise there is no point
81  break;
82  case IntMask:
83  data = maskInt;
84  break;
85  case RawISR:
86  data = rawInt;
87  break;
88  case MaskedISR:
89  data = pendingInt;
90  break;
91  default:
92  if (readId(pkt, ambaId, pioAddr)) {
93  // Hack for variable sized access
94  data = pkt->get<uint32_t>();
95  break;
96  }
97  panic("Tried to read PL031 at offset %#x that doesn't exist\n", daddr);
98  break;
99  }
100 
101  switch(pkt->getSize()) {
102  case 1:
103  pkt->set<uint8_t>(data);
104  break;
105  case 2:
106  pkt->set<uint16_t>(data);
107  break;
108  case 4:
109  pkt->set<uint32_t>(data);
110  break;
111  default:
112  panic("Uart read size too big?\n");
113  break;
114  }
115 
116 
117  pkt->makeAtomicResponse();
118  return pioDelay;
119 }
120 
121 Tick
123 {
124  assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
125  assert(pkt->getSize() == 4);
126  Addr daddr = pkt->getAddr() - pioAddr;
127  DPRINTF(Timer, "Writing to RTC at offset: %#x\n", daddr);
128 
129  switch (daddr) {
130  case DataReg:
131  break;
132  case MatchReg:
133  matchVal = pkt->get<uint32_t>();
134  resyncMatch();
135  break;
136  case LoadReg:
138  timeVal = pkt->get<uint32_t>();
139  loadVal = timeVal;
140  resyncMatch();
141  break;
142  case ControlReg:
143  break; // Can't stop when started
144  case IntMask:
145  maskInt = pkt->get<uint32_t>();
146  break;
147  case IntClear:
148  if (pkt->get<uint32_t>()) {
149  rawInt = false;
150  pendingInt = false;
151  }
152  break;
153  default:
154  if (readId(pkt, ambaId, pioAddr))
155  break;
156  panic("Tried to read PL031 at offset %#x that doesn't exist\n", daddr);
157  break;
158  }
159 
160  pkt->makeAtomicResponse();
161  return pioDelay;
162 }
163 
164 void
166 {
167  DPRINTF(Timer, "Setting up new match event match=%d time=%d\n", matchVal,
168  timeVal);
169 
170  uint32_t seconds_until = matchVal - timeVal;
171  Tick ticks_until = SimClock::Int::s * seconds_until;
172 
173  if (matchEvent.scheduled()) {
174  DPRINTF(Timer, "-- Event was already schedule, de-scheduling\n");
176  }
177  schedule(matchEvent, curTick() + ticks_until);
178  DPRINTF(Timer, "-- Scheduling new event for: %d\n", curTick() + ticks_until);
179 }
180 
181 void
183 {
184  DPRINTF(Timer, "Counter reached zero\n");
185 
186  rawInt = true;
187  bool old_pending = pendingInt;
189  if (pendingInt && !old_pending) {
190  DPRINTF(Timer, "-- Causing interrupt\n");
191  gic->sendInt(intNum);
192  }
193 }
194 
195 void
197 {
198  DPRINTF(Checkpoint, "Serializing Arm PL031\n");
206 
207  bool is_in_event = matchEvent.scheduled();
208  SERIALIZE_SCALAR(is_in_event);
209 
210  Tick event_time;
211  if (is_in_event){
212  event_time = matchEvent.when();
213  SERIALIZE_SCALAR(event_time);
214  }
215 }
216 
217 void
219 {
220  DPRINTF(Checkpoint, "Unserializing Arm PL031\n");
221 
229 
230  bool is_in_event;
231  UNSERIALIZE_SCALAR(is_in_event);
232 
233  Tick event_time;
234  if (is_in_event){
235  UNSERIALIZE_SCALAR(event_time);
236  schedule(matchEvent, event_time);
237  }
238 }
239 
240 
241 
242 PL031 *
243 PL031Params::create()
244 {
245  return new PL031(this);
246 }
#define DPRINTF(x,...)
Definition: trace.hh:212
uint32_t matchVal
Definition: rtc_pl031.hh:77
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
#define panic(...)
Definition: misc.hh:153
Tick read(PacketPtr pkt) override
Handle a read to the device.
Definition: rtc_pl031.cc:60
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:381
AmbaPioDeviceParams Params
Definition: amba_device.hh:84
Tick write(PacketPtr pkt) override
Handle writes to the device.
Definition: rtc_pl031.cc:122
void resyncMatch()
Called to update the matchEvent when the load Value or match value are written.
Definition: rtc_pl031.cc:165
bool rawInt
If timer has caused an interrupt.
Definition: rtc_pl031.hh:81
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.
const char data[]
Definition: circlebuf.cc:43
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
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
Addr pioSize
Size that the device's address range.
Definition: io_device.hh:142
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: rtc_pl031.cc:196
This is a base class for AMBA devices that have to respond to Device and Implementer ID calls...
Tick when() const
Get the time that the event is scheduled.
Definition: eventq.hh:397
virtual void sendInt(uint32_t num)=0
Post an interrupt from a device that is connected to the GIC.
void makeAtomicResponse()
Definition: packet.hh:857
uint64_t Tick
Tick count type.
Definition: types.hh:63
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: rtc_pl031.cc:218
EventWrapper< PL031,&PL031::counterMatch > matchEvent
Definition: rtc_pl031.hh:94
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
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:245
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
Tick s
second
Definition: core.cc:63
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:67
time_t mkutctime(struct tm *time)
Definition: time.cc:152
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:145
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:728
void counterMatch()
Called when the counter reaches matches.
Definition: rtc_pl031.cc:182
unsigned getSize() const
Definition: packet.hh:649
Bitfield< 0 > p
Addr pioAddr
Address that the device listens to.
Definition: io_device.hh:139
uint32_t timeVal
Definition: rtc_pl031.hh:66
BaseGic * gic
Definition: amba_device.hh:92
Addr getAddr() const
Definition: packet.hh:639

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