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
This commit is contained in:
parent
a994f6e07b
commit
e8bcecd0a0
6 changed files with 96 additions and 41 deletions
|
@ -134,6 +134,8 @@ IdeDisk::reset(int id)
|
||||||
memset(&cmdReg, 0, sizeof(CommandReg_t));
|
memset(&cmdReg, 0, sizeof(CommandReg_t));
|
||||||
memset(&curPrd.entry, 0, sizeof(PrdEntry_t));
|
memset(&curPrd.entry, 0, sizeof(PrdEntry_t));
|
||||||
|
|
||||||
|
cmdReg.error = 1;
|
||||||
|
|
||||||
dmaInterfaceBytes = 0;
|
dmaInterfaceBytes = 0;
|
||||||
curPrdAddr = 0;
|
curPrdAddr = 0;
|
||||||
curSector = 0;
|
curSector = 0;
|
||||||
|
@ -745,6 +747,7 @@ IdeDisk::intrPost()
|
||||||
|
|
||||||
// talk to controller to set interrupt
|
// talk to controller to set interrupt
|
||||||
if (ctrl)
|
if (ctrl)
|
||||||
|
ctrl->bmi_regs[BMIS0] |= IDEINTS;
|
||||||
ctrl->intrPost();
|
ctrl->intrPost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,13 +65,16 @@ TsunamiIO::RTCEvent::RTCEvent(Tsunami* t, Tick i)
|
||||||
void
|
void
|
||||||
TsunamiIO::RTCEvent::process()
|
TsunamiIO::RTCEvent::process()
|
||||||
{
|
{
|
||||||
|
static int intr_count = 0;
|
||||||
DPRINTF(MC146818, "RTC Timer Interrupt\n");
|
DPRINTF(MC146818, "RTC Timer Interrupt\n");
|
||||||
schedule(curTick + interval);
|
schedule(curTick + interval);
|
||||||
//Actually interrupt the processor here
|
//Actually interrupt the processor here
|
||||||
tsunami->cchip->postRTC();
|
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 *
|
const char *
|
||||||
|
@ -109,6 +112,11 @@ TsunamiIO::ClockEvent::ClockEvent()
|
||||||
|
|
||||||
DPRINTF(Tsunami, "Clock Event Initilizing\n");
|
DPRINTF(Tsunami, "Clock Event Initilizing\n");
|
||||||
mode = 0;
|
mode = 0;
|
||||||
|
|
||||||
|
current_count.whole = 0;
|
||||||
|
latched_count.whole = 0;
|
||||||
|
latch_on = false;
|
||||||
|
read_msb = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -119,6 +127,8 @@ TsunamiIO::ClockEvent::process()
|
||||||
status = 0x20; // set bit that linux is looking for
|
status = 0x20; // set bit that linux is looking for
|
||||||
else
|
else
|
||||||
schedule(curTick + interval);
|
schedule(curTick + interval);
|
||||||
|
|
||||||
|
current_count.whole--; //decrement count
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -127,6 +137,8 @@ TsunamiIO::ClockEvent::Program(int count)
|
||||||
DPRINTF(Tsunami, "Timer set to curTick + %d\n", count * interval);
|
DPRINTF(Tsunami, "Timer set to curTick + %d\n", count * interval);
|
||||||
schedule(curTick + count * interval);
|
schedule(curTick + count * interval);
|
||||||
status = 0;
|
status = 0;
|
||||||
|
|
||||||
|
current_count.whole = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
@ -147,6 +159,38 @@ TsunamiIO::ClockEvent::Status()
|
||||||
return 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
|
void
|
||||||
TsunamiIO::ClockEvent::serialize(std::ostream &os)
|
TsunamiIO::ClockEvent::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
|
@ -238,6 +282,9 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
|
||||||
case TSDEV_TMR_CTL:
|
case TSDEV_TMR_CTL:
|
||||||
*(uint8_t*)data = timer2.Status();
|
*(uint8_t*)data = timer2.Status();
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
|
case TSDEV_TMR0_DATA:
|
||||||
|
*(uint8_t *)data = timer0.Read();
|
||||||
|
return No_Fault;
|
||||||
case TSDEV_RTC_DATA:
|
case TSDEV_RTC_DATA:
|
||||||
switch(RTCAddress) {
|
switch(RTCAddress) {
|
||||||
case RTC_CNTRL_REGA:
|
case RTC_CNTRL_REGA:
|
||||||
|
@ -376,8 +423,24 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
|
||||||
case TSDEV_TMR_CTL:
|
case TSDEV_TMR_CTL:
|
||||||
return No_Fault;
|
return No_Fault;
|
||||||
case TSDEV_TMR2_CTL:
|
case TSDEV_TMR2_CTL:
|
||||||
if ((*(uint8_t*)data & 0x30) != 0x30)
|
switch((*(uint8_t*)data >> 4) & 0x3) {
|
||||||
panic("Only L/M write supported\n");
|
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) {
|
switch(*(uint8_t*)data >> 6) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
|
@ -75,6 +75,18 @@ class TsunamiIO : public PioDevice
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
/** The status of the PIT */
|
/** The status of the PIT */
|
||||||
uint8_t status;
|
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:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -110,6 +122,17 @@ class TsunamiIO : public PioDevice
|
||||||
*/
|
*/
|
||||||
uint8_t Status();
|
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.
|
* Serialize this object to the given output stream.
|
||||||
* @param os The stream to serialize to.
|
* @param os The stream to serialize to.
|
||||||
|
|
|
@ -55,32 +55,13 @@ FreebsdSystem::FreebsdSystem(Params *p)
|
||||||
Addr addr = 0;
|
Addr addr = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any time ide_delay_50ms, calibarte_delay or
|
* Any time DELAY is called just skip the function.
|
||||||
* determine_cpu_caches is called just skip the
|
* Replace calibrate_clocks with function below.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
skipDelayEvent = new SkipFuncEvent(&pcEventQueue, "DELAY");
|
skipDelayEvent = new SkipFuncEvent(&pcEventQueue, "DELAY");
|
||||||
if (kernelSymtab->findAddress("DELAY", addr))
|
if (kernelSymtab->findAddress("DELAY", addr))
|
||||||
skipDelayEvent->schedule(addr+sizeof(MachInst));
|
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");
|
skipCalibrateClocks = new FreebsdSkipCalibrateClocksEvent(&pcEventQueue, "calibrate_clocks");
|
||||||
if (kernelSymtab->findAddress("calibrate_clocks", addr))
|
if (kernelSymtab->findAddress("calibrate_clocks", addr))
|
||||||
skipCalibrateClocks->schedule(addr + sizeof(MachInst) * 2);
|
skipCalibrateClocks->schedule(addr + sizeof(MachInst) * 2);
|
||||||
|
@ -91,10 +72,6 @@ FreebsdSystem::FreebsdSystem(Params *p)
|
||||||
FreebsdSystem::~FreebsdSystem()
|
FreebsdSystem::~FreebsdSystem()
|
||||||
{
|
{
|
||||||
delete skipDelayEvent;
|
delete skipDelayEvent;
|
||||||
delete skipOROMEvent;
|
|
||||||
delete skipAicEvent;
|
|
||||||
delete skipATAEvent;
|
|
||||||
delete skipPNPEvent;
|
|
||||||
delete skipCalibrateClocks;
|
delete skipCalibrateClocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,24 +35,12 @@
|
||||||
#include "kern/freebsd/freebsd_events.hh"
|
#include "kern/freebsd/freebsd_events.hh"
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class skips lengthy functions in the FreeBSD kernel.
|
|
||||||
*/
|
|
||||||
class FreebsdSystem : public System
|
class FreebsdSystem : public System
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** PC based event to skip the DELAY call */
|
|
||||||
SkipFuncEvent *skipDelayEvent;
|
SkipFuncEvent *skipDelayEvent;
|
||||||
|
|
||||||
SkipFuncEvent *skipOROMEvent;
|
|
||||||
|
|
||||||
SkipFuncEvent *skipAicEvent;
|
|
||||||
|
|
||||||
SkipFuncEvent *skipPNPEvent;
|
|
||||||
|
|
||||||
SkipFuncEvent *skipATAEvent;
|
|
||||||
|
|
||||||
FreebsdSkipCalibrateClocksEvent *skipCalibrateClocks;
|
FreebsdSkipCalibrateClocksEvent *skipCalibrateClocks;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -13,6 +13,7 @@ class TsunamiCChip(FooPioDevice):
|
||||||
|
|
||||||
class TsunamiFake(FooPioDevice):
|
class TsunamiFake(FooPioDevice):
|
||||||
type = 'TsunamiFake'
|
type = 'TsunamiFake'
|
||||||
|
size = Param.Addr("Size of address range")
|
||||||
|
|
||||||
class TsunamiIO(FooPioDevice):
|
class TsunamiIO(FooPioDevice):
|
||||||
type = 'TsunamiIO'
|
type = 'TsunamiIO'
|
||||||
|
|
Loading…
Reference in a new issue