summaryrefslogtreecommitdiff
path: root/src/mem/packet.cc
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@gmail.com>2008-01-02 12:20:15 -0800
committerSteve Reinhardt <stever@gmail.com>2008-01-02 12:20:15 -0800
commit3952e41ab1f1dfaa2f97a6a486528e4ea0bfc5a1 (patch)
treee186dc9429d37ea5e9ca6657ce746e60447dee32 /src/mem/packet.cc
parent659aef3eb8ff2803601851b85347fee04c2721b8 (diff)
downloadgem5-3952e41ab1f1dfaa2f97a6a486528e4ea0bfc5a1.tar.xz
Add functional PrintReq command for memory-system debugging.
--HG-- extra : convert_revision : 73b753e57c355b7e6873f047ddc8cb371c3136b7
Diffstat (limited to 'src/mem/packet.cc')
-rw-r--r--src/mem/packet.cc121
1 files changed, 90 insertions, 31 deletions
diff --git a/src/mem/packet.cc b/src/mem/packet.cc
index 7b36be599..164363860 100644
--- a/src/mem/packet.cc
+++ b/src/mem/packet.cc
@@ -37,6 +37,7 @@
#include <iostream>
#include <cstring>
+#include "base/cprintf.hh"
#include "base/misc.hh"
#include "base/trace.hh"
#include "mem/packet.hh"
@@ -121,7 +122,9 @@ MemCmd::commandInfo[] =
/* InvalidDestError -- packet dest field invalid */
{ SET2(IsResponse, IsError), InvalidCmd, "InvalidDestError" },
/* BadAddressError -- memory address invalid */
- { SET2(IsResponse, IsError), InvalidCmd, "BadAddressError" }
+ { SET2(IsResponse, IsError), InvalidCmd, "BadAddressError" },
+ /* PrintReq */
+ { SET2(IsRequest, IsPrint), InvalidCmd, "PrintReq" }
};
@@ -154,7 +157,7 @@ Packet::allocate()
bool
-Packet::checkFunctional(Addr addr, int size, uint8_t *data)
+Packet::checkFunctional(Printable *obj, Addr addr, int size, uint8_t *data)
{
Addr func_start = getAddr();
Addr func_end = getAddr() + getSize() - 1;
@@ -166,6 +169,17 @@ Packet::checkFunctional(Addr addr, int size, uint8_t *data)
return false;
}
+ // check print first since it doesn't require data
+ if (isPrint()) {
+ dynamic_cast<PrintReqState*>(senderState)->printObj(obj);
+ return false;
+ }
+
+ // if there's no data, there's no need to look further
+ if (!data) {
+ return false;
+ }
+
// offset of functional request into supplied value (could be
// negative if partial overlap)
int offset = func_start - val_start;
@@ -194,40 +208,85 @@ Packet::checkFunctional(Addr addr, int size, uint8_t *data)
std::memcpy(data, getPtr<uint8_t>() - offset,
(std::min(func_end, val_end) - val_start) + 1);
}
- // we always want to keep going with a write
- return false;
- } else
+ } else {
panic("Don't know how to handle command %s\n", cmdString());
+ }
+
+ // keep going with request by default
+ return false;
+}
+
+
+void
+Packet::print(std::ostream &o, const int verbosity,
+ const std::string &prefix) const
+{
+ ccprintf(o, "%s[%x:%x] %s\n", prefix,
+ getAddr(), getAddr() + getSize() - 1, cmdString());
+}
+
+
+Packet::PrintReqState::PrintReqState(std::ostream &_os, int _verbosity)
+ : curPrefixPtr(new std::string("")), os(_os), verbosity(_verbosity)
+{
+ labelStack.push_back(LabelStackEntry("", curPrefixPtr));
+}
+
+
+Packet::PrintReqState::~PrintReqState()
+{
+ labelStack.pop_back();
+ assert(labelStack.empty());
+ delete curPrefixPtr;
+}
+
+
+Packet::PrintReqState::
+LabelStackEntry::LabelStackEntry(const std::string &_label,
+ std::string *_prefix)
+ : label(_label), prefix(_prefix), labelPrinted(false)
+{
}
-std::ostream &
-operator<<(std::ostream &o, const Packet &p)
+void
+Packet::PrintReqState::pushLabel(const std::string &lbl,
+ const std::string &prefix)
+{
+ labelStack.push_back(LabelStackEntry(lbl, curPrefixPtr));
+ curPrefixPtr = new std::string(*curPrefixPtr);
+ *curPrefixPtr += prefix;
+}
+
+void
+Packet::PrintReqState::popLabel()
{
+ delete curPrefixPtr;
+ curPrefixPtr = labelStack.back().prefix;
+ labelStack.pop_back();
+ assert(!labelStack.empty());
+}
- o << "[0x";
- o.setf(std::ios_base::hex, std::ios_base::showbase);
- o << p.getAddr();
- o.unsetf(std::ios_base::hex| std::ios_base::showbase);
- o << ":";
- o.setf(std::ios_base::hex, std::ios_base::showbase);
- o << p.getAddr() + p.getSize() - 1 << "] ";
- o.unsetf(std::ios_base::hex| std::ios_base::showbase);
-
- if (p.isRead())
- o << "Read ";
- if (p.isWrite())
- o << "Write ";
- if (p.isInvalidate())
- o << "Invalidate ";
- if (p.isRequest())
- o << "Request ";
- if (p.isResponse())
- o << "Response ";
- if (p.hasData())
- o << "w/Data ";
-
- o << std::endl;
- return o;
+void
+Packet::PrintReqState::printLabels()
+{
+ if (!labelStack.back().labelPrinted) {
+ LabelStack::iterator i = labelStack.begin();
+ LabelStack::iterator end = labelStack.end();
+ while (i != end) {
+ if (!i->labelPrinted) {
+ ccprintf(os, "%s%s\n", *(i->prefix), i->label);
+ i->labelPrinted = true;
+ }
+ i++;
+ }
+ }
}
+
+void
+Packet::PrintReqState::printObj(Printable *obj)
+{
+ printLabels();
+ obj->print(os, verbosity, curPrefix());
+}