inorder-stc: update interface to handle store conditionals
This commit is contained in:
parent
6211fe5d2e
commit
fe4cd9847d
6 changed files with 29 additions and 21 deletions
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue