Implement a state machine clock that acutally limits how fast
the nsgige state machine can run. The frequency is of the actual state transitions, and not the rate of what underlying instructions might run at. dev/ns_gige.cc: Implement a state machine clock that acutally limits how fast the state machine can run. After each state transition, a variable is kept to hold the next state transition until the next clock. The frequency is of the actual state transitions, and not the rate of what underlying instructions might run at. dev/ns_gige.hh: Add back the rxKickEvent and txKickEvent events. python/m5/objects/Ethernet.py: Default the state machine clock to '0ns' so the default behaviour doesn't change when we actually implement the state machine clock. --HG-- extra : convert_revision : 2db1943dee4e91ea75aaee6a91e88f27f01a09dd
This commit is contained in:
parent
5ea3c1c8f3
commit
c4029ecb30
3 changed files with 52 additions and 22 deletions
|
@ -102,7 +102,7 @@ NSGigE::NSGigE(Params *p)
|
||||||
txDmaReadEvent(this), txDmaWriteEvent(this),
|
txDmaReadEvent(this), txDmaWriteEvent(this),
|
||||||
dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free),
|
dmaDescFree(p->dma_desc_free), dmaDataFree(p->dma_data_free),
|
||||||
txDelay(p->tx_delay), rxDelay(p->rx_delay),
|
txDelay(p->tx_delay), rxDelay(p->rx_delay),
|
||||||
rxKickTick(0), txKickTick(0),
|
rxKickTick(0), rxKickEvent(this), txKickTick(0), txKickEvent(this),
|
||||||
txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false),
|
txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false),
|
||||||
acceptMulticast(false), acceptUnicast(false),
|
acceptMulticast(false), acceptUnicast(false),
|
||||||
acceptPerfect(false), acceptArp(false),
|
acceptPerfect(false), acceptArp(false),
|
||||||
|
@ -841,7 +841,8 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
|
||||||
panic("writing to read-only or reserved CFGR bits!\n");
|
panic("writing to read-only or reserved CFGR bits!\n");
|
||||||
|
|
||||||
regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |
|
regs.config |= reg & ~(CFGR_LNKSTS | CFGR_SPDSTS | CFGR_DUPSTS |
|
||||||
CFGR_RESERVED | CFGR_T64ADDR | CFGR_PCI64_DET);
|
CFGR_RESERVED | CFGR_T64ADDR |
|
||||||
|
CFGR_PCI64_DET);
|
||||||
|
|
||||||
// all these #if 0's are because i don't THINK the kernel needs to
|
// all these #if 0's are because i don't THINK the kernel needs to
|
||||||
// have these implemented. if there is a problem relating to one of
|
// have these implemented. if there is a problem relating to one of
|
||||||
|
@ -1487,13 +1488,19 @@ NSGigE::rxKick()
|
||||||
DPRINTF(EthernetSM, "receive kick rxState=%s (rxBuf.size=%d)\n",
|
DPRINTF(EthernetSM, "receive kick rxState=%s (rxBuf.size=%d)\n",
|
||||||
NsRxStateStrings[rxState], rxFifo.size());
|
NsRxStateStrings[rxState], rxFifo.size());
|
||||||
|
|
||||||
|
next:
|
||||||
|
if (clock) {
|
||||||
if (rxKickTick > curTick) {
|
if (rxKickTick > curTick) {
|
||||||
DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n",
|
DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n",
|
||||||
rxKickTick);
|
rxKickTick);
|
||||||
return;
|
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to the next state machine clock tick.
|
||||||
|
rxKickTick = curTick + cycles(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
|
||||||
switch(rxDmaState) {
|
switch(rxDmaState) {
|
||||||
case dmaReadWaiting:
|
case dmaReadWaiting:
|
||||||
if (doRxDmaRead())
|
if (doRxDmaRead())
|
||||||
|
@ -1561,8 +1568,7 @@ NSGigE::rxKick()
|
||||||
if (rxDmaState != dmaIdle)
|
if (rxDmaState != dmaIdle)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
DPRINTF(EthernetDesc,
|
DPRINTF(EthernetDesc, "rxDescCache: addr=%08x read descriptor\n",
|
||||||
"rxDescCache: addr=%08x read descriptor\n",
|
|
||||||
regs.rxdp & 0x3fffffff);
|
regs.rxdp & 0x3fffffff);
|
||||||
DPRINTF(EthernetDesc,
|
DPRINTF(EthernetDesc,
|
||||||
"rxDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
|
"rxDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
|
||||||
|
@ -1783,7 +1789,6 @@ NSGigE::rxKick()
|
||||||
|
|
||||||
DPRINTF(EthernetSM, "entering next rxState=%s\n",
|
DPRINTF(EthernetSM, "entering next rxState=%s\n",
|
||||||
NsRxStateStrings[rxState]);
|
NsRxStateStrings[rxState]);
|
||||||
|
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -1792,6 +1797,9 @@ NSGigE::rxKick()
|
||||||
*/
|
*/
|
||||||
DPRINTF(EthernetSM, "rx state machine exited rxState=%s\n",
|
DPRINTF(EthernetSM, "rx state machine exited rxState=%s\n",
|
||||||
NsRxStateStrings[rxState]);
|
NsRxStateStrings[rxState]);
|
||||||
|
|
||||||
|
if (clock && !rxKickEvent.scheduled())
|
||||||
|
rxKickEvent.schedule(rxKickTick);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1954,13 +1962,18 @@ NSGigE::txKick()
|
||||||
DPRINTF(EthernetSM, "transmit kick txState=%s\n",
|
DPRINTF(EthernetSM, "transmit kick txState=%s\n",
|
||||||
NsTxStateStrings[txState]);
|
NsTxStateStrings[txState]);
|
||||||
|
|
||||||
|
next:
|
||||||
|
if (clock) {
|
||||||
if (txKickTick > curTick) {
|
if (txKickTick > curTick) {
|
||||||
DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n",
|
DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n",
|
||||||
txKickTick);
|
txKickTick);
|
||||||
return;
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to the next state machine clock tick.
|
||||||
|
txKickTick = curTick + cycles(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
|
||||||
switch(txDmaState) {
|
switch(txDmaState) {
|
||||||
case dmaReadWaiting:
|
case dmaReadWaiting:
|
||||||
if (doTxDmaRead())
|
if (doTxDmaRead())
|
||||||
|
@ -2022,6 +2035,8 @@ NSGigE::txKick()
|
||||||
if (txDmaState != dmaIdle)
|
if (txDmaState != dmaIdle)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
DPRINTF(EthernetDesc, "txDescCache: addr=%08x read descriptor\n",
|
||||||
|
regs.txdp & 0x3fffffff);
|
||||||
DPRINTF(EthernetDesc,
|
DPRINTF(EthernetDesc,
|
||||||
"txDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
|
"txDescCache: link=%08x bufptr=%08x cmdsts=%08x extsts=%08x\n",
|
||||||
txDescCache.link, txDescCache.bufptr, txDescCache.cmdsts,
|
txDescCache.link, txDescCache.bufptr, txDescCache.cmdsts,
|
||||||
|
@ -2186,6 +2201,11 @@ NSGigE::txKick()
|
||||||
if (txDescCache.cmdsts & CMDSTS_INTR)
|
if (txDescCache.cmdsts & CMDSTS_INTR)
|
||||||
devIntrPost(ISR_TXDESC);
|
devIntrPost(ISR_TXDESC);
|
||||||
|
|
||||||
|
if (!txEnable) {
|
||||||
|
DPRINTF(EthernetSM, "halting TX state machine\n");
|
||||||
|
txState = txIdle;
|
||||||
|
goto exit;
|
||||||
|
} else
|
||||||
txState = txAdvance;
|
txState = txAdvance;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2215,7 +2235,6 @@ NSGigE::txKick()
|
||||||
|
|
||||||
DPRINTF(EthernetSM, "entering next txState=%s\n",
|
DPRINTF(EthernetSM, "entering next txState=%s\n",
|
||||||
NsTxStateStrings[txState]);
|
NsTxStateStrings[txState]);
|
||||||
|
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
@ -2224,6 +2243,9 @@ NSGigE::txKick()
|
||||||
*/
|
*/
|
||||||
DPRINTF(EthernetSM, "tx state machine exited txState=%s\n",
|
DPRINTF(EthernetSM, "tx state machine exited txState=%s\n",
|
||||||
NsTxStateStrings[txState]);
|
NsTxStateStrings[txState]);
|
||||||
|
|
||||||
|
if (clock && !txKickEvent.scheduled())
|
||||||
|
txKickEvent.schedule(txKickTick);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2429,6 +2451,7 @@ NSGigE::serialize(ostream &os)
|
||||||
SERIALIZE_SCALAR(rxDescCache.bufptr);
|
SERIALIZE_SCALAR(rxDescCache.bufptr);
|
||||||
SERIALIZE_SCALAR(rxDescCache.cmdsts);
|
SERIALIZE_SCALAR(rxDescCache.cmdsts);
|
||||||
SERIALIZE_SCALAR(rxDescCache.extsts);
|
SERIALIZE_SCALAR(rxDescCache.extsts);
|
||||||
|
SERIALIZE_SCALAR(extstsEnable);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Serialize tx state machine
|
* Serialize tx state machine
|
||||||
|
@ -2441,6 +2464,7 @@ NSGigE::serialize(ostream &os)
|
||||||
SERIALIZE_SCALAR(txDescCnt);
|
SERIALIZE_SCALAR(txDescCnt);
|
||||||
int txDmaState = this->txDmaState;
|
int txDmaState = this->txDmaState;
|
||||||
SERIALIZE_SCALAR(txDmaState);
|
SERIALIZE_SCALAR(txDmaState);
|
||||||
|
SERIALIZE_SCALAR(txKickTick);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Serialize rx state machine
|
* Serialize rx state machine
|
||||||
|
@ -2454,8 +2478,7 @@ NSGigE::serialize(ostream &os)
|
||||||
SERIALIZE_SCALAR(rxDescCnt);
|
SERIALIZE_SCALAR(rxDescCnt);
|
||||||
int rxDmaState = this->rxDmaState;
|
int rxDmaState = this->rxDmaState;
|
||||||
SERIALIZE_SCALAR(rxDmaState);
|
SERIALIZE_SCALAR(rxDmaState);
|
||||||
|
SERIALIZE_SCALAR(rxKickTick);
|
||||||
SERIALIZE_SCALAR(extstsEnable);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's a pending transmit, store the time so we can
|
* If there's a pending transmit, store the time so we can
|
||||||
|
@ -2575,6 +2598,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
UNSERIALIZE_SCALAR(rxDescCache.bufptr);
|
UNSERIALIZE_SCALAR(rxDescCache.bufptr);
|
||||||
UNSERIALIZE_SCALAR(rxDescCache.cmdsts);
|
UNSERIALIZE_SCALAR(rxDescCache.cmdsts);
|
||||||
UNSERIALIZE_SCALAR(rxDescCache.extsts);
|
UNSERIALIZE_SCALAR(rxDescCache.extsts);
|
||||||
|
UNSERIALIZE_SCALAR(extstsEnable);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* unserialize tx state machine
|
* unserialize tx state machine
|
||||||
|
@ -2589,6 +2613,9 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
int txDmaState;
|
int txDmaState;
|
||||||
UNSERIALIZE_SCALAR(txDmaState);
|
UNSERIALIZE_SCALAR(txDmaState);
|
||||||
this->txDmaState = (DmaState) txDmaState;
|
this->txDmaState = (DmaState) txDmaState;
|
||||||
|
UNSERIALIZE_SCALAR(txKickTick);
|
||||||
|
if (txKickTick)
|
||||||
|
txKickEvent.schedule(txKickTick);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* unserialize rx state machine
|
* unserialize rx state machine
|
||||||
|
@ -2604,8 +2631,9 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
int rxDmaState;
|
int rxDmaState;
|
||||||
UNSERIALIZE_SCALAR(rxDmaState);
|
UNSERIALIZE_SCALAR(rxDmaState);
|
||||||
this->rxDmaState = (DmaState) rxDmaState;
|
this->rxDmaState = (DmaState) rxDmaState;
|
||||||
|
UNSERIALIZE_SCALAR(rxKickTick);
|
||||||
UNSERIALIZE_SCALAR(extstsEnable);
|
if (rxKickTick)
|
||||||
|
rxKickEvent.schedule(rxKickTick);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's a pending transmit, reschedule it now
|
* If there's a pending transmit, reschedule it now
|
||||||
|
|
|
@ -266,11 +266,13 @@ class NSGigE : public PciDev
|
||||||
Tick rxKickTick;
|
Tick rxKickTick;
|
||||||
typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
|
typedef EventWrapper<NSGigE, &NSGigE::rxKick> RxKickEvent;
|
||||||
friend void RxKickEvent::process();
|
friend void RxKickEvent::process();
|
||||||
|
RxKickEvent rxKickEvent;
|
||||||
|
|
||||||
void txKick();
|
void txKick();
|
||||||
Tick txKickTick;
|
Tick txKickTick;
|
||||||
typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
|
typedef EventWrapper<NSGigE, &NSGigE::txKick> TxKickEvent;
|
||||||
friend void TxKickEvent::process();
|
friend void TxKickEvent::process();
|
||||||
|
TxKickEvent txKickEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retransmit event
|
* Retransmit event
|
||||||
|
|
|
@ -64,7 +64,7 @@ class NSGigE(PciDevice):
|
||||||
hardware_address = Param.EthernetAddr(NextEthernetAddr,
|
hardware_address = Param.EthernetAddr(NextEthernetAddr,
|
||||||
"Ethernet Hardware Address")
|
"Ethernet Hardware Address")
|
||||||
|
|
||||||
clock = Param.Clock('100MHz', "State machine processor frequency")
|
clock = Param.Clock('0ns', "State machine processor frequency")
|
||||||
|
|
||||||
dma_data_free = Param.Bool(False, "DMA of Data is free")
|
dma_data_free = Param.Bool(False, "DMA of Data is free")
|
||||||
dma_desc_free = Param.Bool(False, "DMA of Descriptors is free")
|
dma_desc_free = Param.Bool(False, "DMA of Descriptors is free")
|
||||||
|
|
Loading…
Reference in a new issue