Removed "adding instead of dividing" trick.
[gem5.git] / src / mem / bridge.hh
index d1154eda046e23f8bad71e382dfff1ef453ab4cf..89d62661182c012656f1c3b0b7ec5f66cca49c8f 100644 (file)
@@ -66,6 +66,9 @@ class Bridge : public MemObject
         /** Minimum delay though this bridge. */
         Tick delay;
 
+        /** Min delay to respond to a nack. */
+        Tick nackDelay;
+
         bool fixPartialWrite;
 
         class PacketBuffer : public Packet::SenderState {
@@ -77,15 +80,13 @@ class Bridge : public MemObject
             short origSrc;
             bool expectResponse;
 
-            bool partialWriteFixed;
-            PacketPtr oldPkt;
-
-            PacketBuffer(PacketPtr _pkt, Tick t)
+            PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
                 : ready(t), pkt(_pkt),
                   origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
-                  expectResponse(_pkt->needsResponse()), partialWriteFixed(false)
+                  expectResponse(_pkt->needsResponse() && !nack)
+
             {
-                if (!pkt->isResponse())
+                if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked)
                     pkt->senderState = this;
             }
 
@@ -94,46 +95,7 @@ class Bridge : public MemObject
                 assert(pkt->senderState == this);
                 pkt->setDest(origSrc);
                 pkt->senderState = origSenderState;
-                if (partialWriteFixed)
-                    delete oldPkt;
-            }
-
-            void partialWriteFix(Port *port)
-            {
-                assert(!partialWriteFixed);
-                assert(expectResponse);
-
-                int pbs = port->peerBlockSize();
-                partialWriteFixed = true;
-                PacketDataPtr data;
-
-                data = new uint8_t[pbs];
-                PacketPtr funcPkt = new Packet(pkt->req, MemCmd::ReadReq,
-                        Packet::Broadcast, pbs);
-
-                funcPkt->dataStatic(data);
-                port->sendFunctional(funcPkt);
-                assert(funcPkt->result == Packet::Success);
-                delete funcPkt;
-
-                oldPkt = pkt;
-                memcpy(data + oldPkt->getOffset(pbs), pkt->getPtr<uint8_t>(),
-                        pkt->getSize());
-                pkt = new Packet(oldPkt->req, MemCmd::WriteInvalidateReq,
-                        Packet::Broadcast, pbs);
-                pkt->dataDynamicArray(data);
-                pkt->senderState = oldPkt->senderState;
             }
-
-            void undoPartialWriteFix()
-            {
-                if (!partialWriteFixed)
-                    return;
-                delete pkt;
-                pkt = oldPkt;
-                partialWriteFixed = false;
-            }
-
         };
 
         /**
@@ -144,19 +106,29 @@ class Bridge : public MemObject
         std::list<PacketBuffer*> sendQueue;
 
         int outstandingResponses;
+        int queuedRequests;
+
+        /** If we're waiting for a retry to happen.*/
+        bool inRetry;
 
         /** Max queue size for outbound packets */
-        int queueLimit;
+        int reqQueueLimit;
+
+        /** Max queue size for reserved responses. */
+        int respQueueLimit;
 
         /**
          * Is this side blocked from accepting outbound packets?
          */
-        bool queueFull() { return (sendQueue.size() == queueLimit); }
+        bool respQueueFull();
+        bool reqQueueFull();
 
-        bool queueForSendTiming(PacketPtr pkt);
+        void queueForSendTiming(PacketPtr pkt);
 
         void finishSend(PacketBuffer *buf);
 
+        void nackRequest(PacketPtr pkt);
+
         /**
          * Handle send event, scheduled when the packet at the head of
          * the outbound queue is ready to transmit (for timing
@@ -180,11 +152,10 @@ class Bridge : public MemObject
         SendEvent sendEvent;
 
       public:
-
         /** Constructor for the BusPort.*/
-        BridgePort(const std::string &_name,
-                   Bridge *_bridge, BridgePort *_otherPort,
-                   int _delay, int _queueLimit, bool fix_partial_write);
+        BridgePort(const std::string &_name, Bridge *_bridge,
+                BridgePort *_otherPort, int _delay, int _nack_delay,
+                int _req_limit, int _resp_limit, bool fix_partial_write);
 
       protected:
 
@@ -211,7 +182,7 @@ class Bridge : public MemObject
         /** When receiving a address range request the peer port,
             pass it to the bridge. */
         virtual void getDeviceAddressRanges(AddrRangeList &resp,
-                                            AddrRangeList &snoop);
+                                            bool &snoop);
     };
 
     BridgePort portA, portB;
@@ -220,14 +191,32 @@ class Bridge : public MemObject
     bool ackWrites;
 
   public:
+    struct Params
+    {
+        std::string name;
+        int req_size_a;
+        int req_size_b;
+        int resp_size_a;
+        int resp_size_b;
+        Tick delay;
+        Tick nack_delay;
+        bool write_ack;
+        bool fix_partial_write_a;
+        bool fix_partial_write_b;
+    };
+
+  protected:
+    Params *_params;
+
+  public:
+    const Params *params() const { return _params; }
 
     /** A function used to return the port associated with this bus object. */
     virtual Port *getPort(const std::string &if_name, int idx = -1);
 
     virtual void init();
 
-    Bridge(const std::string &n, int qsa, int qsb, Tick _delay, int write_ack,
-            bool fix_partial_write_a, bool fix_partial_write_b);
+    Bridge(Params *p);
 };
 
 #endif //__MEM_BUS_HH__