Merge in bus DPRINTF changes.
[gem5.git] / src / dev / i8254xGBe.hh
index b6da53b09ac8d9c30b0b55b75a828e02ab8f960d..30aa6430e9de593e46c73699bdde3a38b702c1ea 100644 (file)
 
 #include "base/inet.hh"
 #include "base/statistics.hh"
+#include "dev/etherdevice.hh"
 #include "dev/etherint.hh"
 #include "dev/etherpkt.hh"
 #include "dev/i8254xGBe_defs.hh"
 #include "dev/pcidev.hh"
 #include "dev/pktfifo.hh"
+#include "params/IGbE.hh"
 #include "sim/eventq.hh"
 
 class IGbEInt;
 
-class IGbE : public PciDev
+class IGbE : public EtherDevice
 {
   private:
     IGbEInt *etherInt;
@@ -145,9 +147,10 @@ class IGbE : public PciDev
 
     /** Send an interrupt to the cpu
      */
+    void delayIntEvent();
     void cpuPostInt();
     // Event to moderate interrupts
-    EventWrapper<IGbE, &IGbE::cpuPostInt> interEvent;
+    EventWrapper<IGbE, &IGbE::delayIntEvent> interEvent;
 
     /** Clear the interupt line to the cpu
      */
@@ -175,6 +178,7 @@ class IGbE : public PciDev
         virtual void updateHead(long h) = 0;
         virtual void enableSm() = 0;
         virtual void intAfterWb() const {}
+        virtual void fetchAfterWb() = 0;
 
         std::deque<T*> usedCache;
         std::deque<T*> unusedCache;
@@ -281,12 +285,6 @@ class IGbE : public PciDev
             for (int x = 0; x < wbOut; x++)
                 memcpy(&wbBuf[x], usedCache[x], sizeof(T));
 
-            for (int x = 0; x < wbOut; x++) {
-                assert(usedCache.size());
-                delete usedCache[0];
-                usedCache.pop_front();
-            };
-
 
             assert(wbOut);
             igbe->dmaWrite(igbe->platform->pciToDma(descBase() + curHead * sizeof(T)),
@@ -305,7 +303,6 @@ class IGbE : public PciDev
             else
                 max_to_fetch = descLen() - cachePnt;
 
-
             max_to_fetch = std::min(max_to_fetch, (size - usedCache.size() -
                         unusedCache.size()));
 
@@ -367,10 +364,16 @@ class IGbE : public PciDev
          */
         void wbComplete()
         {
+
             long  curHead = descHead();
 #ifndef NDEBUG
             long oldHead = curHead;
 #endif
+            for (int x = 0; x < wbOut; x++) {
+                assert(usedCache.size());
+                delete usedCache[0];
+                usedCache.pop_front();
+            };
 
             curHead += wbOut;
             wbOut = 0;
@@ -385,12 +388,16 @@ class IGbE : public PciDev
                     oldHead, curHead);
 
             // If we still have more to wb, call wb now
+            intAfterWb();
             if (moreToWb) {
                 DPRINTF(EthernetDesc, "Writeback has more todo\n");
                 writeback(wbAlignment);
             }
-            intAfterWb();
-            igbe->checkDrain();
+
+            if (!wbOut) {
+                igbe->checkDrain();
+            }
+            fetchAfterWb();
         }
 
 
@@ -500,6 +507,10 @@ class IGbE : public PciDev
         virtual long descTail() const { return igbe->regs.rdt(); }
         virtual void updateHead(long h) { igbe->regs.rdh(h); }
         virtual void enableSm();
+        virtual void fetchAfterWb() {
+            if (!igbe->rxTick && igbe->getState() == SimObject::Running)
+                fetchDescriptors();
+        }
 
         bool pktDone;
 
@@ -542,7 +553,13 @@ class IGbE : public PciDev
         virtual long descLen() const { return igbe->regs.tdlen() >> 4; }
         virtual void updateHead(long h) { igbe->regs.tdh(h); }
         virtual void enableSm();
-        virtual void intAfterWb() const { igbe->postInterrupt(iGbReg::IT_TXDW);}
+        virtual void intAfterWb() const {
+            igbe->postInterrupt(iGbReg::IT_TXDW);
+        }
+        virtual void fetchAfterWb() {
+            if (!igbe->txTick && igbe->getState() == SimObject::Running)
+                fetchDescriptors();
+        }
 
         bool pktDone;
         bool isTcp;
@@ -585,22 +602,19 @@ class IGbE : public PciDev
     TxDescCache txDescCache;
 
   public:
-    struct Params : public PciDev::Params
+    typedef IGbEParams Params;
+    const Params *
+    params() const
     {
-        Net::EthAddr hardware_address;
-        bool use_flow_control;
-        int rx_fifo_size;
-        int tx_fifo_size;
-        int rx_desc_cache_size;
-        int tx_desc_cache_size;
-        Tick clock;
-    };
+        return dynamic_cast<const Params *>(_params);
+    }
+    IGbE(const Params *params);
+    ~IGbE() {}
 
-    IGbE(Params *params);
-    ~IGbE() {;}
+    virtual EtherInt *getEthPort(const std::string &if_name, int idx);
 
     Tick clock;
-    inline Tick cycles(int numCycles) const { return numCycles * clock; }
+    inline Tick ticks(int numCycles) const { return numCycles * clock; }
 
     virtual Tick read(PacketPtr pkt);
     virtual Tick write(PacketPtr pkt);
@@ -610,11 +624,6 @@ class IGbE : public PciDev
     bool ethRxPkt(EthPacketPtr packet);
     void ethTxDone();
 
-    void setEthInt(IGbEInt *i) { assert(!etherInt); etherInt = i; }
-
-
-    const Params *params() const {return (const Params *)_params; }
-
     virtual void serialize(std::ostream &os);
     virtual void unserialize(Checkpoint *cp, const std::string &section);
     virtual unsigned int drain(Event *de);
@@ -630,7 +639,7 @@ class IGbEInt : public EtherInt
   public:
     IGbEInt(const std::string &name, IGbE *d)
         : EtherInt(name), dev(d)
-        { dev->setEthInt(this); }
+    { }
 
     virtual bool recvPacket(EthPacketPtr pkt) { return dev->ethRxPkt(pkt); }
     virtual void sendDone() { dev->ethTxDone(); }