summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2009-05-12 15:01:15 -0400
committerKorey Sewell <ksewell@umich.edu>2009-05-12 15:01:15 -0400
commitfe4cd9847db2b2d7d566a921670c92fa39d14136 (patch)
treea27928cb7e56f26cdd9bb34899d747ff0a91644f
parent6211fe5d2ee00dae9cd72d9cccdc900241a8f9a2 (diff)
downloadgem5-fe4cd9847db2b2d7d566a921670c92fa39d14136.tar.xz
inorder-stc: update interface to handle store conditionals
-rw-r--r--src/cpu/inorder/cpu.cc4
-rw-r--r--src/cpu/inorder/cpu.hh2
-rw-r--r--src/cpu/inorder/inorder_dyn_inst.cc2
-rw-r--r--src/cpu/inorder/resource.hh2
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc36
-rw-r--r--src/cpu/inorder/resources/cache_unit.hh4
6 files changed, 29 insertions, 21 deletions
diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index e17d82041..51f763112 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -1258,10 +1258,10 @@ InOrderCPU::read(DynInstPtr inst)
}
Fault
-InOrderCPU::write(DynInstPtr inst)
+InOrderCPU::write(DynInstPtr inst, uint64_t *res)
{
Resource *mem_res = resPool->getResource(dataPortIdx);
- return mem_res->doDataAccess(inst);
+ return mem_res->doDataAccess(inst, res);
}
void
diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh
index 9426171c1..e3bfbb7f0 100644
--- a/src/cpu/inorder/cpu.hh
+++ b/src/cpu/inorder/cpu.hh
@@ -495,7 +495,7 @@ class InOrderCPU : public BaseCPU
/** Forwards an instruction write. to the appropriate data
* resource (indexes into Resource Pool thru "dataPortIdx")
*/
- Fault write(DynInstPtr inst);
+ Fault write(DynInstPtr inst, uint64_t *res = NULL);
/** Forwards an instruction prefetch to the appropriate data
* resource (indexes into Resource Pool thru "dataPortIdx")
diff --git a/src/cpu/inorder/inorder_dyn_inst.cc b/src/cpu/inorder/inorder_dyn_inst.cc
index 9609db22f..3983821e7 100644
--- a/src/cpu/inorder/inorder_dyn_inst.cc
+++ b/src/cpu/inorder/inorder_dyn_inst.cc
@@ -657,7 +657,7 @@ InOrderDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res)
DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting store data to %#x.\n",
threadNumber, seqNum, memData);
- return cpu->write(this);
+ return cpu->write(this, res);
}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
diff --git a/src/cpu/inorder/resource.hh b/src/cpu/inorder/resource.hh
index 0c0aad758..0378c0f50 100644
--- a/src/cpu/inorder/resource.hh
+++ b/src/cpu/inorder/resource.hh
@@ -140,7 +140,7 @@ class Resource {
* if instruction is actually in resource before
* trying to do access.Needs to be defined for derived units.
*/
- virtual Fault doDataAccess(DynInstPtr inst)
+ virtual Fault doDataAccess(DynInstPtr inst, uint64_t *res=NULL)
{ panic("doDataAccess undefined for %s", name()); return NoFault; }
virtual void prefetch(DynInstPtr inst)
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc
index 4ac1fb77e..c5d35dfb3 100644
--- a/src/cpu/inorder/resources/cache_unit.cc
+++ b/src/cpu/inorder/resources/cache_unit.cc
@@ -175,7 +175,7 @@ CacheUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
inst->readTid(), req_size, inst->seqNum, inst->getMemAddr());
} else if (sched_entry->cmd == InitiateFetch){
pkt_cmd = MemCmd::ReadReq;
- req_size = sizeof(MachInst); //@TODO: mips16e
+ req_size = sizeof(MachInst);
DPRINTF(InOrderCachePort,
"[tid:%i]: %i byte Fetch request from [sn:%i] for addr %08p\n",
@@ -356,7 +356,7 @@ CacheUnit::writeHint(DynInstPtr inst)
}
Fault
-CacheUnit::doDataAccess(DynInstPtr inst)
+CacheUnit::doDataAccess(DynInstPtr inst, uint64_t *write_res)
{
Fault fault = NoFault;
int tid = 0;
@@ -367,6 +367,17 @@ CacheUnit::doDataAccess(DynInstPtr inst)
= dynamic_cast<CacheReqPtr>(reqMap[inst->getCurResSlot()]);
assert(cache_req);
+ // Check for LL/SC and if so change command
+ if (cache_req->memReq->isLLSC() && cache_req->pktCmd == MemCmd::ReadReq) {
+ cache_req->pktCmd = MemCmd::LoadLockedReq;
+ }
+
+ if (cache_req->pktCmd == MemCmd::WriteReq) {
+ cache_req->pktCmd =
+ cache_req->memReq->isSwap() ? MemCmd::SwapReq :
+ (cache_req->memReq->isLLSC() ? MemCmd::StoreCondReq : MemCmd::WriteReq);
+ }
+
cache_req->dataPkt = new CacheReqPacket(cache_req, cache_req->pktCmd,
Packet::Broadcast);
@@ -374,6 +385,11 @@ CacheUnit::doDataAccess(DynInstPtr inst)
cache_req->dataPkt->dataStatic(cache_req->reqData);
} else if (cache_req->dataPkt->isWrite()) {
cache_req->dataPkt->dataStatic(&cache_req->inst->storeData);
+
+ if (cache_req->memReq->isCondSwap()) {
+ assert(write_res);
+ cache_req->memReq->setExtraData(*write_res);
+ }
}
cache_req->dataPkt->time = curTick;
@@ -382,7 +398,7 @@ CacheUnit::doDataAccess(DynInstPtr inst)
Request *memReq = cache_req->dataPkt->req;
- if (cache_req->dataPkt->isWrite() && memReq->isLLSC()) {
+ if (cache_req->dataPkt->isWrite() && cache_req->memReq->isLLSC()) {
assert(cache_req->inst->isStoreConditional());
DPRINTF(InOrderCachePort, "Evaluating Store Conditional access\n");
do_access = TheISA::handleLockedWrite(cpu, memReq);
@@ -392,11 +408,7 @@ CacheUnit::doDataAccess(DynInstPtr inst)
"[tid:%i] [sn:%i] attempting to access cache\n",
tid, inst->seqNum);
- //@TODO: If you want to ignore failed store conditional accesses, then
- // enable this. However, this might skew memory stats because
- // the failed store conditional access will get ignored.
- // - Remove optionality here ...
- if (1/*do_access*/) {
+ if (do_access) {
if (!cachePort->sendTiming(cache_req->dataPkt)) {
DPRINTF(InOrderCachePort,
"[tid:%i] [sn:%i] is waiting to retry request\n",
@@ -431,13 +443,7 @@ CacheUnit::doDataAccess(DynInstPtr inst)
"[tid:%i]: T%i Ignoring Failed Store Conditional Access\n",
tid, tid);
- cache_req->dataPkt->req->setExtraData(0);
-
processCacheCompletion(cache_req->dataPkt);
-
- // Automatically set these since we ignored the memory access
- //cache_req->setMemAccPending(false);
- //cache_req->setMemAccCompleted();
} else {
// Make cache request again since access due to
// inability to access
@@ -535,7 +541,7 @@ CacheUnit::processCacheCompletion(PacketPtr pkt)
TheISA::handleLockedRead(cpu, cache_pkt->req);
}
- // @TODO: Hardcoded to for load instructions. Assumes that
+ // @NOTE: Hardcoded to for load instructions. Assumes that
// the dest. idx 0 is always where the data is loaded to.
DPRINTF(InOrderCachePort,
"[tid:%u]: [sn:%i]: Data loaded was: %08p\n",
diff --git a/src/cpu/inorder/resources/cache_unit.hh b/src/cpu/inorder/resources/cache_unit.hh
index 06ccf3bec..226a35a52 100644
--- a/src/cpu/inorder/resources/cache_unit.hh
+++ b/src/cpu/inorder/resources/cache_unit.hh
@@ -162,7 +162,7 @@ class CacheUnit : public Resource
/** Read/Write on behalf of an instruction.
* curResSlot needs to be a valid value in instruction.
*/
- Fault doDataAccess(DynInstPtr inst);
+ Fault doDataAccess(DynInstPtr inst, uint64_t *write_result=NULL);
void prefetch(DynInstPtr inst);
@@ -245,6 +245,8 @@ class CacheRequest : public ResourceRequest
memReq = inst->dataMemReq;
}
+ //@ Only matters for Fetch / Read requests
+ // Don't allocate for Writes!
reqData = new uint8_t[req_size];
retryPkt = NULL;
}