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 "dev/alpha/tsunami.hh"
47 #include "dev/alpha/tsunami_cchip.hh"
48 #include "dev/alpha/tsunami_io.hh"
49 #include "dev/alpha/tsunamireg.h"
50 #include "dev/rtcreg.h"
51 #include "mem/packet.hh"
52 #include "mem/packet_access.hh"
53 #include "mem/port.hh"
54 #include "sim/system.hh"
57 //Should this be AlphaISA?
58 using namespace TheISA
;
60 TsunamiIO::RTC::RTC(const string
&n
, const TsunamiIOParams
*p
)
61 : MC146818(p
->tsunami
, n
, p
->time
, p
->year_is_bcd
, p
->frequency
),
66 TsunamiIO::TsunamiIO(const Params
*p
)
67 : BasicPioDevice(p
), tsunami(p
->tsunami
),
68 pitimer(this, p
->name
+ "pitimer"), rtc(p
->name
+ ".rtc", p
)
72 // set the back pointer from tsunami to myself
77 picInterrupting
= false;
81 TsunamiIO::frequency() const
83 return SimClock::Frequency
/ params()->frequency
;
87 TsunamiIO::read(PacketPtr pkt
)
89 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
91 Addr daddr
= pkt
->getAddr() - pioAddr
;
93 DPRINTF(Tsunami
, "io read va=%#x size=%d IOPorrt=%#x\n", pkt
->getAddr(),
94 pkt
->getSize(), daddr
);
98 if (pkt
->getSize() == sizeof(uint8_t)) {
101 case TSDEV_PIC1_MASK
:
104 case TSDEV_PIC2_MASK
:
108 // !!! If this is modified 64bit case needs to be too
109 // Pal code has to do a 64 bit physical read because there is
110 // no load physical byte instruction
114 // PIC2 not implemnted... just return 0
117 case TSDEV_TMR0_DATA
:
118 pkt
->set(pitimer
.readCounter(0));
120 case TSDEV_TMR1_DATA
:
121 pkt
->set(pitimer
.readCounter(1));
123 case TSDEV_TMR2_DATA
:
124 pkt
->set(pitimer
.readCounter(2));
127 pkt
->set(rtc
.readData(rtcAddr
));
129 case TSDEV_CTRL_PORTB
:
130 if (pitimer
.outputHigh(2))
131 pkt
->set(PORTB_SPKR_HIGH
);
136 panic("I/O Read - va%#x size %d\n", pkt
->getAddr(), pkt
->getSize());
138 } else if (pkt
->getSize() == sizeof(uint64_t)) {
139 if (daddr
== TSDEV_PIC1_ISR
)
140 pkt
->set
<uint64_t>(picr
);
142 panic("I/O Read - invalid addr - va %#x size %d\n",
143 pkt
->getAddr(), pkt
->getSize());
145 panic("I/O Read - invalid size - va %#x size %d\n", pkt
->getAddr(), pkt
->getSize());
147 pkt
->makeAtomicResponse();
152 TsunamiIO::write(PacketPtr pkt
)
154 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
155 Addr daddr
= pkt
->getAddr() - pioAddr
;
157 DPRINTF(Tsunami
, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
158 pkt
->getAddr(), pkt
->getSize(), pkt
->getAddr() & 0xfff, (uint32_t)pkt
->get
<uint8_t>());
160 assert(pkt
->getSize() == sizeof(uint8_t));
163 case TSDEV_PIC1_MASK
:
164 mask1
= ~(pkt
->get
<uint8_t>());
165 if ((picr
& mask1
) && !picInterrupting
) {
166 picInterrupting
= true;
167 tsunami
->cchip
->postDRIR(55);
168 DPRINTF(Tsunami
, "posting pic interrupt to cchip\n");
170 if ((!(picr
& mask1
)) && picInterrupting
) {
171 picInterrupting
= false;
172 tsunami
->cchip
->clearDRIR(55);
173 DPRINTF(Tsunami
, "clearing pic interrupt\n");
176 case TSDEV_PIC2_MASK
:
177 mask2
= pkt
->get
<uint8_t>();
178 //PIC2 Not implemented to interrupt
181 // clear the interrupt on the PIC
182 picr
&= ~(1 << (pkt
->get
<uint8_t>() & 0xF));
184 tsunami
->cchip
->clearDRIR(55);
186 case TSDEV_DMA1_MODE
:
187 mode1
= pkt
->get
<uint8_t>();
189 case TSDEV_DMA2_MODE
:
190 mode2
= pkt
->get
<uint8_t>();
192 case TSDEV_TMR0_DATA
:
193 pitimer
.writeCounter(0, pkt
->get
<uint8_t>());
195 case TSDEV_TMR1_DATA
:
196 pitimer
.writeCounter(1, pkt
->get
<uint8_t>());
198 case TSDEV_TMR2_DATA
:
199 pitimer
.writeCounter(2, pkt
->get
<uint8_t>());
202 pitimer
.writeControl(pkt
->get
<uint8_t>());
205 rtcAddr
= pkt
->get
<uint8_t>();
208 rtc
.writeData(rtcAddr
, pkt
->get
<uint8_t>());
211 case TSDEV_DMA1_CMND
:
212 case TSDEV_DMA2_CMND
:
213 case TSDEV_DMA1_MMASK
:
214 case TSDEV_DMA2_MMASK
:
216 case TSDEV_DMA1_RESET
:
217 case TSDEV_DMA2_RESET
:
218 case TSDEV_DMA1_MASK
:
219 case TSDEV_DMA2_MASK
:
220 case TSDEV_CTRL_PORTB
:
223 panic("I/O Write - va%#x size %d data %#x\n", pkt
->getAddr(), pkt
->getSize(), pkt
->get
<uint8_t>());
226 pkt
->makeAtomicResponse();
231 TsunamiIO::postPIC(uint8_t bitvector
)
233 //PIC2 Is not implemented, because nothing of interest there
236 tsunami
->cchip
->postDRIR(55);
237 DPRINTF(Tsunami
, "posting pic interrupt to cchip\n");
242 TsunamiIO::clearPIC(uint8_t bitvector
)
244 //PIC2 Is not implemented, because nothing of interest there
246 if (!(picr
& mask1
)) {
247 tsunami
->cchip
->clearDRIR(55);
248 DPRINTF(Tsunami
, "clearing pic interrupt to cchip\n");
253 TsunamiIO::serialize(ostream
&os
)
255 SERIALIZE_SCALAR(rtcAddr
);
256 SERIALIZE_SCALAR(timerData
);
257 SERIALIZE_SCALAR(mask1
);
258 SERIALIZE_SCALAR(mask2
);
259 SERIALIZE_SCALAR(mode1
);
260 SERIALIZE_SCALAR(mode2
);
261 SERIALIZE_SCALAR(picr
);
262 SERIALIZE_SCALAR(picInterrupting
);
264 // Serialize the timers
265 pitimer
.serialize("pitimer", os
);
266 rtc
.serialize("rtc", os
);
270 TsunamiIO::unserialize(Checkpoint
*cp
, const string
§ion
)
272 UNSERIALIZE_SCALAR(rtcAddr
);
273 UNSERIALIZE_SCALAR(timerData
);
274 UNSERIALIZE_SCALAR(mask1
);
275 UNSERIALIZE_SCALAR(mask2
);
276 UNSERIALIZE_SCALAR(mode1
);
277 UNSERIALIZE_SCALAR(mode2
);
278 UNSERIALIZE_SCALAR(picr
);
279 UNSERIALIZE_SCALAR(picInterrupting
);
281 // Unserialize the timers
282 pitimer
.unserialize("pitimer", cp
, section
);
283 rtc
.unserialize("rtc", cp
, section
);
287 TsunamiIOParams::create()
289 return new TsunamiIO(this);