changeset 45df88079f04 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=45df88079f04
description:
mem: Adding verbose debug output in the memory system
This patch provides useful printouts throughut the memory system. This
includes pretty-printed cache tags and function call messages
(call-stack like).
diffstat:
src/mem/abstract_mem.cc | 5 ++-
src/mem/cache/SConscript | 1 +
src/mem/cache/blk.hh | 36 ++++++++++++++++++++++++++
src/mem/cache/cache_impl.hh | 60 +++++++++++++++++++++++++++++++++----------
src/mem/cache/mshr.cc | 22 ++++++++++++++++
src/mem/cache/mshr.hh | 19 +++++++++++++
src/mem/cache/tags/base.hh | 5 +++
src/mem/cache/tags/fa_lru.hh | 5 +++
src/mem/cache/tags/lru.cc | 30 ++++++++++++++++++++++
src/mem/cache/tags/lru.hh | 5 +++
src/mem/coherent_bus.cc | 3 ++
src/mem/packet.cc | 9 +++++-
src/mem/packet.hh | 8 +++++
src/mem/packet_queue.cc | 2 +
14 files changed, 194 insertions(+), 16 deletions(-)
diffs (truncated from 517 to 300 lines):
diff -r 59a7df953d5e -r 45df88079f04 src/mem/abstract_mem.cc
--- a/src/mem/abstract_mem.cc Mon Apr 22 13:20:33 2013 -0400
+++ b/src/mem/abstract_mem.cc Mon Apr 22 13:20:33 2013 -0400
@@ -363,8 +363,11 @@
bytesInstRead[pkt->req->masterId()] += pkt->getSize();
} else if (pkt->isWrite()) {
if (writeOK(pkt)) {
- if (pmemAddr)
+ if (pmemAddr) {
memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
+ DPRINTF(MemoryAccess, "%s wrote %x bytes to address %x\n",
+ __func__, pkt->getSize(), pkt->getAddr());
+ }
assert(!pkt->req->isInstFetch());
TRACE_PACKET("Write");
numWrites[pkt->req->masterId()]++;
diff -r 59a7df953d5e -r 45df88079f04 src/mem/cache/SConscript
--- a/src/mem/cache/SConscript Mon Apr 22 13:20:33 2013 -0400
+++ b/src/mem/cache/SConscript Mon Apr 22 13:20:33 2013 -0400
@@ -45,4 +45,5 @@
DebugFlag('Cache')
DebugFlag('CachePort')
DebugFlag('CacheRepl')
+DebugFlag('CacheTags')
DebugFlag('HWPrefetch')
diff -r 59a7df953d5e -r 45df88079f04 src/mem/cache/blk.hh
--- a/src/mem/cache/blk.hh Mon Apr 22 13:20:33 2013 -0400
+++ b/src/mem/cache/blk.hh Mon Apr 22 13:20:33 2013 -0400
@@ -289,6 +289,42 @@
}
/**
+ * Pretty-print a tag, and interpret state bits to readable form
+ * including mapping to a MOESI stat.
+ *
+ * @return string with basic state information
+ */
+ std::string print() const
+ {
+ /**
+ * state M O E S I
+ * writable 1 0 1 0 0
+ * dirty 1 1 0 0 0
+ * valid 1 1 1 1 0
+ *
+ * state writable dirty valid
+ * M 1 1 1
+ * O 0 1 1
+ * E 1 0 1
+ * S 0 0 1
+ * I 0 0 0
+ **/
+ unsigned state = isWritable() << 2 | isDirty() << 1 | isValid();
+ char s = '?';
+ switch (state) {
+ case 0b111: s = 'M'; break;
+ case 0b011: s = 'O'; break;
+ case 0b101: s = 'E'; break;
+ case 0b001: s = 'S'; break;
+ case 0b000: s = 'I'; break;
+ default: s = 'T'; break; // @TODO add other types
+ }
+ return csprintf("state: %x (%c) valid: %d writable: %d readable: %d "
+ "dirty: %d tag: %x data: %x", status, s, isValid(),
+ isWritable(), isReadable(), isDirty(), tag, *data);
+ }
+
+ /**
* Handle interaction of load-locked operations and stores.
* @return True if write should proceed, false otherwise. Returns
* false only in the case of a failed store conditional.
diff -r 59a7df953d5e -r 45df88079f04 src/mem/cache/cache_impl.hh
--- a/src/mem/cache/cache_impl.hh Mon Apr 22 13:20:33 2013 -0400
+++ b/src/mem/cache/cache_impl.hh Mon Apr 22 13:20:33 2013 -0400
@@ -55,6 +55,7 @@
#include "base/types.hh"
#include "debug/Cache.hh"
#include "debug/CachePort.hh"
+#include "debug/CacheTags.hh"
#include "mem/cache/prefetch/base.hh"
#include "mem/cache/blk.hh"
#include "mem/cache/cache.hh"
@@ -278,6 +279,8 @@
Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk,
Cycles &lat, PacketList &writebacks)
{
+ DPRINTF(Cache, "%s for %s address %x size %d\n", __func__,
+ pkt->cmdString(), pkt->getAddr(), pkt->getSize());
if (pkt->req->isUncacheable()) {
uncacheableFlush(pkt);
blk = NULL;
@@ -288,9 +291,9 @@
int id = pkt->req->hasContextId() ? pkt->req->contextId() : -1;
blk = tags->accessBlock(pkt->getAddr(), lat, id);
- DPRINTF(Cache, "%s%s %x %s\n", pkt->cmdString(),
+ DPRINTF(Cache, "%s%s %x %s %s\n", pkt->cmdString(),
pkt->req->isInstFetch() ? " (ifetch)" : "",
- pkt->getAddr(), (blk) ? "hit" : "miss");
+ pkt->getAddr(), blk ? "hit" : "miss", blk ? blk->print() : "");
if (blk != NULL) {
@@ -330,6 +333,7 @@
}
// nothing else to do; writeback doesn't expect response
assert(!pkt->needsResponse());
+ DPRINTF(Cache, "%s new state is %s\n", __func__, blk->print());
incHitCount(pkt);
return true;
}
@@ -360,6 +364,8 @@
void
Cache<TagStore>::recvTimingSnoopResp(PacketPtr pkt)
{
+ DPRINTF(Cache, "%s for %s address %x size %d\n", __func__,
+ pkt->cmdString(), pkt->getAddr(), pkt->getSize());
Tick time = clockEdge(hitLatency);
assert(pkt->isResponse());
@@ -391,6 +397,7 @@
bool
Cache<TagStore>::recvTimingReq(PacketPtr pkt)
{
+ DPRINTF(CacheTags, "%s tags: %s\n", __func__, tags->print());
//@todo Add back in MemDebug Calls
// MemDebug::cacheAccess(pkt);
@@ -630,6 +637,8 @@
PacketPtr pkt = new Packet(cpu_pkt->req, cmd, blkSize);
pkt->allocate();
+ DPRINTF(Cache, "%s created %s address %x size %d\n",
+ __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize());
return pkt;
}
@@ -850,7 +859,8 @@
"cmd: %s\n", pkt->getAddr(), pkt->cmdString());
}
- DPRINTF(Cache, "Handling response to %x\n", pkt->getAddr());
+ DPRINTF(Cache, "Handling response to %s for address %x\n",
+ pkt->cmdString(), pkt->getAddr());
MSHRQueue *mq = mshr->queue;
bool wasFull = mq->isFull();
@@ -959,6 +969,9 @@
// propagate that. Response should not have
// isInvalidate() set otherwise.
target->pkt->cmd = MemCmd::ReadRespWithInvalidate;
+ DPRINTF(Cache, "%s updated cmd to %s for address %x\n",
+ __func__, target->pkt->cmdString(),
+ target->pkt->getAddr());
}
// reset the bus additional time as it is now accounted for
target->pkt->busFirstWordDelay = target->pkt->busLastWordDelay = 0;
@@ -1031,6 +1044,8 @@
blk->invalidate();
}
+ DPRINTF(Cache, "Leaving %s with %s for address %x\n", __func__,
+ pkt->cmdString(), pkt->getAddr());
delete pkt;
}
@@ -1234,8 +1249,8 @@
blk->status |= BlkDirty;
}
- DPRINTF(Cache, "Block addr %x moving from state %i to %i\n",
- addr, old_state, blk->status);
+ DPRINTF(Cache, "Block addr %x moving from state %x to %s\n",
+ addr, old_state, blk->print());
// if we got new data, copy it in
if (pkt->isRead()) {
@@ -1261,6 +1276,8 @@
doTimingSupplyResponse(PacketPtr req_pkt, uint8_t *blk_data,
bool already_copied, bool pending_inval)
{
+ DPRINTF(Cache, "%s for %s address %x size %d\n", __func__,
+ req_pkt->cmdString(), req_pkt->getAddr(), req_pkt->getSize());
// timing-mode snoop responses require a new packet, unless we
// already made a copy...
PacketPtr pkt = already_copied ? req_pkt : new Packet(req_pkt);
@@ -1282,6 +1299,8 @@
// invalidate it.
pkt->cmd = MemCmd::ReadRespWithInvalidate;
}
+ DPRINTF(Cache, "%s created response: %s address %x size %d\n",
+ __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize());
memSidePort->schedTimingSnoopResp(pkt, clockEdge(hitLatency));
}
@@ -1291,6 +1310,8 @@
bool is_timing, bool is_deferred,
bool pending_inval)
{
+ DPRINTF(Cache, "%s for %s address %x size %d\n", __func__,
+ pkt->cmdString(), pkt->getAddr(), pkt->getSize());
// deferred snoops can only happen in timing mode
assert(!(is_deferred && !is_timing));
// pending_inval only makes sense on deferred snoops
@@ -1336,9 +1357,15 @@
}
}
- if (!blk || !blk->isValid()) {
- return;
- }
+ if (!blk || !blk->isValid()) {
+ DPRINTF(Cache, "%s snoop miss for %s address %x size %d\n",
+ __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize());
+ return;
+ } else {
+ DPRINTF(Cache, "%s snoop hit for %s for address %x size %d, "
+ "old state is %s\n", __func__, pkt->cmdString(),
+ pkt->getAddr(), pkt->getSize(), blk->print());
+ }
// we may end up modifying both the block state and the packet (if
// we respond in atomic mode), so just figure out what to do now
@@ -1360,10 +1387,6 @@
blk->status &= ~bits_to_clear;
}
- DPRINTF(Cache, "snooped a %s request for addr %x, %snew state is %i\n",
- pkt->cmdString(), blockAlign(pkt->getAddr()),
- respond ? "responding, " : "", invalidate ? 0 : blk->status);
-
if (respond) {
assert(!pkt->memInhibitAsserted());
pkt->assertMemInhibit();
@@ -1390,6 +1413,8 @@
tags->invalidate(blk);
blk->invalidate();
}
+
+ DPRINTF(Cache, "new state is %s\n", blk->print());
}
@@ -1397,6 +1422,9 @@
void
Cache<TagStore>::recvTimingSnoopReq(PacketPtr pkt)
{
+ DPRINTF(Cache, "%s for %s address %x size %d\n", __func__,
+ pkt->cmdString(), pkt->getAddr(), pkt->getSize());
+
// Snoops shouldn't happen when bypassing caches
assert(!system->bypassCaches());
@@ -1417,8 +1445,9 @@
// Let the MSHR itself track the snoop and decide whether we want
// to go ahead and do the regular cache snoop
if (mshr && mshr->handleSnoop(pkt, order++)) {
- DPRINTF(Cache, "Deferring snoop on in-service MSHR to blk %x\n",
- blk_addr);
+ DPRINTF(Cache, "Deferring snoop on in-service MSHR to blk %x."
+ "mshrs: %s\n", blk_addr, mshr->print());
+
if (mshr->getNumTargets() > numTarget)
warn("allocating bonus target for snoop"); //handle later
return;
@@ -1598,6 +1627,9 @@
PacketPtr tgt_pkt = mshr->getTarget()->pkt;
PacketPtr pkt = NULL;
+ DPRINTF(CachePort, "%s %s for address %x size %d\n", __func__,
+ tgt_pkt->cmdString(), tgt_pkt->getAddr(), tgt_pkt->getSize());
+
if (tgt_pkt->cmd == MemCmd::SCUpgradeFailReq ||
tgt_pkt->cmd == MemCmd::StoreCondFailReq) {
// SCUpgradeReq or StoreCondReq saw invalidation while queued
diff -r 59a7df953d5e -r 45df88079f04 src/mem/cache/mshr.cc
--- a/src/mem/cache/mshr.cc Mon Apr 22 13:20:33 2013 -0400
+++ b/src/mem/cache/mshr.cc Mon Apr 22 13:20:33 2013 -0400
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2012 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* Copyright (c) 2010 Advanced Micro Devices, Inc.
* All rights reserved.
@@ -303,6 +315,8 @@
bool
MSHR::handleSnoop(PacketPtr pkt, Counter _order)
{
+ DPRINTF(Cache, "%s for %s address %x size %d\n", __func__,
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev