Get rid of the code that delays PIO write accesses

until the cache access occurs.  The fundamental problem
is that a subsequent read that occurs functionally will
get a functionally incorrect result that can break
driver code.

dev/ns_gige.cc:
dev/ns_gige.hh:
dev/sinic.cc:
dev/sinic.hh:
    get rid of pio_delay write and the associated code to move
    the write to the cache access function
dev/sinicreg.hh:
    no more write delays
python/m5/objects/Ethernet.py:
    get rid of pio_delay write

--HG--
extra : convert_revision : 1dcb51b8f4514e717bc334a782dfdf06d29ae69d
This commit is contained in:
Nathan Binkert 2006-02-20 23:41:50 -05:00
parent 7c642b7106
commit 3a0102536b
6 changed files with 28 additions and 131 deletions

View file

@ -131,8 +131,6 @@ NSGigE::NSGigE(Params *p)
} else if (p->payload_bus) } else if (p->payload_bus)
panic("Must define a header bus if defining a payload bus"); panic("Must define a header bus if defining a payload bus");
pioDelayWrite = p->pio_delay_write && pioInterface;
intrDelay = p->intr_delay; intrDelay = p->intr_delay;
dmaReadDelay = p->dma_read_delay; dmaReadDelay = p->dma_read_delay;
dmaWriteDelay = p->dma_write_delay; dmaWriteDelay = p->dma_write_delay;
@ -805,13 +803,6 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
} else if (daddr > 0x3FC) } else if (daddr > 0x3FC)
panic("Something is messed up!\n"); panic("Something is messed up!\n");
if (pioDelayWrite) {
int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff;
if (cpu >= writeQueue.size())
writeQueue.resize(cpu + 1);
writeQueue[cpu].push_back(RegWriteData(daddr, *(uint32_t *)data));
}
if (req->size == sizeof(uint32_t)) { if (req->size == sizeof(uint32_t)) {
uint32_t reg = *(uint32_t *)data; uint32_t reg = *(uint32_t *)data;
uint16_t rfaddr; uint16_t rfaddr;
@ -824,25 +815,21 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
if (reg & CR_TXD) { if (reg & CR_TXD) {
txEnable = false; txEnable = false;
} else if (reg & CR_TXE) { } else if (reg & CR_TXE) {
if (!pioDelayWrite) {
txEnable = true; txEnable = true;
// the kernel is enabling the transmit machine // the kernel is enabling the transmit machine
if (txState == txIdle) if (txState == txIdle)
txKick(); txKick();
} }
}
if (reg & CR_RXD) { if (reg & CR_RXD) {
rxEnable = false; rxEnable = false;
} else if (reg & CR_RXE) { } else if (reg & CR_RXE) {
if (!pioDelayWrite) {
rxEnable = true; rxEnable = true;
if (rxState == rxIdle) if (rxState == rxIdle)
rxKick(); rxKick();
} }
}
if (reg & CR_TXR) if (reg & CR_TXR)
txReset(); txReset();
@ -2949,38 +2936,9 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
Tick Tick
NSGigE::cacheAccess(MemReqPtr &req) NSGigE::cacheAccess(MemReqPtr &req)
{ {
Addr daddr = req->paddr & 0xfff;
DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n", DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n",
req->paddr, daddr); req->paddr, req->paddr & 0xfff);
if (!pioDelayWrite || !req->cmd.isWrite())
return curTick + pioLatency;
int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff;
std::list<RegWriteData> &wq = writeQueue[cpu];
if (wq.empty())
panic("WriteQueue for cpu %d empty timing daddr=%#x", cpu, daddr);
const RegWriteData &data = wq.front();
if (data.daddr != daddr)
panic("read mismatch on cpu %d, daddr functional=%#x timing=%#x",
cpu, data.daddr, daddr);
if (daddr == CR) {
if ((data.value & (CR_TXD | CR_TXE)) == CR_TXE) {
txEnable = true;
if (txState == txIdle)
txKick();
}
if ((data.value & (CR_RXD | CR_RXE)) == CR_RXE) {
rxEnable = true;
if (rxState == rxIdle)
rxKick();
}
}
wq.pop_front();
return curTick + pioLatency; return curTick + pioLatency;
} }
@ -3040,7 +2998,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
Param<Tick> dma_write_factor; Param<Tick> dma_write_factor;
Param<bool> dma_no_allocate; Param<bool> dma_no_allocate;
Param<Tick> pio_latency; Param<Tick> pio_latency;
Param<bool> pio_delay_write;
Param<Tick> intr_delay; Param<Tick> intr_delay;
Param<Tick> rx_delay; Param<Tick> rx_delay;
@ -3081,7 +3038,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
INIT_PARAM(dma_write_factor, "multiplier for dma writes"), INIT_PARAM(dma_write_factor, "multiplier for dma writes"),
INIT_PARAM(dma_no_allocate, "Should DMA reads allocate cache lines"), INIT_PARAM(dma_no_allocate, "Should DMA reads allocate cache lines"),
INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"), INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"),
INIT_PARAM(pio_delay_write, ""),
INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"), INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"),
INIT_PARAM(rx_delay, "Receive Delay"), INIT_PARAM(rx_delay, "Receive Delay"),
@ -3126,7 +3082,6 @@ CREATE_SIM_OBJECT(NSGigE)
params->dma_write_factor = dma_write_factor; params->dma_write_factor = dma_write_factor;
params->dma_no_allocate = dma_no_allocate; params->dma_no_allocate = dma_no_allocate;
params->pio_latency = pio_latency; params->pio_latency = pio_latency;
params->pio_delay_write = pio_delay_write;
params->intr_delay = intr_delay; params->intr_delay = intr_delay;
params->rx_delay = rx_delay; params->rx_delay = rx_delay;

View file

@ -236,15 +236,6 @@ class NSGigE : public PciDev
uint32_t rxDescCnt; uint32_t rxDescCnt;
DmaState rxDmaState; DmaState rxDmaState;
struct RegWriteData {
Addr daddr;
uint32_t value;
RegWriteData(Addr da, uint32_t val) : daddr(da), value(val) {}
};
std::vector<std::list<RegWriteData> > writeQueue;
bool pioDelayWrite;
bool extstsEnable; bool extstsEnable;
/** EEPROM State Machine */ /** EEPROM State Machine */
@ -382,7 +373,6 @@ class NSGigE : public PciDev
Tick tx_delay; Tick tx_delay;
Tick rx_delay; Tick rx_delay;
Tick pio_latency; Tick pio_latency;
bool pio_delay_write;
bool dma_desc_free; bool dma_desc_free;
bool dma_data_free; bool dma_data_free;
Tick dma_read_delay; Tick dma_read_delay;

View file

@ -113,8 +113,6 @@ Device::Device(Params *p)
p->dma_no_allocate); p->dma_no_allocate);
} else if (p->payload_bus) } else if (p->payload_bus)
panic("must define a header bus if defining a payload bus"); panic("must define a header bus if defining a payload bus");
pioDelayWrite = p->pio_delay_write && pioInterface;
} }
Device::~Device() Device::~Device()
@ -353,9 +351,6 @@ Device::prepareRead(int cpu, int index)
void void
Device::prepareWrite(int cpu, int index) Device::prepareWrite(int cpu, int index)
{ {
if (cpu >= writeQueue.size())
writeQueue.resize(cpu + 1);
prepareIO(cpu, index); prepareIO(cpu, index);
} }
@ -503,10 +498,6 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
prepareWrite(cpu, index); prepareWrite(cpu, index);
if (pioDelayWrite)
writeQueue[cpu].push_back(RegWriteData(daddr, reg64));
if (!pioDelayWrite || !info.delay_write)
regWrite(daddr, cpu, data); regWrite(daddr, cpu, data);
return NoFault; return NoFault;
@ -1571,27 +1562,6 @@ Device::cacheAccess(MemReqPtr &req)
DPRINTF(EthernetPIO, "timing %s to paddr=%#x bar=%d daddr=%#x\n", DPRINTF(EthernetPIO, "timing %s to paddr=%#x bar=%d daddr=%#x\n",
req->cmd.toString(), req->paddr, bar, daddr); req->cmd.toString(), req->paddr, bar, daddr);
if (!pioDelayWrite || !req->cmd.isWrite())
return curTick + pioLatency;
if (bar == 0) {
int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff;
std::list<RegWriteData> &wq = writeQueue[cpu];
if (wq.empty())
panic("WriteQueue for cpu %d empty timing daddr=%#x", cpu, daddr);
const RegWriteData &data = wq.front();
if (data.daddr != daddr)
panic("read mismatch on cpu %d, daddr functional=%#x timing=%#x",
cpu, data.daddr, daddr);
const Regs::Info &info = regInfo(data.daddr);
if (info.delay_write)
regWrite(daddr, cpu, (uint8_t *)&data.value);
wq.pop_front();
}
return curTick + pioLatency; return curTick + pioLatency;
} }
@ -1649,7 +1619,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
Param<Tick> dma_write_factor; Param<Tick> dma_write_factor;
Param<bool> dma_no_allocate; Param<bool> dma_no_allocate;
Param<Tick> pio_latency; Param<Tick> pio_latency;
Param<bool> pio_delay_write;
Param<Tick> intr_delay; Param<Tick> intr_delay;
Param<Tick> rx_delay; Param<Tick> rx_delay;
@ -1693,7 +1662,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Device)
INIT_PARAM(dma_write_factor, "multiplier for dma writes"), INIT_PARAM(dma_write_factor, "multiplier for dma writes"),
INIT_PARAM(dma_no_allocate, "Should we allocat on read in cache"), INIT_PARAM(dma_no_allocate, "Should we allocat on read in cache"),
INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"), INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"),
INIT_PARAM(pio_delay_write, ""),
INIT_PARAM(intr_delay, "Interrupt Delay"), INIT_PARAM(intr_delay, "Interrupt Delay"),
INIT_PARAM(rx_delay, "Receive Delay"), INIT_PARAM(rx_delay, "Receive Delay"),
@ -1741,7 +1709,6 @@ CREATE_SIM_OBJECT(Device)
params->dma_write_factor = dma_write_factor; params->dma_write_factor = dma_write_factor;
params->dma_no_allocate = dma_no_allocate; params->dma_no_allocate = dma_no_allocate;
params->pio_latency = pio_latency; params->pio_latency = pio_latency;
params->pio_delay_write = pio_delay_write;
params->intr_delay = intr_delay; params->intr_delay = intr_delay;
params->tx_delay = tx_delay; params->tx_delay = tx_delay;

View file

@ -283,17 +283,6 @@ class Device : public Base
void regWrite(Addr daddr, int cpu, const uint8_t *data); void regWrite(Addr daddr, int cpu, const uint8_t *data);
Tick cacheAccess(MemReqPtr &req); Tick cacheAccess(MemReqPtr &req);
protected:
struct RegWriteData {
Addr daddr;
uint64_t value;
RegWriteData(Addr da, uint64_t val) : daddr(da), value(val) {}
};
std::vector<std::list<RegWriteData> > writeQueue;
bool pioDelayWrite;
/** /**
* Statistics * Statistics
*/ */
@ -349,7 +338,6 @@ class Device : public Base
Bus *header_bus; Bus *header_bus;
Bus *payload_bus; Bus *payload_bus;
Tick pio_latency; Tick pio_latency;
bool pio_delay_write;
PhysicalMemory *physmem; PhysicalMemory *physmem;
IntrControl *intctrl; IntrControl *intctrl;
bool rx_filter; bool rx_filter;

View file

@ -157,8 +157,6 @@ struct Info
uint8_t size; uint8_t size;
bool read; bool read;
bool write; bool write;
bool delay_read;
bool delay_write;
const char *name; const char *name;
}; };
@ -167,33 +165,33 @@ struct Info
inline const Regs::Info& inline const Regs::Info&
regInfo(TheISA::Addr daddr) regInfo(TheISA::Addr daddr)
{ {
static Regs::Info invalid = { 0, false, false, false, false, "invalid" }; static Regs::Info invalid = { 0, false, false, "invalid" };
static Regs::Info info [] = { static Regs::Info info [] = {
{ 4, true, true, false, false, "Config" }, { 4, true, true, "Config" },
{ 4, false, true, false, false, "Command" }, { 4, false, true, "Command" },
{ 4, true, true, false, false, "IntrStatus" }, { 4, true, true, "IntrStatus" },
{ 4, true, true, false, false, "IntrMask" }, { 4, true, true, "IntrMask" },
{ 4, true, false, false, false, "RxMaxCopy" }, { 4, true, false, "RxMaxCopy" },
{ 4, true, false, false, false, "TxMaxCopy" }, { 4, true, false, "TxMaxCopy" },
{ 4, true, false, false, false, "RxMaxIntr" }, { 4, true, false, "RxMaxIntr" },
invalid, invalid,
{ 4, true, false, false, false, "RxFifoSize" }, { 4, true, false, "RxFifoSize" },
{ 4, true, false, false, false, "TxFifoSize" }, { 4, true, false, "TxFifoSize" },
{ 4, true, false, false, false, "RxFifoMark" }, { 4, true, false, "RxFifoMark" },
{ 4, true, false, false, false, "TxFifoMark" }, { 4, true, false, "TxFifoMark" },
{ 8, true, true, false, true, "RxData" }, { 8, true, true, "RxData" },
invalid, invalid,
{ 8, true, false, false, false, "RxDone" }, { 8, true, false, "RxDone" },
invalid, invalid,
{ 8, true, false, false, false, "RxWait" }, { 8, true, false, "RxWait" },
invalid, invalid,
{ 8, true, true, false, true, "TxData" }, { 8, true, true, "TxData" },
invalid, invalid,
{ 8, true, false, false, false, "TxDone" }, { 8, true, false, "TxDone" },
invalid, invalid,
{ 8, true, false, false, false, "TxWait" }, { 8, true, false, "TxWait" },
invalid, invalid,
{ 8, true, false, false, false, "HwAddr" }, { 8, true, false, "HwAddr" },
invalid, invalid,
}; };

View file

@ -76,7 +76,6 @@ class EtherDevBase(PciDevice):
dma_write_delay = Param.Latency('0us', "fixed delay for dma writes") dma_write_delay = Param.Latency('0us', "fixed delay for dma writes")
dma_write_factor = Param.Latency('0us', "multiplier for dma writes") dma_write_factor = Param.Latency('0us', "multiplier for dma writes")
dma_no_allocate = Param.Bool(True, "Should we allocate cache on read") dma_no_allocate = Param.Bool(True, "Should we allocate cache on read")
pio_delay_write = Param.Bool(False, "Delay pio writes until timing occurs")
rx_delay = Param.Latency('1us', "Receive Delay") rx_delay = Param.Latency('1us', "Receive Delay")
tx_delay = Param.Latency('1us', "Transmit Delay") tx_delay = Param.Latency('1us', "Transmit Delay")