diff --git a/src/base/printable.hh b/src/base/printable.hh index 1f71cce12..f79843ee5 100644 --- a/src/base/printable.hh +++ b/src/base/printable.hh @@ -36,6 +36,11 @@ #include #include +/** + * Abstract base class for objects which support being printed + * to a stream for debugging. Primarily used to support PrintReq + * in memory system. + */ class Printable { public: diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc index e2acff4ca..29da517b3 100644 --- a/src/cpu/memtest/memtest.cc +++ b/src/cpu/memtest/memtest.cc @@ -394,15 +394,16 @@ MemTest::doRetry() } } -MemTest * -MemTestParams::create() -{ - return new MemTest(this); -} - void MemTest::printAddr(Addr a) { cachePort.printAddr(a); } + + +MemTest * +MemTestParams::create() +{ + return new MemTest(this); +} diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh index eb0c822f1..1a330319f 100644 --- a/src/cpu/memtest/memtest.hh +++ b/src/cpu/memtest/memtest.hh @@ -62,6 +62,10 @@ class MemTest : public MemObject virtual Port *getPort(const std::string &if_name, int idx = -1); + /** + * Print state of address in memory system via PrintReq (for + * debugging). + */ void printAddr(Addr a); protected: diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 4553c0ae2..aa548b46f 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -783,6 +783,13 @@ AtomicSimpleCPU::tick() } +void +AtomicSimpleCPU::printAddr(Addr a) +{ + dcachePort.printAddr(a); +} + + //////////////////////////////////////////////////////////////////////// // // AtomicSimpleCPU Simulation Object diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh index f68f41a90..f14dd6f99 100644 --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -156,6 +156,12 @@ class AtomicSimpleCPU : public BaseSimpleCPU int size, unsigned flags); Fault translateDataWriteAddr(Addr vaddr, Addr &paddr, int size, unsigned flags); + + /** + * Print state of address in memory system via PrintReq (for + * debugging). + */ + void printAddr(Addr a); }; #endif // __CPU_SIMPLE_ATOMIC_HH__ diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 2f3ee5c73..fc35f2666 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -822,6 +822,13 @@ TimingSimpleCPU::IprEvent::description() } +void +TimingSimpleCPU::printAddr(Addr a) +{ + dcachePort.printAddr(a); +} + + //////////////////////////////////////////////////////////////////////// // // TimingSimpleCPU Simulation Object diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh index d7554f6de..79fbe0f5f 100644 --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -203,6 +203,12 @@ class TimingSimpleCPU : public BaseSimpleCPU void completeDataAccess(PacketPtr ); void advanceInst(Fault fault); + /** + * Print state of address in memory system via PrintReq (for + * debugging). + */ + void printAddr(Addr a); + private: typedef EventWrapper FetchEvent; diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index e7c2d1a02..bafb46a89 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -253,6 +253,12 @@ class CacheBlk } }; +/** + * Simple class to provide virtual print() method on cache blocks + * without allocating a vtable pointer for every single cache block. + * Just wrap the CacheBlk object in an instance of this before passing + * to a function that requires a Printable object. + */ class CacheBlkPrintWrapper : public Printable { CacheBlk *blk; diff --git a/src/mem/packet.hh b/src/mem/packet.hh index c97413e85..30ef71507 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -299,7 +299,12 @@ class Packet : public FastAlloc, public Printable virtual ~SenderState() {} }; + /** + * Object used to maintain state of a PrintReq. The senderState + * field of a PrintReq should always be of this type. + */ class PrintReqState : public SenderState { + /** An entry in the label stack. */ class LabelStackEntry { public: const std::string label; @@ -321,11 +326,23 @@ class Packet : public FastAlloc, public Printable PrintReqState(std::ostream &os, int verbosity = 0); ~PrintReqState(); + /** Returns the current line prefix. */ const std::string &curPrefix() { return *curPrefixPtr; } + + /** Push a label onto the label stack, and prepend the given + * prefix string onto the current prefix. Labels will only be + * printed if an object within the label's scope is + * printed. */ void pushLabel(const std::string &lbl, const std::string &prefix = " "); + /** Pop a label off the label stack. */ void popLabel(); + /** Print all of the pending unprinted labels on the + * stack. Called by printObj(), so normally not called by + * users unless bypassing printObj(). */ void printLabels(); + /** Print a Printable object to os, because it matched the + * address on a PrintReq. */ void printObj(Printable *obj); }; @@ -613,13 +630,7 @@ class Packet : public FastAlloc, public Printable /** * Check a functional request against a memory value stored in - * another packet (i.e. an in-transit request or response). If - * possible, the request will be satisfied and transformed - * in-place into a response (at which point no further checking - * need be done). - * - * @return True if the memory location addressed by the request - * overlaps with the location addressed by otherPkt. + * another packet (i.e. an in-transit request or response). */ bool checkFunctional(PacketPtr otherPkt) { return checkFunctional(otherPkt, @@ -628,12 +639,18 @@ class Packet : public FastAlloc, public Printable otherPkt->getPtr() : NULL); } + /** + * Push label for PrintReq (safe to call unconditionally). + */ void pushLabel(const std::string &lbl) { if (isPrint()) { dynamic_cast(senderState)->pushLabel(lbl); } } + /** + * Pop label for PrintReq (safe to call unconditionally). + */ void popLabel() { if (isPrint()) { dynamic_cast(senderState)->popLabel(); diff --git a/src/mem/physical.cc b/src/mem/physical.cc index 40dc30afb..3560fc670 100644 --- a/src/mem/physical.cc +++ b/src/mem/physical.cc @@ -323,8 +323,12 @@ PhysicalMemory::doFunctionalAccess(PacketPtr pkt) TRACE_PACKET("Write"); pkt->makeAtomicResponse(); } else if (pkt->isPrint()) { - Packet::PrintReqState *prs = dynamic_cast(pkt->senderState); + Packet::PrintReqState *prs = + dynamic_cast(pkt->senderState); + // Need to call printLabels() explicitly since we're not going + // through printObj(). prs->printLabels(); + // Right now we just print the single byte at the specified address. ccprintf(prs->os, "%s%#x\n", prs->curPrefix(), *hostAddr); } else { panic("PhysicalMemory: unimplemented functional command %s", diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh index 20a35a32b..ec565ce82 100644 --- a/src/sim/sim_object.hh +++ b/src/sim/sim_object.hh @@ -133,7 +133,7 @@ class SimObject : public Serializable, protected StartupCallback /** * Find the SimObject with the given name and return a pointer to - * it. Priarily used for interactive debugging. Argument is + * it. Primarily used for interactive debugging. Argument is * char* rather than std::string to make it callable from gdb. */ static SimObject *find(const char *name);