diff options
Diffstat (limited to 'src/cpu/o3/fetch_impl.hh')
-rw-r--r-- | src/cpu/o3/fetch_impl.hh | 89 |
1 files changed, 49 insertions, 40 deletions
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh index f3793db6d..c0a2a5d09 100644 --- a/src/cpu/o3/fetch_impl.hh +++ b/src/cpu/o3/fetch_impl.hh @@ -43,8 +43,6 @@ #include "arch/tlb.hh" #include "arch/vtophys.hh" #include "base/remote_gdb.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" #include "sim/system.hh" #endif // FULL_SYSTEM @@ -90,18 +88,7 @@ template<class Impl> void DefaultFetch<Impl>::IcachePort::recvRetry() { - panic("DefaultFetch doesn't support retry yet."); - // we shouldn't get a retry unless we have a packet that we're - // waiting to transmit -/* - assert(cpu->dcache_pkt != NULL); - assert(cpu->_status == DcacheRetry); - Packet *tmp = cpu->dcache_pkt; - if (sendTiming(tmp)) { - cpu->_status = DcacheWaitResponse; - cpu->dcache_pkt = NULL; - } -*/ + fetch->recvRetry(); } template<class Impl> @@ -113,6 +100,9 @@ DefaultFetch<Impl>::DefaultFetch(Params *params) iewToFetchDelay(params->iewToFetchDelay), commitToFetchDelay(params->commitToFetchDelay), fetchWidth(params->fetchWidth), + cacheBlocked(false), + retryPkt(NULL), + retryTid(-1), numThreads(params->numberOfThreads), numFetchingThreads(params->smtNumFetchingThreads), interruptPending(false), @@ -332,18 +322,6 @@ DefaultFetch<Impl>::setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr) toDecode = fetchQueue->getWire(0); } -#if 0 -template<class Impl> -void -DefaultFetch<Impl>::setPageTable(PageTable *pt_ptr) -{ - DPRINTF(Fetch, "Setting the page table pointer.\n"); -#if !FULL_SYSTEM - pTable = pt_ptr; -#endif -} -#endif - template<class Impl> void DefaultFetch<Impl>::initStage() @@ -391,8 +369,6 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt) fetchStatus[tid] = IcacheAccessComplete; } -// memcpy(cacheData[tid], memReq[tid]->data, memReq[tid]->size); - // Reset the mem req to NULL. delete pkt->req; delete pkt; @@ -512,9 +488,11 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid unsigned flags = 0; #endif // FULL_SYSTEM - if (interruptPending && flags == 0 || switchedOut) { - // Hold off fetch from getting new instructions while an interrupt - // is pending. + if (cacheBlocked || (interruptPending && flags == 0) || switchedOut) { + // Hold off fetch from getting new instructions when: + // Cache is blocked, or + // while an interrupt is pending and we're not in PAL mode, or + // fetch is switched out. return false; } @@ -530,11 +508,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid memReq[tid] = mem_req; // Translate the instruction request. -//#if FULL_SYSTEM - fault = cpu->translateInstReq(mem_req); -//#else -// fault = pTable->translate(memReq[tid]); -//#endif + fault = cpu->translateInstReq(mem_req, cpu->thread[tid]); // In the case of faults, the fetch stage may need to stall and wait // for the ITB miss to be handled. @@ -542,7 +516,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid // If translation was successful, attempt to read the first // instruction. if (fault == NoFault) { -#if FULL_SYSTEM +#if 0 if (cpu->system->memctrl->badaddr(memReq[tid]->paddr) || memReq[tid]->flags & UNCACHEABLE) { DPRINTF(Fetch, "Fetch: Bad address %#x (hopefully on a " @@ -565,8 +539,13 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid // Now do the timing access to see whether or not the instruction // exists within the cache. if (!icachePort->sendTiming(data_pkt)) { + assert(retryPkt == NULL); + assert(retryTid == -1); DPRINTF(Fetch, "[tid:%i] Out of MSHRs!\n", tid); - ret_fault = NoFault; + fetchStatus[tid] = IcacheWaitRetry; + retryPkt = data_pkt; + retryTid = tid; + cacheBlocked = true; return false; } @@ -601,11 +580,19 @@ DefaultFetch<Impl>::doSquash(const Addr &new_PC, unsigned tid) if (fetchStatus[tid] == IcacheWaitResponse) { DPRINTF(Fetch, "[tid:%i]: Squashing outstanding Icache miss.\n", tid); - // Should I delete this here or when it comes back from the cache? -// delete memReq[tid]; memReq[tid] = NULL; } + // Get rid of the retrying packet if it was from this thread. + if (retryTid == tid) { + assert(cacheBlocked); + cacheBlocked = false; + retryTid = -1; + retryPkt = NULL; + delete retryPkt->req; + delete retryPkt; + } + fetchStatus[tid] = Squashing; ++fetchSquashCycles; @@ -1105,6 +1092,28 @@ DefaultFetch<Impl>::fetch(bool &status_change) } } +template<class Impl> +void +DefaultFetch<Impl>::recvRetry() +{ + assert(cacheBlocked); + if (retryPkt != NULL) { + assert(retryTid != -1); + assert(fetchStatus[retryTid] == IcacheWaitRetry); + + if (icachePort->sendTiming(retryPkt)) { + fetchStatus[retryTid] = IcacheWaitResponse; + retryPkt = NULL; + retryTid = -1; + cacheBlocked = false; + } + } else { + assert(retryTid == -1); + // Access has been squashed since it was sent out. Just clear + // the cache being blocked. + cacheBlocked = false; + } +} /////////////////////////////////////// // // |