summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRadhika Jagtap <radhika.jagtap@ARM.com>2015-12-07 16:42:16 -0600
committerRadhika Jagtap <radhika.jagtap@ARM.com>2015-12-07 16:42:16 -0600
commit54519fd51f739c3a37c4ad712b86a353eabbbfec (patch)
tree21002ebffe820d302b839ac625636830b141964b
parent3080bbcc365e6ed663787a4c06cd2b7c4a118d47 (diff)
downloadgem5-54519fd51f739c3a37c4ad712b86a353eabbbfec.tar.xz
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.
-rw-r--r--src/cpu/o3/probe/ElasticTrace.py4
-rw-r--r--src/cpu/o3/probe/elastic_trace.cc21
-rw-r--r--src/cpu/o3/probe/elastic_trace.hh11
-rw-r--r--src/cpu/trace/trace_cpu.cc38
-rw-r--r--src/cpu/trace/trace_cpu.hh8
-rw-r--r--src/mem/request.hh9
-rw-r--r--src/proto/inst_dep_record.proto4
-rwxr-xr-xutil/decode_inst_dep_trace.py11
-rwxr-xr-xutil/encode_inst_dep_trace.py12
9 files changed, 86 insertions, 32 deletions
diff --git a/src/cpu/o3/probe/ElasticTrace.py b/src/cpu/o3/probe/ElasticTrace.py
index fb3093a2c..20057ab97 100644
--- a/src/cpu/o3/probe/ElasticTrace.py
+++ b/src/cpu/o3/probe/ElasticTrace.py
@@ -59,4 +59,6 @@ class ElasticTrace(ProbeListenerObject):
"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 --git a/src/cpu/o3/probe/elastic_trace.cc b/src/cpu/o3/probe/elastic_trace.cc
index e1a41b696..3332816ca 100644
--- a/src/cpu/o3/probe/elastic_trace.cc
+++ b/src/cpu/o3/probe/elastic_trace.cc
@@ -57,7 +57,8 @@ ElasticTrace::ElasticTrace(const ElasticTraceParams* params)
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 @@ ElasticTrace::addDepTraceRecord(const DynInstPtr &head_inst,
// 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 @@ ElasticTrace::writeDepTrace(uint32_t num_to_write)
"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 @@ ElasticTrace::writeDepTrace(uint32_t num_to_write)
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 --git a/src/cpu/o3/probe/elastic_trace.hh b/src/cpu/o3/probe/elastic_trace.hh
index 001dc0e13..584cdf182 100644
--- a/src/cpu/o3/probe/elastic_trace.hh
+++ b/src/cpu/o3/probe/elastic_trace.hh
@@ -289,8 +289,12 @@ class ElasticTrace : public ProbeListenerObject
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 @@ class ElasticTrace : public ProbeListenerObject
*/
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 --git a/src/cpu/trace/trace_cpu.cc b/src/cpu/trace/trace_cpu.cc
index ffa64014a..f940be2f9 100644
--- a/src/cpu/trace/trace_cpu.cc
+++ b/src/cpu/trace/trace_cpu.cc
@@ -597,8 +597,9 @@ PacketPtr
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 @@ TraceCPU::ElasticDataGen::executeMemReq(GraphNode* node_ptr)
// 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 @@ TraceCPU::ElasticDataGen::InputStream::read(GraphNode* element)
}
// 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->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->addr = 0;
+ element->asid = 0;
if (pkt_msg.has_size())
element->size = pkt_msg.size();
@@ -1383,7 +1403,7 @@ TraceCPU::ElasticDataGen::GraphNode::writeElementAsTrace() const
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 --git a/src/cpu/trace/trace_cpu.hh b/src/cpu/trace/trace_cpu.hh
index 751321491..bb59c3fab 100644
--- a/src/cpu/trace/trace_cpu.hh
+++ b/src/cpu/trace/trace_cpu.hh
@@ -596,7 +596,13 @@ class TraceCPU : public BaseCPU
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 --git a/src/mem/request.hh b/src/mem/request.hh
index 177f17de2..287a823ad 100644
--- a/src/mem/request.hh
+++ b/src/mem/request.hh
@@ -300,7 +300,7 @@ class Request
Addr _pc;
/** Sequence number of the instruction that creates the request */
- const InstSeqNum _reqInstSeqNum;
+ InstSeqNum _reqInstSeqNum;
public:
@@ -675,6 +675,13 @@ class Request
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 --git a/src/proto/inst_dep_record.proto b/src/proto/inst_dep_record.proto
index 98c070efc..f89e51d81 100644
--- a/src/proto/inst_dep_record.proto
+++ b/src/proto/inst_dep_record.proto
@@ -69,7 +69,7 @@ message InstDepRecord {
}
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 @@ message InstDepRecord {
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 --git a/util/decode_inst_dep_trace.py b/util/decode_inst_dep_trace.py
index 2e7e6381c..6e4030146 100755
--- a/util/decode_inst_dep_trace.py
+++ b/util/decode_inst_dep_trace.py
@@ -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 @@ def main():
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 --git a/util/encode_inst_dep_trace.py b/util/encode_inst_dep_trace.py
index 6293fb0ab..e54e82d70 100755
--- a/util/encode_inst_dep_trace.py
+++ b/util/encode_inst_dep_trace.py
@@ -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 @@ def main():
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)