diff -r 87cafa076695 -r fbfa38428d04 src/cpu/inorder/cpu.hh --- a/src/cpu/inorder/cpu.hh Thu Mar 08 02:10:03 2012 -0800 +++ b/src/cpu/inorder/cpu.hh Thu Mar 08 10:41:40 2012 -0500 @@ -67,6 +67,7 @@ #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/timebuf.hh" +#include "cpu/translation.hh" #include "mem/packet.hh" #include "mem/port.hh" #include "mem/request.hh" @@ -868,6 +869,13 @@ /** Update Thread , used for statistic purposes*/ inline void tickThreadStats(); + /** + * Finish a DTB translation. + * @param state The DTB translation state. + */ + // Copied from TimingSimpleCPU + void finishTranslation(WholeTranslationState *state); + /** Per-Thread Tick */ Stats::Vector threadCycles; diff -r 87cafa076695 -r fbfa38428d04 src/cpu/inorder/cpu.cc --- a/src/cpu/inorder/cpu.cc Thu Mar 08 02:10:03 2012 -0800 +++ b/src/cpu/inorder/cpu.cc Thu Mar 08 10:41:40 2012 -0500 @@ -1798,3 +1798,28 @@ return resPool->getDataUnit()->write(inst, data, size, addr, flags, write_res); } + +void +InOrderCPU::finishTranslation(WholeTranslationState *state) +{ + _status = Running; + + if (state->getFault() != NoFault) { + if (state->isPrefetch()) { + state->setNoFault(); + } + delete [] state->data; + state->deleteReqs(); + + //translationFault(state->getFault()); + state->inst->fault = stage->getFault(); + } + + //@note: doCacheAccess needs to check state for a fault + // and mark translation finished to unstall + // subsequent instructions + resPool->getDataUnit()->doCacheAccess(state); + + //@note: must delete state in InOrderDynInst destructor + //delete state; +} diff -r 87cafa076695 -r fbfa38428d04 src/cpu/inorder/resources/cache_unit.cc --- a/src/cpu/inorder/resources/cache_unit.cc Thu Mar 08 02:10:03 2012 -0800 +++ b/src/cpu/inorder/resources/cache_unit.cc Thu Mar 08 10:41:40 2012 -0500 @@ -38,9 +38,11 @@ #include "arch/utility.hh" #include "config/the_isa.hh" #include "cpu/inorder/resources/cache_unit.hh" +#include "cpu/inorder/resources/inorder_translation.hh" #include "cpu/inorder/cpu.hh" #include "cpu/inorder/pipeline_traits.hh" #include "cpu/inorder/resource_pool.hh" +#include "cpu/translation.hh" #include "debug/Activity.hh" #include "debug/AddrDep.hh" #include "debug/InOrderCachePort.hh" @@ -356,6 +358,7 @@ { ThreadID tid = inst->readTid(); + // This function doesn't look right; simpler to set up here setupMemRequest(inst, cache_req, acc_size, flags); //@todo: HACK: the DTB expects the correct PC in the ThreadContext @@ -365,6 +368,35 @@ PCState old_pc = tc->pcState(); tc->pcState() = inst->pcState(); + // Set up Translation object similarly to simple/timing.cc + // The data and res values in WholeTranslationState should not be needed + // as that is handled in doCacheAccess() later + if (cache_req->splitAccess) { + RequestPtr req1, req2; + cache_req->memReq->splitOnVaddr(inst->split2ndAddr, req1, req2); + WholeTranslationState *state = + new WholeTranslationState(cache_req->memReq, req1, req2, NULL, NULL, + tlb_mode); + //@note: who deallocates these? + InOrderTranslation *trans1 = + new InOrderTranslation(cpu, state, 0, tid, this); + InOrderTranslation *trans2 = + new InOrderTranslation(cpu, state, 1, tid, this); + + inst->fault = _tlb->translateTiming(req1, tc, trans1, tlb_mode); + if (inst->fault == NoFault){ + inst->fault = _tlb->translateTiming(req2, tc, trans2, tlb_mode); + } + } else { + WholeTranslationState *state = + new WholeTranslationState(cache_req->memReq, NULL, NULL, tlb_mode); + //@note: who deallocates this? + InOrderTranslation *trans = + new InOrderTranslation(cpu, state, tid, this); + + inst->fault = _tlb->translateTiming(cache_req->memReq, tc, trans, tlb_mode); + } + inst->fault = _tlb->translateAtomic(cache_req->memReq, tc, tlb_mode); tc->pcState() = old_pc; @@ -395,7 +427,8 @@ void CacheUnit::trap(Fault fault, ThreadID tid, DynInstPtr inst) { - tlbBlocked[tid] = false; + // Unblocking is done by InOrderDataTranslation + //tlbBlocked[tid] = false; } Fault @@ -670,7 +703,7 @@ } else { inst->initiateAcc(); } - + break; case InitSecondSplitRead: @@ -702,7 +735,13 @@ tid, inst->seqNum); - //@todo: timing translations need to check here... + if (tlbBlocked[tid]) + { + DPRINTF(InOrderCachePort, " Failed because ", + "translation ongoing\n"); + break; + } + assert(!inst->isInstPrefetch() && "Can't Handle Inst. Prefecthes"); if (cache_req->isMemAccComplete() || inst->isDataPrefetch()) { finishCacheUnitReq(inst, cache_req); @@ -721,7 +760,13 @@ tid, inst->seqNum); - //@todo: check that timing translation is finished here + if (tlbBlocked[tid]) + { + DPRINTF(InOrderCachePort, " Failed because ", + "translation ongoing\n"); + break; + } + RequestPtr mem_req = cache_req->memReq; if (mem_req->isCondSwap() || mem_req->isLLSC() || mem_req->isSwap()) { DPRINTF(InOrderCachePort, "Detected Conditional Store Inst.\n"); @@ -754,7 +799,13 @@ "[tid:%i]: [sn:%i]: Trying to Complete Split Data Read " "Access\n", tid, inst->seqNum); - //@todo: check that timing translation is finished here + if (tlbBlocked[tid]) + { + DPRINTF(InOrderCachePort, " Failed because ", + "translation ongoing\n"); + break; + } + assert(!inst->isInstPrefetch() && "Can't Handle Inst. Prefecthes"); if (cache_req->isMemAccComplete() || inst->isDataPrefetch()) { finishCacheUnitReq(inst, cache_req); @@ -779,10 +830,16 @@ cache_req->dataPkt->memReq = cache_req->memReq; } - //@todo: check that timing translation is finished here + if (tlbBlocked[tid]) + { + DPRINTF(InOrderCachePort, " Failed because ", + "translation ongoing\n"); + break; + } + finishCacheUnitReq(inst, cache_req); break; - + default: fatal("Unrecognized command to %s", resName); } @@ -998,7 +1055,7 @@ cache_pkt->cacheReq->getInst()->seqNum, cache_pkt->cacheReq->getInst()->getMemAddr()); } - + assert(cache_req); assert(cache_req == cache_pkt->cacheReq); @@ -1090,13 +1147,13 @@ cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) { DPRINTF(InOrderCachePort, "[tid:%u] Waking up from Cache Miss.\n", tid); - + cpu->activateContext(tid); - + DPRINTF(ThreadModel, "Activating [tid:%i] after return from cache" "miss.\n", tid); } - + // Wake up the CPU (if it went to sleep and was waiting on this // completion event). cpu->wakeCPU(); @@ -1111,7 +1168,7 @@ CacheUnit::recvRetry() { DPRINTF(InOrderCachePort, "Unblocking Cache Port. \n"); - + assert(cachePortBlocked); // Clear the cache port for use again @@ -1127,6 +1184,11 @@ void CacheUnitEvent::process() { + // CacheUnitEvent is apparently deprecated, and process() shouldn't be + // called. + // process() can unset tlbBlocked[tid], which could be bad. + assert(0); + DynInstPtr inst = resource->reqs[slotIdx]->inst; int stage_num = resource->reqs[slotIdx]->getStageNum(); ThreadID tid = inst->threadNumber;