tsunami_io.cc revision 1817
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 52using namespace std; 53 54TsunamiIO::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 62void 63TsunamiIO::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 79void 80TsunamiIO::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 88void 89TsunamiIO::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 121void 122TsunamiIO::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 144void 145TsunamiIO::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 157void 158TsunamiIO::RTC::unserialize(Checkpoint *cp, const std::string §ion) 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 169TsunamiIO::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 176void 177TsunamiIO::RTC::RTCEvent::scheduleIntr() 178{ 179 schedule(curTick + interval); 180} 181 182void 183TsunamiIO::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 191const char * 192TsunamiIO::RTC::RTCEvent::description() 193{ 194 return "tsunami RTC interrupt"; 195} 196 197void 198TsunamiIO::RTC::RTCEvent::serialize(std::ostream &os) 199{ 200 Tick time = when(); 201 SERIALIZE_SCALAR(time); 202} 203 204void 205TsunamiIO::RTC::RTCEvent::unserialize(Checkpoint *cp, const std::string §ion) 206{ 207 Tick time; 208 UNSERIALIZE_SCALAR(time); 209 reschedule(time); 210} 211 212TsunamiIO::PITimer::PITimer() 213 : SimObject("PITimer"), counter0(counter[0]), counter1(counter[1]), 214 counter2(counter[2]) 215{ 216 217} 218 219void 220TsunamiIO::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 241void 242TsunamiIO::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 255void 256TsunamiIO::PITimer::unserialize(Checkpoint *cp, const std::string §ion) 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 264TsunamiIO::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 272void 273TsunamiIO::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 283void 284TsunamiIO::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 312void 313TsunamiIO::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 338void 339TsunamiIO::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 345void 346TsunamiIO::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 355void 356TsunamiIO::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 362bool 363TsunamiIO::PITimer::Counter::outputHigh() 364{ 365 return output_high; 366} 367 368void 369TsunamiIO::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 385void 386TsunamiIO::PITimer::Counter::unserialize(Checkpoint *cp, const std::string §ion) 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 401TsunamiIO::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 408void 409TsunamiIO::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 423const char * 424TsunamiIO::PITimer::Counter::CounterEvent::description() 425{ 426 return "tsunami 8254 Interval timer"; 427} 428 429void 430TsunamiIO::PITimer::Counter::CounterEvent::serialize(std::ostream &os) 431{ 432 Tick time = scheduled() ? when() : 0; 433 SERIALIZE_SCALAR(time); 434 SERIALIZE_SCALAR(interval); 435} 436 437void 438TsunamiIO::PITimer::Counter::CounterEvent::unserialize(Checkpoint *cp, const std::string §ion) 439{ 440 Tick time; 441 UNSERIALIZE_SCALAR(time); 442 UNSERIALIZE_SCALAR(interval); 443 if (time) 444 schedule(time); 445} 446 447TsunamiIO::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 470Tick 471TsunamiIO::frequency() const 472{ 473 return Clock::Frequency / clockInterval; 474} 475 476Fault 477TsunamiIO::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 553Fault 554TsunamiIO::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 654void 655TsunamiIO::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 665void 666TsunamiIO::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 676Tick 677TsunamiIO::cacheAccess(MemReqPtr &req) 678{ 679 return curTick + pioLatency; 680} 681 682void 683TsunamiIO::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 700void 701TsunamiIO::unserialize(Checkpoint *cp, const std::string §ion) 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 716BEGIN_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 727END_DECLARE_SIM_OBJECT_PARAMS(TsunamiIO) 728 729BEGIN_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 740END_INIT_SIM_OBJECT_PARAMS(TsunamiIO) 741 742CREATE_SIM_OBJECT(TsunamiIO) 743{ 744 return new TsunamiIO(getInstanceName(), tsunami, time, addr, mmu, hier, 745 io_bus, pio_latency, frequency); 746} 747 748REGISTER_SIM_OBJECT("TsunamiIO", TsunamiIO) 749