summaryrefslogtreecommitdiff
path: root/dev/tsunami_io.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dev/tsunami_io.cc')
-rw-r--r--dev/tsunami_io.cc142
1 files changed, 139 insertions, 3 deletions
diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc
index da1062237..82fe40e0a 100644
--- a/dev/tsunami_io.cc
+++ b/dev/tsunami_io.cc
@@ -52,11 +52,14 @@ using namespace std;
#define UNIX_YEAR_OFFSET 52
+struct tm TsunamiIO::tm = { 0 };
+
// Timer Event for Periodic interrupt of RTC
TsunamiIO::RTCEvent::RTCEvent(Tsunami* t, Tick i)
: Event(&mainEventQueue), tsunami(t), interval(i)
{
DPRINTF(MC146818, "RTC Event Initilizing\n");
+ intr_count = 0;
schedule(curTick + interval);
}
@@ -67,6 +70,11 @@ TsunamiIO::RTCEvent::process()
schedule(curTick + interval);
//Actually interrupt the processor here
tsunami->cchip->postRTC();
+
+ if (intr_count == 1023)
+ tm.tm_sec = (tm.tm_sec + 1) % 60;
+
+ intr_count = (intr_count + 1) % 1024;
}
const char *
@@ -104,6 +112,11 @@ TsunamiIO::ClockEvent::ClockEvent()
DPRINTF(Tsunami, "Clock Event Initilizing\n");
mode = 0;
+
+ current_count = 0;
+ latched_count = 0;
+ latch_on = false;
+ read_byte = READ_LSB;
}
void
@@ -114,6 +127,8 @@ TsunamiIO::ClockEvent::process()
status = 0x20; // set bit that linux is looking for
else
schedule(curTick + interval);
+
+ current_count--; //decrement count
}
void
@@ -122,6 +137,8 @@ TsunamiIO::ClockEvent::Program(int count)
DPRINTF(Tsunami, "Timer set to curTick + %d\n", count * interval);
schedule(curTick + count * interval);
status = 0;
+
+ current_count = (uint16_t)count;
}
const char *
@@ -143,6 +160,51 @@ TsunamiIO::ClockEvent::Status()
}
void
+TsunamiIO::ClockEvent::LatchCount()
+{
+ // behave like a real latch
+ if(!latch_on) {
+ latch_on = true;
+ read_byte = READ_LSB;
+ latched_count = current_count;
+ }
+}
+
+uint8_t
+TsunamiIO::ClockEvent::Read()
+{
+ uint8_t result = 0;
+
+ if(latch_on) {
+ switch (read_byte) {
+ case READ_LSB:
+ read_byte = READ_MSB;
+ result = (uint8_t)latched_count;
+ break;
+ case READ_MSB:
+ read_byte = READ_LSB;
+ latch_on = false;
+ result = latched_count >> 8;
+ break;
+ }
+ } else {
+ switch (read_byte) {
+ case READ_LSB:
+ read_byte = READ_MSB;
+ result = (uint8_t)current_count;
+ break;
+ case READ_MSB:
+ read_byte = READ_LSB;
+ result = current_count >> 8;
+ break;
+ }
+ }
+
+ return result;
+}
+
+
+void
TsunamiIO::ClockEvent::serialize(std::ostream &os)
{
Tick time = scheduled() ? when() : 0;
@@ -213,6 +275,13 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
switch(req->size) {
case sizeof(uint8_t):
switch(daddr) {
+ // PIC1 mask read
+ case TSDEV_PIC1_MASK:
+ *(uint8_t*)data = ~mask1;
+ return No_Fault;
+ case TSDEV_PIC2_MASK:
+ *(uint8_t*)data = ~mask2;
+ return No_Fault;
case TSDEV_PIC1_ISR:
// !!! If this is modified 64bit case needs to be too
// Pal code has to do a 64 bit physical read because there is
@@ -226,6 +295,9 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
case TSDEV_TMR_CTL:
*(uint8_t*)data = timer2.Status();
return No_Fault;
+ case TSDEV_TMR0_DATA:
+ *(uint8_t *)data = timer0.Read();
+ return No_Fault;
case TSDEV_RTC_DATA:
switch(RTCAddress) {
case RTC_CNTRL_REGA:
@@ -243,6 +315,12 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
return No_Fault;
case RTC_CNTRL_REGD:
panic("RTC Control Register D not implemented");
+ case RTC_SEC_ALRM:
+ case RTC_MIN_ALRM:
+ case RTC_HR_ALRM:
+ // RTC alarm functionality is not currently implemented
+ *(uint8_t *)data = 0x00;
+ return No_Fault;
case RTC_SEC:
*(uint8_t *)data = tm.tm_sec;
return No_Fault;
@@ -257,6 +335,7 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
return No_Fault;
case RTC_DOM:
*(uint8_t *)data = tm.tm_mday;
+ return No_Fault;
case RTC_MON:
*(uint8_t *)data = tm.tm_mon + 1;
return No_Fault;
@@ -267,6 +346,14 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
panic("Unknown RTC Address\n");
}
+ /* Added for keyboard reads */
+ case TSDEV_KBD:
+ *(uint8_t *)data = 0x00;
+ return No_Fault;
+ /* Added for ATA PCI DMA */
+ case ATA_PCI_DMA:
+ *(uint8_t *)data = 0x00;
+ return No_Fault;
default:
panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
}
@@ -355,8 +442,24 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
case TSDEV_TMR_CTL:
return No_Fault;
case TSDEV_TMR2_CTL:
- if ((*(uint8_t*)data & 0x30) != 0x30)
- panic("Only L/M write supported\n");
+ switch((*(uint8_t*)data >> 4) & 0x3) {
+ case 0x0:
+ switch(*(uint8_t*)data >> 6) {
+ case 0:
+ timer0.LatchCount();
+ break;
+ case 2:
+ timer2.LatchCount();
+ break;
+ default:
+ panic("Read Back Command not implemented\n");
+ }
+ break;
+ case 0x3:
+ break;
+ default:
+ panic("Only L/M write and Counter-Latch read supported\n");
+ }
switch(*(uint8_t*)data >> 6) {
case 0:
@@ -396,8 +499,41 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
case TSDEV_RTC_ADDR:
RTCAddress = *(uint8_t*)data;
return No_Fault;
+ case TSDEV_KBD:
+ return No_Fault;
case TSDEV_RTC_DATA:
- panic("RTC Write not implmented (rtc.o won't work)\n");
+ switch(RTCAddress) {
+ case RTC_CNTRL_REGA:
+ return No_Fault;
+ case RTC_CNTRL_REGB:
+ return No_Fault;
+ case RTC_CNTRL_REGC:
+ return No_Fault;
+ case RTC_CNTRL_REGD:
+ return No_Fault;
+ case RTC_SEC:
+ tm.tm_sec = *(uint8_t *)data;
+ return No_Fault;
+ case RTC_MIN:
+ tm.tm_min = *(uint8_t *)data;
+ return No_Fault;
+ case RTC_HR:
+ tm.tm_hour = *(uint8_t *)data;
+ return No_Fault;
+ case RTC_DOW:
+ tm.tm_wday = *(uint8_t *)data;
+ return No_Fault;
+ case RTC_DOM:
+ tm.tm_mday = *(uint8_t *)data;
+ return No_Fault;
+ case RTC_MON:
+ tm.tm_mon = *(uint8_t *)data - 1;
+ return No_Fault;
+ case RTC_YEAR:
+ tm.tm_year = *(uint8_t *)data + UNIX_YEAR_OFFSET;
+ return No_Fault;
+ //panic("RTC Write not implmented (rtc.o won't work)\n");
+ }
default:
panic("I/O Write - va%#x size %d\n", req->vaddr, req->size);
}