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:
parent
7c642b7106
commit
3a0102536b
6 changed files with 28 additions and 131 deletions
|
@ -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 §ion)
|
||||||
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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
33
dev/sinic.cc
33
dev/sinic.cc
|
@ -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;
|
||||||
|
|
12
dev/sinic.hh
12
dev/sinic.hh
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in a new issue