Only issue responses if we aren;t already blocked
[gem5.git] / src / dev / ns_gige.cc
index decffaf7379ce52463156e856e40f9cb839527b7..704afcf7d2376915ab43c8ec3e92a782625f3b78 100644 (file)
@@ -25,7 +25,8 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * Authors: Lisa Hsu
+ * Authors: Nathan Binkert
+ *          Lisa Hsu
  */
 
 /** @file
@@ -464,11 +465,12 @@ NSGigE::regStats()
 /**
  * This is to write to the PCI general configuration registers
  */
-void
-NSGigE::writeConfig(int offset, const uint16_t data)
+Tick
+NSGigE::writeConfig(Packet *pkt)
 {
+    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
     if (offset < PCI_DEVICE_SPECIFIC)
-        PciDev::writeConfig(offset,  data);
+        PciDev::writeConfig(pkt);
     else
         panic("Device specific PCI config space not implemented!\n");
 
@@ -483,6 +485,8 @@ NSGigE::writeConfig(int offset, const uint16_t data)
             ioEnable = false;
         break;
     }
+    pkt->result = Packet::Success;
+    return configDelay;
 }
 
 /**
@@ -507,14 +511,7 @@ NSGigE::read(Packet *pkt)
     if (daddr > LAST && daddr <=  RESERVED) {
         panic("Accessing reserved register");
     } else if (daddr > RESERVED && daddr <= 0x3FC) {
-        if (pkt->getSize() == sizeof(uint8_t))
-            readConfig(daddr & 0xff, pkt->getPtr<uint8_t>());
-        if (pkt->getSize() == sizeof(uint16_t))
-            readConfig(daddr & 0xff, pkt->getPtr<uint16_t>());
-        if (pkt->getSize() == sizeof(uint32_t))
-            readConfig(daddr & 0xff, pkt->getPtr<uint32_t>());
-        pkt->result = Packet::Success;
-        return pioDelay;
+        return readConfig(pkt);
     } else if (daddr >= MIB_START && daddr <= MIB_END) {
         // don't implement all the MIB's.  hopefully the kernel
         // doesn't actually DEPEND upon their values
@@ -732,14 +729,7 @@ NSGigE::write(Packet *pkt)
     if (daddr > LAST && daddr <=  RESERVED) {
         panic("Accessing reserved register");
     } else if (daddr > RESERVED && daddr <= 0x3FC) {
-        if (pkt->getSize() == sizeof(uint8_t))
-            writeConfig(daddr & 0xff, pkt->get<uint8_t>());
-        if (pkt->getSize() == sizeof(uint16_t))
-            writeConfig(daddr & 0xff, pkt->get<uint16_t>());
-        if (pkt->getSize() == sizeof(uint32_t))
-            writeConfig(daddr & 0xff, pkt->get<uint32_t>());
-        pkt->result = Packet::Success;
-        return pioDelay;
+        return writeConfig(pkt);
     } else if (daddr > 0x3FC)
         panic("Something is messed up!\n");
 
@@ -1387,7 +1377,7 @@ NSGigE::doRxDmaRead()
     assert(rxDmaState == dmaIdle || rxDmaState == dmaReadWaiting);
     rxDmaState = dmaReading;
 
-    if (dmaPending())
+    if (dmaPending() || getState() != Running)
         rxDmaState = dmaReadWaiting;
     else
         dmaRead(rxDmaAddr, rxDmaLen, &rxDmaReadEvent, (uint8_t*)rxDmaData);
@@ -1418,7 +1408,7 @@ NSGigE::doRxDmaWrite()
     assert(rxDmaState == dmaIdle || rxDmaState == dmaWriteWaiting);
     rxDmaState = dmaWriting;
 
-    if (dmaPending())
+    if (dmaPending() || getState() != Running)
         rxDmaState = dmaWriteWaiting;
     else
         dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaWriteEvent, (uint8_t*)rxDmaData);
@@ -1836,7 +1826,7 @@ NSGigE::doTxDmaRead()
     assert(txDmaState == dmaIdle || txDmaState == dmaReadWaiting);
     txDmaState = dmaReading;
 
-    if (dmaPending())
+    if (dmaPending() || getState() != Running)
         txDmaState = dmaReadWaiting;
     else
         dmaRead(txDmaAddr, txDmaLen, &txDmaReadEvent, (uint8_t*)txDmaData);
@@ -1867,7 +1857,7 @@ NSGigE::doTxDmaWrite()
     assert(txDmaState == dmaIdle || txDmaState == dmaWriteWaiting);
     txDmaState = dmaWriting;
 
-    if (dmaPending())
+    if (dmaPending() || getState() != Running)
         txDmaState = dmaWriteWaiting;
     else
         dmaWrite(txDmaAddr, txDmaLen, &txDmaWriteEvent, (uint8_t*)txDmaData);
@@ -2416,6 +2406,20 @@ NSGigE::recvPacket(EthPacketPtr packet)
     return true;
 }
 
+
+void
+NSGigE::resume()
+{
+    SimObject::resume();
+
+    // During drain we could have left the state machines in a waiting state and
+    // they wouldn't get out until some other event occured to kick them.
+    // This way they'll get out immediately
+    txKick();
+    rxKick();
+}
+
+
 //=====================================================================
 //
 //
@@ -2806,12 +2810,12 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
 
     SimObjectParam<System *> system;
     SimObjectParam<Platform *> platform;
-    SimObjectParam<PciConfigAll *> configspace;
     SimObjectParam<PciConfigData *> configdata;
     Param<uint32_t> pci_bus;
     Param<uint32_t> pci_dev;
     Param<uint32_t> pci_func;
     Param<Tick> pio_latency;
+    Param<Tick> config_latency;
 
     Param<Tick> clock;
     Param<bool> dma_desc_free;
@@ -2840,12 +2844,12 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
 
     INIT_PARAM(system, "System pointer"),
     INIT_PARAM(platform, "Platform pointer"),
-    INIT_PARAM(configspace, "PCI Configspace"),
     INIT_PARAM(configdata, "PCI Config data"),
     INIT_PARAM(pci_bus, "PCI bus ID"),
     INIT_PARAM(pci_dev, "PCI device number"),
     INIT_PARAM(pci_func, "PCI function code"),
     INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
+    INIT_PARAM(config_latency, "Number of cycles for a config read or write"),
     INIT_PARAM(clock, "State machine cycle time"),
 
     INIT_PARAM(dma_desc_free, "DMA of Descriptors is free"),
@@ -2878,12 +2882,12 @@ CREATE_SIM_OBJECT(NSGigE)
     params->name = getInstanceName();
     params->platform = platform;
     params->system = system;
-    params->configSpace = configspace;
     params->configData = configdata;
     params->busNum = pci_bus;
     params->deviceNum = pci_dev;
     params->functionNum = pci_func;
     params->pio_delay = pio_latency;
+    params->config_delay = config_latency;
 
     params->clock = clock;
     params->dma_desc_free = dma_desc_free;