inorder-stc: update interface to handle store conditionals

This commit is contained in:
Korey Sewell 2009-05-12 15:01:15 -04:00
parent 6211fe5d2e
commit fe4cd9847d
6 changed files with 29 additions and 21 deletions

View file

@ -1258,10 +1258,10 @@ InOrderCPU::read(DynInstPtr inst)
} }
Fault Fault
InOrderCPU::write(DynInstPtr inst) InOrderCPU::write(DynInstPtr inst, uint64_t *res)
{ {
Resource *mem_res = resPool->getResource(dataPortIdx); Resource *mem_res = resPool->getResource(dataPortIdx);
return mem_res->doDataAccess(inst); return mem_res->doDataAccess(inst, res);
} }
void void

View file

@ -495,7 +495,7 @@ class InOrderCPU : public BaseCPU
/** Forwards an instruction write. to the appropriate data /** Forwards an instruction write. to the appropriate data
* resource (indexes into Resource Pool thru "dataPortIdx") * 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 /** Forwards an instruction prefetch to the appropriate data
* resource (indexes into Resource Pool thru "dataPortIdx") * resource (indexes into Resource Pool thru "dataPortIdx")

View file

@ -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", DPRINTF(InOrderDynInst, "[tid:%i]: [sn:%i] Setting store data to %#x.\n",
threadNumber, seqNum, memData); threadNumber, seqNum, memData);
return cpu->write(this); return cpu->write(this, res);
} }
#ifndef DOXYGEN_SHOULD_SKIP_THIS #ifndef DOXYGEN_SHOULD_SKIP_THIS

View file

@ -140,7 +140,7 @@ class Resource {
* if instruction is actually in resource before * if instruction is actually in resource before
* trying to do access.Needs to be defined for derived units. * 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; } { panic("doDataAccess undefined for %s", name()); return NoFault; }
virtual void prefetch(DynInstPtr inst) virtual void prefetch(DynInstPtr inst)

View file

@ -175,7 +175,7 @@ CacheUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
inst->readTid(), req_size, inst->seqNum, inst->getMemAddr()); inst->readTid(), req_size, inst->seqNum, inst->getMemAddr());
} else if (sched_entry->cmd == InitiateFetch){ } else if (sched_entry->cmd == InitiateFetch){
pkt_cmd = MemCmd::ReadReq; pkt_cmd = MemCmd::ReadReq;
req_size = sizeof(MachInst); //@TODO: mips16e req_size = sizeof(MachInst);
DPRINTF(InOrderCachePort, DPRINTF(InOrderCachePort,
"[tid:%i]: %i byte Fetch request from [sn:%i] for addr %08p\n", "[tid:%i]: %i byte Fetch request from [sn:%i] for addr %08p\n",
@ -356,7 +356,7 @@ CacheUnit::writeHint(DynInstPtr inst)
} }
Fault Fault
CacheUnit::doDataAccess(DynInstPtr inst) CacheUnit::doDataAccess(DynInstPtr inst, uint64_t *write_res)
{ {
Fault fault = NoFault; Fault fault = NoFault;
int tid = 0; int tid = 0;
@ -367,6 +367,17 @@ CacheUnit::doDataAccess(DynInstPtr inst)
= dynamic_cast<CacheReqPtr>(reqMap[inst->getCurResSlot()]); = dynamic_cast<CacheReqPtr>(reqMap[inst->getCurResSlot()]);
assert(cache_req); 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, cache_req->dataPkt = new CacheReqPacket(cache_req, cache_req->pktCmd,
Packet::Broadcast); Packet::Broadcast);
@ -374,6 +385,11 @@ CacheUnit::doDataAccess(DynInstPtr inst)
cache_req->dataPkt->dataStatic(cache_req->reqData); cache_req->dataPkt->dataStatic(cache_req->reqData);
} else if (cache_req->dataPkt->isWrite()) { } else if (cache_req->dataPkt->isWrite()) {
cache_req->dataPkt->dataStatic(&cache_req->inst->storeData); 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; cache_req->dataPkt->time = curTick;
@ -382,7 +398,7 @@ CacheUnit::doDataAccess(DynInstPtr inst)
Request *memReq = cache_req->dataPkt->req; 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()); assert(cache_req->inst->isStoreConditional());
DPRINTF(InOrderCachePort, "Evaluating Store Conditional access\n"); DPRINTF(InOrderCachePort, "Evaluating Store Conditional access\n");
do_access = TheISA::handleLockedWrite(cpu, memReq); do_access = TheISA::handleLockedWrite(cpu, memReq);
@ -392,11 +408,7 @@ CacheUnit::doDataAccess(DynInstPtr inst)
"[tid:%i] [sn:%i] attempting to access cache\n", "[tid:%i] [sn:%i] attempting to access cache\n",
tid, inst->seqNum); tid, inst->seqNum);
//@TODO: If you want to ignore failed store conditional accesses, then if (do_access) {
// 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 (!cachePort->sendTiming(cache_req->dataPkt)) { if (!cachePort->sendTiming(cache_req->dataPkt)) {
DPRINTF(InOrderCachePort, DPRINTF(InOrderCachePort,
"[tid:%i] [sn:%i] is waiting to retry request\n", "[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:%i]: T%i Ignoring Failed Store Conditional Access\n",
tid, tid); tid, tid);
cache_req->dataPkt->req->setExtraData(0);
processCacheCompletion(cache_req->dataPkt); processCacheCompletion(cache_req->dataPkt);
// Automatically set these since we ignored the memory access
//cache_req->setMemAccPending(false);
//cache_req->setMemAccCompleted();
} else { } else {
// Make cache request again since access due to // Make cache request again since access due to
// inability to access // inability to access
@ -535,7 +541,7 @@ CacheUnit::processCacheCompletion(PacketPtr pkt)
TheISA::handleLockedRead(cpu, cache_pkt->req); 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. // the dest. idx 0 is always where the data is loaded to.
DPRINTF(InOrderCachePort, DPRINTF(InOrderCachePort,
"[tid:%u]: [sn:%i]: Data loaded was: %08p\n", "[tid:%u]: [sn:%i]: Data loaded was: %08p\n",

View file

@ -162,7 +162,7 @@ class CacheUnit : public Resource
/** Read/Write on behalf of an instruction. /** Read/Write on behalf of an instruction.
* curResSlot needs to be a valid value in 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); void prefetch(DynInstPtr inst);
@ -245,6 +245,8 @@ class CacheRequest : public ResourceRequest
memReq = inst->dataMemReq; memReq = inst->dataMemReq;
} }
//@ Only matters for Fetch / Read requests
// Don't allocate for Writes!
reqData = new uint8_t[req_size]; reqData = new uint8_t[req_size];
retryPkt = NULL; retryPkt = NULL;
} }