Changes for getting FreeBSD to run.
[gem5.git] / dev / tsunami_io.cc
1 /*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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.
15 *
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.
27 */
28
29 /** @file
30 * Tsunami I/O including PIC, PIT, RTC, DMA
31 */
32
33 #include <sys/time.h>
34
35 #include <deque>
36 #include <string>
37 #include <vector>
38
39 #include "base/trace.hh"
40 #include "dev/tsunami_io.hh"
41 #include "dev/tsunami.hh"
42 #include "dev/pitreg.h"
43 #include "mem/bus/bus.hh"
44 #include "mem/bus/pio_interface.hh"
45 #include "mem/bus/pio_interface_impl.hh"
46 #include "sim/builder.hh"
47 #include "dev/tsunami_cchip.hh"
48 #include "dev/tsunamireg.h"
49 #include "dev/rtcreg.h"
50 #include "mem/functional/memory_control.hh"
51
52 using namespace std;
53
54 TsunamiIO::RTC::RTC(Tsunami* t, Tick i)
55 : SimObject("RTC"), event(t, i), addr(0)
56 {
57 memset(clock_data, 0, sizeof(clock_data));
58 stat_regA = RTCA_32768HZ | RTCA_1024HZ;
59 stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR;
60 }
61
62 void
63 TsunamiIO::RTC::set_time(time_t t)
64 {
65 struct tm tm;
66 gmtime_r(&t, &tm);
67
68 sec = tm.tm_sec;
69 min = tm.tm_min;
70 hour = tm.tm_hour;
71 wday = tm.tm_wday + 1;
72 mday = tm.tm_mday;
73 mon = tm.tm_mon + 1;
74 year = tm.tm_year;
75
76 DPRINTFN("Real-time clock set to %s", asctime(&tm));
77 }
78
79 void
80 TsunamiIO::RTC::writeAddr(const uint8_t *data)
81 {
82 if (*data <= RTC_STAT_REGD)
83 addr = *data;
84 else
85 panic("RTC addresses over 0xD are not implemented.\n");
86 }
87
88 void
89 TsunamiIO::RTC::writeData(const uint8_t *data)
90 {
91 if (addr < RTC_STAT_REGA)
92 clock_data[addr] = *data;
93 else {
94 switch (addr) {
95 case RTC_STAT_REGA:
96 if (*data != (RTCA_32768HZ | RTCA_1024HZ))
97 panic("Unimplemented RTC register A value write!\n");
98 stat_regA = *data;
99 break;
100 case RTC_STAT_REGB:
101 if ((*data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR))
102 panic("Write to RTC reg B bits that are not implemented!\n");
103
104 if (*data & RTCB_PRDC_IE) {
105 if (!event.scheduled())
106 event.scheduleIntr();
107 } else {
108 if (event.scheduled())
109 event.deschedule();
110 }
111 stat_regB = *data;
112 break;
113 case RTC_STAT_REGC:
114 case RTC_STAT_REGD:
115 panic("RTC status registers C and D are not implemented.\n");
116 break;
117 }
118 }
119 }
120
121 void
122 TsunamiIO::RTC::readData(uint8_t *data)
123 {
124 if (addr < RTC_STAT_REGA)
125 *data = clock_data[addr];
126 else {
127 switch (addr) {
128 case RTC_STAT_REGA:
129 // toggle UIP bit for linux
130 stat_regA ^= RTCA_UIP;
131 *data = stat_regA;
132 break;
133 case RTC_STAT_REGB:
134 *data = stat_regB;
135 break;
136 case RTC_STAT_REGC:
137 case RTC_STAT_REGD:
138 *data = 0x00;
139 break;
140 }
141 }
142 }
143
144 void
145 TsunamiIO::RTC::serialize(std::ostream &os)
146 {
147 SERIALIZE_SCALAR(addr);
148 SERIALIZE_ARRAY(clock_data, sizeof(clock_data));
149 SERIALIZE_SCALAR(stat_regA);
150 SERIALIZE_SCALAR(stat_regB);
151
152 // serialize the RTC event
153 nameOut(os, csprintf("%s.event", name()));
154 event.serialize(os);
155 }
156
157 void
158 TsunamiIO::RTC::unserialize(Checkpoint *cp, const std::string &section)
159 {
160 UNSERIALIZE_SCALAR(addr);
161 UNSERIALIZE_ARRAY(clock_data, sizeof(clock_data));
162 UNSERIALIZE_SCALAR(stat_regA);
163 UNSERIALIZE_SCALAR(stat_regB);
164
165 // unserialze the event
166 event.unserialize(cp, csprintf("%s.event", section));
167 }
168
169 TsunamiIO::RTC::RTCEvent::RTCEvent(Tsunami*t, Tick i)
170 : Event(&mainEventQueue), tsunami(t), interval(i)
171 {
172 DPRINTF(MC146818, "RTC Event Initilizing\n");
173 schedule(curTick + interval);
174 }
175
176 void
177 TsunamiIO::RTC::RTCEvent::scheduleIntr()
178 {
179 schedule(curTick + interval);
180 }
181
182 void
183 TsunamiIO::RTC::RTCEvent::process()
184 {
185 DPRINTF(MC146818, "RTC Timer Interrupt\n");
186 schedule(curTick + interval);
187 //Actually interrupt the processor here
188 tsunami->cchip->postRTC();
189 }
190
191 const char *
192 TsunamiIO::RTC::RTCEvent::description()
193 {
194 return "tsunami RTC interrupt";
195 }
196
197 void
198 TsunamiIO::RTC::RTCEvent::serialize(std::ostream &os)
199 {
200 Tick time = when();
201 SERIALIZE_SCALAR(time);
202 }
203
204 void
205 TsunamiIO::RTC::RTCEvent::unserialize(Checkpoint *cp, const std::string &section)
206 {
207 Tick time;
208 UNSERIALIZE_SCALAR(time);
209 reschedule(time);
210 }
211
212 TsunamiIO::PITimer::PITimer()
213 : SimObject("PITimer"), counter0(counter[0]), counter1(counter[1]),
214 counter2(counter[2])
215 {
216
217 }
218
219 void
220 TsunamiIO::PITimer::writeControl(const uint8_t *data)
221 {
222 int rw;
223 int sel;
224
225 sel = GET_CTRL_SEL(*data);
226
227 if (sel == PIT_READ_BACK)
228 panic("PITimer Read-Back Command is not implemented.\n");
229
230 rw = GET_CTRL_RW(*data);
231
232 if (rw == PIT_RW_LATCH_COMMAND)
233 counter[sel].latchCount();
234 else {
235 counter[sel].setRW(rw);
236 counter[sel].setMode(GET_CTRL_MODE(*data));
237 counter[sel].setBCD(GET_CTRL_BCD(*data));
238 }
239 }
240
241 void
242 TsunamiIO::PITimer::serialize(std::ostream &os)
243 {
244 // serialize the counters
245 nameOut(os, csprintf("%s.counter0", name()));
246 counter0.serialize(os);
247
248 nameOut(os, csprintf("%s.counter1", name()));
249 counter1.serialize(os);
250
251 nameOut(os, csprintf("%s.counter2", name()));
252 counter2.serialize(os);
253 }
254
255 void
256 TsunamiIO::PITimer::unserialize(Checkpoint *cp, const std::string &section)
257 {
258 // unserialze the counters
259 counter0.unserialize(cp, csprintf("%s.counter0", section));
260 counter1.unserialize(cp, csprintf("%s.counter1", section));
261 counter2.unserialize(cp, csprintf("%s.counter2", section));
262 }
263
264 TsunamiIO::PITimer::Counter::Counter()
265 : SimObject("Counter"), event(this), count(0), latched_count(0), period(0),
266 mode(0), output_high(false), latch_on(false), read_byte(LSB),
267 write_byte(LSB)
268 {
269
270 }
271
272 void
273 TsunamiIO::PITimer::Counter::latchCount()
274 {
275 // behave like a real latch
276 if(!latch_on) {
277 latch_on = true;
278 read_byte = LSB;
279 latched_count = count;
280 }
281 }
282
283 void
284 TsunamiIO::PITimer::Counter::read(uint8_t *data)
285 {
286 if (latch_on) {
287 switch (read_byte) {
288 case LSB:
289 read_byte = MSB;
290 *data = (uint8_t)latched_count;
291 break;
292 case MSB:
293 read_byte = LSB;
294 latch_on = false;
295 *data = latched_count >> 8;
296 break;
297 }
298 } else {
299 switch (read_byte) {
300 case LSB:
301 read_byte = MSB;
302 *data = (uint8_t)count;
303 break;
304 case MSB:
305 read_byte = LSB;
306 *data = count >> 8;
307 break;
308 }
309 }
310 }
311
312 void
313 TsunamiIO::PITimer::Counter::write(const uint8_t *data)
314 {
315 switch (write_byte) {
316 case LSB:
317 count = (count & 0xFF00) | *data;
318
319 if (event.scheduled())
320 event.deschedule();
321 output_high = false;
322 write_byte = MSB;
323 break;
324
325 case MSB:
326 count = (count & 0x00FF) | (*data << 8);
327 period = count;
328
329 if (period > 0) {
330 DPRINTF(Tsunami, "Timer set to curTick + %d\n", count * event.interval);
331 event.schedule(curTick + count * event.interval);
332 }
333 write_byte = LSB;
334 break;
335 }
336 }
337
338 void
339 TsunamiIO::PITimer::Counter::setRW(int rw_val)
340 {
341 if (rw_val != PIT_RW_16BIT)
342 panic("Only LSB/MSB read/write is implemented.\n");
343 }
344
345 void
346 TsunamiIO::PITimer::Counter::setMode(int mode_val)
347 {
348 if(mode_val != PIT_MODE_INTTC && mode_val != PIT_MODE_RATEGEN &&
349 mode_val != PIT_MODE_SQWAVE)
350 panic("PIT mode %#x is not implemented: \n", mode_val);
351
352 mode = mode_val;
353 }
354
355 void
356 TsunamiIO::PITimer::Counter::setBCD(int bcd_val)
357 {
358 if (bcd_val != PIT_BCD_FALSE)
359 panic("PITimer does not implement BCD counts.\n");
360 }
361
362 bool
363 TsunamiIO::PITimer::Counter::outputHigh()
364 {
365 return output_high;
366 }
367
368 void
369 TsunamiIO::PITimer::Counter::serialize(std::ostream &os)
370 {
371 SERIALIZE_SCALAR(count);
372 SERIALIZE_SCALAR(latched_count);
373 SERIALIZE_SCALAR(period);
374 SERIALIZE_SCALAR(mode);
375 SERIALIZE_SCALAR(output_high);
376 SERIALIZE_SCALAR(latch_on);
377 SERIALIZE_SCALAR(read_byte);
378 SERIALIZE_SCALAR(write_byte);
379
380 // serialize the counter event
381 nameOut(os, csprintf("%s.event", name()));
382 event.serialize(os);
383 }
384
385 void
386 TsunamiIO::PITimer::Counter::unserialize(Checkpoint *cp, const std::string &section)
387 {
388 UNSERIALIZE_SCALAR(count);
389 UNSERIALIZE_SCALAR(latched_count);
390 UNSERIALIZE_SCALAR(period);
391 UNSERIALIZE_SCALAR(mode);
392 UNSERIALIZE_SCALAR(output_high);
393 UNSERIALIZE_SCALAR(latch_on);
394 UNSERIALIZE_SCALAR(read_byte);
395 UNSERIALIZE_SCALAR(write_byte);
396
397 // unserialze the counter event
398 event.unserialize(cp, csprintf("%s.event", section));
399 }
400
401 TsunamiIO::PITimer::Counter::CounterEvent::CounterEvent(Counter* c_ptr)
402 : Event(&mainEventQueue)
403 {
404 interval = (Tick)(Clock::Float::s / 1193180.0);
405 counter = c_ptr;
406 }
407
408 void
409 TsunamiIO::PITimer::Counter::CounterEvent::process()
410 {
411 DPRINTF(Tsunami, "Timer Interrupt\n");
412 switch (counter->mode) {
413 case PIT_MODE_INTTC:
414 counter->output_high = true;
415 case PIT_MODE_RATEGEN:
416 case PIT_MODE_SQWAVE:
417 break;
418 default:
419 panic("Unimplemented PITimer mode.\n");
420 }
421 }
422
423 const char *
424 TsunamiIO::PITimer::Counter::CounterEvent::description()
425 {
426 return "tsunami 8254 Interval timer";
427 }
428
429 void
430 TsunamiIO::PITimer::Counter::CounterEvent::serialize(std::ostream &os)
431 {
432 Tick time = scheduled() ? when() : 0;
433 SERIALIZE_SCALAR(time);
434 SERIALIZE_SCALAR(interval);
435 }
436
437 void
438 TsunamiIO::PITimer::Counter::CounterEvent::unserialize(Checkpoint *cp, const std::string &section)
439 {
440 Tick time;
441 UNSERIALIZE_SCALAR(time);
442 UNSERIALIZE_SCALAR(interval);
443 if (time)
444 schedule(time);
445 }
446
447 TsunamiIO::TsunamiIO(const string &name, Tsunami *t, time_t init_time,
448 Addr a, MemoryController *mmu, HierParams *hier, Bus *bus,
449 Tick pio_latency, Tick ci)
450 : PioDevice(name, t), addr(a), clockInterval(ci), tsunami(t), rtc(t, ci)
451 {
452 mmu->add_child(this, RangeSize(addr, size));
453
454 if (bus) {
455 pioInterface = newPioInterface(name, hier, bus, this,
456 &TsunamiIO::cacheAccess);
457 pioInterface->addAddrRange(RangeSize(addr, size));
458 pioLatency = pio_latency * bus->clockRate;
459 }
460
461 // set the back pointer from tsunami to myself
462 tsunami->io = this;
463
464 timerData = 0;
465 rtc.set_time(init_time == 0 ? time(NULL) : init_time);
466 picr = 0;
467 picInterrupting = false;
468 }
469
470 Tick
471 TsunamiIO::frequency() const
472 {
473 return Clock::Frequency / clockInterval;
474 }
475
476 Fault
477 TsunamiIO::read(MemReqPtr &req, uint8_t *data)
478 {
479 DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n",
480 req->vaddr, req->size, req->vaddr & 0xfff);
481
482 Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
483
484
485 switch(req->size) {
486 case sizeof(uint8_t):
487 switch(daddr) {
488 // PIC1 mask read
489 case TSDEV_PIC1_MASK:
490 *(uint8_t*)data = ~mask1;
491 return No_Fault;
492 case TSDEV_PIC2_MASK:
493 *(uint8_t*)data = ~mask2;
494 return No_Fault;
495 case TSDEV_PIC1_ISR:
496 // !!! If this is modified 64bit case needs to be too
497 // Pal code has to do a 64 bit physical read because there is
498 // no load physical byte instruction
499 *(uint8_t*)data = picr;
500 return No_Fault;
501 case TSDEV_PIC2_ISR:
502 // PIC2 not implemnted... just return 0
503 *(uint8_t*)data = 0x00;
504 return No_Fault;
505 case TSDEV_TMR0_DATA:
506 pitimer.counter0.read(data);
507 return No_Fault;
508 case TSDEV_TMR1_DATA:
509 pitimer.counter1.read(data);
510 return No_Fault;
511 case TSDEV_TMR2_DATA:
512 pitimer.counter2.read(data);
513 return No_Fault;
514 case TSDEV_RTC_DATA:
515 rtc.readData(data);
516 return No_Fault;
517 case TSDEV_CTRL_PORTB:
518 if (pitimer.counter2.outputHigh())
519 *data = PORTB_SPKR_HIGH;
520 else
521 *data = 0x00;
522 return No_Fault;
523 default:
524 panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
525 }
526 case sizeof(uint16_t):
527 case sizeof(uint32_t):
528 panic("I/O Read - invalid size - va %#x size %d\n",
529 req->vaddr, req->size);
530
531 case sizeof(uint64_t):
532 switch(daddr) {
533 case TSDEV_PIC1_ISR:
534 // !!! If this is modified 8bit case needs to be too
535 // Pal code has to do a 64 bit physical read because there is
536 // no load physical byte instruction
537 *(uint64_t*)data = (uint64_t)picr;
538 return No_Fault;
539 default:
540 panic("I/O Read - invalid size - va %#x size %d\n",
541 req->vaddr, req->size);
542 }
543
544 default:
545 panic("I/O Read - invalid size - va %#x size %d\n",
546 req->vaddr, req->size);
547 }
548 panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
549
550 return No_Fault;
551 }
552
553 Fault
554 TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
555 {
556
557 #if TRACING_ON
558 uint8_t dt = *(uint8_t*)data;
559 uint64_t dt64 = dt;
560 #endif
561
562 DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n",
563 req->vaddr, req->size, req->vaddr & 0xfff, dt64);
564
565 Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
566
567 switch(req->size) {
568 case sizeof(uint8_t):
569 switch(daddr) {
570 case TSDEV_PIC1_MASK:
571 mask1 = ~(*(uint8_t*)data);
572 if ((picr & mask1) && !picInterrupting) {
573 picInterrupting = true;
574 tsunami->cchip->postDRIR(55);
575 DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
576 }
577 if ((!(picr & mask1)) && picInterrupting) {
578 picInterrupting = false;
579 tsunami->cchip->clearDRIR(55);
580 DPRINTF(Tsunami, "clearing pic interrupt\n");
581 }
582 return No_Fault;
583 case TSDEV_PIC2_MASK:
584 mask2 = *(uint8_t*)data;
585 //PIC2 Not implemented to interrupt
586 return No_Fault;
587 case TSDEV_PIC1_ACK:
588 // clear the interrupt on the PIC
589 picr &= ~(1 << (*(uint8_t*)data & 0xF));
590 if (!(picr & mask1))
591 tsunami->cchip->clearDRIR(55);
592 return No_Fault;
593 case TSDEV_DMA1_CMND:
594 return No_Fault;
595 case TSDEV_DMA2_CMND:
596 return No_Fault;
597 case TSDEV_DMA1_MMASK:
598 return No_Fault;
599 case TSDEV_DMA2_MMASK:
600 return No_Fault;
601 case TSDEV_PIC2_ACK:
602 return No_Fault;
603 case TSDEV_DMA1_RESET:
604 return No_Fault;
605 case TSDEV_DMA2_RESET:
606 return No_Fault;
607 case TSDEV_DMA1_MODE:
608 mode1 = *(uint8_t*)data;
609 return No_Fault;
610 case TSDEV_DMA2_MODE:
611 mode2 = *(uint8_t*)data;
612 return No_Fault;
613 case TSDEV_DMA1_MASK:
614 case TSDEV_DMA2_MASK:
615 return No_Fault;
616 case TSDEV_TMR0_DATA:
617 pitimer.counter0.write(data);
618 return No_Fault;
619 case TSDEV_TMR1_DATA:
620 pitimer.counter1.write(data);
621 return No_Fault;
622 case TSDEV_TMR2_DATA:
623 pitimer.counter2.write(data);
624 return No_Fault;
625 case TSDEV_TMR_CTRL:
626 pitimer.writeControl(data);
627 return No_Fault;
628 case TSDEV_RTC_ADDR:
629 rtc.writeAddr(data);
630 return No_Fault;
631 case TSDEV_KBD:
632 return No_Fault;
633 case TSDEV_RTC_DATA:
634 rtc.writeData(data);
635 return No_Fault;
636 case TSDEV_CTRL_PORTB:
637 // System Control Port B not implemented
638 return No_Fault;
639 default:
640 panic("I/O Write - va%#x size %d data %#x\n", req->vaddr, req->size, (int)*data);
641 }
642 case sizeof(uint16_t):
643 case sizeof(uint32_t):
644 case sizeof(uint64_t):
645 default:
646 panic("I/O Write - invalid size - va %#x size %d\n",
647 req->vaddr, req->size);
648 }
649
650
651 return No_Fault;
652 }
653
654 void
655 TsunamiIO::postPIC(uint8_t bitvector)
656 {
657 //PIC2 Is not implemented, because nothing of interest there
658 picr |= bitvector;
659 if (picr & mask1) {
660 tsunami->cchip->postDRIR(55);
661 DPRINTF(Tsunami, "posting pic interrupt to cchip\n");
662 }
663 }
664
665 void
666 TsunamiIO::clearPIC(uint8_t bitvector)
667 {
668 //PIC2 Is not implemented, because nothing of interest there
669 picr &= ~bitvector;
670 if (!(picr & mask1)) {
671 tsunami->cchip->clearDRIR(55);
672 DPRINTF(Tsunami, "clearing pic interrupt to cchip\n");
673 }
674 }
675
676 Tick
677 TsunamiIO::cacheAccess(MemReqPtr &req)
678 {
679 return curTick + pioLatency;
680 }
681
682 void
683 TsunamiIO::serialize(std::ostream &os)
684 {
685 SERIALIZE_SCALAR(timerData);
686 SERIALIZE_SCALAR(mask1);
687 SERIALIZE_SCALAR(mask2);
688 SERIALIZE_SCALAR(mode1);
689 SERIALIZE_SCALAR(mode2);
690 SERIALIZE_SCALAR(picr);
691 SERIALIZE_SCALAR(picInterrupting);
692
693 // Serialize the timers
694 nameOut(os, csprintf("%s.pitimer", name()));
695 pitimer.serialize(os);
696 nameOut(os, csprintf("%s.rtc", name()));
697 rtc.serialize(os);
698 }
699
700 void
701 TsunamiIO::unserialize(Checkpoint *cp, const std::string &section)
702 {
703 UNSERIALIZE_SCALAR(timerData);
704 UNSERIALIZE_SCALAR(mask1);
705 UNSERIALIZE_SCALAR(mask2);
706 UNSERIALIZE_SCALAR(mode1);
707 UNSERIALIZE_SCALAR(mode2);
708 UNSERIALIZE_SCALAR(picr);
709 UNSERIALIZE_SCALAR(picInterrupting);
710
711 // Unserialize the timers
712 pitimer.unserialize(cp, csprintf("%s.pitimer", section));
713 rtc.unserialize(cp, csprintf("%s.rtc", section));
714 }
715
716 BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
717
718 SimObjectParam<Tsunami *> tsunami;
719 Param<time_t> time;
720 SimObjectParam<MemoryController *> mmu;
721 Param<Addr> addr;
722 SimObjectParam<Bus*> io_bus;
723 Param<Tick> pio_latency;
724 SimObjectParam<HierParams *> hier;
725 Param<Tick> frequency;
726
727 END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO)
728
729 BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
730
731 INIT_PARAM(tsunami, "Tsunami"),
732 INIT_PARAM(time, "System time to use (0 for actual time"),
733 INIT_PARAM(mmu, "Memory Controller"),
734 INIT_PARAM(addr, "Device Address"),
735 INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to", NULL),
736 INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
737 INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
738 INIT_PARAM(frequency, "clock interrupt frequency")
739
740 END_INIT_SIM_OBJECT_PARAMS(TsunamiIO)
741
742 CREATE_SIM_OBJECT(TsunamiIO)
743 {
744 return new TsunamiIO(getInstanceName(), tsunami, time, addr, mmu, hier,
745 io_bus, pio_latency, frequency);
746 }
747
748 REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO)