From e8bcecd0a04638e9d9e6306cbe515c40e9ba0817 Mon Sep 17 00:00:00 2001 From: Benjamin Nash Date: Thu, 23 Jun 2005 16:27:06 -0400 Subject: [PATCH] Changed timer functionality, ide disk interrupts, and TsunamiFake class to improve FreeBSD compatibility. dev/ide_disk.cc: Make ide disk set interrupts correctly. dev/tsunami_io.cc: dev/tsunami_io.hh: Implement read of timer counts. kern/freebsd/freebsd_system.cc: kern/freebsd/freebsd_system.hh: Remove SkipFuncEvents that we don't need to skip. python/m5/objects/Tsunami.py: Add size parameter to TsunamiFake class. --HG-- extra : convert_revision : a87e74f2cac0036060ca8cb3fde4760d8c91a5db --- dev/ide_disk.cc | 3 ++ dev/tsunami_io.cc | 71 ++++++++++++++++++++++++++++++++-- dev/tsunami_io.hh | 23 +++++++++++ kern/freebsd/freebsd_system.cc | 27 +------------ kern/freebsd/freebsd_system.hh | 12 ------ python/m5/objects/Tsunami.py | 1 + 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 * @@ -147,6 +159,38 @@ TsunamiIO::ClockEvent::Status() return 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) { @@ -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'