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
), tsunami(p
->tsunami
),
73 pitimer(this, p
->name
+ "pitimer"), rtc(p
->name
+ ".rtc", p
)
77 // set the back pointer from tsunami to myself
82 picInterrupting
= false;
86 TsunamiIO::frequency() const
88 return SimClock::Frequency
/ params()->frequency
;
92 TsunamiIO::read(PacketPtr pkt
)
94 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
96 Addr daddr
= pkt
->getAddr() - pioAddr
;
98 DPRINTF(Tsunami
, "io read va=%#x size=%d IOPorrt=%#x\n", pkt
->getAddr(),
99 pkt
->getSize(), daddr
);
103 if (pkt
->getSize() == sizeof(uint8_t)) {
106 case TSDEV_PIC1_MASK
:
109 case TSDEV_PIC2_MASK
:
113 // !!! If this is modified 64bit case needs to be too
114 // Pal code has to do a 64 bit physical read because there is
115 // no load physical byte instruction
119 // PIC2 not implemnted... just return 0
122 case TSDEV_TMR0_DATA
:
123 pkt
->set(pitimer
.readCounter(0));
125 case TSDEV_TMR1_DATA
:
126 pkt
->set(pitimer
.readCounter(1));
128 case TSDEV_TMR2_DATA
:
129 pkt
->set(pitimer
.readCounter(2));
132 pkt
->set(rtc
.readData(rtcAddr
));
134 case TSDEV_CTRL_PORTB
:
135 if (pitimer
.outputHigh(2))
136 pkt
->set(PORTB_SPKR_HIGH
);
141 panic("I/O Read - va%#x size %d\n", pkt
->getAddr(), pkt
->getSize());
143 } else if (pkt
->getSize() == sizeof(uint64_t)) {
144 if (daddr
== TSDEV_PIC1_ISR
)
145 pkt
->set
<uint64_t>(picr
);
147 panic("I/O Read - invalid addr - va %#x size %d\n",
148 pkt
->getAddr(), pkt
->getSize());
150 panic("I/O Read - invalid size - va %#x size %d\n", pkt
->getAddr(), pkt
->getSize());
152 pkt
->makeAtomicResponse();
157 TsunamiIO::write(PacketPtr pkt
)
159 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
160 Addr daddr
= pkt
->getAddr() - pioAddr
;
162 DPRINTF(Tsunami
, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
163 pkt
->getAddr(), pkt
->getSize(), pkt
->getAddr() & 0xfff, (uint32_t)pkt
->get
<uint8_t>());
165 assert(pkt
->getSize() == sizeof(uint8_t));
168 case TSDEV_PIC1_MASK
:
169 mask1
= ~(pkt
->get
<uint8_t>());
170 if ((picr
& mask1
) && !picInterrupting
) {
171 picInterrupting
= true;
172 tsunami
->cchip
->postDRIR(55);
173 DPRINTF(Tsunami
, "posting pic interrupt to cchip\n");
175 if ((!(picr
& mask1
)) && picInterrupting
) {
176 picInterrupting
= false;
177 tsunami
->cchip
->clearDRIR(55);
178 DPRINTF(Tsunami
, "clearing pic interrupt\n");
181 case TSDEV_PIC2_MASK
:
182 mask2
= pkt
->get
<uint8_t>();
183 //PIC2 Not implemented to interrupt
186 // clear the interrupt on the PIC
187 picr
&= ~(1 << (pkt
->get
<uint8_t>() & 0xF));
189 tsunami
->cchip
->clearDRIR(55);
191 case TSDEV_DMA1_MODE
:
192 mode1
= pkt
->get
<uint8_t>();
194 case TSDEV_DMA2_MODE
:
195 mode2
= pkt
->get
<uint8_t>();
197 case TSDEV_TMR0_DATA
:
198 pitimer
.writeCounter(0, pkt
->get
<uint8_t>());
200 case TSDEV_TMR1_DATA
:
201 pitimer
.writeCounter(1, pkt
->get
<uint8_t>());
203 case TSDEV_TMR2_DATA
:
204 pitimer
.writeCounter(2, pkt
->get
<uint8_t>());
207 pitimer
.writeControl(pkt
->get
<uint8_t>());
210 rtcAddr
= pkt
->get
<uint8_t>();
213 rtc
.writeData(rtcAddr
, pkt
->get
<uint8_t>());
216 case TSDEV_DMA1_CMND
:
217 case TSDEV_DMA2_CMND
:
218 case TSDEV_DMA1_MMASK
:
219 case TSDEV_DMA2_MMASK
:
221 case TSDEV_DMA1_RESET
:
222 case TSDEV_DMA2_RESET
:
223 case TSDEV_DMA1_MASK
:
224 case TSDEV_DMA2_MASK
:
225 case TSDEV_CTRL_PORTB
:
228 panic("I/O Write - va%#x size %d data %#x\n", pkt
->getAddr(), pkt
->getSize(), pkt
->get
<uint8_t>());
231 pkt
->makeAtomicResponse();
236 TsunamiIO::postPIC(uint8_t bitvector
)
238 //PIC2 Is not implemented, because nothing of interest there
241 tsunami
->cchip
->postDRIR(55);
242 DPRINTF(Tsunami
, "posting pic interrupt to cchip\n");
247 TsunamiIO::clearPIC(uint8_t bitvector
)
249 //PIC2 Is not implemented, because nothing of interest there
251 if (!(picr
& mask1
)) {
252 tsunami
->cchip
->clearDRIR(55);
253 DPRINTF(Tsunami
, "clearing pic interrupt to cchip\n");
258 TsunamiIO::serialize(ostream
&os
)
260 SERIALIZE_SCALAR(rtcAddr
);
261 SERIALIZE_SCALAR(timerData
);
262 SERIALIZE_SCALAR(mask1
);
263 SERIALIZE_SCALAR(mask2
);
264 SERIALIZE_SCALAR(mode1
);
265 SERIALIZE_SCALAR(mode2
);
266 SERIALIZE_SCALAR(picr
);
267 SERIALIZE_SCALAR(picInterrupting
);
269 // Serialize the timers
270 pitimer
.serialize("pitimer", os
);
271 rtc
.serialize("rtc", os
);
275 TsunamiIO::unserialize(Checkpoint
*cp
, const string
§ion
)
277 UNSERIALIZE_SCALAR(rtcAddr
);
278 UNSERIALIZE_SCALAR(timerData
);
279 UNSERIALIZE_SCALAR(mask1
);
280 UNSERIALIZE_SCALAR(mask2
);
281 UNSERIALIZE_SCALAR(mode1
);
282 UNSERIALIZE_SCALAR(mode2
);
283 UNSERIALIZE_SCALAR(picr
);
284 UNSERIALIZE_SCALAR(picInterrupting
);
286 // Unserialize the timers
287 pitimer
.unserialize("pitimer", cp
, section
);
288 rtc
.unserialize("rtc", cp
, section
);
292 TsunamiIOParams::create()
294 return new TsunamiIO(this);