inorder-mem: skeleton support for prefetch/writehints
This commit is contained in:
@@ -164,14 +164,6 @@ def template MemAccSizeDeclare {{
|
||||
int memAccSize(%(CPU_exec_context)s *xc);
|
||||
}};
|
||||
|
||||
def template MiscMemAccSize {{
|
||||
int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
|
||||
{
|
||||
panic("Misc instruction does not support split access method!");
|
||||
return 0;
|
||||
}
|
||||
}};
|
||||
|
||||
def template LoadStoreMemAccSize {{
|
||||
int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
|
||||
{
|
||||
@@ -451,7 +443,8 @@ def template MiscInitiateAcc {{
|
||||
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
warn("Misc instruction does not support split access method!");
|
||||
warn("initiateAcc undefined: Misc instruction does not support split "
|
||||
"access method!");
|
||||
return NoFault;
|
||||
}
|
||||
}};
|
||||
@@ -462,7 +455,8 @@ def template MiscCompleteAcc {{
|
||||
%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
warn("Misc instruction does not support split access method!");
|
||||
warn("completeAcc undefined: Misc instruction does not support split "
|
||||
"access method!");
|
||||
|
||||
return NoFault;
|
||||
}
|
||||
@@ -471,7 +465,9 @@ def template MiscCompleteAcc {{
|
||||
def template MiscMemAccSize {{
|
||||
int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
|
||||
{
|
||||
panic("Misc instruction does not support split access method!");
|
||||
return (%(mem_acc_size)d / 8);
|
||||
panic("memAccSize undefined: Misc instruction does not support split "
|
||||
"access method!");
|
||||
return 0;
|
||||
}
|
||||
}};
|
||||
|
||||
@@ -452,7 +452,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
|
||||
* Check for alignment faults
|
||||
*/
|
||||
if (req->getVaddr() & (req->getSize() - 1)) {
|
||||
DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(),
|
||||
DPRINTF(TLB, "Alignment Fault on %#x, size = %d\n", req->getVaddr(),
|
||||
req->getSize());
|
||||
uint64_t flags = write ? MM_STAT_WR_MASK : 0;
|
||||
return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);
|
||||
|
||||
@@ -1264,6 +1264,21 @@ InOrderCPU::write(DynInstPtr inst)
|
||||
return mem_res->doDataAccess(inst);
|
||||
}
|
||||
|
||||
void
|
||||
InOrderCPU::prefetch(DynInstPtr inst)
|
||||
{
|
||||
Resource *mem_res = resPool->getResource(dataPortIdx);
|
||||
return mem_res->prefetch(inst);
|
||||
}
|
||||
|
||||
void
|
||||
InOrderCPU::writeHint(DynInstPtr inst)
|
||||
{
|
||||
Resource *mem_res = resPool->getResource(dataPortIdx);
|
||||
return mem_res->writeHint(inst);
|
||||
}
|
||||
|
||||
|
||||
TheISA::TLB*
|
||||
InOrderCPU::getITBPtr()
|
||||
{
|
||||
|
||||
@@ -497,6 +497,16 @@ class InOrderCPU : public BaseCPU
|
||||
*/
|
||||
Fault write(DynInstPtr inst);
|
||||
|
||||
/** Forwards an instruction prefetch to the appropriate data
|
||||
* resource (indexes into Resource Pool thru "dataPortIdx")
|
||||
*/
|
||||
void prefetch(DynInstPtr inst);
|
||||
|
||||
/** Forwards an instruction writeHint to the appropriate data
|
||||
* resource (indexes into Resource Pool thru "dataPortIdx")
|
||||
*/
|
||||
void writeHint(DynInstPtr inst);
|
||||
|
||||
/** Executes a syscall.*/
|
||||
void syscall(int64_t callnum, int tid);
|
||||
|
||||
|
||||
@@ -296,13 +296,13 @@ InOrderDynInst::syscall(int64_t callnum)
|
||||
void
|
||||
InOrderDynInst::prefetch(Addr addr, unsigned flags)
|
||||
{
|
||||
panic("Prefetch Unimplemented\n");
|
||||
cpu->prefetch(this);
|
||||
}
|
||||
|
||||
void
|
||||
InOrderDynInst::writeHint(Addr addr, int size, unsigned flags)
|
||||
{
|
||||
panic("Write-Hint Unimplemented\n");
|
||||
cpu->writeHint(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -143,6 +143,13 @@ class Resource {
|
||||
virtual Fault doDataAccess(DynInstPtr inst)
|
||||
{ panic("doDataAccess undefined for %s", name()); return NoFault; }
|
||||
|
||||
virtual void prefetch(DynInstPtr inst)
|
||||
{ panic("prefetch undefined for %s", name()); }
|
||||
|
||||
virtual void writeHint(DynInstPtr inst)
|
||||
{ panic("doDataAccess undefined for %s", name()); }
|
||||
|
||||
|
||||
/** Squash All Requests After This Seq Num */
|
||||
virtual void squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num, unsigned tid);
|
||||
|
||||
|
||||
@@ -55,35 +55,18 @@ AGENUnit::execute(int slot_num)
|
||||
// Load/Store Instruction
|
||||
if (inst->isMemRef()) {
|
||||
DPRINTF(InOrderAGEN, "[tid:%i] Generating Address for [sn:%i] (%s).\n",
|
||||
tid, inst->seqNum, inst->staticInst->getName());
|
||||
tid, inst->seqNum, inst->staticInst->getName());
|
||||
|
||||
fault = inst->calcEA();
|
||||
inst->setMemAddr(inst->getEA());
|
||||
|
||||
// We are not handdling Prefetches quite yet
|
||||
if (inst->isDataPrefetch() || inst->isInstPrefetch()) {
|
||||
panic("Prefetches arent handled yet.\n");
|
||||
DPRINTF(InOrderAGEN, "[tid:%i] [sn:%i] Effective address calculated to be: "
|
||||
"%#x.\n", tid, inst->seqNum, inst->getEA());
|
||||
|
||||
if (fault == NoFault) {
|
||||
agen_req->done();
|
||||
} else {
|
||||
if (inst->isLoad()) {
|
||||
fault = inst->calcEA();
|
||||
inst->setMemAddr(inst->getEA());
|
||||
//inst->setExecuted();
|
||||
|
||||
DPRINTF(InOrderAGEN, "[tid:%i] [sn:%i] Effective address calculated to be: "
|
||||
"%#x.\n", tid, inst->seqNum, inst->getEA());
|
||||
} else if (inst->isStore()) {
|
||||
fault = inst->calcEA();
|
||||
inst->setMemAddr(inst->getEA());
|
||||
|
||||
DPRINTF(InOrderAGEN, "[tid:%i] [sn:%i] Effective address calculated to be: "
|
||||
"%#x.\n", tid, inst->seqNum, inst->getEA());
|
||||
} else {
|
||||
panic("Unexpected memory type!\n");
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
agen_req->done();
|
||||
} else {
|
||||
fatal("%s encountered @ [sn:%i]",fault->name(), seq_num);
|
||||
}
|
||||
fatal("%s encountered while calculating address for [sn:%i]",fault->name(), seq_num);
|
||||
}
|
||||
} else {
|
||||
DPRINTF(InOrderAGEN, "[tid:] Ignoring non-memory instruction [sn:%i].\n", tid, seq_num);
|
||||
|
||||
@@ -230,11 +230,10 @@ CacheUnit::execute(int slot_num)
|
||||
|
||||
DynInstPtr inst = cache_req->inst;
|
||||
int tid;
|
||||
tid = inst->readTid();
|
||||
int seq_num;
|
||||
seq_num = inst->seqNum;
|
||||
//int stage_num = cache_req->getStageNum();
|
||||
|
||||
tid = inst->readTid();
|
||||
seq_num = inst->seqNum;
|
||||
cache_req->fault = NoFault;
|
||||
|
||||
switch (cache_req->cmd)
|
||||
@@ -304,8 +303,13 @@ CacheUnit::execute(int slot_num)
|
||||
tid, name(), cache_req->inst->getMemAddr());
|
||||
|
||||
inst->setCurResSlot(slot_num);
|
||||
//inst->memAccess();
|
||||
inst->initiateAcc();
|
||||
|
||||
if (inst->isDataPrefetch() || inst->isInstPrefetch()) {
|
||||
inst->execute();
|
||||
} else {
|
||||
inst->initiateAcc();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CompleteReadData:
|
||||
@@ -313,7 +317,10 @@ CacheUnit::execute(int slot_num)
|
||||
DPRINTF(InOrderCachePort,
|
||||
"[tid:%i]: [sn:%i]: Trying to Complete Data Access\n",
|
||||
tid, inst->seqNum);
|
||||
if (cache_req->isMemAccComplete()) {
|
||||
|
||||
if (cache_req->isMemAccComplete() ||
|
||||
inst->isDataPrefetch() ||
|
||||
inst->isInstPrefetch()) {
|
||||
cache_req->done();
|
||||
} else {
|
||||
DPRINTF(InOrderStall, "STALL: [tid:%i]: Data miss from %08p\n",
|
||||
@@ -327,6 +334,45 @@ CacheUnit::execute(int slot_num)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheUnit::prefetch(DynInstPtr inst)
|
||||
{
|
||||
warn_once("Prefetching currently unimplemented");
|
||||
|
||||
CacheReqPtr cache_req
|
||||
= dynamic_cast<CacheReqPtr>(reqMap[inst->getCurResSlot()]);
|
||||
assert(cache_req);
|
||||
|
||||
// Clean-Up cache resource request so
|
||||
// other memory insts. can use them
|
||||
cache_req->setCompleted();
|
||||
cacheStatus = cacheAccessComplete;
|
||||
cacheBlocked = false;
|
||||
cache_req->setMemAccPending(false);
|
||||
cache_req->setMemAccCompleted();
|
||||
inst->unsetMemAddr();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CacheUnit::writeHint(DynInstPtr inst)
|
||||
{
|
||||
warn_once("Write Hints currently unimplemented");
|
||||
|
||||
CacheReqPtr cache_req
|
||||
= dynamic_cast<CacheReqPtr>(reqMap[inst->getCurResSlot()]);
|
||||
assert(cache_req);
|
||||
|
||||
// Clean-Up cache resource request so
|
||||
// other memory insts. can use them
|
||||
cache_req->setCompleted();
|
||||
cacheStatus = cacheAccessComplete;
|
||||
cacheBlocked = false;
|
||||
cache_req->setMemAccPending(false);
|
||||
cache_req->setMemAccCompleted();
|
||||
inst->unsetMemAddr();
|
||||
}
|
||||
|
||||
Fault
|
||||
CacheUnit::doDataAccess(DynInstPtr inst)
|
||||
{
|
||||
|
||||
@@ -172,6 +172,10 @@ class CacheUnit : public Resource
|
||||
*/
|
||||
Fault doDataAccess(DynInstPtr inst);
|
||||
|
||||
void prefetch(DynInstPtr inst);
|
||||
|
||||
void writeHint(DynInstPtr inst);
|
||||
|
||||
uint64_t getMemData(Packet *packet);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -158,8 +158,8 @@ TLBUnit::execute(int slot_idx)
|
||||
|
||||
if (tlb_req->fault != NoFault) {
|
||||
DPRINTF(InOrderTLB, "[tid:%i]: %s encountered while translating "
|
||||
"addr:%08p for [sn:%i].\n", tid, tlb_req->fault->name(),
|
||||
tlb_req->memReq->getVaddr(), seq_num);
|
||||
"addr:%08p for [sn:%i] %s.\n", tid, tlb_req->fault->name(),
|
||||
tlb_req->memReq->getVaddr(), seq_num, inst->instName());
|
||||
//insert(inst);
|
||||
cpu->pipelineStage[stage_num]->setResStall(tlb_req, tid);
|
||||
tlbBlocked[tid] = true;
|
||||
|
||||
@@ -112,6 +112,10 @@ class TLBUnitRequest : public ResourceRequest {
|
||||
flags = inst->getMemFlags();
|
||||
}
|
||||
|
||||
if (req_size == 0 && (inst->isDataPrefetch() || inst->isInstPrefetch())) {
|
||||
req_size = 8;
|
||||
}
|
||||
|
||||
// @TODO: Add Vaddr & Paddr functions
|
||||
inst->memReq = new Request(inst->readTid(), aligned_addr, req_size,
|
||||
flags, inst->readPC(), res->cpu->readCpuId(), inst->readTid());
|
||||
|
||||
Reference in New Issue
Block a user