6586cd9809fcf920462003d7396392819f9dcb08
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Tsunami I/O including PIC, PIT, RTC, DMA
43 #include "base/time.hh"
44 #include "base/trace.hh"
45 #include "config/the_isa.hh"
46 #include "debug/Tsunami.hh"
47 #include "dev/alpha/tsunami.hh"
48 #include "dev/alpha/tsunami_cchip.hh"
49 #include "dev/alpha/tsunami_io.hh"
50 #include "dev/alpha/tsunamireg.h"
51 #include "dev/rtcreg.h"
52 #include "mem/packet.hh"
53 #include "mem/packet_access.hh"
54 #include "mem/port.hh"
55 #include "sim/system.hh"
57 // clang complains about std::set being overloaded with Packet::set if
58 // we open up the entire namespace std
62 //Should this be AlphaISA?
63 using namespace TheISA
;
65 TsunamiIO::RTC::RTC(const string
&n
, const TsunamiIOParams
*p
)
66 : MC146818(p
->tsunami
, n
, p
->time
, p
->year_is_bcd
, p
->frequency
),
71 TsunamiIO::TsunamiIO(const Params
*p
)
72 : BasicPioDevice(p
, 0x100), tsunami(p
->tsunami
),
73 pitimer(this, p
->name
+ "pitimer"), rtc(p
->name
+ ".rtc", p
)
75 // set the back pointer from tsunami to myself
80 picInterrupting
= false;
84 TsunamiIO::frequency() const
86 return SimClock::Frequency
/ params()->frequency
;
90 TsunamiIO::read(PacketPtr pkt
)
92 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
94 Addr daddr
= pkt
->getAddr() - pioAddr
;
96 DPRINTF(Tsunami
, "io read va=%#x size=%d IOPorrt=%#x\n", pkt
->getAddr(),
97 pkt
->getSize(), daddr
);
101 if (pkt
->getSize() == sizeof(uint8_t)) {
104 case TSDEV_PIC1_MASK
:
107 case TSDEV_PIC2_MASK
:
111 // !!! If this is modified 64bit case needs to be too
112 // Pal code has to do a 64 bit physical read because there is
113 // no load physical byte instruction
117 // PIC2 not implemnted... just return 0
120 case TSDEV_TMR0_DATA
:
121 pkt
->set(pitimer
.readCounter(0));
123 case TSDEV_TMR1_DATA
:
124 pkt
->set(pitimer
.readCounter(1));
126 case TSDEV_TMR2_DATA
:
127 pkt
->set(pitimer
.readCounter(2));
130 pkt
->set(rtc
.readData(rtcAddr
));
132 case TSDEV_CTRL_PORTB
:
133 if (pitimer
.outputHigh(2))
134 pkt
->set(PORTB_SPKR_HIGH
);
139 panic("I/O Read - va%#x size %d\n", pkt
->getAddr(), pkt
->getSize());
141 } else if (pkt
->getSize() == sizeof(uint64_t)) {
142 if (daddr
== TSDEV_PIC1_ISR
)
143 pkt
->set
<uint64_t>(picr
);
145 panic("I/O Read - invalid addr - va %#x size %d\n",
146 pkt
->getAddr(), pkt
->getSize());
148 panic("I/O Read - invalid size - va %#x size %d\n", pkt
->getAddr(), pkt
->getSize());
150 pkt
->makeAtomicResponse();
155 TsunamiIO::write(PacketPtr pkt
)
157 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
158 Addr daddr
= pkt
->getAddr() - pioAddr
;
160 DPRINTF(Tsunami
, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
161 pkt
->getAddr(), pkt
->getSize(), pkt
->getAddr() & 0xfff, (uint32_t)pkt
->get
<uint8_t>());
163 assert(pkt
->getSize() == sizeof(uint8_t));
166 case TSDEV_PIC1_MASK
:
167 mask1
= ~(pkt
->get
<uint8_t>());
168 if ((picr
& mask1
) && !picInterrupting
) {
169 picInterrupting
= true;
170 tsunami
->cchip
->postDRIR(55);
171 DPRINTF(Tsunami
, "posting pic interrupt to cchip\n");
173 if ((!(picr
& mask1
)) && picInterrupting
) {
174 picInterrupting
= false;
175 tsunami
->cchip
->clearDRIR(55);
176 DPRINTF(Tsunami
, "clearing pic interrupt\n");
179 case TSDEV_PIC2_MASK
:
180 mask2
= pkt
->get
<uint8_t>();
181 //PIC2 Not implemented to interrupt
184 // clear the interrupt on the PIC
185 picr
&= ~(1 << (pkt
->get
<uint8_t>() & 0xF));
187 tsunami
->cchip
->clearDRIR(55);
189 case TSDEV_DMA1_MODE
:
190 mode1
= pkt
->get
<uint8_t>();
192 case TSDEV_DMA2_MODE
:
193 mode2
= pkt
->get
<uint8_t>();
195 case TSDEV_TMR0_DATA
:
196 pitimer
.writeCounter(0, pkt
->get
<uint8_t>());
198 case TSDEV_TMR1_DATA
:
199 pitimer
.writeCounter(1, pkt
->get
<uint8_t>());
201 case TSDEV_TMR2_DATA
:
202 pitimer
.writeCounter(2, pkt
->get
<uint8_t>());
205 pitimer
.writeControl(pkt
->get
<uint8_t>());
208 rtcAddr
= pkt
->get
<uint8_t>();
211 rtc
.writeData(rtcAddr
, pkt
->get
<uint8_t>());
214 case TSDEV_DMA1_CMND
:
215 case TSDEV_DMA2_CMND
:
216 case TSDEV_DMA1_MMASK
:
217 case TSDEV_DMA2_MMASK
:
219 case TSDEV_DMA1_RESET
:
220 case TSDEV_DMA2_RESET
:
221 case TSDEV_DMA1_MASK
:
222 case TSDEV_DMA2_MASK
:
223 case TSDEV_CTRL_PORTB
:
226 panic("I/O Write - va%#x size %d data %#x\n", pkt
->getAddr(), pkt
->getSize(), pkt
->get
<uint8_t>());
229 pkt
->makeAtomicResponse();
234 TsunamiIO::postPIC(uint8_t bitvector
)
236 //PIC2 Is not implemented, because nothing of interest there
239 tsunami
->cchip
->postDRIR(55);
240 DPRINTF(Tsunami
, "posting pic interrupt to cchip\n");
245 TsunamiIO::clearPIC(uint8_t bitvector
)
247 //PIC2 Is not implemented, because nothing of interest there
249 if (!(picr
& mask1
)) {
250 tsunami
->cchip
->clearDRIR(55);
251 DPRINTF(Tsunami
, "clearing pic interrupt to cchip\n");
256 TsunamiIO::serialize(ostream
&os
)
258 SERIALIZE_SCALAR(rtcAddr
);
259 SERIALIZE_SCALAR(timerData
);
260 SERIALIZE_SCALAR(mask1
);
261 SERIALIZE_SCALAR(mask2
);
262 SERIALIZE_SCALAR(mode1
);
263 SERIALIZE_SCALAR(mode2
);
264 SERIALIZE_SCALAR(picr
);
265 SERIALIZE_SCALAR(picInterrupting
);
267 // Serialize the timers
268 pitimer
.serialize("pitimer", os
);
269 rtc
.serialize("rtc", os
);
273 TsunamiIO::unserialize(Checkpoint
*cp
, const string
§ion
)
275 UNSERIALIZE_SCALAR(rtcAddr
);
276 UNSERIALIZE_SCALAR(timerData
);
277 UNSERIALIZE_SCALAR(mask1
);
278 UNSERIALIZE_SCALAR(mask2
);
279 UNSERIALIZE_SCALAR(mode1
);
280 UNSERIALIZE_SCALAR(mode2
);
281 UNSERIALIZE_SCALAR(picr
);
282 UNSERIALIZE_SCALAR(picInterrupting
);
284 // Unserialize the timers
285 pitimer
.unserialize("pitimer", cp
, section
);
286 rtc
.unserialize("rtc", cp
, section
);
290 TsunamiIOParams::create()
292 return new TsunamiIO(this);