* Definition of the Packet Class, a packet is a transaction occuring
* between a single level of the memory heirarchy (ie L1->L2).
*/
+
+#include <iostream>
#include "base/misc.hh"
#include "mem/packet.hh"
+#include "base/trace.hh"
static const std::string ReadReqString("ReadReq");
static const std::string WriteReqString("WriteReq");
bool
fixPacket(Packet *func, Packet *timing)
{
- panic("Need to implement!");
+ Addr funcStart = func->getAddr();
+ Addr funcEnd = func->getAddr() + func->getSize() - 1;
+ Addr timingStart = timing->getAddr();
+ Addr timingEnd = timing->getAddr() + timing->getSize() - 1;
+
+ assert(!(funcStart > timingEnd || timingStart < funcEnd));
+
+ if (DTRACE(FunctionalAccess)) {
+ DebugOut() << func;
+ DebugOut() << timing;
+ }
+
+ // this packet can't solve our problem, continue on
+ if (!timing->hasData())
+ return true;
+
+ if (func->isRead()) {
+ if (funcStart >= timingStart && funcEnd <= timingEnd) {
+ func->allocate();
+ memcpy(func->getPtr<uint8_t>(), timing->getPtr<uint8_t>() +
+ funcStart - timingStart, func->getSize());
+ func->result = Packet::Success;
+ return false;
+ } else {
+ // In this case the timing packet only partially satisfies the
+ // requset, so we would need more information to make this work.
+ // Like bytes valid in the packet or something, so the request could
+ // continue and get this bit of possibly newer data along with the
+ // older data not written to yet.
+ panic("Timing packet only partially satisfies the functional"
+ "request. Now what?");
+ }
+ } else if (func->isWrite()) {
+ if (funcStart >= timingStart) {
+ memcpy(timing->getPtr<uint8_t>() + (funcStart - timingStart),
+ func->getPtr<uint8_t>(),
+ funcStart - std::min(funcEnd, timingEnd));
+ } else { // timingStart > funcStart
+ memcpy(timing->getPtr<uint8_t>(),
+ func->getPtr<uint8_t>() + (timingStart - funcStart),
+ timingStart - std::min(funcEnd, timingEnd));
+ }
+ // we always want to keep going with a write
+ return true;
+ } else
+ panic("Don't know how to handle command type %#x\n",
+ func->cmdToIndex());
+
+}
+
+
+std::ostream &
+operator<<(std::ostream &o, const Packet &p)
+{
+
+ 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.result == Packet::Success)
+ o << "Successful ";
+ if (p.result == Packet::BadAddress)
+ o << "BadAddress ";
+ if (p.result == Packet::Nacked)
+ o << "Nacked ";
+ if (p.result == Packet::Unknown)
+ o << "Inflight ";
+
+ if (p.isRead())
+ o << "Read ";
+ if (p.isWrite())
+ o << "Read ";
+ if (p.isInvalidate())
+ o << "Read ";
+ if (p.isRequest())
+ o << "Request ";
+ if (p.isResponse())
+ o << "Response ";
+ if (p.hasData())
+ o << "w/Data ";
+
+ o << std::endl;
+ return o;
}
+
// as well.
enum CommandAttribute
{
- IsRead = 1 << 0,
- IsWrite = 1 << 1,
- IsPrefetch = 1 << 2,
- IsInvalidate = 1 << 3,
- IsRequest = 1 << 4,
- IsResponse = 1 << 5,
- NeedsResponse = 1 << 6,
+ IsRead = 1 << 0,
+ IsWrite = 1 << 1,
+ IsPrefetch = 1 << 2,
+ IsInvalidate = 1 << 3,
+ IsRequest = 1 << 4,
+ IsResponse = 1 << 5,
+ NeedsResponse = 1 << 6,
IsSWPrefetch = 1 << 7,
IsHWPrefetch = 1 << 8,
IsUpgrade = 1 << 9,
- HasData = 1 << 10
+ HasData = 1 << 10
};
public:
enum Command
{
InvalidCmd = 0,
- ReadReq = IsRead | IsRequest | NeedsResponse,
- WriteReq = IsWrite | IsRequest | NeedsResponse | HasData,
- WriteReqNoAck = IsWrite | IsRequest | HasData,
- ReadResp = IsRead | IsResponse | NeedsResponse | HasData,
- WriteResp = IsWrite | IsResponse | NeedsResponse,
+ ReadReq = IsRead | IsRequest | NeedsResponse,
+ WriteReq = IsWrite | IsRequest | NeedsResponse | HasData,
+ WriteReqNoAck = IsWrite | IsRequest | HasData,
+ ReadResp = IsRead | IsResponse | NeedsResponse | HasData,
+ WriteResp = IsWrite | IsResponse | NeedsResponse,
Writeback = IsWrite | IsRequest | HasData,
SoftPFReq = IsRead | IsRequest | IsSWPrefetch | NeedsResponse,
HardPFReq = IsRead | IsRequest | IsHWPrefetch | NeedsResponse,
SoftPFResp = IsRead | IsResponse | IsSWPrefetch
| NeedsResponse | HasData,
HardPFResp = IsRead | IsResponse | IsHWPrefetch
- | NeedsResponse | HasData,
+ | NeedsResponse | HasData,
InvalidateReq = IsInvalidate | IsRequest,
WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest | HasData,
UpgradeReq = IsInvalidate | IsRequest | IsUpgrade,
/** The command field of the packet. */
Command cmd;
- bool isRead() { return (cmd & IsRead) != 0; }
- bool isWrite() { return (cmd & IsWrite) != 0; }
- bool isRequest() { return (cmd & IsRequest) != 0; }
- bool isResponse() { return (cmd & IsResponse) != 0; }
- bool needsResponse() { return (cmd & NeedsResponse) != 0; }
- bool isInvalidate() { return (cmd & IsInvalidate) != 0; }
- bool hasData() { return (cmd & HasData) != 0; }
+ bool isRead() const { return (cmd & IsRead) != 0; }
+ bool isWrite() const { return (cmd & IsWrite) != 0; }
+ bool isRequest() const { return (cmd & IsRequest) != 0; }
+ bool isResponse() const { return (cmd & IsResponse) != 0; }
+ bool needsResponse() const { return (cmd & NeedsResponse) != 0; }
+ bool isInvalidate() const { return (cmd & IsInvalidate) != 0; }
+ bool hasData() const { return (cmd & HasData) != 0; }
- bool isCacheFill() { return (flags & CACHE_LINE_FILL) != 0; }
- bool isNoAllocate() { return (flags & NO_ALLOCATE) != 0; }
- bool isCompressed() { return (flags & COMPRESSED) != 0; }
+ bool isCacheFill() const { return (flags & CACHE_LINE_FILL) != 0; }
+ bool isNoAllocate() const { return (flags & NO_ALLOCATE) != 0; }
+ bool isCompressed() const { return (flags & COMPRESSED) != 0; }
bool nic_pkt() { assert("Unimplemented\n" && 0); return false; }
bool intersect(Packet *p);
};
+
+/** This function given a functional packet and a timing packet either satisfies
+ * the timing packet, or updates the timing packet to reflect the updated state
+ * in the timing packet. It returns if the functional packet should continue to
+ * traverse the memory hierarchy or not.
+ */
bool fixPacket(Packet *func, Packet *timing);
+
+std::ostream & operator<<(std::ostream &o, const Packet &p);
+
#endif //__MEM_PACKET_HH