summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2011-02-04 00:09:20 -0500
committerKorey Sewell <ksewell@umich.edu>2011-02-04 00:09:20 -0500
commite396a34b0155d5054a099c67a91baa66c095d3d8 (patch)
tree9372731b0110d067b4377ab73b1d62bbabf5efe3
parente57613588b15f25b5b912ae98134b6f1007988fd (diff)
downloadgem5-e396a34b0155d5054a099c67a91baa66c095d3d8.tar.xz
inorder: fault handling
Maintain all information about an instruction's fault in the DynInst object rather than any cpu-request object. Also, if there is a fault during the execution stage then just save the fault inside the instruction and trap once the instruction tries to graduate
-rw-r--r--src/cpu/inorder/pipeline_stage.cc7
-rw-r--r--src/cpu/inorder/resource.cc1
-rw-r--r--src/cpu/inorder/resource.hh3
-rw-r--r--src/cpu/inorder/resources/agen_unit.cc9
-rw-r--r--src/cpu/inorder/resources/branch_predictor.cc4
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc24
-rw-r--r--src/cpu/inorder/resources/cache_unit.hh4
-rw-r--r--src/cpu/inorder/resources/decode_unit.cc3
-rw-r--r--src/cpu/inorder/resources/execution_unit.cc18
-rw-r--r--src/cpu/inorder/resources/fetch_seq_unit.cc2
-rw-r--r--src/cpu/inorder/resources/fetch_unit.cc5
-rw-r--r--src/cpu/inorder/resources/graduation_unit.cc25
-rw-r--r--src/cpu/inorder/resources/inst_buffer.cc2
-rw-r--r--src/cpu/inorder/resources/mult_div_unit.cc17
14 files changed, 39 insertions, 85 deletions
diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc
index e10ceb326..744ffd4d2 100644
--- a/src/cpu/inorder/pipeline_stage.cc
+++ b/src/cpu/inorder/pipeline_stage.cc
@@ -944,12 +944,7 @@ PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed)
"completed.\n", tid, inst->seqNum,
cpu->resPool->name(res_num));
- if (req->fault == NoFault) {
- inst->popSchedEntry();
- } else {
- panic("%i: encountered %s fault!\n",
- curTick(), req->fault->name());
- }
+ inst->popSchedEntry();
reqs_processed++;
diff --git a/src/cpu/inorder/resource.cc b/src/cpu/inorder/resource.cc
index 8c5f86c73..51beb5aa0 100644
--- a/src/cpu/inorder/resource.cc
+++ b/src/cpu/inorder/resource.cc
@@ -277,7 +277,6 @@ Resource::execute(int slot_idx)
DPRINTF(Resource, "[tid:%i]: Executing %s resource.\n",
reqMap[slot_idx]->getTid(), name());
reqMap[slot_idx]->setCompleted(true);
- reqMap[slot_idx]->fault = NoFault;
reqMap[slot_idx]->done();
}
diff --git a/src/cpu/inorder/resource.hh b/src/cpu/inorder/resource.hh
index 5684dc166..bd9ec48ca 100644
--- a/src/cpu/inorder/resource.hh
+++ b/src/cpu/inorder/resource.hh
@@ -350,9 +350,6 @@ class ResourceRequest
/** Not guaranteed to be set, used for debugging */
InstSeqNum seqNum;
- /** Fault Associated With This Resource Request */
- Fault fault;
-
/** Command For This Resource */
unsigned cmd;
diff --git a/src/cpu/inorder/resources/agen_unit.cc b/src/cpu/inorder/resources/agen_unit.cc
index 2de586c82..f1862b94a 100644
--- a/src/cpu/inorder/resources/agen_unit.cc
+++ b/src/cpu/inorder/resources/agen_unit.cc
@@ -52,14 +52,11 @@ AGENUnit::execute(int slot_num)
{
ResourceRequest* agen_req = reqMap[slot_num];
DynInstPtr inst = reqMap[slot_num]->inst;
- Fault fault = reqMap[slot_num]->fault;
#if TRACING_ON
ThreadID tid = inst->readTid();
#endif
int seq_num = inst->seqNum;
- agen_req->fault = NoFault;
-
switch (agen_req->cmd)
{
case GenerateAddr:
@@ -70,18 +67,18 @@ AGENUnit::execute(int slot_num)
"[tid:%i] Generating Address for [sn:%i] (%s).\n",
tid, seq_num, inst->staticInst->getName());
- fault = inst->calcEA();
+ inst->fault = inst->calcEA();
inst->setMemAddr(inst->getEA());
DPRINTF(InOrderAGEN,
"[tid:%i] [sn:%i] Effective address calculated as: %#x\n",
tid, seq_num, inst->getEA());
- if (fault == NoFault) {
+ if (inst->fault == NoFault) {
agen_req->done();
} else {
fatal("%s encountered while calculating address [sn:%i]",
- fault->name(), seq_num);
+ inst->fault->name(), seq_num);
}
agens++;
diff --git a/src/cpu/inorder/resources/branch_predictor.cc b/src/cpu/inorder/resources/branch_predictor.cc
index c849ba163..8ca5a9718 100644
--- a/src/cpu/inorder/resources/branch_predictor.cc
+++ b/src/cpu/inorder/resources/branch_predictor.cc
@@ -67,13 +67,9 @@ BranchPredictor::execute(int slot_num)
// After this is working, change this to a reinterpret cast
// for performance considerations
ResourceRequest* bpred_req = reqMap[slot_num];
-
DynInstPtr inst = bpred_req->inst;
ThreadID tid = inst->readTid();
int seq_num = inst->seqNum;
- //int stage_num = bpred_req->getStageNum();
-
- bpred_req->fault = NoFault;
switch (bpred_req->cmd)
{
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc
index 6c9da67f5..8b4dd4402 100644
--- a/src/cpu/inorder/resources/cache_unit.cc
+++ b/src/cpu/inorder/resources/cache_unit.cc
@@ -405,7 +405,7 @@ CacheUnit::setupMemRequest(DynInstPtr inst, CacheReqPtr cache_req,
}
}
-Fault
+void
CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
int flags, TheISA::TLB::Mode tlb_mode)
{
@@ -416,13 +416,13 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
setupMemRequest(inst, cache_req, acc_size, flags);
- cache_req->fault =
+ inst->fault =
_tlb->translateAtomic(cache_req->memReq,
cpu->thread[tid]->getTC(), tlb_mode);
- if (cache_req->fault != NoFault) {
+ if (inst->fault != NoFault) {
DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating "
- "addr:%08p for [sn:%i].\n", tid, cache_req->fault->name(),
+ "addr:%08p for [sn:%i].\n", tid, inst->fault->name(),
cache_req->memReq->getVaddr(), inst->seqNum);
cpu->pipelineStage[stage_num]->setResStall(cache_req, tid);
@@ -433,7 +433,7 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
scheduleEvent(slot_idx, 1);
- cpu->trap(cache_req->fault, tid, inst);
+ cpu->trap(inst->fault, tid, inst);
} else {
DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
"to phys. addr:%08p.\n", tid, inst->seqNum,
@@ -441,7 +441,6 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
cache_req->memReq->getPaddr());
}
- return cache_req->fault;
}
Fault
@@ -531,7 +530,7 @@ CacheUnit::read(DynInstPtr inst, Addr addr,
doTLBAccess(inst, cache_req, size, flags, TheISA::TLB::Read);
- if (cache_req->fault == NoFault) {
+ if (inst->fault == NoFault) {
if (!cache_req->splitAccess) {
cache_req->reqData = new uint8_t[size];
doCacheAccess(inst, NULL);
@@ -546,7 +545,7 @@ CacheUnit::read(DynInstPtr inst, Addr addr,
}
}
- return cache_req->fault;
+ return inst->fault;
}
Fault
@@ -638,7 +637,7 @@ CacheUnit::write(DynInstPtr inst, uint8_t *data, unsigned size,
doTLBAccess(inst, cache_req, size, flags, TheISA::TLB::Write);
- if (cache_req->fault == NoFault) {
+ if (inst->fault == NoFault) {
if (!cache_req->splitAccess) {
// Remove this line since storeData is saved in INST?
cache_req->reqData = new uint8_t[size];
@@ -649,7 +648,7 @@ CacheUnit::write(DynInstPtr inst, uint8_t *data, unsigned size,
}
- return cache_req->fault;
+ return inst->fault;
}
@@ -672,7 +671,7 @@ CacheUnit::execute(int slot_num)
std::string acc_type = "write";
#endif
- cache_req->fault = NoFault;
+ inst->fault = NoFault;
switch (cache_req->cmd)
{
@@ -785,7 +784,7 @@ CacheUnit::execute(int slot_num)
}
// @TODO: Split into doCacheRead() and doCacheWrite()
-Fault
+void
CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res,
CacheReqPtr split_req)
{
@@ -883,7 +882,6 @@ CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res,
cache_req->setCompleted(false);
}
- return fault;
}
void
diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh
index 0d911999d..afcb36a24 100644
--- a/src/cpu/inorder/resources/cache_unit.hh
+++ b/src/cpu/inorder/resources/cache_unit.hh
@@ -161,13 +161,13 @@ class CacheUnit : public Resource
Fault write(DynInstPtr inst, uint8_t *data, unsigned size,
Addr addr, unsigned flags, uint64_t *res);
- Fault doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
+ void doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size,
int flags, TheISA::TLB::Mode tlb_mode);
/** Read/Write on behalf of an instruction.
* curResSlot needs to be a valid value in instruction.
*/
- Fault doCacheAccess(DynInstPtr inst, uint64_t *write_result=NULL,
+ void doCacheAccess(DynInstPtr inst, uint64_t *write_result=NULL,
CacheReqPtr split_req=NULL);
uint64_t getMemData(Packet *packet);
diff --git a/src/cpu/inorder/resources/decode_unit.cc b/src/cpu/inorder/resources/decode_unit.cc
index 50cf6c7b7..c2f7ae22d 100644
--- a/src/cpu/inorder/resources/decode_unit.cc
+++ b/src/cpu/inorder/resources/decode_unit.cc
@@ -51,11 +51,8 @@ DecodeUnit::execute(int slot_num)
{
ResourceRequest* decode_req = reqMap[slot_num];
DynInstPtr inst = reqMap[slot_num]->inst;
- Fault fault = reqMap[slot_num]->fault;
ThreadID tid = inst->readTid();
- decode_req->fault = NoFault;
-
switch (decode_req->cmd)
{
case DecodeInst:
diff --git a/src/cpu/inorder/resources/execution_unit.cc b/src/cpu/inorder/resources/execution_unit.cc
index cae007deb..36bf2a4dc 100644
--- a/src/cpu/inorder/resources/execution_unit.cc
+++ b/src/cpu/inorder/resources/execution_unit.cc
@@ -84,14 +84,11 @@ ExecutionUnit::execute(int slot_num)
{
ResourceRequest* exec_req = reqMap[slot_num];
DynInstPtr inst = reqMap[slot_num]->inst;
- Fault fault = reqMap[slot_num]->fault;
- ThreadID tid = inst->readTid();
+ Fault fault = NoFault;
int seq_num = inst->seqNum;
- exec_req->fault = NoFault;
-
DPRINTF(InOrderExecute, "[tid:%i] Executing [sn:%i] [PC:%s] %s.\n",
- tid, seq_num, inst->pcState(), inst->instName());
+ inst->readTid(), seq_num, inst->pcState(), inst->instName());
switch (exec_req->cmd)
{
@@ -126,7 +123,6 @@ ExecutionUnit::execute(int slot_num)
if (inst->mispredicted()) {
int stage_num = exec_req->getStageNum();
ThreadID tid = inst->readTid();
-
// If it's a branch ...
if (inst->isDirectCtrl()) {
assert(!inst->isIndirectCtrl());
@@ -247,13 +243,13 @@ ExecutionUnit::execute(int slot_num)
seq_num,
(inst->resultType(0) == InOrderDynInst::Float) ?
inst->readFloatResult(0) : inst->readIntResult(0));
-
- exec_req->done();
} else {
- warn("inst [sn:%i] had a %s fault",
- seq_num, fault->name());
- cpu->trap(fault, tid, inst);
+ DPRINTF(InOrderExecute, "[tid:%i]: [sn:%i]: had a %s "
+ "fault.\n", inst->readTid(), seq_num, fault->name());
+ inst->fault = fault;
}
+
+ exec_req->done();
}
}
break;
diff --git a/src/cpu/inorder/resources/fetch_seq_unit.cc b/src/cpu/inorder/resources/fetch_seq_unit.cc
index 6ed949df3..6f84a333d 100644
--- a/src/cpu/inorder/resources/fetch_seq_unit.cc
+++ b/src/cpu/inorder/resources/fetch_seq_unit.cc
@@ -74,8 +74,6 @@ FetchSeqUnit::execute(int slot_num)
int stage_num = fs_req->getStageNum();
int seq_num = inst->seqNum;
- fs_req->fault = NoFault;
-
DPRINTF(InOrderFetchSeq, "[tid:%i]: Current PC is %s\n", tid,
pc[tid]);
diff --git a/src/cpu/inorder/resources/fetch_unit.cc b/src/cpu/inorder/resources/fetch_unit.cc
index 7bbeffadd..0e9866708 100644
--- a/src/cpu/inorder/resources/fetch_unit.cc
+++ b/src/cpu/inorder/resources/fetch_unit.cc
@@ -227,7 +227,8 @@ FetchUnit::execute(int slot_num)
ThreadID tid = inst->readTid();
Addr block_addr = cacheBlockAlign(inst->getMemAddr());
int asid = cpu->asid[tid];
- cache_req->fault = NoFault;
+
+ inst->fault = NoFault;
switch (cache_req->cmd)
{
@@ -275,7 +276,7 @@ FetchUnit::execute(int slot_num)
doTLBAccess(inst, cache_req, cacheBlkSize, 0, TheISA::TLB::Execute);
- if (cache_req->fault == NoFault) {
+ if (inst->fault == NoFault) {
DPRINTF(InOrderCachePort,
"[tid:%u]: Initiating fetch access to %s for "
"addr:%#x (block:%#x)\n", tid, name(),
diff --git a/src/cpu/inorder/resources/graduation_unit.cc b/src/cpu/inorder/resources/graduation_unit.cc
index 9d19c2eef..8ccdaa36a 100644
--- a/src/cpu/inorder/resources/graduation_unit.cc
+++ b/src/cpu/inorder/resources/graduation_unit.cc
@@ -51,31 +51,23 @@ GraduationUnit::execute(int slot_num)
{
ResourceRequest* grad_req = reqMap[slot_num];
DynInstPtr inst = reqMap[slot_num]->inst;
- Fault fault = reqMap[slot_num]->fault;
ThreadID tid = inst->readTid();
int stage_num = inst->resSched.top()->stageNum;
- grad_req->fault = NoFault;
-
switch (grad_req->cmd)
{
case GraduateInst:
{
- // @TODO: Instructions should never really get to this point since
- // this should be handled through the request interface. Check to
- // make sure this happens and delete this code.
- if (lastCycleGrad != curTick()) {
- lastCycleGrad = curTick();
- numCycleGrad = 0;
- } else if (numCycleGrad > width) {
- DPRINTF(InOrderGraduation,
- "Graduation bandwidth reached for this cycle.\n");
- return;
- }
-
// Make sure this is the last thing on the resource schedule
assert(inst->resSched.size() == 1);
+ // Handle Any Faults Before Graduating Instruction
+ if (inst->fault != NoFault) {
+ cpu->trap(inst->fault, tid, inst);
+ grad_req->setCompleted(false);
+ return;
+ }
+
DPRINTF(InOrderGraduation,
"[tid:%i] Graduating instruction [sn:%i].\n",
tid, inst->seqNum);
@@ -97,9 +89,6 @@ GraduationUnit::execute(int slot_num)
// Tell CPU that instruction is finished processing
cpu->instDone(inst, tid);
- //cpu->pipelineStage[stage_num]->toPrevStages->
- //stageInfo[stage_num][tid].doneSeqNum = inst->seqNum;
-
grad_req->done();
}
break;
diff --git a/src/cpu/inorder/resources/inst_buffer.cc b/src/cpu/inorder/resources/inst_buffer.cc
index 1db618b61..18dd26a78 100644
--- a/src/cpu/inorder/resources/inst_buffer.cc
+++ b/src/cpu/inorder/resources/inst_buffer.cc
@@ -67,8 +67,6 @@ InstBuffer::execute(int slot_idx)
ThreadID tid = inst->readTid();
int stage_num = ib_req->getStageNum();
- ib_req->fault = NoFault;
-
switch (ib_req->cmd)
{
case ScheduleOrBypass:
diff --git a/src/cpu/inorder/resources/mult_div_unit.cc b/src/cpu/inorder/resources/mult_div_unit.cc
index 55df1cc43..5aa0b0aa1 100644
--- a/src/cpu/inorder/resources/mult_div_unit.cc
+++ b/src/cpu/inorder/resources/mult_div_unit.cc
@@ -204,11 +204,7 @@ MultDivUnit::execute(int slot_num)
{
ResourceRequest* mult_div_req = reqMap[slot_num];
DynInstPtr inst = reqMap[slot_num]->inst;
- Fault fault = reqMap[slot_num]->fault;
- //ThreadID tid = inst->readTid();
- //int seq_num = inst->seqNum;
-
switch (mult_div_req->cmd)
{
case StartMultDiv:
@@ -281,11 +277,8 @@ MultDivUnit::exeMulDiv(int slot_num)
{
ResourceRequest* mult_div_req = reqMap[slot_num];
DynInstPtr inst = reqMap[slot_num]->inst;
- Fault fault = reqMap[slot_num]->fault;
- ThreadID tid = inst->readTid();
- int seq_num = inst->seqNum;
- fault = inst->execute();
+ inst->fault = inst->execute();
if (inst->opClass() == IntMultOp) {
multiplies++;
@@ -293,15 +286,15 @@ MultDivUnit::exeMulDiv(int slot_num)
divides++;
}
- if (fault == NoFault) {
+ if (inst->fault == NoFault) {
inst->setExecuted();
mult_div_req->setCompleted();
- DPRINTF(Resource, "[tid:%i]: The result of execution is 0x%x.\n",
+ DPRINTF(InOrderMDU, "[tid:%i]: The result of execution is 0x%x.\n",
inst->readTid(), inst->readIntResult(0));
} else {
- warn("inst [sn:%i] had a %s fault", seq_num, fault->name());
- cpu->trap(fault, tid, inst);
+ DPRINTF(InOrderMDU, "[tid:%i]: [sn:%i]: had a %s "
+ "fault.\n", inst->readTid(), inst->seqNum, inst->fault->name());
}
}