From 078f914e69d6a08b0ff881b0909535307464553f Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 19 Jun 2011 21:43:42 -0400 Subject: [PATCH] inorder: SE mode TLB faults handle them like we do in FS mode, by blocking the TLB until the fault is handled by the fault->invoke() --- src/cpu/inorder/resource.cc | 17 +++++------ src/cpu/inorder/resources/cache_unit.cc | 39 +++++++++++++------------ src/cpu/inorder/resources/cache_unit.hh | 3 ++ src/cpu/inorder/resources/use_def.cc | 18 ++++++------ 4 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/cpu/inorder/resource.cc b/src/cpu/inorder/resource.cc index dfca83a8f..d2327795e 100644 --- a/src/cpu/inorder/resource.cc +++ b/src/cpu/inorder/resource.cc @@ -46,7 +46,8 @@ using namespace std; Resource::Resource(string res_name, int res_id, int res_width, int res_latency, InOrderCPU *_cpu) : resName(res_name), id(res_id), - width(res_width), latency(res_latency), cpu(_cpu) + width(res_width), latency(res_latency), cpu(_cpu), + resourceEvent(NULL) { reqs.resize(width); @@ -75,15 +76,13 @@ Resource::init() // If the resource has a zero-cycle (no latency) // function, then no reason to have events // that will process them for the right tick - if (latency > 0) { - resourceEvent = new ResourceEvent[width]; - } else { - resourceEvent = NULL; - } + if (latency > 0) + resourceEvent = new ResourceEvent[width]; + + + for (int i = 0; i < width; i++) + reqs[i] = new ResourceRequest(this); - for (int i = 0; i < width; i++) { - reqs[i] = new ResourceRequest(this); - } initSlots(); } diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 350e2d1dd..8b487dd3f 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -178,10 +178,6 @@ CacheUnit::init() reqs[i] = new CacheRequest(this); } - // Currently Used to Model TLB Latency. Eventually - // Switch to Timing TLB translations. - resourceEvent = new CacheUnitEvent[width]; - cacheBlkSize = this->cachePort->peerBlockSize(); cacheBlkMask = cacheBlkSize - 1; @@ -433,30 +429,22 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size, ThreadContext *tc = cpu->thread[tid]->getTC(); PCState old_pc = tc->pcState(); tc->pcState() = inst->pcState(); + inst->fault = _tlb->translateAtomic(cache_req->memReq, tc, tlb_mode); tc->pcState() = old_pc; if (inst->fault != NoFault) { DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating " - "addr:%08p for [sn:%i].\n", tid, inst->fault->name(), + "addr:%08p for [sn:%i].\n", tid, tlb_fault->name(), cache_req->memReq->getVaddr(), inst->seqNum); 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 - unsigned slot_idx = cache_req->getSlot(); - scheduleEvent(slot_idx, 1); -#endif + // Make sure nothing gets executed until after this faulting + // instruction gets handled. + inst->setSerializeAfter(); // Mark it as complete so it can pass through next stage. // Fault Handling will happen at commit/graduation @@ -467,9 +455,16 @@ CacheUnit::doTLBAccess(DynInstPtr inst, CacheReqPtr cache_req, int acc_size, cache_req->memReq->getVaddr(), cache_req->memReq->getPaddr()); } - } +#if !FULL_SYSTEM +void +CacheUnit::trap(Fault fault, ThreadID tid, DynInstPtr inst) +{ + tlbBlocked[tid] = false; +} +#endif + Fault CacheUnit::read(DynInstPtr inst, Addr addr, uint8_t *data, unsigned size, unsigned flags) @@ -703,6 +698,14 @@ CacheUnit::execute(int slot_num) return; } + if (inst->isSquashed()) { + DPRINTF(InOrderCachePort, + "[tid:%i]: [sn:%i]: Detected squashed instruction " + "next stage.\n", inst->readTid(), inst->seqNum); + finishCacheUnitReq(inst, cache_req); + return; + } + #if TRACING_ON ThreadID tid = inst->readTid(); std::string acc_type = "write"; diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh index 611ab62f2..f74a9136d 100644 --- a/src/cpu/inorder/resources/cache_unit.hh +++ b/src/cpu/inorder/resources/cache_unit.hh @@ -157,6 +157,9 @@ class CacheUnit : public Resource bool processSquash(CacheReqPacket *cache_pkt); +#if !FULL_SYSTEM + void trap(Fault fault, ThreadID tid, DynInstPtr inst); +#endif void recvRetry(); /** Returns a specific port. */ diff --git a/src/cpu/inorder/resources/use_def.cc b/src/cpu/inorder/resources/use_def.cc index 9d0100565..38a2eb040 100644 --- a/src/cpu/inorder/resources/use_def.cc +++ b/src/cpu/inorder/resources/use_def.cc @@ -159,15 +159,6 @@ UseDefUnit::execute(int slot_idx) InstSeqNum seq_num = inst->seqNum; int ud_idx = ud_req->useDefIdx; - if (inst->fault != NoFault) { - DPRINTF(InOrderUseDef, - "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " - "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(), - inst->pcState()); - ud_req->done(); - return; - } - if (serializeOnNextInst[tid] && seq_num > serializeAfterSeqNum[tid]) { inst->setSerializeBefore(); @@ -187,6 +178,15 @@ UseDefUnit::execute(int slot_idx) serializeAfterSeqNum[tid] = seq_num; } + if (inst->fault != NoFault) { + DPRINTF(InOrderUseDef, + "[tid:%i]: [sn:%i]: Detected %s fault @ %x. Forwarding to " + "next stage.\n", inst->readTid(), inst->seqNum, inst->fault->name(), + inst->pcState()); + ud_req->done(); + return; + } + // If there is a non-speculative instruction // in the pipeline then stall instructions here // ---