summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2013-10-17 10:20:45 -0500
committerAli Saidi <Ali.Saidi@ARM.com>2013-10-17 10:20:45 -0500
commitcf266f05a97b7a0e613fd10cb01f38fec6a4f16c (patch)
tree1d6180180b8839bbcbb0bcf32528fda00423e5b2 /src
parent60ce2b34fedcb999e249c7b9d277605303b741cf (diff)
downloadgem5-cf266f05a97b7a0e613fd10cb01f38fec6a4f16c.tar.xz
cpu: Fix O3 uncacheable load that is replayed but misses the TLB
This change fixes an issue in the O3 CPU where an uncachable instruction is attempted to be executed before it reaches the head of the ROB. It is determined to be uncacheable, and is replayed, but a PanicFault is attached to the instruction to make sure that it is properly executed before committing. If the TLB entry it was using is replaced in the interveaning time, the TLB returns a delayed translation when the load is replayed at the head of the ROB, however the LSQ code can't differntiate between the old fault and the new one. If the translation isn't complete it can't be faulting, so clear the fault.
Diffstat (limited to 'src')
-rw-r--r--src/cpu/base_dyn_inst.hh15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index 6aecd32dc..b7b076820 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -1009,8 +1009,16 @@ BaseDynInst<Impl>::initiateTranslation(RequestPtr req, RequestPtr sreqLow,
// One translation if the request isn't split.
DataTranslation<BaseDynInstPtr> *trans =
new DataTranslation<BaseDynInstPtr>(this, state);
+
cpu->dtb->translateTiming(req, thread->getTC(), trans, mode);
+
if (!translationCompleted()) {
+ // The translation isn't yet complete, so we can't possibly have a
+ // fault. Overwrite any existing fault we might have from a previous
+ // execution of this instruction (e.g. an uncachable load that
+ // couldn't execute because it wasn't at the head of the ROB).
+ fault = NoFault;
+
// Save memory requests.
savedReq = state->mainReq;
savedSreqLow = state->sreqLow;
@@ -1028,7 +1036,14 @@ BaseDynInst<Impl>::initiateTranslation(RequestPtr req, RequestPtr sreqLow,
cpu->dtb->translateTiming(sreqLow, thread->getTC(), stransLow, mode);
cpu->dtb->translateTiming(sreqHigh, thread->getTC(), stransHigh, mode);
+
if (!translationCompleted()) {
+ // The translation isn't yet complete, so we can't possibly have a
+ // fault. Overwrite any existing fault we might have from a previous
+ // execution of this instruction (e.g. an uncachable load that
+ // couldn't execute because it wasn't at the head of the ROB).
+ fault = NoFault;
+
// Save memory requests.
savedReq = state->mainReq;
savedSreqLow = state->sreqLow;