summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/bus.cc25
-rw-r--r--src/mem/bus.hh23
-rw-r--r--src/mem/cache/cache_impl.hh48
-rw-r--r--src/mem/cache/miss/miss_queue.cc2
-rw-r--r--src/mem/packet.cc29
-rw-r--r--src/mem/packet.hh4
-rw-r--r--src/mem/physical.cc4
-rw-r--r--src/mem/tport.cc38
8 files changed, 132 insertions, 41 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 3998666c7..75ffed0d2 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -144,7 +144,10 @@ Bus::recvTiming(Packet *pkt)
DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
- BusPort *pktPort = interfaces[pkt->getSrc()];
+ BusPort *pktPort;
+ if (pkt->getSrc() == defaultId)
+ pktPort = defaultPort;
+ else pktPort = interfaces[pkt->getSrc()];
// If the bus is busy, or other devices are in line ahead of the current
// one, put this device on the retry list.
@@ -173,6 +176,7 @@ Bus::recvTiming(Packet *pkt)
port = findPort(pkt->getAddr(), pkt->getSrc());
} else {
//Snoop didn't succeed
+ DPRINTF(Bus, "Adding a retry to RETRY list %i\n", pktPort);
addToRetryList(pktPort);
return false;
}
@@ -293,16 +297,22 @@ Bus::findSnoopPorts(Addr addr, int id)
return ports;
}
-void
+Tick
Bus::atomicSnoop(Packet *pkt)
{
std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc());
+ Tick response_time = 0;
while (!ports.empty())
{
- interfaces[ports.back()]->sendAtomic(pkt);
+ Tick response = interfaces[ports.back()]->sendAtomic(pkt);
+ if (response) {
+ assert(!response_time); //Multiple responders
+ response_time = response;
+ }
ports.pop_back();
}
+ return response_time;
}
void
@@ -341,8 +351,11 @@ Bus::recvAtomic(Packet *pkt)
DPRINTF(Bus, "recvAtomic: packet src %d dest %d addr 0x%x cmd %s\n",
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
assert(pkt->getDest() == Packet::Broadcast);
- atomicSnoop(pkt);
- return findPort(pkt->getAddr(), pkt->getSrc())->sendAtomic(pkt);
+ Tick snoopTime = atomicSnoop(pkt);
+ if (snoopTime)
+ return snoopTime; //Snoop satisfies it
+ else
+ return findPort(pkt->getAddr(), pkt->getSrc())->sendAtomic(pkt);
}
/** Function called by the port when the bus is receiving a Functional
@@ -382,7 +395,7 @@ Bus::recvStatusChange(Port::Status status, int id)
}
} else {
- assert((id < interfaces.size() && id >= 0) || id == -1);
+ assert((id < interfaces.size() && id >= 0) || id == defaultId);
Port *port = interfaces[id];
std::vector<DevMap>::iterator portIter;
std::vector<DevMap>::iterator snoopIter;
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 3d0d07a7f..509b8cf9b 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -59,7 +59,7 @@ class Bus : public MemObject
/** the next tick at which the bus will be idle */
Tick tickNextIdle;
- static const int defaultId = -1;
+ static const int defaultId = -3; //Make it unique from Broadcast
struct DevMap {
int portId;
@@ -107,7 +107,7 @@ class Bus : public MemObject
std::vector<int> findSnoopPorts(Addr addr, int id);
/** Snoop all relevant ports atomicly. */
- void atomicSnoop(Packet *pkt);
+ Tick atomicSnoop(Packet *pkt);
/** Snoop all relevant ports functionally. */
void functionalSnoop(Packet *pkt);
@@ -224,18 +224,21 @@ class Bus : public MemObject
port->onRetryList(true);
retryList.push_back(port);
} else {
- // The device was retrying a packet. It didn't work, so we'll leave
- // it at the head of the retry list.
- inRetry = false;
-
-/* // We shouldn't be receiving a packet from one port when a different
- // one is retrying.
- assert(port == retryingPort);*/
+ if (port->onRetryList()) {
+ // The device was retrying a packet. It didn't work, so we'll leave
+ // it at the head of the retry list.
+ assert(port == retryList.front());
+ inRetry = false;
+ }
+ else {
+ port->onRetryList(true);
+ retryList.push_back(port);
+ }
}
}
/** Port that handles requests that don't match any of the interfaces.*/
- Port *defaultPort;
+ BusPort *defaultPort;
public:
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 58eb0bdbc..150abbe52 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -100,7 +100,7 @@ doAtomicAccess(Packet *pkt, bool isCpuSide)
if (pkt->isResponse())
handleResponse(pkt);
else
- snoopProbe(pkt);
+ return snoopProbe(pkt);
}
//Fix this timing info
return hitLatency;
@@ -148,7 +148,8 @@ Cache(const std::string &_name,
prefetchAccess(params.prefetchAccess),
tags(params.tags), missQueue(params.missQueue),
coherence(params.coherence), prefetcher(params.prefetcher),
- doCopy(params.doCopy), blockOnCopy(params.blockOnCopy)
+ doCopy(params.doCopy), blockOnCopy(params.blockOnCopy),
+ hitLatency(params.hitLatency)
{
//FIX BUS POINTERS
// if (params.in == NULL) {
@@ -284,8 +285,9 @@ Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr, bool
BlkType *blk = tags->findBlock(pkt);
CacheBlk::State old_state = (blk) ? blk->status : 0;
CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
- DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n",
- pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state);
+ if (old_state != new_state)
+ DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n",
+ pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state);
//Set the state on the upgrade
memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize);
PacketList writebacks;
@@ -324,8 +326,9 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt)
CacheBlk::State old_state = (blk) ? blk->status : 0;
PacketList writebacks;
CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
- DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n",
- pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state);
+ if (old_state != new_state)
+ DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n",
+ pkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state);
blk = tags->handleFill(blk, (MSHR*)pkt->senderState,
new_state, writebacks, pkt);
while (!writebacks.empty()) {
@@ -386,6 +389,11 @@ template<class TagStore, class Buffering, class Coherence>
void
Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
{
+ if (pkt->req->isUncacheable()) {
+ //Can't get a hit on an uncacheable address
+ //Revisit this for multi level coherence
+ return;
+ }
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
BlkType *blk = tags->findBlock(pkt);
MSHR *mshr = missQueue->findMSHR(blk_addr);
@@ -531,6 +539,10 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort
int lat;
BlkType *blk = tags->handleAccess(pkt, lat, writebacks, update);
+ DPRINTF(Cache, "%s %x %s blk_addr: %x\n", pkt->cmdString(),
+ pkt->getAddr() & (((ULL(1))<<48)-1), (blk) ? "hit" : "miss",
+ pkt->getAddr() & ~((Addr)blkSize - 1));
+
if (!blk) {
// Need to check for outstanding misses and writes
Addr blk_addr = pkt->getAddr() & ~(blkSize - 1);
@@ -637,6 +649,11 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort
busPkt->time = curTick;
+ DPRINTF(Cache, "Sending a atomic %s for %x blk_addr: %x\n",
+ busPkt->cmdString(),
+ busPkt->getAddr() & (((ULL(1))<<48)-1),
+ busPkt->getAddr() & ~((Addr)blkSize - 1));
+
lat = memSidePort->sendAtomic(busPkt);
//Be sure to flip the response to a request for coherence
@@ -652,13 +669,26 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort
*/ misses[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
CacheBlk::State old_state = (blk) ? blk->status : 0;
+ CacheBlk::State new_state = coherence->getNewState(busPkt, old_state);
+ DPRINTF(Cache, "Receive response:%s for blk addr %x in state %i\n",
+ busPkt->cmdString(),
+ busPkt->getAddr() & (((ULL(1))<<48)-1), old_state);
+ if (old_state != new_state)
+ DPRINTF(Cache, "Block for blk addr %x moving from state %i to %i\n",
+ busPkt->getAddr() & (((ULL(1))<<48)-1), old_state, new_state);
+
tags->handleFill(blk, busPkt,
- coherence->getNewState(busPkt, old_state),
+ new_state,
writebacks, pkt);
+ //Free the packet
+ delete busPkt;
+
// Handle writebacks if needed
while (!writebacks.empty()){
- memSidePort->sendAtomic(writebacks.front());
+ Packet *wbPkt = writebacks.front();
+ memSidePort->sendAtomic(wbPkt);
writebacks.pop_front();
+ delete wbPkt;
}
return lat + hitLatency;
} else {
@@ -679,7 +709,7 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update, CachePort
// Still need to change data in all locations.
otherSidePort->sendFunctional(pkt);
}
- return curTick + lat;
+ return hitLatency;
}
fatal("Probe not handled.\n");
return 0;
diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc
index c7b0e0890..c23b542f5 100644
--- a/src/mem/cache/miss/miss_queue.cc
+++ b/src/mem/cache/miss/miss_queue.cc
@@ -352,7 +352,7 @@ MissQueue::setPrefetcher(BasePrefetcher *_prefetcher)
MSHR*
MissQueue::allocateMiss(Packet * &pkt, int size, Tick time)
{
- MSHR* mshr = mq.allocate(pkt, blkSize);
+ MSHR* mshr = mq.allocate(pkt, size);
mshr->order = order++;
if (!pkt->req->isUncacheable() ){//&& !pkt->isNoAllocate()) {
// Mark this as a cache line fill
diff --git a/src/mem/packet.cc b/src/mem/packet.cc
index cc88827e3..64c65dcca 100644
--- a/src/mem/packet.cc
+++ b/src/mem/packet.cc
@@ -42,9 +42,18 @@
static const std::string ReadReqString("ReadReq");
static const std::string WriteReqString("WriteReq");
-static const std::string WriteReqNoAckString("WriteReqNoAck");
+static const std::string WriteReqNoAckString("WriteReqNoAck|Writeback");
static const std::string ReadRespString("ReadResp");
static const std::string WriteRespString("WriteResp");
+static const std::string SoftPFReqString("SoftPFReq");
+static const std::string SoftPFRespString("SoftPFResp");
+static const std::string HardPFReqString("HardPFReq");
+static const std::string HardPFRespString("HardPFResp");
+static const std::string InvalidateReqString("InvalidateReq");
+static const std::string WriteInvalidateReqString("WriteInvalidateReq");
+static const std::string UpgradeReqString("UpgradeReq");
+static const std::string ReadExReqString("ReadExReq");
+static const std::string ReadExRespString("ReadExResp");
static const std::string OtherCmdString("<other>");
const std::string &
@@ -56,6 +65,15 @@ Packet::cmdString() const
case WriteReqNoAck: return WriteReqNoAckString;
case ReadResp: return ReadRespString;
case WriteResp: return WriteRespString;
+ case SoftPFReq: return SoftPFReqString;
+ case SoftPFResp: return SoftPFRespString;
+ case HardPFReq: return HardPFReqString;
+ case HardPFResp: return HardPFRespString;
+ case InvalidateReq: return InvalidateReqString;
+ case WriteInvalidateReq:return WriteInvalidateReqString;
+ case UpgradeReq: return UpgradeReqString;
+ case ReadExReq: return ReadExReqString;
+ case ReadExResp: return ReadExRespString;
default: return OtherCmdString;
}
}
@@ -69,6 +87,15 @@ Packet::cmdIdxToString(Packet::Command idx)
case WriteReqNoAck: return WriteReqNoAckString;
case ReadResp: return ReadRespString;
case WriteResp: return WriteRespString;
+ case SoftPFReq: return SoftPFReqString;
+ case SoftPFResp: return SoftPFRespString;
+ case HardPFReq: return HardPFReqString;
+ case HardPFResp: return HardPFRespString;
+ case InvalidateReq: return InvalidateReqString;
+ case WriteInvalidateReq:return WriteInvalidateReqString;
+ case UpgradeReq: return UpgradeReqString;
+ case ReadExReq: return ReadExReqString;
+ case ReadExResp: return ReadExRespString;
default: return OtherCmdString;
}
}
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index 0bb51e924..48b32ec47 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -348,6 +348,10 @@ class Packet
int icmd = (int)cmd;
icmd &= ~(IsRequest);
icmd |= IsResponse;
+ if (isRead())
+ icmd |= HasData;
+ if (isWrite())
+ icmd &= ~HasData;
cmd = (Command)icmd;
}
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index 7303f278e..f5a0ade15 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -201,12 +201,16 @@ PhysicalMemory::doFunctionalAccess(Packet *pkt)
if (pkt->req->isLocked()) {
trackLoadLocked(pkt->req);
}
+ DPRINTF(MemoryAccess, "Performing Read of size %i on address 0x%x\n",
+ pkt->getSize(), pkt->getAddr());
memcpy(pkt->getPtr<uint8_t>(),
pmemAddr + pkt->getAddr() - params()->addrRange.start,
pkt->getSize());
}
else if (pkt->isWrite()) {
if (writeOK(pkt->req)) {
+ DPRINTF(MemoryAccess, "Performing Write of size %i on address 0x%x\n",
+ pkt->getSize(), pkt->getAddr());
memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start,
pkt->getPtr<uint8_t>(), pkt->getSize());
}
diff --git a/src/mem/tport.cc b/src/mem/tport.cc
index 528067170..456878d0a 100644
--- a/src/mem/tport.cc
+++ b/src/mem/tport.cc
@@ -58,15 +58,17 @@ SimpleTimingPort::recvTiming(Packet *pkt)
void
SimpleTimingPort::recvRetry()
{
- bool result = true;
-
- assert(transmitList.size());
- while (result && transmitList.size()) {
- result = sendTiming(transmitList.front());
- if (result)
- transmitList.pop_front();
+ assert(outTiming > 0);
+ assert(!transmitList.empty());
+ if (sendTiming(transmitList.front())) {
+ transmitList.pop_front();
+ outTiming--;
+ DPRINTF(Bus, "No Longer waiting on retry\n");
+ if (!transmitList.empty())
+ sendTimingLater(transmitList.front(), 1);
}
- if (transmitList.size() == 0 && drainEvent) {
+
+ if (transmitList.empty() && drainEvent) {
drainEvent->process();
drainEvent = NULL;
}
@@ -75,20 +77,28 @@ SimpleTimingPort::recvRetry()
void
SimpleTimingPort::SendEvent::process()
{
- port->outTiming--;
- assert(port->outTiming >= 0);
- if (port->transmitList.size()) {
+ assert(port->outTiming > 0);
+ if (!port->transmitList.empty() && port->transmitList.front() != packet) {
+ //We are not the head of the list
port->transmitList.push_back(packet);
} else if (port->sendTiming(packet)) {
// send successful
- if (port->transmitList.size() == 0 && port->drainEvent) {
+ if (port->transmitList.size()) {
+ port->transmitList.pop_front();
+ port->outTiming--;
+ if (!port->transmitList.empty())
+ port->sendTimingLater(port->transmitList.front(), 1);
+ }
+ if (port->transmitList.empty() && port->drainEvent) {
port->drainEvent->process();
port->drainEvent = NULL;
}
} else {
// send unsuccessful (due to flow control). Will get retry
- // callback later; save for then.
- port->transmitList.push_back(packet);
+ // callback later; save for then if not already
+ DPRINTF(Bus, "Waiting on retry\n");
+ if (!(port->transmitList.front() == packet))
+ port->transmitList.push_back(packet);
}
}