summaryrefslogtreecommitdiff
path: root/src/mem/bus.cc
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2007-06-17 17:27:53 -0700
committerSteve Reinhardt <stever@eecs.umich.edu>2007-06-17 17:27:53 -0700
commit35cf19d441ed15d054d00674ec67ab5bc769f6d7 (patch)
tree86a97bf419e3c46834a446039ef8f4a85f74b7cc /src/mem/bus.cc
parenta9b7c558fd6c00dacbdf36f4617c03a19c198b08 (diff)
downloadgem5-35cf19d441ed15d054d00674ec67ab5bc769f6d7.tar.xz
More major reorg of cache. Seems to work for atomic mode now,
timing mode still broken. configs/example/memtest.py: Revamp options. src/cpu/memtest/memtest.cc: No need for memory initialization. No need to make atomic response... memory system should do that now. src/cpu/memtest/memtest.hh: MemTest really doesn't want to snoop. src/mem/bridge.cc: checkFunctional() cleanup. src/mem/bus.cc: src/mem/bus.hh: src/mem/cache/base_cache.cc: src/mem/cache/base_cache.hh: src/mem/cache/cache.cc: src/mem/cache/cache.hh: src/mem/cache/cache_blk.hh: src/mem/cache/cache_builder.cc: src/mem/cache/cache_impl.hh: src/mem/cache/coherence/coherence_protocol.cc: src/mem/cache/coherence/coherence_protocol.hh: src/mem/cache/coherence/simple_coherence.hh: src/mem/cache/miss/SConscript: src/mem/cache/miss/mshr.cc: src/mem/cache/miss/mshr.hh: src/mem/cache/miss/mshr_queue.cc: src/mem/cache/miss/mshr_queue.hh: src/mem/cache/prefetch/base_prefetcher.cc: src/mem/cache/tags/fa_lru.cc: src/mem/cache/tags/fa_lru.hh: src/mem/cache/tags/iic.cc: src/mem/cache/tags/iic.hh: src/mem/cache/tags/lru.cc: src/mem/cache/tags/lru.hh: src/mem/cache/tags/split.cc: src/mem/cache/tags/split.hh: src/mem/cache/tags/split_lifo.cc: src/mem/cache/tags/split_lifo.hh: src/mem/cache/tags/split_lru.cc: src/mem/cache/tags/split_lru.hh: src/mem/packet.cc: src/mem/packet.hh: src/mem/physical.cc: src/mem/physical.hh: src/mem/tport.cc: More major reorg. Seems to work for atomic mode now, timing mode still broken. --HG-- extra : convert_revision : 7e70dfc4a752393b911880ff028271433855ae87
Diffstat (limited to 'src/mem/bus.cc')
-rw-r--r--src/mem/bus.cc87
1 files changed, 51 insertions, 36 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index ec33bd4c5..bde90c83f 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -33,7 +33,7 @@
* Definition of a bus object.
*/
-
+#include <algorithm>
#include <limits>
#include "base/misc.hh"
@@ -182,8 +182,7 @@ Bus::recvTiming(PacketPtr pkt)
// If the bus is busy, or other devices are in line ahead of the current
// one, put this device on the retry list.
- if (!(pkt->flags & EXPRESS_SNOOP) &&
- tickNextIdle > curTick ||
+ if (tickNextIdle > curTick ||
(retryList.size() && (!inRetry || pktPort != retryList.front())))
{
addToRetryList(pktPort);
@@ -199,7 +198,7 @@ Bus::recvTiming(PacketPtr pkt)
port = findPort(pkt->getAddr(), pkt->getSrc());
timingSnoop(pkt, port ? port : interfaces[pkt->getSrc()]);
- if (pkt->flags & SATISFIED) {
+ if (pkt->memInhibitAsserted()) {
//Cache-Cache transfer occuring
if (inRetry) {
retryList.front()->onRetryList(false);
@@ -321,27 +320,6 @@ Bus::findPort(Addr addr, int id)
return interfaces[dest_id];
}
-Tick
-Bus::atomicSnoop(PacketPtr pkt, Port *responder)
-{
- Tick response_time = 0;
-
- for (SnoopIter s_iter = snoopPorts.begin();
- s_iter != snoopPorts.end();
- s_iter++) {
- BusPort *p = *s_iter;
- if (p != responder && p->getId() != pkt->getSrc()) {
- Tick response = p->sendAtomic(pkt);
- if (response) {
- assert(!response_time); //Multiple responders
- response_time = response;
- }
- }
- }
-
- return response_time;
-}
-
void
Bus::functionalSnoop(PacketPtr pkt, Port *responder)
{
@@ -390,19 +368,56 @@ Bus::recvAtomic(PacketPtr pkt)
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
assert(pkt->getDest() == Packet::Broadcast);
- // Assume one bus cycle in order to get through. This may have
- // some clock skew issues yet again...
- pkt->finishTime = curTick + clock;
+ // Variables for recording original command and snoop response (if
+ // any)... if a snooper respondes, we will need to restore
+ // original command so that additional snoops can take place
+ // properly
+ MemCmd orig_cmd = pkt->cmd;
+ Packet::Result response_result = Packet::Unknown;
+ MemCmd response_cmd = MemCmd::InvalidCmd;
- Port *port = findPort(pkt->getAddr(), pkt->getSrc());
- Tick snoopTime = atomicSnoop(pkt, port ? port : interfaces[pkt->getSrc()]);
+ Port *target_port = findPort(pkt->getAddr(), pkt->getSrc());
- if (snoopTime)
- return snoopTime; //Snoop satisfies it
- else if (port)
- return port->sendAtomic(pkt);
- else
- return 0;
+ SnoopIter s_end = snoopPorts.end();
+ for (SnoopIter s_iter = snoopPorts.begin(); s_iter != s_end; s_iter++) {
+ BusPort *p = *s_iter;
+ // same port should not have both target addresses and snooping
+ assert(p != target_port);
+ if (p->getId() != pkt->getSrc()) {
+ p->sendAtomic(pkt);
+ if (pkt->result != Packet::Unknown) {
+ // response from snoop agent
+ assert(pkt->cmd != orig_cmd);
+ assert(pkt->memInhibitAsserted());
+ assert(pkt->isResponse());
+ // should only happen once
+ assert(response_result == Packet::Unknown);
+ assert(response_cmd == MemCmd::InvalidCmd);
+ // save response state
+ response_result = pkt->result;
+ response_cmd = pkt->cmd;
+ // restore original packet state for remaining snoopers
+ pkt->cmd = orig_cmd;
+ pkt->result = Packet::Unknown;
+ }
+ }
+ }
+
+ Tick response_time = target_port->sendAtomic(pkt);
+
+ // if we got a response from a snooper, restore it here
+ if (response_result != Packet::Unknown) {
+ assert(response_cmd != MemCmd::InvalidCmd);
+ // no one else should have responded
+ assert(pkt->result == Packet::Unknown);
+ assert(pkt->cmd == orig_cmd);
+ pkt->cmd = response_cmd;
+ pkt->result = response_result;
+ }
+
+ // why do we have this packet field and the return value both???
+ pkt->finishTime = std::max(response_time, curTick + clock);
+ return pkt->finishTime;
}
/** Function called by the port when the bus is receiving a Functional