// Also make this a parameter, or perhaps get it from xc or cpu.
asid = 0;
- // Initialize the fault to be unimplemented opcode.
-// fault = new UnimplementedOpcodeFault;
+ // Initialize the fault to be NoFault.
fault = NoFault;
++instcount;
outstring = s.str();
}
-#if 0
-template <class Impl>
-Fault
-BaseDynInst<Impl>::mem_access(mem_cmd cmd, Addr addr, void *p, int nbytes)
-{
- Fault fault;
-
- // check alignments, even speculative this test should always pass
- if ((nbytes & nbytes - 1) != 0 || (addr & nbytes - 1) != 0) {
- for (int i = 0; i < nbytes; i++)
- ((char *) p)[i] = 0;
-
- // I added the following because according to the comment above,
- // we should never get here. The comment lies
-#if 0
- panic("unaligned access. Cycle = %n", curTick);
-#endif
- return NoFault;
- }
-
- MemReqPtr req = new MemReq(addr, thread, nbytes);
- switch(cmd) {
- case Read:
- fault = spec_mem->read(req, (uint8_t *)p);
- break;
-
- case Write:
- fault = spec_mem->write(req, (uint8_t *)p);
- if (fault != NoFault)
- break;
-
- specMemWrite = true;
- storeSize = nbytes;
- switch(nbytes) {
- case sizeof(uint8_t):
- *(uint8_t)&storeData = (uint8_t *)p;
- break;
- case sizeof(uint16_t):
- *(uint16_t)&storeData = (uint16_t *)p;
- break;
- case sizeof(uint32_t):
- *(uint32_t)&storeData = (uint32_t *)p;
- break;
- case sizeof(uint64_t):
- *(uint64_t)&storeData = (uint64_t *)p;
- break;
- }
- break;
-
- default:
- fault = genMachineCheckFault();
- break;
- }
-
- trace_mem(fault, cmd, addr, p, nbytes);
-
- return fault;
-}
-
-#endif
-
template <class Impl>
void
BaseDynInst<Impl>::markSrcRegReady()
SimObjectParam<AlphaDTB *> dtb;
#else
SimObjectVectorParam<Process *> workload;
-//SimObjectParam<PageTable *> page_table;
#endif // FULL_SYSTEM
SimObjectParam<MemObject *> mem;
INIT_PARAM(dtb, "Data translation buffer"),
#else
INIT_PARAM(workload, "Processes to run"),
-// INIT_PARAM(page_table, "Page table"),
#endif // FULL_SYSTEM
INIT_PARAM(mem, "Memory"),
params->dtb = dtb;
#else
params->workload = workload;
-// params->pTable = page_table;
#endif // FULL_SYSTEM
params->mem = mem;
Process *process;
#endif // FULL_SYSTEM
- //Page Table
-// PageTable *pTable;
-
MemObject *mem;
BaseCPU *checker;
/** Pointers to all of the threads in the CPU. */
std::vector<Thread *> thread;
-#if 0
- /** Page table pointer. */
- PageTable *pTable;
-#endif
-
/** Pointer to the icache interface. */
MemInterface *icacheInterface;
/** Pointer to the dcache interface. */
typedef TheISA::MachInst MachInst;
typedef TheISA::ExtMachInst ExtMachInst;
+ /** IcachePort class for DefaultFetch. Handles doing the
+ * communication with the cache/memory.
+ */
class IcachePort : public Port
{
protected:
+ /** Pointer to fetch. */
DefaultFetch<Impl> *fetch;
public:
+ /** Default constructor. */
IcachePort(DefaultFetch<Impl> *_fetch)
: Port(_fetch->name() + "-iport"), fetch(_fetch)
{ }
protected:
+ /** Atomic version of receive. Panics. */
virtual Tick recvAtomic(PacketPtr pkt);
+ /** Functional version of receive. Panics. */
virtual void recvFunctional(PacketPtr pkt);
+ /** Receives status change. Other than range changing, panics. */
virtual void recvStatusChange(Status status);
+ /** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
{ resp.clear(); snoop.clear(); }
+ /** Timing version of receive. Handles setting fetch to the
+ * proper status to start fetching. */
virtual bool recvTiming(PacketPtr pkt);
+ /** Handles doing a retry of a failed fetch. */
virtual void recvRetry();
};
/** Sets pointer to time buffer used to communicate to the next stage. */
void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
- /** Sets pointer to page table. */
-// void setPageTable(PageTable *pt_ptr);
-
/** Initialize stage. */
void initStage();
}
private:
+ /** Handles retrying the fetch access. */
void recvRetry();
/** Returns the appropriate thread to fetch, given the fetch policy. */
/** Records if fetch is switched out. */
bool switchedOut;
-#if !FULL_SYSTEM
- /** Page table pointer. */
-// PageTable *pTable;
-#endif
-
// @todo: Consider making these vectors and tracking on a per thread basis.
/** Stat for total number of cycles stalled due to an icache miss. */
Stats::Scalar<> icacheStallCycles;
toDecode = fetchQueue->getWire(0);
}
-#if 0
-template<class Impl>
-void
-DefaultFetch<Impl>::setPageTable(PageTable *pt_ptr)
-{
- DPRINTF(Fetch, "Setting the page table pointer.\n");
-#if !FULL_SYSTEM
- pTable = pt_ptr;
-#endif
-}
-#endif
-
template<class Impl>
void
DefaultFetch<Impl>::initStage()
fetchStatus[tid] = IcacheAccessComplete;
}
-// memcpy(cacheData[tid], memReq[tid]->data, memReq[tid]->size);
-
// Reset the mem req to NULL.
delete pkt->req;
delete pkt;
if (fetchStatus[tid] == IcacheWaitResponse) {
DPRINTF(Fetch, "[tid:%i]: Squashing outstanding Icache miss.\n",
tid);
- // Should I delete this here or when it comes back from the cache?
-// delete memReq[tid];
memReq[tid] = NULL;
}
/** Returns if IEW is switched out. */
bool isSwitchedOut() { return switchedOut; }
- /** Sets page table pointer within LSQ. */
-// void setPageTable(PageTable *pt_ptr);
-
/** Squashes instructions in IEW for a specific thread. */
void squash(unsigned tid);
scoreboard = sb_ptr;
}
-#if 0
-template<class Impl>
-void
-DefaultIEW<Impl>::setPageTable(PageTable *pt_ptr)
-{
- ldstQueue.setPageTable(pt_ptr);
-}
-#endif
-
template <class Impl>
void
DefaultIEW<Impl>::switchOut()
fetchRedirect[tid] = false;
}
-#if 0
- printAvailableInsts();
-#endif
+ // Uncomment this if you want to see all available instructions.
+// printAvailableInsts();
// Execute/writeback any instructions that are available.
int insts_to_execute = fromIssue->size;
DynInstPtr inst = toCommit->insts[inst_num];
int tid = inst->threadNumber;
- DPRINTF(IEW, "Sending instructions to commit, PC %#x.\n",
- inst->readPC());
+ DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %#x.\n",
+ inst->seqNum, inst->readPC());
iewInstsToCommit[tid]++;
int
InstructionQueue<Impl>::countInsts()
{
+#if 0
//ksewell:This works but definitely could use a cleaner write
//with a more intuitive way of counting. Right now it's
//just brute force ....
-
-#if 0
+ // Change the #if if you want to use this method.
int total_insts = 0;
for (int i = 0; i < numThreads; ++i) {
#include "config/full_system.hh"
#include "cpu/inst_seq.hh"
-//#include "cpu/o3/cpu_policy.hh"
#include "cpu/o3/lsq_unit.hh"
#include "mem/port.hh"
-//#include "mem/page_table.hh"
#include "sim/sim_object.hh"
template <class Impl>
void setCPU(FullCPU *cpu_ptr);
/** Sets the IEW stage pointer. */
void setIEW(IEW *iew_ptr);
- /** Sets the page table pointer. */
-// void setPageTable(PageTable *pt_ptr);
/** Switches out the LSQ. */
void switchOut();
/** Takes over execution from another CPU's thread. */
/** The IEW stage pointer. */
IEW *iewStage;
- /** The pointer to the page table. */
-// PageTable *pTable;
-
/** List of Active Threads in System. */
std::list<unsigned> *activeThreads;
}
}
-#if 0
-template<class Impl>
-void
-LSQ<Impl>::setPageTable(PageTable *pt_ptr)
-{
- for (int tid=0; tid < numThreads; tid++) {
- thread[tid].setPageTable(pt_ptr);
- }
-}
-#endif
-
template <class Impl>
void
LSQ<Impl>::switchOut()
#include "cpu/inst_seq.hh"
#include "mem/packet.hh"
#include "mem/port.hh"
-//#include "mem/page_table.hh"
-//#include "sim/debug.hh"
-//#include "sim/sim_object.hh"
/**
* Class that implements the actual LQ and SQ for each specific
void setIEW(IEW *iew_ptr)
{ iewStage = iew_ptr; }
- /** Sets the page table pointer. */
-// void setPageTable(PageTable *pt_ptr);
-
/** Switches out LSQ unit. */
void switchOut();
!isStoreBlocked; }
private:
+ /** Writes back the instruction, sending it to IEW. */
void writeback(DynInstPtr &inst, PacketPtr pkt);
+ /** Handles completing the send of a store to memory. */
void storePostSend(Packet *pkt);
/** Completes the store at the specified index. */
/** Pointer to the IEW stage. */
IEW *iewStage;
+ /** Pointer to memory object. */
MemObject *mem;
+ /** DcachePort class for this LSQ Unit. Handles doing the
+ * communication with the cache/memory.
+ * @todo: Needs to be moved to the LSQ level and have some sort
+ * of arbitration.
+ */
class DcachePort : public Port
{
protected:
+ /** Pointer to CPU. */
FullCPU *cpu;
+ /** Pointer to LSQ. */
LSQUnit *lsq;
public:
+ /** Default constructor. */
DcachePort(FullCPU *_cpu, LSQUnit *_lsq)
: Port(_lsq->name() + "-dport"), cpu(_cpu), lsq(_lsq)
{ }
protected:
+ /** Atomic version of receive. Panics. */
virtual Tick recvAtomic(PacketPtr pkt);
+ /** Functional version of receive. Panics. */
virtual void recvFunctional(PacketPtr pkt);
+ /** Receives status change. Other than range changing, panics. */
virtual void recvStatusChange(Status status);
+ /** Returns the address ranges of this device. */
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
{ resp.clear(); snoop.clear(); }
+ /** Timing version of receive. Handles writing back and
+ * completing the load or store that has returned from
+ * memory. */
virtual bool recvTiming(PacketPtr pkt);
+ /** Handles doing a retry of the previous send. */
virtual void recvRetry();
};
/** Pointer to the D-cache. */
DcachePort *dcachePort;
+ /** Derived class to hold any sender state the LSQ needs. */
class LSQSenderState : public Packet::SenderState
{
public:
+ /** Default constructor. */
LSQSenderState()
: noWB(false)
{ }
-// protected:
+ /** Instruction who initiated the access to memory. */
DynInstPtr inst;
+ /** Whether or not it is a load. */
bool isLoad;
+ /** The LQ/SQ index of the instruction. */
int idx;
+ /** Whether or not the instruction will need to writeback. */
bool noWB;
};
- /** Pointer to the page table. */
-// PageTable *pTable;
-
+ /** Writeback event, specifically for when stores forward data to loads. */
class WritebackEvent : public Event {
public:
/** Constructs a writeback event. */
const char *description();
private:
+ /** Instruction whose results are being written back. */
DynInstPtr inst;
+ /** The packet that would have been sent to memory. */
PacketPtr pkt;
/** The pointer to the LSQ unit that issued the store. */
/** The index of the above store. */
int stallingLoadIdx;
- PacketPtr sendingPkt;
+ /** The packet that needs to be retried. */
+ PacketPtr retryPkt;
+ /** Whehter or not a store is blocked due to the memory system. */
bool isStoreBlocked;
/** Whether or not a load is blocked due to the memory system. */
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);
+ DPRINTF(Activity, "Activity: Writeback event [sn:%lli]\n", inst->seqNum);
//iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum);
storeQueue.clear();
}
-#if 0
-template<class Impl>
-void
-LSQUnit<Impl>::setPageTable(PageTable *pt_ptr)
-{
- DPRINTF(LSQUnit, "Setting the page table pointer.\n");
- pTable = pt_ptr;
-}
-#endif
-
template<class Impl>
void
LSQUnit<Impl>::switchOut()
// Need to handle becoming blocked on a store.
isStoreBlocked = true;
- assert(sendingPkt == NULL);
- sendingPkt = data_pkt;
+ assert(retryPkt == NULL);
+ retryPkt = data_pkt;
} else {
storePostSend(data_pkt);
}
void
LSQUnit<Impl>::recvRetry()
{
- assert(sendingPkt != NULL);
-
if (isStoreBlocked) {
- if (dcachePort->sendTiming(sendingPkt)) {
- storePostSend(sendingPkt);
+ assert(retryPkt != NULL);
+
+ if (dcachePort->sendTiming(retryPkt)) {
+ storePostSend(retryPkt);
sendingPkt = NULL;
isStoreBlocked = false;
} else {
if (renameStatus[tid] == Blocked ||
renameStatus[tid] == Unblocking ||
renameStatus[tid] == SerializeStall) {
-#if 0
- // In syscall emulation, we can have both a block and a squash due
- // to a syscall in the same cycle. This would cause both signals to
- // be high. This shouldn't happen in full system.
- if (toDecode->renameBlock[tid]) {
- toDecode->renameBlock[tid] = 0;
- } else {
- toDecode->renameUnblock[tid] = 1;
- }
-#else
+
toDecode->renameUnblock[tid] = 1;
-#endif
+
serializeInst[tid] = NULL;
}
void setBE(BackEnd *be_ptr)
{ be = be_ptr; }
- /** Sets the page table pointer. */
- void setPageTable(PageTable *pt_ptr);
-
/** Ticks the LSQ unit, which in this case only resets the number of
* used cache ports.
* @todo: Move the number of used ports up to the LSQ level so it can
storeQueue.clear();
}
-template<class Impl>
-void
-OzoneLSQ<Impl>::setPageTable(PageTable *pt_ptr)
-{
- DPRINTF(OzoneLSQ, "Setting the page table pointer.\n");
- pTable = pt_ptr;
-}
-
template<class Impl>
void
OzoneLSQ<Impl>::resizeLQ(unsigned size)