inorder: squash and trap behind a tlb fault
This commit is contained in:
parent
e0e387c2a9
commit
5f608dd2e9
6 changed files with 65 additions and 22 deletions
|
@ -847,6 +847,7 @@ void
|
||||||
InOrderCPU::trap(Fault fault, ThreadID tid, DynInstPtr inst)
|
InOrderCPU::trap(Fault fault, ThreadID tid, DynInstPtr inst)
|
||||||
{
|
{
|
||||||
fault->invoke(tcBase(tid), inst->staticInst);
|
fault->invoke(tcBase(tid), inst->staticInst);
|
||||||
|
removePipelineStalls(tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1650,6 +1651,7 @@ InOrderCPU::wakeup()
|
||||||
void
|
void
|
||||||
InOrderCPU::syscallContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
|
InOrderCPU::syscallContext(Fault fault, ThreadID tid, DynInstPtr inst, int delay)
|
||||||
{
|
{
|
||||||
|
//@todo: squash behind syscall
|
||||||
scheduleCpuEvent(Syscall, fault, tid, inst, delay, Syscall_Pri);
|
scheduleCpuEvent(Syscall, fault, tid, inst, delay, Syscall_Pri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -336,6 +336,25 @@ Resource::squashDueToMemStall(DynInstPtr inst, int stage_num,
|
||||||
squash(inst, stage_num, squash_seq_num, tid);
|
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
|
Tick
|
||||||
Resource::ticks(int num_cycles)
|
Resource::ticks(int num_cycles)
|
||||||
{
|
{
|
||||||
|
|
|
@ -168,6 +168,9 @@ class Resource {
|
||||||
virtual void squashDueToMemStall(DynInstPtr inst, int stage_num,
|
virtual void squashDueToMemStall(DynInstPtr inst, int stage_num,
|
||||||
InstSeqNum squash_seq_num, ThreadID tid);
|
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
|
/** The number of instructions available that this resource can
|
||||||
* can still process
|
* can still process
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -119,6 +119,7 @@ CacheUnit::CacheUnit(string res_name, int res_id, int res_width,
|
||||||
|
|
||||||
for (int i=0; i < MaxThreads; i++) {
|
for (int i=0; i < MaxThreads; i++) {
|
||||||
tlbBlocked[i] = false;
|
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)
|
int flags, TheISA::TLB::Mode tlb_mode)
|
||||||
{
|
{
|
||||||
ThreadID tid = inst->readTid();
|
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);
|
setupMemRequest(inst, cache_req, acc_size, flags);
|
||||||
|
|
||||||
inst->fault =
|
inst->fault =
|
||||||
_tlb->translateAtomic(cache_req->memReq,
|
_tlb->translateAtomic(cache_req->memReq,
|
||||||
cpu->thread[tid]->getTC(), tlb_mode);
|
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(),
|
"addr:%08p for [sn:%i].\n", tid, inst->fault->name(),
|
||||||
cache_req->memReq->getVaddr(), inst->seqNum);
|
cache_req->memReq->getVaddr(), inst->seqNum);
|
||||||
|
|
||||||
cpu->pipelineStage[stage_num]->setResStall(cache_req, tid);
|
|
||||||
|
|
||||||
tlbBlocked[tid] = true;
|
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;
|
cache_req->tlbStall = true;
|
||||||
|
|
||||||
// schedule a time to process the tlb miss.
|
// schedule a time to process the tlb miss.
|
||||||
// latency hardcoded to 1 (for now), but will be updated
|
// latency hardcoded to 1 (for now), but will be updated
|
||||||
// when timing translation gets added in
|
// when timing translation gets added in
|
||||||
scheduleEvent(slot_idx, 1);
|
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 {
|
} else {
|
||||||
DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
|
DPRINTF(InOrderTLB, "[tid:%i]: [sn:%i] virt. addr %08p translated "
|
||||||
"to phys. addr:%08p.\n", tid, inst->seqNum,
|
"to phys. addr:%08p.\n", tid, inst->seqNum,
|
||||||
|
@ -654,8 +660,6 @@ CacheUnit::execute(int slot_num)
|
||||||
std::string acc_type = "write";
|
std::string acc_type = "write";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inst->fault = NoFault;
|
|
||||||
|
|
||||||
switch (cache_req->cmd)
|
switch (cache_req->cmd)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -712,6 +716,16 @@ CacheUnit::execute(int slot_num)
|
||||||
DPRINTF(InOrderCachePort,
|
DPRINTF(InOrderCachePort,
|
||||||
"[tid:%i]: [sn:%i]: Trying to Complete Data Read Access\n",
|
"[tid:%i]: [sn:%i]: Trying to Complete Data Read Access\n",
|
||||||
tid, inst->seqNum);
|
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...
|
//@todo: timing translations need to check here...
|
||||||
assert(!inst->isInstPrefetch() && "Can't Handle Inst. Prefecthes");
|
assert(!inst->isInstPrefetch() && "Can't Handle Inst. Prefecthes");
|
||||||
if (cache_req->isMemAccComplete() || inst->isDataPrefetch()) {
|
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:%i]: [sn:%i]: Trying to Complete Data Write Access\n",
|
||||||
tid, inst->seqNum);
|
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
|
//@todo: check that timing translation is finished here
|
||||||
RequestPtr mem_req = cache_req->memReq;
|
RequestPtr mem_req = cache_req->memReq;
|
||||||
DPRINTF(InOrderCachePort,
|
DPRINTF(InOrderCachePort,
|
||||||
|
@ -789,7 +812,8 @@ CacheUnit::execute(int slot_num)
|
||||||
"[tid:%i]: [sn:%i]: Trying to Complete Split Data Write "
|
"[tid:%i]: [sn:%i]: Trying to Complete Split Data Write "
|
||||||
"Access\n", tid, inst->seqNum);
|
"Access\n", tid, inst->seqNum);
|
||||||
//@todo: illegal to have a unaligned cond.swap or llsc?
|
//@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()) {
|
if (cache_req->isMemAccPending()) {
|
||||||
cache_req->dataPkt->reqData = cache_req->reqData;
|
cache_req->dataPkt->reqData = cache_req->reqData;
|
||||||
|
@ -1224,6 +1248,12 @@ void
|
||||||
CacheUnit::squash(DynInstPtr inst, int stage_num,
|
CacheUnit::squash(DynInstPtr inst, int stage_num,
|
||||||
InstSeqNum squash_seq_num, ThreadID tid)
|
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++) {
|
for (int i = 0; i < width; i++) {
|
||||||
ResReqPtr req_ptr = reqs[i];
|
ResReqPtr req_ptr = reqs[i];
|
||||||
|
|
||||||
|
|
|
@ -203,9 +203,9 @@ class CacheUnit : public Resource
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tlbBlocked[ThePipeline::MaxThreads];
|
bool tlbBlocked[ThePipeline::MaxThreads];
|
||||||
|
InstSeqNum tlbBlockSeqNum[ThePipeline::MaxThreads];
|
||||||
|
|
||||||
TheISA::TLB* tlb();
|
TheISA::TLB* tlb();
|
||||||
|
|
||||||
TheISA::TLB *_tlb;
|
TheISA::TLB *_tlb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -70,18 +70,7 @@ GraduationUnit::execute(int slot_num)
|
||||||
DPRINTF(Fault, "[sn:%i]: fault %s found for %s\n",
|
DPRINTF(Fault, "[sn:%i]: fault %s found for %s\n",
|
||||||
inst->seqNum, inst->fault->name(),
|
inst->seqNum, inst->fault->name(),
|
||||||
inst->instName());
|
inst->instName());
|
||||||
inst->setSquashInfo(stage_num);
|
squashThenTrap(stage_num, inst);
|
||||||
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);
|
|
||||||
grad_req->done(false);
|
grad_req->done(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue