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 &section)
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 &section)
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 &section)
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}