summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/inorder/cpu.cc2
-rw-r--r--src/cpu/inorder/resource.cc19
-rw-r--r--src/cpu/inorder/resource.hh3
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc48
-rw-r--r--src/cpu/inorder/resources/cache_unit.hh2
-rw-r--r--src/cpu/inorder/resources/graduation_unit.cc13
6 files changed, 65 insertions, 22 deletions
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index cc2b72e4e..834e591f8 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -847,6 +847,7 @@ void
InOrderCPU::trap(Fault fault, ThreadID tid, DynInstPtr inst)
{
fault->invoke(tcBase(tid), inst->staticInst);
+ removePipelineStalls(tid);
}
void
@@ -1650,6 +1651,7 @@ InOrderCPU::wakeup()
void
InOrderCPU::syscallContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
{
+ //@todo: squash behind syscall
scheduleCpuEvent(Syscall, fault, tid, inst, delay, Syscall_Pri);
}
diff --git a/src/cpu/inorder/resource.cc b/src/cpu/inorder/resource.cc
index a21536676..817cc5868 100644
--- a/src/cpu/inorder/resource.cc
+++ b/src/cpu/inorder/resource.cc
@@ -336,6 +336,25 @@ Resource::squashDueToMemStall(DynInstPtr inst, int stage_num,
squash(inst, stage_num, squash_seq_num, tid);
}
+void
+Resource::squashThenTrap(int stage_num, DynInstPtr inst)
+{
+ ThreadID tid = inst->readTid();
+
+ inst->setSquashInfo(stage_num);
+ setupSquash(inst, stage_num, tid);
+
+ if (inst->traceData && DTRACE(ExecFaulting)) {
+ inst->traceData->setStageCycle(stage_num, curTick());
+ inst->traceData->setFetchSeq(inst->seqNum);
+ inst->traceData->dump();
+ delete inst->traceData;
+ inst->traceData = NULL;
+ }
+
+ cpu->trapContext(inst->fault, tid, inst);
+}
+
Tick
Resource::ticks(int num_cycles)
{
diff --git a/src/cpu/inorder/resource.hh b/src/cpu/inorder/resource.hh
index 91d144a64..78e5af5de 100644
--- a/src/cpu/inorder/resource.hh
+++ b/src/cpu/inorder/resource.hh
@@ -168,6 +168,9 @@ class Resource {
virtual void squashDueToMemStall(DynInstPtr inst, int stage_num,
InstSeqNum squash_seq_num, ThreadID tid);
+ /** Handle Squash & Trap that occured from an instruction in a resource */
+ void squashThenTrap(int stage_num, DynInstPtr inst);
+
/** The number of instructions available that this resource can
* can still process
*/
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc
index 0673d6b9b..d0cdfa3c9 100644
--- a/src/cpu/inorder/resources/cache_unit.cc
+++ b/src/cpu/inorder/resources/cache_unit.cc
@@ -119,6 +119,7 @@ CacheUnit::CacheUnit(string res_name, int res_id, int res_width,
for (int i=0; i < MaxThreads; i++) {
tlbBlocked[i] = false;
+ tlbBlockSeqNum[i] = 0;
}
}
@@ -391,12 +392,8 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
int flags, TheISA::TLB::Mode tlb_mode)
{
ThreadID tid = inst->readTid();
- //Addr aligned_addr = inst->getMemAddr();
- unsigned stage_num = cache_req->getStageNum();
- unsigned slot_idx = cache_req->getSlot();
setupMemRequest(inst, cache_req, acc_size, flags);
-
inst->fault =
_tlb->translateAtomic(cache_req->memReq,
cpu->thread[tid]->getTC(), tlb_mode);
@@ -406,16 +403,25 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
"addr:%08p for [sn:%i].\n", tid, inst->fault->name(),
cache_req->memReq->getVaddr(), inst->seqNum);
- cpu->pipelineStage[stage_num]->setResStall(cache_req, tid);
-
tlbBlocked[tid] = true;
+ tlbBlockSeqNum[tid] = inst->seqNum;
+
+#if !FULL_SYSTEM
+ unsigned stage_num = cache_req->getStageNum();
+ cpu->pipelineStage[stage_num]->setResStall(cache_req, tid);
cache_req->tlbStall = true;
// schedule a time to process the tlb miss.
// latency hardcoded to 1 (for now), but will be updated
// when timing translation gets added in
scheduleEvent(slot_idx, 1);
+ unsigned slot_idx = cache_req->getSlot();
+#endif
+
+ // Mark it as complete so it can pass through next stage.
+ // Fault Handling will happen at commit/graduation
+ cache_req->setCompleted();
} else {
DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
"to phys. addr:%08p.\n", tid, inst->seqNum,
@@ -654,8 +660,6 @@ CacheUnit::execute(int slot_num)
std::string acc_type = "write";
#endif
- inst->fault = NoFault;
-
switch (cache_req->cmd)
{
@@ -712,6 +716,16 @@ CacheUnit::execute(int slot_num)
DPRINTF(InOrderCachePort,
"[tid:%i]: [sn:%i]: Trying to Complete Data Read Access\n",
tid, inst->seqNum);
+
+ if (inst->fault != NoFault) {
+ DPRINTF(InOrderCachePort,
+ "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to "
+ "next stage.\n", tid, inst->seqNum, inst->fault->name(),
+ inst->getMemAddr());
+ finishCacheUnitReq(inst, cache_req);
+ return;
+ }
+
//@todo: timing translations need to check here...
assert(!inst->isInstPrefetch() && "Can't Handle Inst. Prefecthes");
if (cache_req->isMemAccComplete() || inst->isDataPrefetch()) {
@@ -730,6 +744,15 @@ CacheUnit::execute(int slot_num)
"[tid:%i]: [sn:%i]: Trying to Complete Data Write Access\n",
tid, inst->seqNum);
+ if (inst->fault != NoFault) {
+ DPRINTF(InOrderCachePort,
+ "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to ",
+ "next stage.\n", tid, inst->seqNum, inst->fault->name(),
+ inst->getMemAddr());
+ finishCacheUnitReq(inst, cache_req);
+ return;
+ }
+
//@todo: check that timing translation is finished here
RequestPtr mem_req = cache_req->memReq;
DPRINTF(InOrderCachePort,
@@ -789,7 +812,8 @@ CacheUnit::execute(int slot_num)
"[tid:%i]: [sn:%i]: Trying to Complete Split Data Write "
"Access\n", tid, inst->seqNum);
//@todo: illegal to have a unaligned cond.swap or llsc?
- assert(!cache_req->memReq->isSwap() && !cache_req->memReq->isCondSwap() && !cache_req->memReq->isLLSC());
+ assert(!cache_req->memReq->isSwap() && !cache_req->memReq->isCondSwap()
+ && !cache_req->memReq->isLLSC());
if (cache_req->isMemAccPending()) {
cache_req->dataPkt->reqData = cache_req->reqData;
@@ -1224,6 +1248,12 @@ void
CacheUnit::squash(DynInstPtr inst, int stage_num,
InstSeqNum squash_seq_num, ThreadID tid)
{
+ if (tlbBlockSeqNum[tid] > squash_seq_num) {
+ DPRINTF(InOrderCachePort, "Releasing TLB Block due to "
+ " squash after [sn:%i].\n", squash_seq_num);
+ tlbBlocked[tid] = false;
+ }
+
for (int i = 0; i < width; i++) {
ResReqPtr req_ptr = reqs[i];
diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh
index dd6fa7638..91a8703f7 100644
--- a/src/cpu/inorder/resources/cache_unit.hh
+++ b/src/cpu/inorder/resources/cache_unit.hh
@@ -203,9 +203,9 @@ class CacheUnit : public Resource
}
bool tlbBlocked[ThePipeline::MaxThreads];
+ InstSeqNum tlbBlockSeqNum[ThePipeline::MaxThreads];
TheISA::TLB* tlb();
-
TheISA::TLB *_tlb;
};
diff --git a/src/cpu/inorder/resources/graduation_unit.cc b/src/cpu/inorder/resources/graduation_unit.cc
index afa9421a8..4f796e933 100644
--- a/src/cpu/inorder/resources/graduation_unit.cc
+++ b/src/cpu/inorder/resources/graduation_unit.cc
@@ -70,18 +70,7 @@ GraduationUnit::execute(int slot_num)
DPRINTF(Fault, "[sn:%i]: fault %s found for %s\n",
inst->seqNum, inst->fault->name(),
inst->instName());
- inst->setSquashInfo(stage_num);
- setupSquash(inst, stage_num, tid);
-
- if (inst->traceData && DTRACE(ExecFaulting)) {
- inst->traceData->setStageCycle(stage_num, curTick());
- inst->traceData->setFetchSeq(inst->seqNum);
- inst->traceData->dump();
- delete inst->traceData;
- inst->traceData = NULL;
- }
-
- cpu->trapContext(inst->fault, tid, inst);
+ squashThenTrap(stage_num, inst);
grad_req->done(false);
return;
}