ruby: move stall and wakeup functions to AbstractController
[gem5.git] / src / mem / coherent_bus.cc
index b1ac6dbcf01f79511753d7630adacc7a41e50acf..0166872a78f2fd99c534d92fc4abf9ac30e6438b 100644 (file)
 #include "debug/BusAddrRanges.hh"
 #include "debug/CoherentBus.hh"
 #include "mem/coherent_bus.hh"
+#include "sim/system.hh"
 
 CoherentBus::CoherentBus(const CoherentBusParams *p)
-    : BaseBus(p), reqLayer(*this, ".reqLayer", p->clock),
-      respLayer(*this, ".respLayer", p->clock),
-      snoopRespLayer(*this, ".snoopRespLayer", p->clock)
+    : BaseBus(p), reqLayer(*this, ".reqLayer"),
+      respLayer(*this, ".respLayer"),
+      snoopRespLayer(*this, ".snoopRespLayer"),
+      system(p->system)
 {
     // create the ports based on the size of the master and slave
     // vector ports, and the presence of the default port, the ports
@@ -133,11 +135,11 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
     // set the source port for routing of the response
     pkt->setSrc(slave_port_id);
 
-    Tick headerFinishTime = is_express_snoop ? 0 : calcPacketTiming(pkt);
-    Tick packetFinishTime = is_express_snoop ? 0 : pkt->finishTime;
+    calcPacketTiming(pkt);
+    Tick packetFinishTime = pkt->busLastWordDelay + curTick();
 
     // uncacheable requests need never be snooped
-    if (!pkt->req->isUncacheable()) {
+    if (!pkt->req->isUncacheable() && !system->bypassCaches()) {
         // the packet is a memory-mapped request and should be
         // broadcasted to our snoopers but the source
         forwardTiming(pkt, slave_port_id);
@@ -177,11 +179,14 @@ CoherentBus::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
             if (add_outstanding)
                 outstandingReq.erase(pkt->req);
 
+            // undo the calculation so we can check for 0 again
+            pkt->busFirstWordDelay = pkt->busLastWordDelay = 0;
+
             DPRINTF(CoherentBus, "recvTimingReq: src %s %s 0x%x RETRY\n",
                     src_port->name(), pkt->cmdString(), pkt->getAddr());
 
             // update the bus state and schedule an idle event
-            reqLayer.failedTiming(src_port, headerFinishTime);
+            reqLayer.failedTiming(src_port, clockEdge(Cycles(headerCycles)));
         } else {
             // update the bus state and schedule an idle event
             reqLayer.succeededTiming(packetFinishTime);
@@ -209,7 +214,7 @@ CoherentBus::recvTimingResp(PacketPtr pkt, PortID master_port_id)
             src_port->name(), pkt->cmdString(), pkt->getAddr());
 
     calcPacketTiming(pkt);
-    Tick packetFinishTime = pkt->finishTime;
+    Tick packetFinishTime = pkt->busLastWordDelay + curTick();
 
     // the packet is a normal response to a request that we should
     // have seen passing through the bus
@@ -279,7 +284,7 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
     assert(!pkt->isExpressSnoop());
 
     calcPacketTiming(pkt);
-    Tick packetFinishTime = pkt->finishTime;
+    Tick packetFinishTime = pkt->busLastWordDelay + curTick();
 
     // determine if the response is from a snoop request we
     // created as the result of a normal request (in which case it
@@ -323,6 +328,9 @@ CoherentBus::recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id)
 void
 CoherentBus::forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id)
 {
+    // snoops should only happen if the system isn't bypassing caches
+    assert(!system->bypassCaches());
+
     for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) {
         SlavePort *p = *s;
         // we could have gotten this request from a snooping master
@@ -357,7 +365,7 @@ CoherentBus::recvAtomic(PacketPtr pkt, PortID slave_port_id)
     Tick snoop_response_latency = 0;
 
     // uncacheable requests need never be snooped
-    if (!pkt->req->isUncacheable()) {
+    if (!pkt->req->isUncacheable() && !system->bypassCaches()) {
         // forward to all snoopers but the source
         std::pair<MemCmd, Tick> snoop_result =
             forwardAtomic(pkt, slave_port_id);
@@ -380,7 +388,8 @@ CoherentBus::recvAtomic(PacketPtr pkt, PortID slave_port_id)
         response_latency = snoop_response_latency;
     }
 
-    pkt->finishTime = curTick() + response_latency;
+    // @todo: Not setting first-word time
+    pkt->busLastWordDelay = response_latency;
     return response_latency;
 }
 
@@ -400,7 +409,8 @@ CoherentBus::recvAtomicSnoop(PacketPtr pkt, PortID master_port_id)
     if (snoop_response_cmd != MemCmd::InvalidCmd)
         pkt->cmd = snoop_response_cmd;
 
-    pkt->finishTime = curTick() + snoop_response_latency;
+    // @todo: Not setting first-word time
+    pkt->busLastWordDelay = snoop_response_latency;
     return snoop_response_latency;
 }
 
@@ -414,6 +424,9 @@ CoherentBus::forwardAtomic(PacketPtr pkt, PortID exclude_slave_port_id)
     MemCmd snoop_response_cmd = MemCmd::InvalidCmd;
     Tick snoop_response_latency = 0;
 
+    // snoops should only happen if the system isn't bypassing caches
+    assert(!system->bypassCaches());
+
     for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) {
         SlavePort *p = *s;
         // we could have gotten this request from a snooping master
@@ -458,7 +471,7 @@ CoherentBus::recvFunctional(PacketPtr pkt, PortID slave_port_id)
     }
 
     // uncacheable requests need never be snooped
-    if (!pkt->req->isUncacheable()) {
+    if (!pkt->req->isUncacheable() && !system->bypassCaches()) {
         // forward to all snoopers but the source
         forwardFunctional(pkt, slave_port_id);
     }
@@ -490,6 +503,9 @@ CoherentBus::recvFunctionalSnoop(PacketPtr pkt, PortID master_port_id)
 void
 CoherentBus::forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id)
 {
+    // snoops should only happen if the system isn't bypassing caches
+    assert(!system->bypassCaches());
+
     for (SlavePortIter s = snoopPorts.begin(); s != snoopPorts.end(); ++s) {
         SlavePort *p = *s;
         // we could have gotten this request from a snooping master