summaryrefslogtreecommitdiff
path: root/src/cpu/o3
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-06-09 12:29:31 -0400
committerKevin Lim <ktlim@umich.edu>2006-06-09 12:29:31 -0400
commita7f5f54ff8d7097c60fdf09bf4bbba121aaff5c6 (patch)
treeb21a4d132044bdd3bf3f3d46d4eba8df8713b6d5 /src/cpu/o3
parent02606ebb26dcdd9e370a72b22aaad11d1b14ac60 (diff)
downloadgem5-a7f5f54ff8d7097c60fdf09bf4bbba121aaff5c6.tar.xz
Allow for fetch to retry access if the sendTiming call fails.
--HG-- extra : convert_revision : ddbcf82e0a3160c93c4e51f5d60b0a7b5983d3ba
Diffstat (limited to 'src/cpu/o3')
-rw-r--r--src/cpu/o3/fetch.hh13
-rw-r--r--src/cpu/o3/fetch_impl.hh67
2 files changed, 59 insertions, 21 deletions
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 9e8aeb8fb..960d42178 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -115,7 +115,7 @@ class DefaultFetch
QuiescePending,
SwitchOut,
IcacheWaitResponse,
- IcacheRetry,
+ IcacheWaitRetry,
IcacheAccessComplete
};
@@ -268,6 +268,8 @@ class DefaultFetch
}
private:
+ void recvRetry();
+
/** Returns the appropriate thread to fetch, given the fetch policy. */
int getFetchingThread(FetchPriority &fetch_priority);
@@ -360,6 +362,15 @@ class DefaultFetch
/** The width of fetch in instructions. */
unsigned fetchWidth;
+ /** Is the cache blocked? If so no threads can access it. */
+ bool cacheBlocked;
+
+ /** The packet that is waiting to be retried. */
+ PacketPtr retryPkt;
+
+ /** The thread that is waiting on the cache to tell fetch to retry. */
+ int retryTid;
+
/** Cache block size. */
int cacheBlkSize;
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 152b69788..e75bc264b 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -88,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>
@@ -111,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),
@@ -510,9 +502,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;
}
@@ -528,11 +522,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, cpu->thread[tid]);
-//#else
-// fault = pTable->translate(memReq[tid]);
-//#endif
// In the case of faults, the fetch stage may need to stall and wait
// for the ITB miss to be handled.
@@ -563,8 +553,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;
}
@@ -604,6 +599,16 @@ DefaultFetch<Impl>::doSquash(const Addr &new_PC, unsigned 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;
@@ -1103,6 +1108,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;
+ }
+}
///////////////////////////////////////
// //