changeset 26a0b8a1ecb8 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=26a0b8a1ecb8
description:
inorder: don't stall after stores
once a ST is sent off, it's OK to keep processing, however it's a
little more
complicated to handle the packet acknowledging the store is completed
diffstat:
src/cpu/inorder/inorder_dyn_inst.cc | 25 +-
src/cpu/inorder/pipeline_stage.cc | 14 -
src/cpu/inorder/resource.cc | 6 +-
src/cpu/inorder/resources/cache_unit.cc | 393 +++++++++++++++++++++----------
src/cpu/inorder/resources/cache_unit.hh | 33 +-
src/cpu/inorder/resources/fetch_unit.cc | 27 +-
6 files changed, 282 insertions(+), 216 deletions(-)
diffs (truncated from 800 to 300 lines):
diff -r 852687db50eb -r 26a0b8a1ecb8 src/cpu/inorder/inorder_dyn_inst.cc
--- a/src/cpu/inorder/inorder_dyn_inst.cc Sun Jun 19 21:43:37 2011 -0400
+++ b/src/cpu/inorder/inorder_dyn_inst.cc Sun Jun 19 21:43:37 2011 -0400
@@ -176,21 +176,6 @@
InOrderDynInst::~InOrderDynInst()
{
- if (fetchMemReq != 0x0) {
- delete fetchMemReq;
- fetchMemReq = NULL;
- }
-
- if (dataMemReq != 0x0) {
- delete dataMemReq;
- dataMemReq = NULL;
- }
-
- if (splitMemReq != 0x0) {
- delete dataMemReq;
- dataMemReq = NULL;
- }
-
if (traceData)
delete traceData;
@@ -557,6 +542,8 @@
traceData->setData(data);
}
Fault fault = readBytes(addr, (uint8_t *)&data, sizeof(T), flags);
+ //@todo: the below lines should be unnecessary, timing access
+ // wont have valid data right here
DPRINTF(InOrderDynInst, "[sn:%i] (1) Received Bytes %x\n", seqNum, data);
data = TheISA::gtoh(data);
DPRINTF(InOrderDynInst, "[sn%:i] (2) Received Bytes %x\n", seqNum, data);
@@ -619,11 +606,7 @@
InOrderDynInst::writeBytes(uint8_t *data, unsigned size,
Addr addr, unsigned flags, uint64_t *res)
{
- assert(sizeof(storeData) >= size);
- memcpy(&storeData, data, size);
- DPRINTF(InOrderDynInst, "(2) [tid:%i]: [sn:%i] Setting store data to
%#x.\n",
- threadNumber, seqNum, storeData);
- return cpu->write(this, (uint8_t *)&storeData, size, addr, flags, res);
+ return cpu->write(this, data, size, addr, flags, res);
}
template<class T>
@@ -635,8 +618,6 @@
traceData->setData(data);
}
data = TheISA::htog(data);
- DPRINTF(InOrderDynInst, "(1) [tid:%i]: [sn:%i] Setting store data to
%#x.\n",
- threadNumber, seqNum, data);
return writeBytes((uint8_t*)&data, sizeof(T), addr, flags, res);
}
diff -r 852687db50eb -r 26a0b8a1ecb8 src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Sun Jun 19 21:43:37 2011 -0400
+++ b/src/cpu/inorder/pipeline_stage.cc Sun Jun 19 21:43:37 2011 -0400
@@ -650,20 +650,6 @@
stalls[tid].stage[stage_idx] = false;
}
}
-
- for (int stage_idx = 0; stage_idx < NumStages;
- stage_idx++) {
-
- DPRINTF(InOrderStage, "[tid:%i] Stall signals from Stage "
- "%i. Block:%i Unblock:%i...NBlock:%i NUnblock:%i\n",
- tid,
- stage_idx,
- fromNextStages->stageBlock[stage_idx][tid],
- fromNextStages->stageUnblock[stage_idx][tid],
- toPrevStages->stageBlock[stage_idx][tid],
- toPrevStages->stageUnblock[stage_idx][tid]);
- }
-
}
diff -r 852687db50eb -r 26a0b8a1ecb8 src/cpu/inorder/resource.cc
--- a/src/cpu/inorder/resource.cc Sun Jun 19 21:43:37 2011 -0400
+++ b/src/cpu/inorder/resource.cc Sun Jun 19 21:43:37 2011 -0400
@@ -413,7 +413,7 @@
std::string
ResourceRequest::name()
{
- return res->name() + "." + to_string(slotNum);
+ return csprintf("%s[slot:%i]:", res->name(), slotNum);
}
void
@@ -452,8 +452,8 @@
void
ResourceRequest::done(bool completed)
{
- DPRINTF(Resource, "%s [slot:%i] done with request from "
- "[sn:%i] [tid:%i].\n", res->name(), slotNum,
+ DPRINTF(Resource, "done with request from "
+ "[sn:%i] [tid:%i].\n",
inst->seqNum, inst->readTid());
setCompleted(completed);
diff -r 852687db50eb -r 26a0b8a1ecb8 src/cpu/inorder/resources/cache_unit.cc
--- a/src/cpu/inorder/resources/cache_unit.cc Sun Jun 19 21:43:37 2011 -0400
+++ b/src/cpu/inorder/resources/cache_unit.cc Sun Jun 19 21:43:37 2011 -0400
@@ -391,17 +391,18 @@
Addr aligned_addr = inst->getMemAddr();
if (!cache_req->is2ndSplit()) {
- if (inst->dataMemReq == NULL) {
- inst->dataMemReq =
+ if (cache_req->memReq == NULL) {
+ cache_req->memReq =
new Request(cpu->asid[tid], aligned_addr, acc_size, flags,
inst->instAddr(), cpu->readCpuId(),
tid);
- cache_req->memReq = inst->dataMemReq;
+ DPRINTF(InOrderCachePort, "[sn:%i] Created memReq @%x, ->%x\n",
+ inst->seqNum, &cache_req->memReq, cache_req->memReq);
}
} else {
assert(inst->splitInst);
- if (inst->splitMemReq == NULL) {
+ if (inst->splitMemReq == NULL) {
inst->splitMemReq = new Request(cpu->asid[tid],
inst->split2ndAddr,
acc_size,
@@ -636,8 +637,6 @@
// ==============================
inst->split2ndSize = addr + fullSize - secondAddr;
inst->split2ndAddr = secondAddr;
- inst->split2ndStoreDataPtr = &cache_req->inst->storeData;
- inst->split2ndStoreDataPtr += size;
inst->split2ndFlags = flags;
inst->splitInstSked = true;
}
@@ -645,7 +644,13 @@
doTLBAccess(inst, cache_req, size, flags, TheISA::TLB::Write);
if (inst->fault == NoFault) {
- if (!cache_req->splitAccess) {
+ if (!cache_req->splitAccess) {
+ cache_req->reqData = new uint8_t[size];
+ memcpy(cache_req->reqData, data, size);
+
+ //inst->split2ndStoreDataPtr = cache_req->reqData;
+ //inst->split2ndStoreDataPtr += size;
+
doCacheAccess(inst, write_res);
} else {
doCacheAccess(inst, write_res, cache_req);
@@ -734,17 +739,13 @@
break;
case CompleteReadData:
- case CompleteWriteData:
DPRINTF(InOrderCachePort,
- "[tid:%i]: [sn:%i]: Trying to Complete Data Access\n",
+ "[tid:%i]: [sn:%i]: Trying to Complete Data Read Access\n",
tid, inst->seqNum);
-
- if (cache_req->isMemAccComplete() ||
- inst->isDataPrefetch() ||
- inst->isInstPrefetch()) {
- removeAddrDependency(inst);
- cache_req->setMemStall(false);
- cache_req->done();
+ //@todo: timing translations need to check here...
+ assert(!inst->isInstPrefetch() && "Can't Handle Inst. Prefecthes");
+ if (cache_req->isMemAccComplete() || inst->isDataPrefetch()) {
+ finishCacheUnitReq(inst, cache_req);
} else {
DPRINTF(InOrderStall, "STALL: [tid:%i]: Data miss from %08p\n",
tid, cache_req->inst->getMemAddr());
@@ -753,17 +754,44 @@
}
break;
+ case CompleteWriteData:
+ DPRINTF(InOrderCachePort,
+ "[tid:%i]: [sn:%i]: Trying to Complete Data Write Access\n",
+ tid, inst->seqNum);
+ //@todo: check that timing translation is finished here
+ if (cache_req->dataPkt->isRead()) {
+ assert(cache_req->memReq->isCondSwap() ||
+ cache_req->memReq->isLLSC() ||
+ cache_req->memReq->isSwap());
+
+ if (!cache_req->isMemAccComplete()) {
+ DPRINTF(InOrderStall, "STALL: [tid:%i]: Data miss from %08p\n",
+ tid, cache_req->inst->getMemAddr());
+ cache_req->setCompleted(false);
+ cache_req->setMemStall(true);
+ return;
+ }
+ }
+
+ if (cache_req->isMemAccPending()) {
+ cache_req->dataPkt->reqData = cache_req->reqData;
+ cache_req->dataPkt->memReq = cache_req->memReq;
+ }
+
+ //@todo: if split inst save data
+
+ finishCacheUnitReq(inst, cache_req);
+ break;
+
case CompleteSecondSplitRead:
DPRINTF(InOrderCachePort,
"[tid:%i]: [sn:%i]: Trying to Complete Split Data Read "
"Access\n", tid, inst->seqNum);
- if (cache_req->isMemAccComplete() ||
- inst->isDataPrefetch() ||
- inst->isInstPrefetch()) {
- removeAddrDependency(inst);
- cache_req->setMemStall(false);
- cache_req->done();
+ //@todo: check that timing translation is finished here
+ assert(!inst->isInstPrefetch() && "Can't Handle Inst. Prefecthes");
+ if (cache_req->isMemAccComplete() || inst->isDataPrefetch()) {
+ finishCacheUnitReq(inst, cache_req);
} else {
DPRINTF(InOrderStall, "STALL: [tid:%i]: Data miss from %08p\n",
tid, cache_req->inst->split2ndAddr);
@@ -776,19 +804,16 @@
DPRINTF(InOrderCachePort,
"[tid:%i]: [sn:%i]: Trying to Complete Split Data Write "
"Access\n", tid, inst->seqNum);
+ //@todo: illegal to have a unaligned cond.swap or llsc?
+ assert(!cache_req->memReq->isSwap() &&
!cache_req->memReq->isCondSwap() && !cache_req->memReq->isLLSC());
- if (cache_req->isMemAccComplete() ||
- inst->isDataPrefetch() ||
- inst->isInstPrefetch()) {
- removeAddrDependency(inst);
- cache_req->setMemStall(false);
- cache_req->done();
- } else {
- DPRINTF(InOrderStall, "STALL: [tid:%i]: Data miss from %08p\n",
- tid, cache_req->inst->split2ndAddr);
- cache_req->setCompleted(false);
- cache_req->setMemStall(true);
+ if (cache_req->isMemAccPending()) {
+ cache_req->dataPkt->reqData = cache_req->reqData;
+ cache_req->dataPkt->memReq = cache_req->memReq;
}
+
+ //@todo: check that timing translation is finished here
+ finishCacheUnitReq(inst, cache_req);
break;
default:
@@ -796,26 +821,17 @@
}
}
-// @TODO: Split into doCacheRead() and doCacheWrite()
void
-CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res,
- CacheReqPtr split_req)
+CacheUnit::finishCacheUnitReq(DynInstPtr inst, CacheRequest *cache_req)
{
- Fault fault = NoFault;
-#if TRACING_ON
- ThreadID tid = inst->readTid();
-#endif
+ removeAddrDependency(inst);
+ cache_req->setMemStall(false);
+ cache_req->done();
+}
- CacheReqPtr cache_req;
-
- if (split_req == NULL) {
- cache_req = dynamic_cast<CacheReqPtr>(reqs[inst->getCurResSlot()]);
- } else{
- cache_req = split_req;
- }
-
- assert(cache_req);
-
+void
+CacheUnit::buildDataPacket(CacheRequest *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;
@@ -832,46 +848,61 @@
cache_req->pktCmd,
Packet::Broadcast,
cache_req->instIdx);
+ DPRINTF(InOrderCachePort, "[slot:%i]: Slot marked for %x [pkt:%x->%x]\n",
+ cache_req->getSlot(),
+ cache_req->dataPkt->getAddr(),
+ &cache_req->dataPkt,
+ cache_req->dataPkt);
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev