add a traceflag for functional accesses
authorAli Saidi <saidi@eecs.umich.edu>
Thu, 12 Oct 2006 18:15:09 +0000 (14:15 -0400)
committerAli Saidi <saidi@eecs.umich.edu>
Thu, 12 Oct 2006 18:15:09 +0000 (14:15 -0400)
implement fix packet and add the ability to print a packet to a ostream
remove tabs in packet.hh (Could people stop inserting them??!?!?!)
mark const functions in packet.hh as such

src/base/traceflags.py:
    add a traceflag for functional accesses
src/mem/packet.cc:
    implement fix packet and add the ability to print a packet to a ostream
src/mem/packet.hh:
    add the ability to print a packet to an ostream
    remove tabs in file
    mark const functions as such

--HG--
extra : convert_revision : 4297bce5e1d3abbab48be5bd9eb9e982b751fc7c

src/base/traceflags.py
src/mem/packet.cc
src/mem/packet.hh

index f871ce35f8912f54aa1152e6aac23cacf54ce3ed..e8b17c960b5372018ec05645507f00b9e3547cf5 100644 (file)
@@ -94,6 +94,7 @@ baseFlags = [
     'Flow',
     'FreeList',
     'FullCPU',
+    'FunctionalAccess',
     'GDBAcc',
     'GDBExtra',
     'GDBMisc',
index 7b8fa4a96880afcafc3879ccf232fdc5d8176468..cc88827e3747edaa8276c1cb4441e19f25a35b89 100644 (file)
  * 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");
@@ -112,5 +115,93 @@ Packet::intersect(Packet *p)
 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;
 }
+
index 3a7286a697caed5cb95bb54b47b6ac3d650d08e4..0bb51e9247fb70f9e794b3bb53b2cccb5375f7ec 100644 (file)
@@ -171,17 +171,17 @@ class Packet
     // 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:
@@ -189,18 +189,18 @@ class Packet
     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,
@@ -222,17 +222,17 @@ class Packet
     /** 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; }
 
@@ -397,5 +397,14 @@ class Packet
     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