0c1937a3288ef611bade5ddf1e650df91748db31
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"
58 //Should this be AlphaISA?
59 using namespace TheISA
;
61 TsunamiIO::RTC::RTC(const string
&n
, const TsunamiIOParams
*p
)
62 : MC146818(p
->tsunami
, n
, p
->time
, p
->year_is_bcd
, p
->frequency
),
67 TsunamiIO::TsunamiIO(const Params
*p
)
68 : BasicPioDevice(p
), tsunami(p
->tsunami
),
69 pitimer(this, p
->name
+ "pitimer"), rtc(p
->name
+ ".rtc", p
)
73 // set the back pointer from tsunami to myself
78 picInterrupting
= false;
82 TsunamiIO::frequency() const
84 return SimClock::Frequency
/ params()->frequency
;
88 TsunamiIO::read(PacketPtr pkt
)
90 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
92 Addr daddr
= pkt
->getAddr() - pioAddr
;
94 DPRINTF(Tsunami
, "io read va=%#x size=%d IOPorrt=%#x\n", pkt
->getAddr(),
95 pkt
->getSize(), daddr
);
99 if (pkt
->getSize() == sizeof(uint8_t)) {
102 case TSDEV_PIC1_MASK
:
105 case TSDEV_PIC2_MASK
:
109 // !!! If this is modified 64bit case needs to be too
110 // Pal code has to do a 64 bit physical read because there is
111 // no load physical byte instruction
115 // PIC2 not implemnted... just return 0
118 case TSDEV_TMR0_DATA
:
119 pkt
->set(pitimer
.readCounter(0));
121 case TSDEV_TMR1_DATA
:
122 pkt
->set(pitimer
.readCounter(1));
124 case TSDEV_TMR2_DATA
:
125 pkt
->set(pitimer
.readCounter(2));
128 pkt
->set(rtc
.readData(rtcAddr
));
130 case TSDEV_CTRL_PORTB
:
131 if (pitimer
.outputHigh(2))
132 pkt
->set(PORTB_SPKR_HIGH
);
137 panic("I/O Read - va%#x size %d\n", pkt
->getAddr(), pkt
->getSize());
139 } else if (pkt
->getSize() == sizeof(uint64_t)) {
140 if (daddr
== TSDEV_PIC1_ISR
)
141 pkt
->set
<uint64_t>(picr
);
143 panic("I/O Read - invalid addr - va %#x size %d\n",
144 pkt
->getAddr(), pkt
->getSize());
146 panic("I/O Read - invalid size - va %#x size %d\n", pkt
->getAddr(), pkt
->getSize());
148 pkt
->makeAtomicResponse();
153 TsunamiIO::write(PacketPtr pkt
)
155 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
156 Addr daddr
= pkt
->getAddr() - pioAddr
;
158 DPRINTF(Tsunami
, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
159 pkt
->getAddr(), pkt
->getSize(), pkt
->getAddr() & 0xfff, (uint32_t)pkt
->get
<uint8_t>());
161 assert(pkt
->getSize() == sizeof(uint8_t));
164 case TSDEV_PIC1_MASK
:
165 mask1
= ~(pkt
->get
<uint8_t>());
166 if ((picr
& mask1
) && !picInterrupting
) {
167 picInterrupting
= true;
168 tsunami
->cchip
->postDRIR(55);
169 DPRINTF(Tsunami
, "posting pic interrupt to cchip\n");
171 if ((!(picr
& mask1
)) && picInterrupting
) {
172 picInterrupting
= false;
173 tsunami
->cchip
->clearDRIR(55);
174 DPRINTF(Tsunami
, "clearing pic interrupt\n");
177 case TSDEV_PIC2_MASK
:
178 mask2
= pkt
->get
<uint8_t>();
179 //PIC2 Not implemented to interrupt
182 // clear the interrupt on the PIC
183 picr
&= ~(1 << (pkt
->get
<uint8_t>() & 0xF));
185 tsunami
->cchip
->clearDRIR(55);
187 case TSDEV_DMA1_MODE
:
188 mode1
= pkt
->get
<uint8_t>();
190 case TSDEV_DMA2_MODE
:
191 mode2
= pkt
->get
<uint8_t>();
193 case TSDEV_TMR0_DATA
:
194 pitimer
.writeCounter(0, pkt
->get
<uint8_t>());
196 case TSDEV_TMR1_DATA
:
197 pitimer
.writeCounter(1, pkt
->get
<uint8_t>());
199 case TSDEV_TMR2_DATA
:
200 pitimer
.writeCounter(2, pkt
->get
<uint8_t>());
203 pitimer
.writeControl(pkt
->get
<uint8_t>());
206 rtcAddr
= pkt
->get
<uint8_t>();
209 rtc
.writeData(rtcAddr
, pkt
->get
<uint8_t>());
212 case TSDEV_DMA1_CMND
:
213 case TSDEV_DMA2_CMND
:
214 case TSDEV_DMA1_MMASK
:
215 case TSDEV_DMA2_MMASK
:
217 case TSDEV_DMA1_RESET
:
218 case TSDEV_DMA2_RESET
:
219 case TSDEV_DMA1_MASK
:
220 case TSDEV_DMA2_MASK
:
221 case TSDEV_CTRL_PORTB
:
224 panic("I/O Write - va%#x size %d data %#x\n", pkt
->getAddr(), pkt
->getSize(), pkt
->get
<uint8_t>());
227 pkt
->makeAtomicResponse();
232 TsunamiIO::postPIC(uint8_t bitvector
)
234 //PIC2 Is not implemented, because nothing of interest there
237 tsunami
->cchip
->postDRIR(55);
238 DPRINTF(Tsunami
, "posting pic interrupt to cchip\n");
243 TsunamiIO::clearPIC(uint8_t bitvector
)
245 //PIC2 Is not implemented, because nothing of interest there
247 if (!(picr
& mask1
)) {
248 tsunami
->cchip
->clearDRIR(55);
249 DPRINTF(Tsunami
, "clearing pic interrupt to cchip\n");
254 TsunamiIO::serialize(ostream
&os
)
256 SERIALIZE_SCALAR(rtcAddr
);
257 SERIALIZE_SCALAR(timerData
);
258 SERIALIZE_SCALAR(mask1
);
259 SERIALIZE_SCALAR(mask2
);
260 SERIALIZE_SCALAR(mode1
);
261 SERIALIZE_SCALAR(mode2
);
262 SERIALIZE_SCALAR(picr
);
263 SERIALIZE_SCALAR(picInterrupting
);
265 // Serialize the timers
266 pitimer
.serialize("pitimer", os
);
267 rtc
.serialize("rtc", os
);
271 TsunamiIO::unserialize(Checkpoint
*cp
, const string
§ion
)
273 UNSERIALIZE_SCALAR(rtcAddr
);
274 UNSERIALIZE_SCALAR(timerData
);
275 UNSERIALIZE_SCALAR(mask1
);
276 UNSERIALIZE_SCALAR(mask2
);
277 UNSERIALIZE_SCALAR(mode1
);
278 UNSERIALIZE_SCALAR(mode2
);
279 UNSERIALIZE_SCALAR(picr
);
280 UNSERIALIZE_SCALAR(picInterrupting
);
282 // Unserialize the timers
283 pitimer
.unserialize("pitimer", cp
, section
);
284 rtc
.unserialize("rtc", cp
, section
);
288 TsunamiIOParams::create()
290 return new TsunamiIO(this);