summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorHongil Yoon <ongal@cs.wisc.edu>2015-09-15 08:14:06 -0500
committerHongil Yoon <ongal@cs.wisc.edu>2015-09-15 08:14:06 -0500
commitfb0f9884e27f33c434ef67a5cfd284331a2a89e0 (patch)
treea3c1c8df37385eb1c2e7b5ace8631a93bd40b3ff /src/cpu
parent6bee1d912482ee57ed79bb557afdad25563e9955 (diff)
downloadgem5-fb0f9884e27f33c434ef67a5cfd284331a2a89e0.tar.xz
cpu, o3: consider split requests for LSQ checksnoop operations
This patch enables instructions in LSQ to track two physical addresses for corresponding two split requests. Later, the information is used in checksnoop() to search for/invalidate the corresponding LD instructions. The current implementation has kept track of only the physical address that is referenced by the first split request. Thus, for checksnoop(), the line accessed by the second request has not been considered, causing potential correctness issues. Committed by: Nilay Vaish <nilay@cs.wisc.edu>
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/base_dyn_inst.hh17
-rw-r--r--src/cpu/base_dyn_inst_impl.hh3
-rw-r--r--src/cpu/o3/iew_impl.hh4
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh18
4 files changed, 31 insertions, 11 deletions
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index aae3af495..c2ef253a7 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -215,7 +215,12 @@ class BaseDynInst : public ExecContext, public RefCounted
Addr effAddr;
/** The effective physical address. */
- Addr physEffAddr;
+ Addr physEffAddrLow;
+
+ /** The effective physical address
+ * of the second request for a split request
+ */
+ Addr physEffAddrHigh;
/** The memory request flags (from translation). */
unsigned memReqFlags;
@@ -1056,7 +1061,15 @@ BaseDynInst<Impl>::finishTranslation(WholeTranslationState *state)
instFlags[IsStrictlyOrdered] = state->isStrictlyOrdered();
if (fault == NoFault) {
- physEffAddr = state->getPaddr();
+ // save Paddr for a single req
+ physEffAddrLow = state->getPaddr();
+
+ // case for the request that has been split
+ if (state->isSplit) {
+ physEffAddrLow = state->sreqLow->getPaddr();
+ physEffAddrHigh = state->sreqHigh->getPaddr();
+ }
+
memReqFlags = state->getFlags();
if (state->mainReq->isCondSwap()) {
diff --git a/src/cpu/base_dyn_inst_impl.hh b/src/cpu/base_dyn_inst_impl.hh
index 976e9ceb0..f55bd8ed5 100644
--- a/src/cpu/base_dyn_inst_impl.hh
+++ b/src/cpu/base_dyn_inst_impl.hh
@@ -88,7 +88,8 @@ BaseDynInst<Impl>::initVars()
{
memData = NULL;
effAddr = 0;
- physEffAddr = 0;
+ physEffAddrLow = 0;
+ physEffAddrHigh = 0;
readyRegs = 0;
memReqFlags = 0;
diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh
index 730eb0cfe..29596db09 100644
--- a/src/cpu/o3/iew_impl.hh
+++ b/src/cpu/o3/iew_impl.hh
@@ -1347,7 +1347,7 @@ DefaultIEW<Impl>::executeInsts()
DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: %s "
"[sn:%lli], inst PC: %s [sn:%lli]. Addr is: %#x.\n",
violator->pcState(), violator->seqNum,
- inst->pcState(), inst->seqNum, inst->physEffAddr);
+ inst->pcState(), inst->seqNum, inst->physEffAddrLow);
fetchRedirect[tid] = true;
@@ -1370,7 +1370,7 @@ DefaultIEW<Impl>::executeInsts()
DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: "
"%s, inst PC: %s. Addr is: %#x.\n",
violator->pcState(), inst->pcState(),
- inst->physEffAddr);
+ inst->physEffAddrLow);
DPRINTF(IEW, "Violation will not be handled because "
"already squashing\n");
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index 3019e80d2..0377faffa 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -453,10 +453,13 @@ LSQUnit<Impl>::checkSnoop(PacketPtr pkt)
DynInstPtr ld_inst = loadQueue[load_idx];
if (ld_inst) {
- Addr load_addr = ld_inst->physEffAddr & cacheBlockMask;
+ Addr load_addr_low = ld_inst->physEffAddrLow & cacheBlockMask;
+ Addr load_addr_high = ld_inst->physEffAddrHigh & cacheBlockMask;
+
// Check that this snoop didn't just invalidate our lock flag
- if (ld_inst->effAddrValid() && load_addr == invalidate_addr &&
- ld_inst->memReqFlags & Request::LLSC)
+ if (ld_inst->effAddrValid() && (load_addr_low == invalidate_addr
+ || load_addr_high == invalidate_addr)
+ && ld_inst->memReqFlags & Request::LLSC)
TheISA::handleLockedSnoopHit(ld_inst.get());
}
@@ -476,11 +479,14 @@ LSQUnit<Impl>::checkSnoop(PacketPtr pkt)
continue;
}
- Addr load_addr = ld_inst->physEffAddr & cacheBlockMask;
+ Addr load_addr_low = ld_inst->physEffAddrLow & cacheBlockMask;
+ Addr load_addr_high = ld_inst->physEffAddrHigh & cacheBlockMask;
+
DPRINTF(LSQUnit, "-- inst [sn:%lli] load_addr: %#x to pktAddr:%#x\n",
- ld_inst->seqNum, load_addr, invalidate_addr);
+ ld_inst->seqNum, load_addr_low, invalidate_addr);
- if (load_addr == invalidate_addr || force_squash) {
+ if ((load_addr_low == invalidate_addr
+ || load_addr_high == invalidate_addr) || force_squash) {
if (needsTSO) {
// If we have a TSO system, as all loads must be ordered with
// all other loads, this load as well as *all* subsequent loads