Fixes to get new CPU model working for simple test case. The CPU does not yet support retrying accesses.
src/cpu/base_dyn_inst.cc: Delete the allocated data in destructor. src/cpu/base_dyn_inst.hh: Only copy the addresses if the translation succeeded. src/cpu/o3/alpha_cpu.hh: Return actual translating port. Don't panic on setNextNPC() as it's always called, regardless of the architecture, when the process initializes. src/cpu/o3/alpha_cpu_impl.hh: Pass in memobject to the thread state in SE mode. src/cpu/o3/commit_impl.hh: Initialize all variables. src/cpu/o3/decode_impl.hh: Handle early resolution of branches properly. src/cpu/o3/fetch.hh: Switch structure back to requests. src/cpu/o3/fetch_impl.hh: Initialize all variables, create/delete requests properly. src/cpu/o3/lsq_unit.hh: Include sender state along with the packet. Also include a more generic writeback event that's only used for stores forwarding data to loads. src/cpu/o3/lsq_unit_impl.hh: Redo writeback code to support the response path of the memory system. src/cpu/o3/mem_dep_unit.cc: src/cpu/o3/mem_dep_unit_impl.hh: Wrap variables in #ifdefs. src/cpu/o3/store_set.cc: Include to get panic() function. src/cpu/o3/thread_state.hh: Create with MemObject as well. src/cpu/thread_state.hh: Have a translating port in the thread state object. src/python/m5/objects/AlphaFullCPU.py: Mem parameter no longer needed. --HG-- extra : convert_revision : a99381fb25cb183322882ce20935a6f3d1f2b64d
This commit is contained in:
parent
295c7a908c
commit
090496bf2d
16 changed files with 231 additions and 128 deletions
|
@ -96,12 +96,14 @@ void
|
||||||
BaseDynInst<Impl>::initVars()
|
BaseDynInst<Impl>::initVars()
|
||||||
{
|
{
|
||||||
req = NULL;
|
req = NULL;
|
||||||
|
memData = NULL;
|
||||||
effAddr = 0;
|
effAddr = 0;
|
||||||
physEffAddr = 0;
|
physEffAddr = 0;
|
||||||
storeSize = 0;
|
storeSize = 0;
|
||||||
|
|
||||||
readyRegs = 0;
|
readyRegs = 0;
|
||||||
|
|
||||||
|
// May want to turn this into a bit vector or something.
|
||||||
completed = false;
|
completed = false;
|
||||||
resultReady = false;
|
resultReady = false;
|
||||||
canIssue = false;
|
canIssue = false;
|
||||||
|
@ -161,7 +163,11 @@ template <class Impl>
|
||||||
BaseDynInst<Impl>::~BaseDynInst()
|
BaseDynInst<Impl>::~BaseDynInst()
|
||||||
{
|
{
|
||||||
if (req) {
|
if (req) {
|
||||||
req = NULL;
|
delete req;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memData) {
|
||||||
|
delete [] memData;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (traceData) {
|
if (traceData) {
|
||||||
|
|
|
@ -660,11 +660,11 @@ BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags)
|
||||||
|
|
||||||
fault = cpu->translateDataReadReq(req);
|
fault = cpu->translateDataReadReq(req);
|
||||||
|
|
||||||
|
if (fault == NoFault) {
|
||||||
effAddr = req->getVaddr();
|
effAddr = req->getVaddr();
|
||||||
physEffAddr = req->getPaddr();
|
physEffAddr = req->getPaddr();
|
||||||
memReqFlags = req->getFlags();
|
memReqFlags = req->getFlags();
|
||||||
|
|
||||||
if (fault == NoFault) {
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
if (cpu->system->memctrl->badaddr(physEffAddr)) {
|
if (cpu->system->memctrl->badaddr(physEffAddr)) {
|
||||||
fault = TheISA::genMachineCheckFault();
|
fault = TheISA::genMachineCheckFault();
|
||||||
|
@ -715,11 +715,10 @@ BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
||||||
|
|
||||||
fault = cpu->translateDataWriteReq(req);
|
fault = cpu->translateDataWriteReq(req);
|
||||||
|
|
||||||
|
if (fault == NoFault) {
|
||||||
effAddr = req->getVaddr();
|
effAddr = req->getVaddr();
|
||||||
physEffAddr = req->getPaddr();
|
physEffAddr = req->getPaddr();
|
||||||
memReqFlags = req->getFlags();
|
memReqFlags = req->getFlags();
|
||||||
|
|
||||||
if (fault == NoFault) {
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
if (cpu->system->memctrl->badaddr(physEffAddr)) {
|
if (cpu->system->memctrl->badaddr(physEffAddr)) {
|
||||||
fault = TheISA::genMachineCheckFault();
|
fault = TheISA::genMachineCheckFault();
|
||||||
|
|
|
@ -96,7 +96,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
|
||||||
/** Reads this CPU's ID. */
|
/** Reads this CPU's ID. */
|
||||||
virtual int readCpuId() { return cpu->cpu_id; }
|
virtual int readCpuId() { return cpu->cpu_id; }
|
||||||
|
|
||||||
virtual TranslatingPort *getMemPort() { return /*thread->port*/ NULL; }
|
virtual TranslatingPort *getMemPort() { return thread->port; }
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
/** Returns a pointer to the system. */
|
/** Returns a pointer to the system. */
|
||||||
|
@ -226,7 +226,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setNextNPC(uint64_t val)
|
virtual void setNextNPC(uint64_t val)
|
||||||
{ panic("Alpha has no NextNPC!"); }
|
{ }
|
||||||
|
|
||||||
/** Reads a miscellaneous register. */
|
/** Reads a miscellaneous register. */
|
||||||
virtual MiscReg readMiscReg(int misc_reg)
|
virtual MiscReg readMiscReg(int misc_reg)
|
||||||
|
|
|
@ -73,7 +73,8 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
|
||||||
if (i < params->workload.size()) {
|
if (i < params->workload.size()) {
|
||||||
DPRINTF(FullCPU, "FullCPU: Workload[%i] process is %#x",
|
DPRINTF(FullCPU, "FullCPU: Workload[%i] process is %#x",
|
||||||
i, this->thread[i]);
|
i, this->thread[i]);
|
||||||
this->thread[i] = new Thread(this, i, params->workload[i], i);
|
this->thread[i] = new Thread(this, i, params->workload[i],
|
||||||
|
i, params->mem);
|
||||||
|
|
||||||
this->thread[i]->setStatus(ExecContext::Suspended);
|
this->thread[i]->setStatus(ExecContext::Suspended);
|
||||||
//usedTids[i] = true;
|
//usedTids[i] = true;
|
||||||
|
@ -83,7 +84,7 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
|
||||||
//when scheduling threads to CPU
|
//when scheduling threads to CPU
|
||||||
Process* dummy_proc = NULL;
|
Process* dummy_proc = NULL;
|
||||||
|
|
||||||
this->thread[i] = new Thread(this, i, dummy_proc, i);
|
this->thread[i] = new Thread(this, i, dummy_proc, i, params->mem);
|
||||||
//usedTids[i] = false;
|
//usedTids[i] = false;
|
||||||
}
|
}
|
||||||
#endif // !FULL_SYSTEM
|
#endif // !FULL_SYSTEM
|
||||||
|
|
|
@ -75,6 +75,7 @@ DefaultCommit<Impl>::DefaultCommit(Params *params)
|
||||||
iewWidth(params->executeWidth),
|
iewWidth(params->executeWidth),
|
||||||
commitWidth(params->commitWidth),
|
commitWidth(params->commitWidth),
|
||||||
numThreads(params->numberOfThreads),
|
numThreads(params->numberOfThreads),
|
||||||
|
switchPending(false),
|
||||||
switchedOut(false),
|
switchedOut(false),
|
||||||
trapLatency(params->trapLatency),
|
trapLatency(params->trapLatency),
|
||||||
fetchTrapLatency(params->fetchTrapLatency)
|
fetchTrapLatency(params->fetchTrapLatency)
|
||||||
|
@ -115,6 +116,7 @@ DefaultCommit<Impl>::DefaultCommit(Params *params)
|
||||||
changedROBNumEntries[i] = false;
|
changedROBNumEntries[i] = false;
|
||||||
trapSquash[i] = false;
|
trapSquash[i] = false;
|
||||||
xcSquash[i] = false;
|
xcSquash[i] = false;
|
||||||
|
PC[i] = nextPC[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchFaultTick = 0;
|
fetchFaultTick = 0;
|
||||||
|
|
|
@ -280,7 +280,7 @@ DefaultDecode<Impl>::squash(DynInstPtr &inst, unsigned tid)
|
||||||
toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
|
toFetch->decodeInfo[tid].doneSeqNum = inst->seqNum;
|
||||||
toFetch->decodeInfo[tid].predIncorrect = true;
|
toFetch->decodeInfo[tid].predIncorrect = true;
|
||||||
toFetch->decodeInfo[tid].squash = true;
|
toFetch->decodeInfo[tid].squash = true;
|
||||||
toFetch->decodeInfo[tid].nextPC = inst->readNextPC();
|
toFetch->decodeInfo[tid].nextPC = inst->branchTarget();
|
||||||
toFetch->decodeInfo[tid].branchTaken =
|
toFetch->decodeInfo[tid].branchTaken =
|
||||||
inst->readNextPC() != (inst->readPC() + sizeof(TheISA::MachInst));
|
inst->readNextPC() != (inst->readPC() + sizeof(TheISA::MachInst));
|
||||||
|
|
||||||
|
@ -723,9 +723,8 @@ DefaultDecode<Impl>::decodeInsts(unsigned tid)
|
||||||
// Go ahead and compute any PC-relative branches.
|
// Go ahead and compute any PC-relative branches.
|
||||||
if (inst->isDirectCtrl() && inst->isUncondCtrl()) {
|
if (inst->isDirectCtrl() && inst->isUncondCtrl()) {
|
||||||
++decodeBranchResolved;
|
++decodeBranchResolved;
|
||||||
inst->setNextPC(inst->branchTarget());
|
|
||||||
|
|
||||||
if (inst->mispredicted()) {
|
if (inst->branchTarget() != inst->readPredTarg()) {
|
||||||
++decodeBranchMispred;
|
++decodeBranchMispred;
|
||||||
|
|
||||||
// Might want to set some sort of boolean and just do
|
// Might want to set some sort of boolean and just do
|
||||||
|
|
|
@ -323,8 +323,8 @@ class DefaultFetch
|
||||||
/** Per-thread next PC. */
|
/** Per-thread next PC. */
|
||||||
Addr nextPC[Impl::MaxThreads];
|
Addr nextPC[Impl::MaxThreads];
|
||||||
|
|
||||||
/** Memory packet used to access cache. */
|
/** Memory request used to access cache. */
|
||||||
PacketPtr memPkt[Impl::MaxThreads];
|
RequestPtr memReq[Impl::MaxThreads];
|
||||||
|
|
||||||
/** Variable that tracks if fetch has written to the time buffer this
|
/** Variable that tracks if fetch has written to the time buffer this
|
||||||
* cycle. Used to tell CPU if there is activity this cycle.
|
* cycle. Used to tell CPU if there is activity this cycle.
|
||||||
|
|
|
@ -105,7 +105,8 @@ DefaultFetch<Impl>::IcachePort::recvRetry()
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
DefaultFetch<Impl>::DefaultFetch(Params *params)
|
DefaultFetch<Impl>::DefaultFetch(Params *params)
|
||||||
: branchPred(params),
|
: mem(params->mem),
|
||||||
|
branchPred(params),
|
||||||
decodeToFetchDelay(params->decodeToFetchDelay),
|
decodeToFetchDelay(params->decodeToFetchDelay),
|
||||||
renameToFetchDelay(params->renameToFetchDelay),
|
renameToFetchDelay(params->renameToFetchDelay),
|
||||||
iewToFetchDelay(params->iewToFetchDelay),
|
iewToFetchDelay(params->iewToFetchDelay),
|
||||||
|
@ -113,7 +114,8 @@ DefaultFetch<Impl>::DefaultFetch(Params *params)
|
||||||
fetchWidth(params->fetchWidth),
|
fetchWidth(params->fetchWidth),
|
||||||
numThreads(params->numberOfThreads),
|
numThreads(params->numberOfThreads),
|
||||||
numFetchingThreads(params->smtNumFetchingThreads),
|
numFetchingThreads(params->smtNumFetchingThreads),
|
||||||
interruptPending(false)
|
interruptPending(false),
|
||||||
|
switchedOut(false)
|
||||||
{
|
{
|
||||||
if (numThreads > Impl::MaxThreads)
|
if (numThreads > Impl::MaxThreads)
|
||||||
fatal("numThreads is not a valid value\n");
|
fatal("numThreads is not a valid value\n");
|
||||||
|
@ -161,7 +163,7 @@ DefaultFetch<Impl>::DefaultFetch(Params *params)
|
||||||
|
|
||||||
priorityList.push_back(tid);
|
priorityList.push_back(tid);
|
||||||
|
|
||||||
memPkt[tid] = NULL;
|
memReq[tid] = NULL;
|
||||||
|
|
||||||
// Create space to store a cache line.
|
// Create space to store a cache line.
|
||||||
cacheData[tid] = new uint8_t[cacheBlkSize];
|
cacheData[tid] = new uint8_t[cacheBlkSize];
|
||||||
|
@ -283,6 +285,10 @@ DefaultFetch<Impl>::setCPU(FullCPU *cpu_ptr)
|
||||||
// Name is finally available, so create the port.
|
// Name is finally available, so create the port.
|
||||||
icachePort = new IcachePort(this);
|
icachePort = new IcachePort(this);
|
||||||
|
|
||||||
|
Port *mem_dport = mem->getPort("");
|
||||||
|
icachePort->setPeer(mem_dport);
|
||||||
|
mem_dport->setPeer(icachePort);
|
||||||
|
|
||||||
// Fetch needs to start fetching instructions at the very beginning,
|
// Fetch needs to start fetching instructions at the very beginning,
|
||||||
// so it must start up in active state.
|
// so it must start up in active state.
|
||||||
switchToActive();
|
switchToActive();
|
||||||
|
@ -355,10 +361,12 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
|
||||||
// Only change the status if it's still waiting on the icache access
|
// Only change the status if it's still waiting on the icache access
|
||||||
// to return.
|
// to return.
|
||||||
if (fetchStatus[tid] != IcacheWaitResponse ||
|
if (fetchStatus[tid] != IcacheWaitResponse ||
|
||||||
pkt != memPkt[tid] ||
|
pkt->req != memReq[tid] ||
|
||||||
isSwitchedOut()) {
|
isSwitchedOut()) {
|
||||||
++fetchIcacheSquashes;
|
++fetchIcacheSquashes;
|
||||||
|
delete pkt->req;
|
||||||
delete pkt;
|
delete pkt;
|
||||||
|
memReq[tid] = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,7 +391,7 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
|
||||||
// Reset the mem req to NULL.
|
// Reset the mem req to NULL.
|
||||||
delete pkt->req;
|
delete pkt->req;
|
||||||
delete pkt;
|
delete pkt;
|
||||||
memPkt[tid] = NULL;
|
memReq[tid] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
@ -514,7 +522,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
|
||||||
RequestPtr mem_req = new Request(tid, fetch_PC, cacheBlkSize, flags,
|
RequestPtr mem_req = new Request(tid, fetch_PC, cacheBlkSize, flags,
|
||||||
fetch_PC, cpu->readCpuId(), tid);
|
fetch_PC, cpu->readCpuId(), tid);
|
||||||
|
|
||||||
memPkt[tid] = NULL;
|
memReq[tid] = mem_req;
|
||||||
|
|
||||||
// Translate the instruction request.
|
// Translate the instruction request.
|
||||||
//#if FULL_SYSTEM
|
//#if FULL_SYSTEM
|
||||||
|
@ -565,6 +573,9 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
|
||||||
"response.\n", tid);
|
"response.\n", tid);
|
||||||
|
|
||||||
fetchStatus[tid] = IcacheWaitResponse;
|
fetchStatus[tid] = IcacheWaitResponse;
|
||||||
|
} else {
|
||||||
|
delete mem_req;
|
||||||
|
memReq[tid] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_fault = fault;
|
ret_fault = fault;
|
||||||
|
@ -585,8 +596,9 @@ DefaultFetch<Impl>::doSquash(const Addr &new_PC, unsigned tid)
|
||||||
if (fetchStatus[tid] == IcacheWaitResponse) {
|
if (fetchStatus[tid] == IcacheWaitResponse) {
|
||||||
DPRINTF(Fetch, "[tid:%i]: Squashing outstanding Icache miss.\n",
|
DPRINTF(Fetch, "[tid:%i]: Squashing outstanding Icache miss.\n",
|
||||||
tid);
|
tid);
|
||||||
delete memPkt[tid];
|
// Should I delete this here or when it comes back from the cache?
|
||||||
memPkt[tid] = NULL;
|
// delete memReq[tid];
|
||||||
|
memReq[tid] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchStatus[tid] = Squashing;
|
fetchStatus[tid] = Squashing;
|
||||||
|
@ -1083,7 +1095,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
|
||||||
|
|
||||||
warn("%lli fault (%d) detected @ PC %08p", curTick, fault, PC[tid]);
|
warn("%lli fault (%d) detected @ PC %08p", curTick, fault, PC[tid]);
|
||||||
#else // !FULL_SYSTEM
|
#else // !FULL_SYSTEM
|
||||||
fatal("fault (%d) detected @ PC %08p", fault, PC[tid]);
|
warn("%lli fault (%d) detected @ PC %08p", curTick, fault, PC[tid]);
|
||||||
#endif // FULL_SYSTEM
|
#endif // FULL_SYSTEM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,8 +130,6 @@ class LSQUnit {
|
||||||
|
|
||||||
void completeDataAccess(PacketPtr pkt);
|
void completeDataAccess(PacketPtr pkt);
|
||||||
|
|
||||||
void completeStoreDataAccess(DynInstPtr &inst);
|
|
||||||
|
|
||||||
// @todo: Include stats in the LSQ unit.
|
// @todo: Include stats in the LSQ unit.
|
||||||
//void regStats();
|
//void regStats();
|
||||||
|
|
||||||
|
@ -206,10 +204,12 @@ class LSQUnit {
|
||||||
|
|
||||||
/** Returns if the LSQ unit will writeback on this cycle. */
|
/** Returns if the LSQ unit will writeback on this cycle. */
|
||||||
bool willWB() { return storeQueue[storeWBIdx].canWB &&
|
bool willWB() { return storeQueue[storeWBIdx].canWB &&
|
||||||
!storeQueue[storeWBIdx].completed/* &&
|
!storeQueue[storeWBIdx].completed &&
|
||||||
!dcacheInterface->isBlocked()*/; }
|
!isStoreBlocked; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void writeback(DynInstPtr &inst, PacketPtr pkt);
|
||||||
|
|
||||||
/** Completes the store at the specified index. */
|
/** Completes the store at the specified index. */
|
||||||
void completeStore(int store_idx);
|
void completeStore(int store_idx);
|
||||||
|
|
||||||
|
@ -265,9 +265,43 @@ class LSQUnit {
|
||||||
/** Pointer to the D-cache. */
|
/** Pointer to the D-cache. */
|
||||||
DcachePort *dcachePort;
|
DcachePort *dcachePort;
|
||||||
|
|
||||||
|
class LSQSenderState : public Packet::SenderState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LSQSenderState()
|
||||||
|
: noWB(false)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
// protected:
|
||||||
|
DynInstPtr inst;
|
||||||
|
bool isLoad;
|
||||||
|
int idx;
|
||||||
|
bool noWB;
|
||||||
|
};
|
||||||
|
|
||||||
/** Pointer to the page table. */
|
/** Pointer to the page table. */
|
||||||
// PageTable *pTable;
|
// PageTable *pTable;
|
||||||
|
|
||||||
|
class WritebackEvent : public Event {
|
||||||
|
public:
|
||||||
|
/** Constructs a writeback event. */
|
||||||
|
WritebackEvent(DynInstPtr &_inst, PacketPtr pkt, LSQUnit *lsq_ptr);
|
||||||
|
|
||||||
|
/** Processes the writeback event. */
|
||||||
|
void process();
|
||||||
|
|
||||||
|
/** Returns the description of this event. */
|
||||||
|
const char *description();
|
||||||
|
|
||||||
|
private:
|
||||||
|
DynInstPtr inst;
|
||||||
|
|
||||||
|
PacketPtr pkt;
|
||||||
|
|
||||||
|
/** The pointer to the LSQ unit that issued the store. */
|
||||||
|
LSQUnit<Impl> *lsqPtr;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct SQEntry {
|
struct SQEntry {
|
||||||
/** Constructs an empty store queue entry. */
|
/** Constructs an empty store queue entry. */
|
||||||
|
@ -362,6 +396,8 @@ class LSQUnit {
|
||||||
/** The index of the above store. */
|
/** The index of the above store. */
|
||||||
int stallingLoadIdx;
|
int stallingLoadIdx;
|
||||||
|
|
||||||
|
bool isStoreBlocked;
|
||||||
|
|
||||||
/** Whether or not a load is blocked due to the memory system. */
|
/** Whether or not a load is blocked due to the memory system. */
|
||||||
bool isLoadBlocked;
|
bool isLoadBlocked;
|
||||||
|
|
||||||
|
@ -521,16 +557,17 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
|
||||||
DPRINTF(LSQUnit, "Forwarding from store idx %i to load to "
|
DPRINTF(LSQUnit, "Forwarding from store idx %i to load to "
|
||||||
"addr %#x, data %#x\n",
|
"addr %#x, data %#x\n",
|
||||||
store_idx, req->getVaddr(), *(load_inst->memData));
|
store_idx, req->getVaddr(), *(load_inst->memData));
|
||||||
/*
|
|
||||||
typename LdWritebackEvent *wb =
|
PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
|
||||||
new typename LdWritebackEvent(load_inst,
|
data_pkt->dataStatic(load_inst->memData);
|
||||||
iewStage);
|
|
||||||
|
WritebackEvent *wb = new WritebackEvent(load_inst, data_pkt, this);
|
||||||
|
|
||||||
// We'll say this has a 1 cycle load-store forwarding latency
|
// We'll say this has a 1 cycle load-store forwarding latency
|
||||||
// for now.
|
// for now.
|
||||||
// @todo: Need to make this a parameter.
|
// @todo: Need to make this a parameter.
|
||||||
wb->schedule(curTick);
|
wb->schedule(curTick);
|
||||||
*/
|
|
||||||
// Should keep track of stat for forwarded data
|
// Should keep track of stat for forwarded data
|
||||||
return NoFault;
|
return NoFault;
|
||||||
} else if ((store_has_lower_limit && lower_load_has_store_part) ||
|
} else if ((store_has_lower_limit && lower_load_has_store_part) ||
|
||||||
|
@ -585,6 +622,12 @@ LSQUnit<Impl>::read(Request *req, T &data, int load_idx)
|
||||||
PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
|
PacketPtr data_pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
|
||||||
data_pkt->dataStatic(load_inst->memData);
|
data_pkt->dataStatic(load_inst->memData);
|
||||||
|
|
||||||
|
LSQSenderState *state = new LSQSenderState;
|
||||||
|
state->isLoad = true;
|
||||||
|
state->idx = load_idx;
|
||||||
|
state->inst = load_inst;
|
||||||
|
data_pkt->senderState = state;
|
||||||
|
|
||||||
// if we have a cache, do cache access too
|
// if we have a cache, do cache access too
|
||||||
if (!dcachePort->sendTiming(data_pkt)) {
|
if (!dcachePort->sendTiming(data_pkt)) {
|
||||||
// There's an older load that's already going to squash.
|
// There's an older load that's already going to squash.
|
||||||
|
|
|
@ -32,65 +32,57 @@
|
||||||
#include "mem/request.hh"
|
#include "mem/request.hh"
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
void
|
LSQUnit<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst, PacketPtr _pkt,
|
||||||
LSQUnit<Impl>::completeDataAccess(PacketPtr pkt)
|
LSQUnit *lsq_ptr)
|
||||||
|
: Event(&mainEventQueue), inst(_inst), pkt(_pkt), lsqPtr(lsq_ptr)
|
||||||
{
|
{
|
||||||
/*
|
this->setFlags(Event::AutoDelete);
|
||||||
DPRINTF(IEW, "Load writeback event [sn:%lli]\n", inst->seqNum);
|
|
||||||
DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum);
|
|
||||||
|
|
||||||
//iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum);
|
|
||||||
|
|
||||||
if (iewStage->isSwitchedOut()) {
|
|
||||||
inst = NULL;
|
|
||||||
return;
|
|
||||||
} else if (inst->isSquashed()) {
|
|
||||||
iewStage->wakeCPU();
|
|
||||||
inst = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
iewStage->wakeCPU();
|
|
||||||
|
|
||||||
if (!inst->isExecuted()) {
|
|
||||||
inst->setExecuted();
|
|
||||||
|
|
||||||
// Complete access to copy data to proper place.
|
|
||||||
inst->completeAcc();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need to insert instruction into queue to commit
|
|
||||||
iewStage->instToCommit(inst);
|
|
||||||
|
|
||||||
iewStage->activityThisCycle();
|
|
||||||
|
|
||||||
inst = NULL;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
void
|
void
|
||||||
LSQUnit<Impl>::completeStoreDataAccess(DynInstPtr &inst)
|
LSQUnit<Impl>::WritebackEvent::process()
|
||||||
{
|
{
|
||||||
/*
|
if (!lsqPtr->isSwitchedOut()) {
|
||||||
DPRINTF(LSQ, "Cache miss complete for store idx:%i\n", storeIdx);
|
lsqPtr->writeback(inst, pkt);
|
||||||
DPRINTF(Activity, "Activity: st writeback event idx:%i\n", storeIdx);
|
}
|
||||||
|
delete pkt;
|
||||||
//lsqPtr->removeMSHR(lsqPtr->storeQueue[storeIdx].inst->seqNum);
|
|
||||||
|
|
||||||
if (lsqPtr->isSwitchedOut()) {
|
|
||||||
if (wbEvent)
|
|
||||||
delete wbEvent;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lsqPtr->cpu->wakeCPU();
|
template<class Impl>
|
||||||
|
const char *
|
||||||
|
LSQUnit<Impl>::WritebackEvent::description()
|
||||||
|
{
|
||||||
|
return "Store writeback event";
|
||||||
|
}
|
||||||
|
|
||||||
if (wb)
|
template<class Impl>
|
||||||
lsqPtr->completeDataAccess(storeIdx);
|
void
|
||||||
lsqPtr->completeStore(storeIdx);
|
LSQUnit<Impl>::completeDataAccess(PacketPtr pkt)
|
||||||
*/
|
{
|
||||||
|
LSQSenderState *state = dynamic_cast<LSQSenderState *>(pkt->senderState);
|
||||||
|
DynInstPtr inst = state->inst;
|
||||||
|
DPRINTF(IEW, "Writeback event [sn:%lli]\n", inst->seqNum);
|
||||||
|
// DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum);
|
||||||
|
|
||||||
|
//iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum);
|
||||||
|
|
||||||
|
if (isSwitchedOut() || inst->isSquashed()) {
|
||||||
|
delete state;
|
||||||
|
delete pkt;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (!state->noWB) {
|
||||||
|
writeback(inst, pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->isStore()) {
|
||||||
|
completeStore(state->idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete state;
|
||||||
|
delete pkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
@ -146,7 +138,8 @@ LSQUnit<Impl>::DcachePort::recvRetry()
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
LSQUnit<Impl>::LSQUnit()
|
LSQUnit<Impl>::LSQUnit()
|
||||||
: loads(0), stores(0), storesToWB(0), stalled(false), isLoadBlocked(false),
|
: loads(0), stores(0), storesToWB(0), stalled(false),
|
||||||
|
isStoreBlocked(false), isLoadBlocked(false),
|
||||||
loadBlockedHandled(false)
|
loadBlockedHandled(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -176,9 +169,7 @@ LSQUnit<Impl>::init(Params *params, unsigned maxLQEntries,
|
||||||
usedPorts = 0;
|
usedPorts = 0;
|
||||||
cachePorts = params->cachePorts;
|
cachePorts = params->cachePorts;
|
||||||
|
|
||||||
Port *mem_dport = params->mem->getPort("");
|
mem = params->mem;
|
||||||
dcachePort->setPeer(mem_dport);
|
|
||||||
mem_dport->setPeer(dcachePort);
|
|
||||||
|
|
||||||
memDepViolator = NULL;
|
memDepViolator = NULL;
|
||||||
|
|
||||||
|
@ -191,6 +182,10 @@ LSQUnit<Impl>::setCPU(FullCPU *cpu_ptr)
|
||||||
{
|
{
|
||||||
cpu = cpu_ptr;
|
cpu = cpu_ptr;
|
||||||
dcachePort = new DcachePort(cpu, this);
|
dcachePort = new DcachePort(cpu, this);
|
||||||
|
|
||||||
|
Port *mem_dport = mem->getPort("");
|
||||||
|
dcachePort->setPeer(mem_dport);
|
||||||
|
mem_dport->setPeer(dcachePort);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Impl>
|
template<class Impl>
|
||||||
|
@ -446,7 +441,6 @@ LSQUnit<Impl>::executeStore(DynInstPtr &store_inst)
|
||||||
int load_idx = store_inst->lqIdx;
|
int load_idx = store_inst->lqIdx;
|
||||||
|
|
||||||
Fault store_fault = store_inst->initiateAcc();
|
Fault store_fault = store_inst->initiateAcc();
|
||||||
// Fault store_fault = store_inst->execute();
|
|
||||||
|
|
||||||
if (storeQueue[store_idx].size == 0) {
|
if (storeQueue[store_idx].size == 0) {
|
||||||
DPRINTF(LSQUnit,"Fault on Store PC %#x, [sn:%lli],Size = 0\n",
|
DPRINTF(LSQUnit,"Fault on Store PC %#x, [sn:%lli],Size = 0\n",
|
||||||
|
@ -562,6 +556,12 @@ LSQUnit<Impl>::writebackStores()
|
||||||
storeQueue[storeWBIdx].canWB &&
|
storeQueue[storeWBIdx].canWB &&
|
||||||
usedPorts < cachePorts) {
|
usedPorts < cachePorts) {
|
||||||
|
|
||||||
|
if (isStoreBlocked) {
|
||||||
|
DPRINTF(LSQUnit, "Unable to write back any more stores, cache"
|
||||||
|
" is blocked!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Store didn't write any data so no need to write it back to
|
// Store didn't write any data so no need to write it back to
|
||||||
// memory.
|
// memory.
|
||||||
if (storeQueue[storeWBIdx].size == 0) {
|
if (storeQueue[storeWBIdx].size == 0) {
|
||||||
|
@ -571,13 +571,7 @@ LSQUnit<Impl>::writebackStores()
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (dcacheInterface && dcacheInterface->isBlocked()) {
|
|
||||||
DPRINTF(LSQUnit, "Unable to write back any more stores, cache"
|
|
||||||
" is blocked!\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
++usedPorts;
|
++usedPorts;
|
||||||
|
|
||||||
if (storeQueue[storeWBIdx].inst->isDataPrefetch()) {
|
if (storeQueue[storeWBIdx].inst->isDataPrefetch()) {
|
||||||
|
@ -596,11 +590,18 @@ LSQUnit<Impl>::writebackStores()
|
||||||
|
|
||||||
assert(!inst->memData);
|
assert(!inst->memData);
|
||||||
inst->memData = new uint8_t[64];
|
inst->memData = new uint8_t[64];
|
||||||
memcpy(inst->memData, (uint8_t *)&storeQueue[storeWBIdx].data, req->getSize());
|
memcpy(inst->memData, (uint8_t *)&storeQueue[storeWBIdx].data,
|
||||||
|
req->getSize());
|
||||||
|
|
||||||
PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
|
PacketPtr data_pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
|
||||||
data_pkt->dataStatic(inst->memData);
|
data_pkt->dataStatic(inst->memData);
|
||||||
|
|
||||||
|
LSQSenderState *state = new LSQSenderState;
|
||||||
|
state->isLoad = false;
|
||||||
|
state->idx = storeWBIdx;
|
||||||
|
state->inst = inst;
|
||||||
|
data_pkt->senderState = state;
|
||||||
|
|
||||||
DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x "
|
DPRINTF(LSQUnit, "D-Cache: Writing back store idx:%i PC:%#x "
|
||||||
"to Addr:%#x, data:%#x [sn:%lli]\n",
|
"to Addr:%#x, data:%#x [sn:%lli]\n",
|
||||||
storeWBIdx, storeQueue[storeWBIdx].inst->readPC(),
|
storeWBIdx, storeQueue[storeWBIdx].inst->readPC(),
|
||||||
|
@ -609,11 +610,8 @@ LSQUnit<Impl>::writebackStores()
|
||||||
|
|
||||||
if (!dcachePort->sendTiming(data_pkt)) {
|
if (!dcachePort->sendTiming(data_pkt)) {
|
||||||
// Need to handle becoming blocked on a store.
|
// Need to handle becoming blocked on a store.
|
||||||
|
isStoreBlocked = true;
|
||||||
} else {
|
} else {
|
||||||
/*
|
|
||||||
StoreCompletionEvent *store_event = new
|
|
||||||
StoreCompletionEvent(storeWBIdx, NULL, this);
|
|
||||||
*/
|
|
||||||
if (isStalled() &&
|
if (isStalled() &&
|
||||||
storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) {
|
storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) {
|
||||||
DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] "
|
DPRINTF(LSQUnit, "Unstalling, stalling store [sn:%lli] "
|
||||||
|
@ -623,18 +621,13 @@ LSQUnit<Impl>::writebackStores()
|
||||||
stallingStoreIsn = 0;
|
stallingStoreIsn = 0;
|
||||||
iewStage->replayMemInst(loadQueue[stallingLoadIdx]);
|
iewStage->replayMemInst(loadQueue[stallingLoadIdx]);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
typename LdWritebackEvent *wb = NULL;
|
if (!(req->getFlags() & LOCKED)) {
|
||||||
if (req->flags & LOCKED) {
|
assert(!storeQueue[storeWBIdx].inst->isStoreConditional());
|
||||||
// Stx_C should not generate a system port transaction
|
// Non-store conditionals do not need a writeback.
|
||||||
// if it misses in the cache, but that might be hard
|
state->noWB = true;
|
||||||
// to accomplish without explicit cache support.
|
|
||||||
wb = new typename
|
|
||||||
LdWritebackEvent(storeQueue[storeWBIdx].inst,
|
|
||||||
iewStage);
|
|
||||||
store_event->wbEvent = wb;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
if (data_pkt->result != Packet::Success) {
|
if (data_pkt->result != Packet::Success) {
|
||||||
DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n",
|
DPRINTF(LSQUnit,"D-Cache Write Miss on idx:%i!\n",
|
||||||
storeWBIdx);
|
storeWBIdx);
|
||||||
|
@ -759,6 +752,31 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Impl>
|
||||||
|
void
|
||||||
|
LSQUnit<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt)
|
||||||
|
{
|
||||||
|
iewStage->wakeCPU();
|
||||||
|
|
||||||
|
// Squashed instructions do not need to complete their access.
|
||||||
|
if (inst->isSquashed()) {
|
||||||
|
assert(!inst->isStore());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inst->isExecuted()) {
|
||||||
|
inst->setExecuted();
|
||||||
|
|
||||||
|
// Complete access to copy data to proper place.
|
||||||
|
inst->completeAcc(pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to insert instruction into queue to commit
|
||||||
|
iewStage->instToCommit(inst);
|
||||||
|
|
||||||
|
iewStage->activityThisCycle();
|
||||||
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
LSQUnit<Impl>::completeStore(int store_idx)
|
LSQUnit<Impl>::completeStore(int store_idx)
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
// AlphaSimpleImpl.
|
// AlphaSimpleImpl.
|
||||||
template class MemDepUnit<StoreSet, AlphaSimpleImpl>;
|
template class MemDepUnit<StoreSet, AlphaSimpleImpl>;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
template <>
|
template <>
|
||||||
int
|
int
|
||||||
MemDepUnit<StoreSet, AlphaSimpleImpl>::MemDepEntry::memdep_count = 0;
|
MemDepUnit<StoreSet, AlphaSimpleImpl>::MemDepEntry::memdep_count = 0;
|
||||||
|
@ -46,3 +47,4 @@ MemDepUnit<StoreSet, AlphaSimpleImpl>::MemDepEntry::memdep_insert = 0;
|
||||||
template <>
|
template <>
|
||||||
int
|
int
|
||||||
MemDepUnit<StoreSet, AlphaSimpleImpl>::MemDepEntry::memdep_erase = 0;
|
MemDepUnit<StoreSet, AlphaSimpleImpl>::MemDepEntry::memdep_erase = 0;
|
||||||
|
#endif
|
||||||
|
|
|
@ -61,7 +61,9 @@ MemDepUnit<MemDepPred, Impl>::~MemDepUnit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
assert(MemDepEntry::memdep_count == 0);
|
assert(MemDepEntry::memdep_count == 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class MemDepPred, class Impl>
|
template <class MemDepPred, class Impl>
|
||||||
|
@ -143,7 +145,9 @@ MemDepUnit<MemDepPred, Impl>::insert(DynInstPtr &inst)
|
||||||
// Add the MemDepEntry to the hash.
|
// Add the MemDepEntry to the hash.
|
||||||
memDepHash.insert(
|
memDepHash.insert(
|
||||||
std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry));
|
std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry));
|
||||||
|
#ifdef DEBUG
|
||||||
MemDepEntry::memdep_insert++;
|
MemDepEntry::memdep_insert++;
|
||||||
|
#endif
|
||||||
|
|
||||||
instList[tid].push_back(inst);
|
instList[tid].push_back(inst);
|
||||||
|
|
||||||
|
@ -229,7 +233,9 @@ MemDepUnit<MemDepPred, Impl>::insertNonSpec(DynInstPtr &inst)
|
||||||
// Insert the MemDepEntry into the hash.
|
// Insert the MemDepEntry into the hash.
|
||||||
memDepHash.insert(
|
memDepHash.insert(
|
||||||
std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry));
|
std::pair<InstSeqNum, MemDepEntryPtr>(inst->seqNum, inst_entry));
|
||||||
|
#ifdef DEBUG
|
||||||
MemDepEntry::memdep_insert++;
|
MemDepEntry::memdep_insert++;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Add the instruction to the list.
|
// Add the instruction to the list.
|
||||||
instList[tid].push_back(inst);
|
instList[tid].push_back(inst);
|
||||||
|
@ -277,7 +283,9 @@ MemDepUnit<MemDepPred, Impl>::insertBarrier(DynInstPtr &barr_inst)
|
||||||
// Add the MemDepEntry to the hash.
|
// Add the MemDepEntry to the hash.
|
||||||
memDepHash.insert(
|
memDepHash.insert(
|
||||||
std::pair<InstSeqNum, MemDepEntryPtr>(barr_sn, inst_entry));
|
std::pair<InstSeqNum, MemDepEntryPtr>(barr_sn, inst_entry));
|
||||||
|
#ifdef DEBUG
|
||||||
MemDepEntry::memdep_insert++;
|
MemDepEntry::memdep_insert++;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Add the instruction to the instruction list.
|
// Add the instruction to the instruction list.
|
||||||
instList[tid].push_back(barr_inst);
|
instList[tid].push_back(barr_inst);
|
||||||
|
@ -377,7 +385,9 @@ MemDepUnit<MemDepPred, Impl>::completed(DynInstPtr &inst)
|
||||||
(*hash_it).second = NULL;
|
(*hash_it).second = NULL;
|
||||||
|
|
||||||
memDepHash.erase(hash_it);
|
memDepHash.erase(hash_it);
|
||||||
|
#ifdef DEBUG
|
||||||
MemDepEntry::memdep_erase++;
|
MemDepEntry::memdep_erase++;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class MemDepPred, class Impl>
|
template <class MemDepPred, class Impl>
|
||||||
|
@ -472,7 +482,9 @@ MemDepUnit<MemDepPred, Impl>::squash(const InstSeqNum &squashed_num,
|
||||||
(*hash_it).second = NULL;
|
(*hash_it).second = NULL;
|
||||||
|
|
||||||
memDepHash.erase(hash_it);
|
memDepHash.erase(hash_it);
|
||||||
|
#ifdef DEBUG
|
||||||
MemDepEntry::memdep_erase++;
|
MemDepEntry::memdep_erase++;
|
||||||
|
#endif
|
||||||
|
|
||||||
instList[tid].erase(squash_it--);
|
instList[tid].erase(squash_it--);
|
||||||
}
|
}
|
||||||
|
@ -553,5 +565,7 @@ MemDepUnit<MemDepPred, Impl>::dumpLists()
|
||||||
|
|
||||||
cprintf("Memory dependence hash size: %i\n", memDepHash.size());
|
cprintf("Memory dependence hash size: %i\n", memDepHash.size());
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
cprintf("Memory dependence entries: %i\n", MemDepEntry::memdep_count);
|
cprintf("Memory dependence entries: %i\n", MemDepEntry::memdep_count);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "base/intmath.hh"
|
#include "base/intmath.hh"
|
||||||
|
#include "base/misc.hh"
|
||||||
#include "base/trace.hh"
|
#include "base/trace.hh"
|
||||||
#include "cpu/o3/store_set.hh"
|
#include "cpu/o3/store_set.hh"
|
||||||
|
|
||||||
|
|
|
@ -86,14 +86,9 @@ struct O3ThreadState : public ThreadState {
|
||||||
inSyscall(0), trapPending(0)
|
inSyscall(0), trapPending(0)
|
||||||
{ }
|
{ }
|
||||||
#else
|
#else
|
||||||
O3ThreadState(FullCPU *_cpu, int _thread_num, Process *_process, int _asid)
|
O3ThreadState(FullCPU *_cpu, int _thread_num, Process *_process, int _asid,
|
||||||
: ThreadState(-1, _thread_num, NULL, _process, _asid),
|
MemObject *mem)
|
||||||
cpu(_cpu), inSyscall(0), trapPending(0)
|
: ThreadState(-1, _thread_num, mem, _process, _asid),
|
||||||
{ }
|
|
||||||
|
|
||||||
O3ThreadState(FullCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
|
|
||||||
int _asid)
|
|
||||||
: ThreadState(-1, _thread_num, _mem, NULL, _asid),
|
|
||||||
cpu(_cpu), inSyscall(0), trapPending(0)
|
cpu(_cpu), inSyscall(0), trapPending(0)
|
||||||
{ }
|
{ }
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,6 +31,10 @@
|
||||||
|
|
||||||
#include "cpu/exec_context.hh"
|
#include "cpu/exec_context.hh"
|
||||||
|
|
||||||
|
#if !FULL_SYSTEM
|
||||||
|
#include "mem/translating_port.hh"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
class EndQuiesceEvent;
|
class EndQuiesceEvent;
|
||||||
class FunctionProfile;
|
class FunctionProfile;
|
||||||
|
@ -51,17 +55,27 @@ class Process;
|
||||||
*/
|
*/
|
||||||
struct ThreadState {
|
struct ThreadState {
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
ThreadState(int _cpuId, int _tid, FunctionalMemory *_mem)
|
ThreadState(int _cpuId, int _tid)
|
||||||
: cpuId(_cpuId), tid(_tid), mem(_mem), lastActivate(0), lastSuspend(0),
|
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
|
||||||
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL)
|
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL)
|
||||||
#else
|
#else
|
||||||
ThreadState(int _cpuId, int _tid, FunctionalMemory *_mem,
|
ThreadState(int _cpuId, int _tid, MemObject *mem,
|
||||||
Process *_process, short _asid)
|
Process *_process, short _asid)
|
||||||
: cpuId(_cpuId), tid(_tid), mem(_mem), process(_process), asid(_asid)
|
: cpuId(_cpuId), tid(_tid), process(_process), asid(_asid)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
funcExeInst = 0;
|
funcExeInst = 0;
|
||||||
storeCondFailures = 0;
|
storeCondFailures = 0;
|
||||||
|
#if !FULL_SYSTEM
|
||||||
|
/* Use this port to for syscall emulation writes to memory. */
|
||||||
|
Port *mem_port;
|
||||||
|
port = new TranslatingPort(csprintf("%d-funcport",
|
||||||
|
tid),
|
||||||
|
process->pTable, false);
|
||||||
|
mem_port = mem->getPort("functional");
|
||||||
|
mem_port->setPeer(port);
|
||||||
|
port->setPeer(mem_port);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecContext::Status status;
|
ExecContext::Status status;
|
||||||
|
@ -79,8 +93,6 @@ struct ThreadState {
|
||||||
Counter numLoad;
|
Counter numLoad;
|
||||||
Counter startNumLoad;
|
Counter startNumLoad;
|
||||||
|
|
||||||
FunctionalMemory *mem; // functional storage for process address space
|
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
Tick lastActivate;
|
Tick lastActivate;
|
||||||
Tick lastSuspend;
|
Tick lastSuspend;
|
||||||
|
@ -93,6 +105,8 @@ struct ThreadState {
|
||||||
|
|
||||||
Kernel::Statistics *kernelStats;
|
Kernel::Statistics *kernelStats;
|
||||||
#else
|
#else
|
||||||
|
TranslatingPort *port;
|
||||||
|
|
||||||
Process *process;
|
Process *process;
|
||||||
|
|
||||||
// Address space ID. Note that this is used for TIMING cache
|
// Address space ID. Note that this is used for TIMING cache
|
||||||
|
|
|
@ -6,9 +6,6 @@ class DerivAlphaFullCPU(BaseCPU):
|
||||||
activity = Param.Unsigned("Initial count")
|
activity = Param.Unsigned("Initial count")
|
||||||
numThreads = Param.Unsigned("number of HW thread contexts")
|
numThreads = Param.Unsigned("number of HW thread contexts")
|
||||||
|
|
||||||
if not build_env['FULL_SYSTEM']:
|
|
||||||
mem = Param.FunctionalMemory(NULL, "memory")
|
|
||||||
|
|
||||||
checker = Param.BaseCPU(NULL, "checker")
|
checker = Param.BaseCPU(NULL, "checker")
|
||||||
|
|
||||||
cachePorts = Param.Unsigned("Cache Ports")
|
cachePorts = Param.Unsigned("Cache Ports")
|
||||||
|
|
Loading…
Reference in a new issue