ruby: added Packet interface to makeRequest and isReady.
[gem5.git] / src / mem / bridge.hh
index 5951eeb98616c2fc8d2dea8258dd8c5c2477cec6..40f033811277e5ac453b4807680045d1d2be0d94 100644 (file)
 #include <inttypes.h>
 #include <queue>
 
+#include "base/fast_alloc.hh"
 #include "mem/mem_object.hh"
 #include "mem/packet.hh"
 #include "mem/port.hh"
+#include "params/Bridge.hh"
 #include "sim/eventq.hh"
 
 class Bridge : public MemObject
@@ -69,28 +71,27 @@ class Bridge : public MemObject
         /** Min delay to respond to a nack. */
         Tick nackDelay;
 
-        bool fixPartialWrite;
+        /** Pass ranges from one side of the bridge to the other? */
+        std::vector<Range<Addr> > filterRanges;
 
-        class PacketBuffer : public Packet::SenderState {
+        class PacketBuffer : public Packet::SenderState, public FastAlloc {
 
           public:
             Tick ready;
             PacketPtr pkt;
+            bool nackedHere;
             Packet::SenderState *origSenderState;
             short origSrc;
             bool expectResponse;
 
-            bool partialWriteFixed;
-            PacketPtr oldPkt;
-
             PacketBuffer(PacketPtr _pkt, Tick t, bool nack = false)
-                : ready(t), pkt(_pkt),
-                  origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
-                  expectResponse(_pkt->needsResponse() && !nack),
-                  partialWriteFixed(false)
+                : ready(t), pkt(_pkt), nackedHere(nack),
+                  origSenderState(_pkt->senderState),
+                  origSrc(nack ? _pkt->getDest() : _pkt->getSrc() ),
+                  expectResponse(_pkt->needsResponse() && !nack)
 
             {
-                if (!pkt->isResponse() && !nack && pkt->result != Packet::Nacked)
+                if (!pkt->isResponse() && !nack)
                     pkt->senderState = this;
             }
 
@@ -99,52 +100,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);
-
-                Addr pbs = port->peerBlockSize();
-                Addr blockAddr = pkt->getAddr() & ~(pbs-1);
-                partialWriteFixed = true;
-                PacketDataPtr data;
-
-                data = new uint8_t[pbs];
-                RequestPtr funcReq = new Request(blockAddr, 4, 0);
-                PacketPtr funcPkt = new Packet(funcReq, MemCmd::ReadReq,
-                            Packet::Broadcast);
-                for (int x = 0; x < pbs; x+=4) {
-                    funcReq->setPhys(blockAddr + x, 4, 0);
-                    funcPkt->reinitFromRequest();
-                    funcPkt->dataStatic(data + x);
-                    port->sendFunctional(funcPkt);
-                    assert(funcPkt->result == Packet::Success);
-                }
-                delete funcPkt;
-                delete funcReq;
-
-                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;
             }
-
         };
 
         /**
@@ -190,12 +146,9 @@ class Bridge : public MemObject
             BridgePort *port;
 
           public:
-            SendEvent(BridgePort *p)
-                : Event(&mainEventQueue), port(p) {}
-
+            SendEvent(BridgePort *p) : port(p) {}
             virtual void process() { port->trySend(); }
-
-            virtual const char *description() { return "bridge send event"; }
+            virtual const char *description() const { return "bridge send"; }
         };
 
         SendEvent sendEvent;
@@ -204,7 +157,8 @@ class Bridge : public MemObject
         /** Constructor for the BusPort.*/
         BridgePort(const std::string &_name, Bridge *_bridge,
                 BridgePort *_otherPort, int _delay, int _nack_delay,
-                int _req_limit, int _resp_limit, bool fix_partial_write);
+                int _req_limit, int _resp_limit,
+                std::vector<Range<Addr> > filter_ranges);
 
       protected:
 
@@ -231,7 +185,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;
@@ -240,19 +194,7 @@ 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;
-    };
+    typedef BridgeParams Params;
 
   protected:
     Params *_params;