summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dev/ide_disk.cc3
-rw-r--r--dev/tsunami_io.cc71
-rw-r--r--dev/tsunami_io.hh23
-rw-r--r--kern/freebsd/freebsd_system.cc27
-rw-r--r--kern/freebsd/freebsd_system.hh12
-rw-r--r--python/m5/objects/Tsunami.py1
6 files changed, 96 insertions, 41 deletions
diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc
index 23d04bb5e..ae394c69e 100644
--- a/dev/ide_disk.cc
+++ b/dev/ide_disk.cc
@@ -134,6 +134,8 @@ IdeDisk::reset(int id)
memset(&cmdReg, 0, sizeof(CommandReg_t));
memset(&curPrd.entry, 0, sizeof(PrdEntry_t));
+ cmdReg.error = 1;
+
dmaInterfaceBytes = 0;
curPrdAddr = 0;
curSector = 0;
@@ -745,6 +747,7 @@ IdeDisk::intrPost()
// talk to controller to set interrupt
if (ctrl)
+ ctrl->bmi_regs[BMIS0] |= IDEINTS;
ctrl->intrPost();
}
diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc
index 7db55b321..963bdc321 100644
--- a/dev/tsunami_io.cc
+++ b/dev/tsunami_io.cc
@@ -65,13 +65,16 @@ TsunamiIO::RTCEvent::RTCEvent(Tsunami* t, Tick i)
void
TsunamiIO::RTCEvent::process()
{
+ static int intr_count = 0;
DPRINTF(MC146818, "RTC Timer Interrupt\n");
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;
- // For FreeBSD
- tm.tm_sec++;
}
const char *
@@ -109,6 +112,11 @@ TsunamiIO::ClockEvent::ClockEvent()
DPRINTF(Tsunami, "Clock Event Initilizing\n");
mode = 0;
+
+ current_count.whole = 0;
+ latched_count.whole = 0;
+ latch_on = false;
+ read_msb = false;
}
void
@@ -119,6 +127,8 @@ TsunamiIO::ClockEvent::process()
status = 0x20; // set bit that linux is looking for
else
schedule(curTick + interval);
+
+ current_count.whole--; //decrement count
}
void
@@ -127,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.whole = count;
}
const char *
@@ -148,6 +160,38 @@ TsunamiIO::ClockEvent::Status()
}
void
+TsunamiIO::ClockEvent::LatchCount()
+{
+ if(!latch_on) {
+ latch_on = true;
+ read_msb = false;
+ latched_count.whole = current_count.whole;
+ }
+}
+
+uint8_t
+TsunamiIO::ClockEvent::Read()
+{
+ if(latch_on) {
+ if(!read_msb) {
+ read_msb = true;
+ return latched_count.half.lsb;
+ } else {
+ latch_on = false;
+ return latched_count.half.msb;
+ }
+ } else {
+ if(!read_msb) {
+ read_msb = true;
+ return current_count.half.lsb;
+ } else {
+ return current_count.half.msb;
+ }
+ }
+}
+
+
+void
TsunamiIO::ClockEvent::serialize(std::ostream &os)
{
Tick time = scheduled() ? when() : 0;
@@ -238,6 +282,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:
@@ -376,8 +423,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:
diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh
index 86c739285..dca651d4b 100644
--- a/dev/tsunami_io.hh
+++ b/dev/tsunami_io.hh
@@ -75,6 +75,18 @@ class TsunamiIO : public PioDevice
uint8_t mode;
/** The status of the PIT */
uint8_t status;
+ /** The counts (current and latched) of the PIT */
+ union {
+ uint16_t whole;
+ struct {
+ uint8_t msb;
+ uint8_t lsb;
+ } half;
+ } current_count, latched_count;
+
+ /** Thse state of the output latch of the PIT */
+ bool latch_on;
+ bool read_msb;
public:
/**
@@ -111,6 +123,17 @@ class TsunamiIO : public PioDevice
uint8_t Status();
/**
+ * Latch the count of the PIT.
+ */
+ void LatchCount();
+
+ /**
+ * The current PIT count.
+ * @return the count of the PIT
+ */
+ uint8_t Read();
+
+ /**
* Serialize this object to the given output stream.
* @param os The stream to serialize to.
*/
diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc
index 08d1af824..d7d32cc66 100644
--- a/kern/freebsd/freebsd_system.cc
+++ b/kern/freebsd/freebsd_system.cc
@@ -55,32 +55,13 @@ FreebsdSystem::FreebsdSystem(Params *p)
Addr addr = 0;
/**
- * Any time ide_delay_50ms, calibarte_delay or
- * determine_cpu_caches is called just skip the
- * function. Currently determine_cpu_caches only is used put
- * information in proc, however if that changes in the future we
- * will have to fill in the cache size variables appropriately.
+ * Any time DELAY is called just skip the function.
+ * Replace calibrate_clocks with function below.
*/
skipDelayEvent = new SkipFuncEvent(&pcEventQueue, "DELAY");
if (kernelSymtab->findAddress("DELAY", addr))
skipDelayEvent->schedule(addr+sizeof(MachInst));
- skipOROMEvent = new SkipFuncEvent(&pcEventQueue, "orm_identify");
- if (kernelSymtab->findAddress("orm_identify", addr))
- skipOROMEvent->schedule(addr+sizeof(MachInst));
-
- skipAicEvent = new SkipFuncEvent(&pcEventQueue, "ahc_isa_identify");
- if (kernelSymtab->findAddress("ahc_isa_identify", addr))
- skipAicEvent->schedule(addr+sizeof(MachInst));
-
- skipPNPEvent = new SkipFuncEvent(&pcEventQueue, "pnp_identify");
- if (kernelSymtab->findAddress("pnp_identify", addr))
- skipPNPEvent->schedule(addr+sizeof(MachInst));
-
- skipATAEvent = new SkipFuncEvent(&pcEventQueue, "ata_attach");
- if (kernelSymtab->findAddress("ata_attach", addr))
- skipATAEvent->schedule(addr+sizeof(MachInst));
-
skipCalibrateClocks = new FreebsdSkipCalibrateClocksEvent(&pcEventQueue, "calibrate_clocks");
if (kernelSymtab->findAddress("calibrate_clocks", addr))
skipCalibrateClocks->schedule(addr + sizeof(MachInst) * 2);
@@ -91,10 +72,6 @@ FreebsdSystem::FreebsdSystem(Params *p)
FreebsdSystem::~FreebsdSystem()
{
delete skipDelayEvent;
- delete skipOROMEvent;
- delete skipAicEvent;
- delete skipATAEvent;
- delete skipPNPEvent;
delete skipCalibrateClocks;
}
diff --git a/kern/freebsd/freebsd_system.hh b/kern/freebsd/freebsd_system.hh
index 3e9867733..a3c5f8b92 100644
--- a/kern/freebsd/freebsd_system.hh
+++ b/kern/freebsd/freebsd_system.hh
@@ -35,24 +35,12 @@
#include "kern/freebsd/freebsd_events.hh"
-/**
- * This class skips lengthy functions in the FreeBSD kernel.
- */
class FreebsdSystem : public System
{
private:
- /** PC based event to skip the DELAY call */
SkipFuncEvent *skipDelayEvent;
- SkipFuncEvent *skipOROMEvent;
-
- SkipFuncEvent *skipAicEvent;
-
- SkipFuncEvent *skipPNPEvent;
-
- SkipFuncEvent *skipATAEvent;
-
FreebsdSkipCalibrateClocksEvent *skipCalibrateClocks;
public:
diff --git a/python/m5/objects/Tsunami.py b/python/m5/objects/Tsunami.py
index c8fd94e2c..8e16d5d1e 100644
--- a/python/m5/objects/Tsunami.py
+++ b/python/m5/objects/Tsunami.py
@@ -13,6 +13,7 @@ class TsunamiCChip(FooPioDevice):
class TsunamiFake(FooPioDevice):
type = 'TsunamiFake'
+ size = Param.Addr("Size of address range")
class TsunamiIO(FooPioDevice):
type = 'TsunamiIO'