changeset daf9f91b11e9 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=daf9f91b11e9
description:
        cpu: Support virtual addr in elastic traces

        This patch adds support to optionally capture the virtual address and 
asid
        for load/store instructions in the elastic traces. If they are present 
in
        the traces, Trace CPU will set those fields of the request during 
replay.

diffstat:

 src/cpu/o3/probe/ElasticTrace.py  |   4 +++-
 src/cpu/o3/probe/elastic_trace.cc |  21 +++++++++++++++------
 src/cpu/o3/probe/elastic_trace.hh |  11 +++++++++--
 src/cpu/trace/trace_cpu.cc        |  38 +++++++++++++++++++++++++++++---------
 src/cpu/trace/trace_cpu.hh        |   8 +++++++-
 src/mem/request.hh                |   9 ++++++++-
 src/proto/inst_dep_record.proto   |   4 +++-
 util/decode_inst_dep_trace.py     |  11 ++++++-----
 util/encode_inst_dep_trace.py     |  12 ++++++------
 9 files changed, 86 insertions(+), 32 deletions(-)

diffs (299 lines):

diff -r 18bb597fc40c -r daf9f91b11e9 src/cpu/o3/probe/ElasticTrace.py
--- a/src/cpu/o3/probe/ElasticTrace.py  Mon Dec 07 16:42:16 2015 -0600
+++ b/src/cpu/o3/probe/ElasticTrace.py  Mon Dec 07 16:42:16 2015 -0600
@@ -59,4 +59,6 @@
                                     "after which to start tracing. Default " \
                                     "zero means start tracing from first " \
                                     "committed instruction.")
-
+    # Whether to trace virtual addresses for memory accesses
+    traceVirtAddr = Param.Bool(False, "Set to true if virtual addresses are " \
+                                "to be traced.")
diff -r 18bb597fc40c -r daf9f91b11e9 src/cpu/o3/probe/elastic_trace.cc
--- a/src/cpu/o3/probe/elastic_trace.cc Mon Dec 07 16:42:16 2015 -0600
+++ b/src/cpu/o3/probe/elastic_trace.cc Mon Dec 07 16:42:16 2015 -0600
@@ -57,7 +57,8 @@
        dataTraceStream(nullptr),
        instTraceStream(nullptr),
        startTraceInst(params->startTraceInst),
-       allProbesReg(false)
+       allProbesReg(false),
+       traceVirtAddr(params->traceVirtAddr)
 {
     cpu = dynamic_cast<FullO3CPU<O3CPUImpl>*>(params->manager);
     fatal_if(!cpu, "Manager of %s is not of type O3CPU and thus does not "\
@@ -391,7 +392,9 @@
 
     // Assign fields for creating a request in case of a load/store
     new_record->reqFlags = head_inst->memReqFlags;
-    new_record->addr = head_inst->physEffAddrLow;
+    new_record->virtAddr = head_inst->effAddr;
+    new_record->asid = head_inst->asid;
+    new_record->physAddr = head_inst->physEffAddrLow;
     // Currently the tracing does not support split requests.
     new_record->size = head_inst->effSize;
     new_record->pc = head_inst->instAddr();
@@ -787,9 +790,9 @@
                      "is as follows:\n", temp_ptr->instNum);
             if (temp_ptr->isLoad() || temp_ptr->isStore()) {
                 DPRINTFR(ElasticTrace, "\tis a %s\n", temp_ptr->typeToStr());
-                DPRINTFR(ElasticTrace, "\thas a request with addr %i, size %i,"
-                         " flags %i\n", temp_ptr->addr, temp_ptr->size,
-                         temp_ptr->reqFlags);
+                DPRINTFR(ElasticTrace, "\thas a request with phys addr %i, "
+                         "size %i, flags %i\n", temp_ptr->physAddr,
+                         temp_ptr->size, temp_ptr->reqFlags);
             } else {
                  DPRINTFR(ElasticTrace, "\tis a %s\n", temp_ptr->typeToStr());
             }
@@ -813,7 +816,13 @@
             dep_pkt.set_pc(temp_ptr->pc);
             if (temp_ptr->isLoad() || temp_ptr->isStore()) {
                 dep_pkt.set_flags(temp_ptr->reqFlags);
-                dep_pkt.set_addr(temp_ptr->addr);
+                dep_pkt.set_p_addr(temp_ptr->physAddr);
+                // If tracing of virtual addresses is enabled, set the optional
+                // field for it
+                if (traceVirtAddr) {
+                    dep_pkt.set_v_addr(temp_ptr->virtAddr);
+                    dep_pkt.set_asid(temp_ptr->asid);
+                }
                 dep_pkt.set_size(temp_ptr->size);
             }
             dep_pkt.set_comp_delay(temp_ptr->compDelay);
diff -r 18bb597fc40c -r daf9f91b11e9 src/cpu/o3/probe/elastic_trace.hh
--- a/src/cpu/o3/probe/elastic_trace.hh Mon Dec 07 16:42:16 2015 -0600
+++ b/src/cpu/o3/probe/elastic_trace.hh Mon Dec 07 16:42:16 2015 -0600
@@ -289,8 +289,12 @@
         Addr pc;
         /* Request flags in case of a load/store instruction */
         Request::FlagsType reqFlags;
-        /* Request address in case of a load/store instruction */
-        Addr addr;
+        /* Request physical address in case of a load/store instruction */
+        Addr physAddr;
+        /* Request virtual address in case of a load/store instruction */
+        Addr virtAddr;
+        /* Address space id in case of a load/store instruction */
+        uint32_t asid;
         /* Request size in case of a load/store instruction */
         unsigned size;
         /** Default Constructor */
@@ -366,6 +370,9 @@
      */
     bool allProbesReg;
 
+    /** Whether to trace virtual addresses for memory requests. */
+    const bool traceVirtAddr;
+
     /** Pointer to the O3CPU that is this listener's parent a.k.a. manager */
     FullO3CPU<O3CPUImpl>* cpu;
 
diff -r 18bb597fc40c -r daf9f91b11e9 src/cpu/trace/trace_cpu.cc
--- a/src/cpu/trace/trace_cpu.cc        Mon Dec 07 16:42:16 2015 -0600
+++ b/src/cpu/trace/trace_cpu.cc        Mon Dec 07 16:42:16 2015 -0600
@@ -597,8 +597,9 @@
 TraceCPU::ElasticDataGen::executeMemReq(GraphNode* node_ptr)
 {
 
-    DPRINTF(TraceCPUData, "Executing memory request %lli (addr %d, pc %#x, "
-            "size %d, flags %d).\n", node_ptr->seqNum, node_ptr->addr,
+    DPRINTF(TraceCPUData, "Executing memory request %lli (phys addr %d, "
+            "virt addr %d, pc %#x, size %d, flags %d).\n",
+            node_ptr->seqNum, node_ptr->physAddr, node_ptr->virtAddr,
             node_ptr->pc, node_ptr->size, node_ptr->flags);
 
     // If the request is strictly ordered, do not send it. Just return nullptr
@@ -617,17 +618,26 @@
     // happens. If required the code could be revised to mimick splitting such
     // a request into two.
     unsigned blk_size = owner.cacheLineSize();
-    Addr blk_offset = (node_ptr->addr & (Addr)(blk_size - 1));
+    Addr blk_offset = (node_ptr->physAddr & (Addr)(blk_size - 1));
     if (!(blk_offset + node_ptr->size <= blk_size)) {
         node_ptr->size = blk_size - blk_offset;
         ++numSplitReqs;
     }
 
     // Create a request and the packet containing request
-    Request* req = new Request(node_ptr->addr, node_ptr->size, node_ptr->flags,
-                               masterID, node_ptr->seqNum,
+    Request* req = new Request(node_ptr->physAddr, node_ptr->size,
+                               node_ptr->flags, masterID, node_ptr->seqNum,
                                ContextID(0), ThreadID(0));
     req->setPC(node_ptr->pc);
+    // If virtual address is valid, set the asid and virtual address fields
+    // of the request.
+    if (node_ptr->virtAddr != 0) {
+        req->setVirt(node_ptr->asid, node_ptr->virtAddr, node_ptr->size,
+                        node_ptr->flags, masterID, node_ptr->pc);
+        req->setPaddr(node_ptr->physAddr);
+        req->setReqInstSeqNum(node_ptr->seqNum);
+    }
+
     PacketPtr pkt;
     uint8_t* pkt_data = new uint8_t[req->getSize()];
     if (node_ptr->isLoad()) {
@@ -1277,10 +1287,20 @@
         }
 
         // Optional fields
-        if (pkt_msg.has_addr())
-            element->addr = pkt_msg.addr();
+        if (pkt_msg.has_p_addr())
+            element->physAddr = pkt_msg.p_addr();
         else
-            element->addr = 0;
+            element->physAddr = 0;
+
+        if (pkt_msg.has_v_addr())
+            element->virtAddr = pkt_msg.v_addr();
+        else
+            element->virtAddr = 0;
+
+        if (pkt_msg.has_asid())
+            element->asid = pkt_msg.asid();
+        else
+            element->asid = 0;
 
         if (pkt_msg.has_size())
             element->size = pkt_msg.size();
@@ -1383,7 +1403,7 @@
     DPRINTFR(TraceCPUData, "%lli", seqNum);
     DPRINTFR(TraceCPUData, ",%s", typeToStr());
     if (isLoad() || isStore()) {
-        DPRINTFR(TraceCPUData, ",%i", addr);
+        DPRINTFR(TraceCPUData, ",%i", physAddr);
         DPRINTFR(TraceCPUData, ",%i", size);
         DPRINTFR(TraceCPUData, ",%i", flags);
     }
diff -r 18bb597fc40c -r daf9f91b11e9 src/cpu/trace/trace_cpu.hh
--- a/src/cpu/trace/trace_cpu.hh        Mon Dec 07 16:42:16 2015 -0600
+++ b/src/cpu/trace/trace_cpu.hh        Mon Dec 07 16:42:16 2015 -0600
@@ -596,7 +596,13 @@
             RecordType type;
 
             /** The address for the request if any */
-            Addr addr;
+            Addr physAddr;
+
+            /** The virtual address for the request if any */
+            Addr virtAddr;
+
+            /** The address space id which is set if the virtual address is 
set */
+            uint32_t asid;
 
             /** Size of request if any */
             uint32_t size;
diff -r 18bb597fc40c -r daf9f91b11e9 src/mem/request.hh
--- a/src/mem/request.hh        Mon Dec 07 16:42:16 2015 -0600
+++ b/src/mem/request.hh        Mon Dec 07 16:42:16 2015 -0600
@@ -300,7 +300,7 @@
     Addr _pc;
 
     /** Sequence number of the instruction that creates the request */
-    const InstSeqNum _reqInstSeqNum;
+    InstSeqNum _reqInstSeqNum;
 
   public:
 
@@ -675,6 +675,13 @@
         return _reqInstSeqNum;
     }
 
+    void
+    setReqInstSeqNum(const InstSeqNum seq_num)
+    {
+        privateFlags.set(VALID_INST_SEQ_NUM);
+        _reqInstSeqNum = seq_num;
+    }
+
     /** Accessor functions for flags.  Note that these are for testing
         only; setting flags should be done via setFlags(). */
     bool isUncacheable() const { return _flags.isSet(UNCACHEABLE); }
diff -r 18bb597fc40c -r daf9f91b11e9 src/proto/inst_dep_record.proto
--- a/src/proto/inst_dep_record.proto   Mon Dec 07 16:42:16 2015 -0600
+++ b/src/proto/inst_dep_record.proto   Mon Dec 07 16:42:16 2015 -0600
@@ -69,7 +69,7 @@
   }
   required uint64 seq_num = 1;
   required RecordType type = 2 [default = INVALID];
-  optional uint64 addr = 3;
+  optional uint64 p_addr = 3;
   optional uint32 size = 4;
   optional uint32 flags = 5;
   repeated uint64 rob_dep = 6;
@@ -77,4 +77,6 @@
   repeated uint64 reg_dep = 8;
   optional uint32 weight = 9;
   optional uint64 pc = 10;
+  optional uint64 v_addr = 11;
+  optional uint32 asid = 12;
 }
\ No newline at end of file
diff -r 18bb597fc40c -r daf9f91b11e9 util/decode_inst_dep_trace.py
--- a/util/decode_inst_dep_trace.py     Mon Dec 07 16:42:16 2015 -0600
+++ b/util/decode_inst_dep_trace.py     Mon Dec 07 16:42:16 2015 -0600
@@ -72,12 +72,12 @@
 #
 # The ASCII trace format uses one line per instruction with the format
 # instruction sequence number, (optional) pc, (optional) weight, type
-# (optional) flags, (optional) addr, (optional) size, comp delay,
+# (optional) flags, (optional) phys addr, (optional) size, comp delay,
 # (repeated) order dependencies comma-separated, and (repeated) register
 # dependencies comma-separated.
 #
 # examples:
-# seq_num,[pc],[weight,]type,[address,size,flags,]comp_delay:[rob_dep]:
+# seq_num,[pc],[weight,]type,[p_addr,size,flags,]comp_delay:[rob_dep]:
 # [reg_dep]
 # 1,35652,1,COMP,8500::
 # 2,35656,1,COMP,0:,1:
@@ -178,9 +178,10 @@
             exit(-1)
 
 
-        # Write to file if it has the optional fields addr, size, flags
-        if packet.HasField('addr'):
-            ascii_out.write(',%s' % (packet.addr))
+        # Write to file if it has the optional fields physical addr, size,
+        # flags
+        if packet.HasField('p_addr'):
+            ascii_out.write(',%s' % (packet.p_addr))
         if packet.HasField('size'):
             ascii_out.write(',%s' % (packet.size))
         if packet.HasField('flags'):
diff -r 18bb597fc40c -r daf9f91b11e9 util/encode_inst_dep_trace.py
--- a/util/encode_inst_dep_trace.py     Mon Dec 07 16:42:16 2015 -0600
+++ b/util/encode_inst_dep_trace.py     Mon Dec 07 16:42:16 2015 -0600
@@ -72,12 +72,12 @@
 #
 # The ASCII trace format uses one line per instruction with the format
 # instruction sequence number, (optional) pc, (optional) weight, type,
-# (optional) flags, (optional) addr, (optional) size, comp delay,
+# (optional) flags, (optional) physical addr, (optional) size, comp delay,
 # (repeated) order dependencies comma-separated, and (repeated) register
 # dependencies comma-separated.
 #
 # examples:
-# seq_num,[pc],[weight,]type,[address,size,flags,]comp_delay:[rob_dep]:
+# seq_num,[pc],[weight,]type,[p_addr,size,flags,]comp_delay:[rob_dep]:
 # [reg_dep]
 # 1,35652,1,COMP,8500::
 # 2,35656,1,COMP,0:,1:
@@ -167,11 +167,11 @@
             print "Seq. num", dep_record.seq_num, "is of INVALID type"
             exit(-1)
 
-        # If the instruction is a load or store record the addr, size flags
-        # in addition to recording the computation delay
+        # If the instruction is a load or store record the physical addr,
+        # size flags in addition to recording the computation delay
         if dep_record.type in [DepRecord.LOAD, DepRecord.STORE]:
-            addr, size, flags, comp_delay = inst_info_list[4:8]
-            dep_record.addr = long(addr)
+            p_addr, size, flags, comp_delay = inst_info_list[4:8]
+            dep_record.p_addr = long(p_addr)
             dep_record.size = int(size)
             dep_record.flags = int(flags)
             dep_record.comp_delay = long(comp_delay)
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to