changeset de51ab31b456 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=de51ab31b456
description:
inorder: implement split stores
diffstat:
4 files changed, 117 insertions(+), 31 deletions(-)
src/cpu/inorder/inorder_dyn_inst.cc | 3
src/cpu/inorder/inorder_dyn_inst.hh | 2
src/cpu/inorder/resources/cache_unit.cc | 140 ++++++++++++++++++++++++-------
src/cpu/inorder/resources/cache_unit.hh | 3
diffs (truncated from 304 to 300 lines):
diff -r 88555fd4d220 -r de51ab31b456 src/cpu/inorder/inorder_dyn_inst.cc
--- a/src/cpu/inorder/inorder_dyn_inst.cc Sun Jan 31 18:30:35 2010 -0500
+++ b/src/cpu/inorder/inorder_dyn_inst.cc Sun Jan 31 18:30:43 2010 -0500
@@ -112,6 +112,7 @@
fetchMemReq = NULL;
dataMemReq = NULL;
splitMemData = NULL;
+ split2ndAddr = 0;
split2ndAccess = false;
splitInst = false;
splitFinishCnt = 0;
@@ -192,7 +193,7 @@
}
if (splitMemData) {
- delete splitMemData;
+ delete [] splitMemData;
}
fault = NoFault;
diff -r 88555fd4d220 -r de51ab31b456 src/cpu/inorder/inorder_dyn_inst.hh
--- a/src/cpu/inorder/inorder_dyn_inst.hh Sun Jan 31 18:30:35 2010 -0500
+++ b/src/cpu/inorder/inorder_dyn_inst.hh Sun Jan 31 18:30:43 2010 -0500
@@ -341,7 +341,7 @@
unsigned split2ndFlags;
bool splitInst;
int splitFinishCnt;
-
+ uint64_t *split2ndStoreDataPtr;
////////////////////////////////////////////////////////////
//
diff -r 88555fd4d220 -r de51ab31b456 src/cpu/inorder/resources/cache_unit.cc
--- a/src/cpu/inorder/resources/cache_unit.cc Sun Jan 31 18:30:35 2010 -0500
+++ b/src/cpu/inorder/resources/cache_unit.cc Sun Jan 31 18:30:43 2010 -0500
@@ -283,6 +283,14 @@
inst->readTid(), inst->seqNum, inst->getMemAddr());
break;
+ case InitSecondSplitWrite:
+ pkt_cmd = MemCmd::WriteReq;
+
+ DPRINTF(InOrderCachePort,
+ "[tid:%i]: Write request from [sn:%i] for addr %08p\n",
+ inst->readTid(), inst->seqNum, inst->split2ndAddr);
+ break;
+
case InitiateWriteData:
pkt_cmd = MemCmd::WriteReq;
@@ -327,7 +335,8 @@
"instruction\n ", inst->readTid(), inst->seqNum);
service_request = true;
- } else if (inst->resSched.top()->idx != CacheUnit::InitSecondSplitRead) {
+ } else if (inst->resSched.top()->idx != CacheUnit::InitSecondSplitRead &&
+ inst->resSched.top()->idx != CacheUnit::InitSecondSplitWrite) {
// If same command, just check to see if memory access was completed
// but dont try to re-execute
DPRINTF(InOrderCachePort,
@@ -406,7 +415,7 @@
CacheUnit::read(DynInstPtr inst, Addr addr, T &data, unsigned flags)
{
CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(findRequest(inst));
- assert(cache_req);
+ assert(cache_req && "Can't Find Instruction for Read!");
// The block size of our peer
unsigned blockSize = this->cachePort->peerBlockSize();
@@ -456,7 +465,8 @@
inst->resSched.push(new ScheduleEntry(stage_num + 1,
1/*stage_pri*/,
cpu->resPool->getResIdx(DCache),
-
CacheUnit::CompleteSecondSplitRead, 1)
+
CacheUnit::CompleteSecondSplitRead,
+ 1)
);
@@ -473,12 +483,8 @@
inst->split2ndFlags = flags;
}
- //cout << "h1" << endl;
-
doTLBAccess(inst, cache_req, dataSize, flags, TheISA::TLB::Read);
- //cout << "h2" << endl;
-
if (cache_req->fault == NoFault) {
if (!cache_req->splitAccess) {
cache_req->reqData = new uint8_t[dataSize];
@@ -494,8 +500,6 @@
}
}
- //cout << "h3" << endl;
-
return cache_req->fault;
}
@@ -505,7 +509,7 @@
uint64_t *write_res)
{
CacheReqPtr cache_req = dynamic_cast<CacheReqPtr>(findRequest(inst));
- assert(cache_req);
+ assert(cache_req && "Can't Find Instruction for Write!");
// The block size of our peer
unsigned blockSize = this->cachePort->peerBlockSize();
@@ -513,22 +517,75 @@
//The size of the data we're trying to read.
int dataSize = sizeof(T);
+ if (inst->split2ndAccess) {
+ dataSize = inst->split2ndSize;
+ cache_req->splitAccess = true;
+ cache_req->split2ndAccess = true;
+
+ DPRINTF(InOrderCachePort, "%i: sn[%i] Split Write Access (2 of 2) for
(%#x, %#x).\n", curTick, inst->seqNum,
+ inst->getMemAddr(), inst->split2ndAddr);
+ }
+
//The address of the second part of this access if it needs to be split
//across a cache line boundary.
Addr secondAddr = roundDown(addr + dataSize - 1, blockSize);
- if (secondAddr > addr) {
- assert(0 && "Need Split Write Code!");
+ if (secondAddr > addr && !inst->split2ndAccess) {
+ DPRINTF(InOrderCachePort, "%i: sn[%i] Split Write Access (1 of 2) for
(%#x, %#x).\n", curTick, inst->seqNum,
+ addr, secondAddr);
+
+ // Save All "Total" Split Information
+ // ==============================
+ inst->splitInst = true;
+ inst->splitTotalSize = dataSize;
+
+ // Schedule Split Read/Complete for Instruction
+ // ==============================
+ int stage_num = cache_req->getStageNum();
+
+ int stage_pri = ThePipeline::getNextPriority(inst, stage_num);
+
+ inst->resSched.push(new ScheduleEntry(stage_num,
+ stage_pri,
+ cpu->resPool->getResIdx(DCache),
+ CacheUnit::InitSecondSplitWrite,
+ 1)
+ );
+
+ inst->resSched.push(new ScheduleEntry(stage_num + 1,
+ 1/*stage_pri*/,
+ cpu->resPool->getResIdx(DCache),
+
CacheUnit::CompleteSecondSplitWrite,
+ 1)
+ );
+
+ // Split Information for First Access
+ // ==============================
+ dataSize = secondAddr - addr;
+ cache_req->splitAccess = true;
+
+ // Split Information for Second Access
+ // ==============================
+ inst->split2ndSize = addr + sizeof(T) - secondAddr;
+ inst->split2ndAddr = secondAddr;
+ inst->split2ndStoreDataPtr = &cache_req->inst->storeData;
+ inst->split2ndStoreDataPtr += dataSize;
+ inst->split2ndFlags = flags;
}
-
- int acc_size = sizeof(T);
- doTLBAccess(inst, cache_req, acc_size, flags, TheISA::TLB::Write);
+
+ doTLBAccess(inst, cache_req, dataSize, flags, TheISA::TLB::Write);
if (cache_req->fault == NoFault) {
- cache_req->reqData = new uint8_t[acc_size];
- doCacheAccess(inst, write_res);
+ if (!cache_req->splitAccess) {
+ // Remove this line since storeData is saved in INST?
+ cache_req->reqData = new uint8_t[dataSize];
+ doCacheAccess(inst, write_res);
+ } else {
+ doCacheAccess(inst, write_res, cache_req);
+ }
+
}
-
+
return cache_req->fault;
}
@@ -596,9 +653,6 @@
inst->execute();
} else {
inst->initiateAcc();
- //if (inst->splitAccess) {
- // assert(0 && " Marked as spill inst");
- //}
}
break;
@@ -608,6 +662,7 @@
"[tid:%u]: [sn:%i] Initiating split data read access to %s for
addr. %08p\n",
tid, inst->seqNum, name(), cache_req->inst->split2ndAddr);
inst->split2ndAccess = true;
+ assert(inst->split2ndAddr != 0);
read(inst, inst->split2ndAddr, inst->split2ndData,
inst->split2ndFlags);
break;
@@ -615,9 +670,10 @@
DPRINTF(InOrderCachePort,
"[tid:%u]: [sn:%i] Initiating split data write access to %s
for addr. %08p\n",
tid, inst->seqNum, name(), cache_req->inst->getMemAddr());
- assert(0);
+
inst->split2ndAccess = true;
- //write(inst, inst->split2ndAddr, inst->split2ndData,
inst->split2ndFlags);
+ assert(inst->split2ndAddr != 0);
+ write(inst, inst->split2ndAddr, inst->split2ndData,
inst->split2ndFlags, NULL);
break;
@@ -682,6 +738,24 @@
cache_req->setMemStall(true);
}
break;
+
+ case CompleteSecondSplitWrite:
+ DPRINTF(InOrderCachePort,
+ "[tid:%i]: [sn:%i]: Trying to Complete Split Data Write
Access\n",
+ tid, inst->seqNum);
+
+ if (cache_req->isMemAccComplete() ||
+ inst->isDataPrefetch() ||
+ inst->isInstPrefetch()) {
+ 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);
+ }
+ break;
default:
fatal("Unrecognized command to %s", resName);
@@ -761,9 +835,13 @@
if (cache_req->dataPkt->isRead()) {
cache_req->dataPkt->dataStatic(cache_req->reqData);
- } else if (cache_req->dataPkt->isWrite()) {
- cache_req->dataPkt->dataStatic(&cache_req->inst->storeData);
-
+ } else if (cache_req->dataPkt->isWrite()) {
+ if (inst->split2ndAccess) {
+ cache_req->dataPkt->dataStatic(inst->split2ndStoreDataPtr);
+ } else {
+ cache_req->dataPkt->dataStatic(&cache_req->inst->storeData);
+ }
+
if (cache_req->memReq->isCondSwap()) {
assert(write_res);
cache_req->memReq->setExtraData(*write_res);
@@ -910,7 +988,6 @@
inst->splitFinishCnt++;
if (inst->splitFinishCnt == 2) {
-
cache_req->memReq->setVirt(0/*inst->tid*/,
inst->getMemAddr(),
inst->splitTotalSize,
@@ -919,7 +996,14 @@
Packet split_pkt(cache_req->memReq, cache_req->pktCmd,
Packet::Broadcast);
- split_pkt.dataStatic(inst->splitMemData);
+
+
+ if (inst->isLoad()) {
+ split_pkt.dataStatic(inst->splitMemData);
+ } else {
+ split_pkt.dataStatic(&inst->storeData);
+ }
+
inst->completeAcc(&split_pkt);
}
} else {
diff -r 88555fd4d220 -r de51ab31b456 src/cpu/inorder/resources/cache_unit.hh
--- a/src/cpu/inorder/resources/cache_unit.hh Sun Jan 31 18:30:35 2010 -0500
+++ b/src/cpu/inorder/resources/cache_unit.hh Sun Jan 31 18:30:43 2010 -0500
@@ -75,7 +75,8 @@
WriteData,
InitSecondSplitRead,
InitSecondSplitWrite,
- CompleteSecondSplitRead
+ CompleteSecondSplitRead,
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev