tsunami_io.cc (5336:c7e21f4e5a2e) | tsunami_io.cc (5392:c3a45fac35f8) |
---|---|
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; --- 43 unchanged lines hidden (view full) --- 52#include "mem/packet_access.hh" 53#include "mem/port.hh" 54#include "sim/system.hh" 55 56using namespace std; 57//Should this be AlphaISA? 58using namespace TheISA; 59 | 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; --- 43 unchanged lines hidden (view full) --- 52#include "mem/packet_access.hh" 53#include "mem/port.hh" 54#include "sim/system.hh" 55 56using namespace std; 57//Should this be AlphaISA? 58using namespace TheISA; 59 |
60TsunamiIO::RTC::RTC(const string &n, Tsunami* tsunami, 61 const TsunamiIO::Params *p) 62 : _name(n), event(tsunami, p->frequency), addr(0) | 60TsunamiIO::TsunamiRTC::TsunamiRTC(const string &n, const TsunamiIOParams *p) : 61 MC146818(n, p->time, p->year_is_bcd, p->frequency), tsunami(p->tsunami) |
63{ | 62{ |
64 memset(clock_data, 0, sizeof(clock_data)); 65 stat_regA = RTCA_32768HZ | RTCA_1024HZ; 66 stat_regB = RTCB_PRDC_IE |RTCB_BIN | RTCB_24HR; 67 68 year = p->time.tm_year; 69 70 if (p->year_is_bcd) { 71 // The datasheet says that the year field can be either BCD or 72 // years since 1900. Linux seems to be happy with years since 73 // 1900. 74 year = year % 100; 75 int tens = year / 10; 76 int ones = year % 10; 77 year = (tens << 4) + ones; 78 } 79 80 // Unix is 0-11 for month, data seet says start at 1 81 mon = p->time.tm_mon + 1; 82 mday = p->time.tm_mday; 83 hour = p->time.tm_hour; 84 min = p->time.tm_min; 85 sec = p->time.tm_sec; 86 87 // Datasheet says 1 is sunday 88 wday = p->time.tm_wday + 1; 89 90 DPRINTFN("Real-time clock set to %s", asctime(&p->time)); | |
91} 92 | 63} 64 |
93void 94TsunamiIO::RTC::writeAddr(const uint8_t data) 95{ 96 if (data <= RTC_STAT_REGD) 97 addr = data; 98 else 99 panic("RTC addresses over 0xD are not implemented.\n"); 100} 101 102void 103TsunamiIO::RTC::writeData(const uint8_t data) 104{ 105 if (addr < RTC_STAT_REGA) 106 clock_data[addr] = data; 107 else { 108 switch (addr) { 109 case RTC_STAT_REGA: 110 if (data != (RTCA_32768HZ | RTCA_1024HZ)) 111 panic("Unimplemented RTC register A value write!\n"); 112 stat_regA = data; 113 break; 114 case RTC_STAT_REGB: 115 if ((data & ~(RTCB_PRDC_IE | RTCB_SQWE)) != (RTCB_BIN | RTCB_24HR)) 116 panic("Write to RTC reg B bits that are not implemented!\n"); 117 118 if (data & RTCB_PRDC_IE) { 119 if (!event.scheduled()) 120 event.scheduleIntr(); 121 } else { 122 if (event.scheduled()) 123 event.deschedule(); 124 } 125 stat_regB = data; 126 break; 127 case RTC_STAT_REGC: 128 case RTC_STAT_REGD: 129 panic("RTC status registers C and D are not implemented.\n"); 130 break; 131 } 132 } 133} 134 135uint8_t 136TsunamiIO::RTC::readData() 137{ 138 if (addr < RTC_STAT_REGA) 139 return clock_data[addr]; 140 else { 141 switch (addr) { 142 case RTC_STAT_REGA: 143 // toggle UIP bit for linux 144 stat_regA ^= RTCA_UIP; 145 return stat_regA; 146 break; 147 case RTC_STAT_REGB: 148 return stat_regB; 149 break; 150 case RTC_STAT_REGC: 151 case RTC_STAT_REGD: 152 return 0x00; 153 break; 154 default: 155 panic("Shouldn't be here"); 156 } 157 } 158} 159 160void 161TsunamiIO::RTC::serialize(const string &base, ostream &os) 162{ 163 paramOut(os, base + ".addr", addr); 164 arrayParamOut(os, base + ".clock_data", clock_data, sizeof(clock_data)); 165 paramOut(os, base + ".stat_regA", stat_regA); 166 paramOut(os, base + ".stat_regB", stat_regB); 167} 168 169void 170TsunamiIO::RTC::unserialize(const string &base, Checkpoint *cp, 171 const string §ion) 172{ 173 paramIn(cp, section, base + ".addr", addr); 174 arrayParamIn(cp, section, base + ".clock_data", clock_data, 175 sizeof(clock_data)); 176 paramIn(cp, section, base + ".stat_regA", stat_regA); 177 paramIn(cp, section, base + ".stat_regB", stat_regB); 178 179 // We're not unserializing the event here, but we need to 180 // rescehedule the event since curTick was moved forward by the 181 // checkpoint 182 event.reschedule(curTick + event.interval); 183} 184 185TsunamiIO::RTC::RTCEvent::RTCEvent(Tsunami*t, Tick i) 186 : Event(&mainEventQueue), tsunami(t), interval(i) 187{ 188 DPRINTF(MC146818, "RTC Event Initilizing\n"); 189 schedule(curTick + interval); 190} 191 192void 193TsunamiIO::RTC::RTCEvent::scheduleIntr() 194{ 195 schedule(curTick + interval); 196} 197 198void 199TsunamiIO::RTC::RTCEvent::process() 200{ 201 DPRINTF(MC146818, "RTC Timer Interrupt\n"); 202 schedule(curTick + interval); 203 //Actually interrupt the processor here 204 tsunami->cchip->postRTC(); 205} 206 207const char * 208TsunamiIO::RTC::RTCEvent::description() const 209{ 210 return "tsunami RTC interrupt"; 211} 212 | |
213TsunamiIO::PITimer::PITimer(const string &name) 214 : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"), 215 counter2(name + ".counter2") 216{ 217 counter[0] = &counter0; 218 counter[1] = &counter0; 219 counter[2] = &counter0; 220} --- 210 unchanged lines hidden (view full) --- 431const char * 432TsunamiIO::PITimer::Counter::CounterEvent::description() const 433{ 434 return "tsunami 8254 Interval timer"; 435} 436 437TsunamiIO::TsunamiIO(const Params *p) 438 : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"), | 65TsunamiIO::PITimer::PITimer(const string &name) 66 : _name(name), counter0(name + ".counter0"), counter1(name + ".counter1"), 67 counter2(name + ".counter2") 68{ 69 counter[0] = &counter0; 70 counter[1] = &counter0; 71 counter[2] = &counter0; 72} --- 210 unchanged lines hidden (view full) --- 283const char * 284TsunamiIO::PITimer::Counter::CounterEvent::description() const 285{ 286 return "tsunami 8254 Interval timer"; 287} 288 289TsunamiIO::TsunamiIO(const Params *p) 290 : BasicPioDevice(p), tsunami(p->tsunami), pitimer(p->name + "pitimer"), |
439 rtc(p->name + ".rtc", p->tsunami, p) | 291 rtc(p->name + ".rtc", p) |
440{ 441 pioSize = 0x100; 442 443 // set the back pointer from tsunami to myself 444 tsunami->io = this; 445 446 timerData = 0; 447 picr = 0; --- 42 unchanged lines hidden (view full) --- 490 break; 491 case TSDEV_TMR1_DATA: 492 pkt->set(pitimer.counter1.read()); 493 break; 494 case TSDEV_TMR2_DATA: 495 pkt->set(pitimer.counter2.read()); 496 break; 497 case TSDEV_RTC_DATA: | 292{ 293 pioSize = 0x100; 294 295 // set the back pointer from tsunami to myself 296 tsunami->io = this; 297 298 timerData = 0; 299 picr = 0; --- 42 unchanged lines hidden (view full) --- 342 break; 343 case TSDEV_TMR1_DATA: 344 pkt->set(pitimer.counter1.read()); 345 break; 346 case TSDEV_TMR2_DATA: 347 pkt->set(pitimer.counter2.read()); 348 break; 349 case TSDEV_RTC_DATA: |
498 pkt->set(rtc.readData()); | 350 pkt->set(rtc.readData(rtcAddr)); |
499 break; 500 case TSDEV_CTRL_PORTB: 501 if (pitimer.counter2.outputHigh()) 502 pkt->set(PORTB_SPKR_HIGH); 503 else 504 pkt->set(0x00); 505 break; 506 default: --- 61 unchanged lines hidden (view full) --- 568 break; 569 case TSDEV_TMR2_DATA: 570 pitimer.counter2.write(pkt->get<uint8_t>()); 571 break; 572 case TSDEV_TMR_CTRL: 573 pitimer.writeControl(pkt->get<uint8_t>()); 574 break; 575 case TSDEV_RTC_ADDR: | 351 break; 352 case TSDEV_CTRL_PORTB: 353 if (pitimer.counter2.outputHigh()) 354 pkt->set(PORTB_SPKR_HIGH); 355 else 356 pkt->set(0x00); 357 break; 358 default: --- 61 unchanged lines hidden (view full) --- 420 break; 421 case TSDEV_TMR2_DATA: 422 pitimer.counter2.write(pkt->get<uint8_t>()); 423 break; 424 case TSDEV_TMR_CTRL: 425 pitimer.writeControl(pkt->get<uint8_t>()); 426 break; 427 case TSDEV_RTC_ADDR: |
576 rtc.writeAddr(pkt->get<uint8_t>()); | 428 rtcAddr = pkt->get<uint8_t>(); |
577 break; 578 case TSDEV_RTC_DATA: | 429 break; 430 case TSDEV_RTC_DATA: |
579 rtc.writeData(pkt->get | 431 rtc.writeData(rtcAddr, pkt->get<uint8_t>()); |
580 break; 581 case TSDEV_KBD: 582 case TSDEV_DMA1_CMND: 583 case TSDEV_DMA2_CMND: 584 case TSDEV_DMA1_MMASK: 585 case TSDEV_DMA2_MMASK: 586 case TSDEV_PIC2_ACK: 587 case TSDEV_DMA1_RESET: --- 30 unchanged lines hidden (view full) --- 618 tsunami->cchip->clearDRIR(55); 619 DPRINTF(Tsunami, "clearing pic interrupt to cchip\n"); 620 } 621} 622 623void 624TsunamiIO::serialize(ostream &os) 625{ | 432 break; 433 case TSDEV_KBD: 434 case TSDEV_DMA1_CMND: 435 case TSDEV_DMA2_CMND: 436 case TSDEV_DMA1_MMASK: 437 case TSDEV_DMA2_MMASK: 438 case TSDEV_PIC2_ACK: 439 case TSDEV_DMA1_RESET: --- 30 unchanged lines hidden (view full) --- 470 tsunami->cchip->clearDRIR(55); 471 DPRINTF(Tsunami, "clearing pic interrupt to cchip\n"); 472 } 473} 474 475void 476TsunamiIO::serialize(ostream &os) 477{ |
478 SERIALIZE_SCALAR(rtcAddr); |
|
626 SERIALIZE_SCALAR(timerData); 627 SERIALIZE_SCALAR(mask1); 628 SERIALIZE_SCALAR(mask2); 629 SERIALIZE_SCALAR(mode1); 630 SERIALIZE_SCALAR(mode2); 631 SERIALIZE_SCALAR(picr); 632 SERIALIZE_SCALAR(picInterrupting); 633 634 // Serialize the timers 635 pitimer.serialize("pitimer", os); 636 rtc.serialize("rtc", os); 637} 638 639void 640TsunamiIO::unserialize(Checkpoint *cp, const string §ion) 641{ | 479 SERIALIZE_SCALAR(timerData); 480 SERIALIZE_SCALAR(mask1); 481 SERIALIZE_SCALAR(mask2); 482 SERIALIZE_SCALAR(mode1); 483 SERIALIZE_SCALAR(mode2); 484 SERIALIZE_SCALAR(picr); 485 SERIALIZE_SCALAR(picInterrupting); 486 487 // Serialize the timers 488 pitimer.serialize("pitimer", os); 489 rtc.serialize("rtc", os); 490} 491 492void 493TsunamiIO::unserialize(Checkpoint *cp, const string §ion) 494{ |
495 UNSERIALIZE_SCALAR(rtcAddr); |
|
642 UNSERIALIZE_SCALAR(timerData); 643 UNSERIALIZE_SCALAR(mask1); 644 UNSERIALIZE_SCALAR(mask2); 645 UNSERIALIZE_SCALAR(mode1); 646 UNSERIALIZE_SCALAR(mode2); 647 UNSERIALIZE_SCALAR(picr); 648 UNSERIALIZE_SCALAR(picInterrupting); 649 650 // Unserialize the timers 651 pitimer.unserialize("pitimer", cp, section); 652 rtc.unserialize("rtc", cp, section); 653} 654 655TsunamiIO * 656TsunamiIOParams::create() 657{ 658 return new TsunamiIO(this); 659} | 496 UNSERIALIZE_SCALAR(timerData); 497 UNSERIALIZE_SCALAR(mask1); 498 UNSERIALIZE_SCALAR(mask2); 499 UNSERIALIZE_SCALAR(mode1); 500 UNSERIALIZE_SCALAR(mode2); 501 UNSERIALIZE_SCALAR(picr); 502 UNSERIALIZE_SCALAR(picInterrupting); 503 504 // Unserialize the timers 505 pitimer.unserialize("pitimer", cp, section); 506 rtc.unserialize("rtc", cp, section); 507} 508 509TsunamiIO * 510TsunamiIOParams::create() 511{ 512 return new TsunamiIO(this); 513} |