44 #include "arch/locked_mem.hh" 45 #include "arch/utility.hh" 46 #include "config/the_isa.hh" 48 #include "debug/Config.hh" 49 #include "debug/Drain.hh" 50 #include "debug/ExecFaulting.hh" 51 #include "debug/Mwait.hh" 52 #include "debug/SimpleCPU.hh" 55 #include "params/TimingSimpleCPU.hh" 73 cpu->schedule(
this, t);
78 dcachePort(this), ifetch_pkt(NULL), dcache_pkt(NULL), previousCycle(0),
101 DPRINTF(Drain,
"No need to drain.\n");
105 DPRINTF(Drain,
"Requesting drain.\n");
124 DPRINTF(SimpleCPU,
"Resume\n");
160 DPRINTF(Drain,
"tryCompleteDrain.\n");
164 DPRINTF(Drain,
"CPU done draining, processing drain event\n");
181 assert(thread->microPC() == 0);
200 fatal(
"The timing CPU requires the memory system to be in " 208 DPRINTF(SimpleCPU,
"ActivateContext %d\n", thread_num);
232 DPRINTF(SimpleCPU,
"SuspendContext %d\n", thread_num);
265 if (pkt->
isRead() && pkt->
req->isLLSC()) {
268 if (req->isLocalAccess()) {
269 Cycles delay = req->localAccessor(thread->
getTC(), pkt);
301 bool do_access =
true;
305 }
else if (req->isCondSwap()) {
307 req->setExtraData(*res);
386 uint8_t *
data,
bool read)
390 assert(!req1->isLocalAccess() && !req2->isLocalAccess());
404 pkt2->
dataStatic<uint8_t>(data + req1->getSize());
408 main_send_state->fragments[0] = pkt1;
409 main_send_state->fragments[1] = pkt2;
410 main_send_state->outstanding = 2;
433 if (!byte_enable.empty()) {
434 req->setByteEnable(byte_enable);
440 assert(split_addr <= addr || split_addr - addr < block_size);
443 if (split_addr > addr) {
445 assert(!req->isLLSC() && !req->isSwap());
446 req->splitOnVaddr(split_addr, req1, req2);
476 if (req->isLocalAccess()) {
499 uint8_t *newData =
new uint8_t[size];
507 memset(newData, 0, size);
509 memcpy(newData, data, size);
517 if (!byte_enable.empty()) {
518 req->setByteEnable(byte_enable);
524 assert(split_addr <= addr || split_addr - addr < block_size);
531 if (split_addr > addr) {
533 assert(!req->isLLSC() && !req->isSwap());
534 req->splitOnVaddr(split_addr, req1, req2);
577 assert(req->hasAtomicOpFunctor());
590 if (split_addr > addr) {
591 panic(
"AMO requests should not access across a cache line boundary\n");
628 delete [] state->
data;
671 RequestPtr ifetch_req = std::make_shared<Request>();
672 ifetch_req->taskId(
taskId());
673 ifetch_req->setContext(thread->
contextId());
675 DPRINTF(SimpleCPU,
"Translating address %#x\n", ifetch_req->getVaddr());
693 DPRINTF(SimpleCPU,
"Sending fetch for addr %#x(pa: %#x)\n",
694 req->getVaddr(), req->getPaddr());
696 ifetch_pkt->dataStatic(&
inst);
697 DPRINTF(SimpleCPU,
" -- pkt addr: %#x\n", ifetch_pkt->getAddr());
709 DPRINTF(SimpleCPU,
"Translation of addr %#x faulted\n", req->getVaddr());
729 DPRINTF(SimpleCPU,
"Fault occured. Handling the fault\n");
739 DPRINTF(SimpleCPU,
"Scheduling fetch event after the Fault\n");
770 DPRINTF(SimpleCPU,
"Complete ICache Fetch for addr %#x\n", pkt ?
775 assert(!pkt || !pkt->
isError());
784 pkt->
req->setAccessLatency();
839 cpu->completeIfetch(pkt);
845 DPRINTF(SimpleCPU,
"Received fetch response %#x\n", pkt->
getAddr());
848 assert(!tickEvent.scheduled());
850 tickEvent.schedule(pkt, cpu->clockEdge());
860 assert(cpu->ifetch_pkt != NULL);
863 if (sendTimingReq(tmp)) {
865 cpu->ifetch_pkt = NULL;
878 pkt->
req->setAccessLatency();
893 assert(main_send_state);
901 delete main_send_state;
941 for (
ThreadID tid = 0; tid < cpu->numThreads; tid++) {
942 if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
952 for (
auto &t_info : cpu->threadInfo) {
961 for (
ThreadID tid = 0; tid < cpu->numThreads; tid++) {
962 if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
971 DPRINTF(SimpleCPU,
"Received load/store response %#x\n", pkt->
getAddr());
975 if (!tickEvent.scheduled()) {
977 tickEvent.schedule(pkt, cpu->clockEdge());
983 if (!retryRespEvent.scheduled())
984 cpu->schedule(retryRespEvent, cpu->clockEdge(
Cycles(1)));
992 cpu->completeDataAccess(pkt);
1000 assert(cpu->dcache_pkt != NULL);
1012 assert(main_send_state);
1014 if (sendTimingReq(tmp)) {
1019 if (other_index > 0) {
1020 tmp = main_send_state->
fragments[other_index];
1021 cpu->dcache_pkt = tmp;
1022 if ((big_pkt->
isRead() && cpu->handleReadPacket(tmp)) ||
1023 (big_pkt->
isWrite() && cpu->handleWritePacket())) {
1024 main_send_state->
fragments[other_index] = NULL;
1029 cpu->dcache_pkt = NULL;
1032 }
else if (sendTimingReq(tmp)) {
1035 cpu->dcache_pkt = NULL;
1041 : pkt(_pkt), cpu(_cpu)
1055 return "Timing Simple CPU Delay IPR event";
1071 TimingSimpleCPUParams::create()
StaticInstPtr curStaticInst
uint32_t taskId() const
Get cpu task id.
#define panic(...)
This implements a cprintf based panic() function.
void advancePC(const Fault &fault)
This class represents part of a data address translation.
virtual const char * description() const
Return a C string describing the event.
std::list< ThreadID > activeThreads
decltype(nullptr) constexpr NoFault
Cycles is a wrapper class for representing cycle counts, i.e.
AddressMonitor * getCpuAddrMonitor(ThreadID tid)
#define fatal(...)
This implements a cprintf based fatal() function.
bool isDelayedCommit() const
void switchOut() override
Prepare for another CPU to take over execution.
void schedule(PacketPtr _pkt, Tick t)
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
bool isCpuDrained() const
Check if a system is in a drained state.
Tick instCnt
Instruction count used for SPARC misc register.
virtual Fault completeAcc(Packet *pkt, ExecContext *xc, Trace::InstRecord *traceData) const
void sendData(const RequestPtr &req, uint8_t *data, uint64_t *res, bool read)
std::shared_ptr< Request > RequestPtr
void suspendContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now suspended.
TheISA::MachInst inst
Current instruction.
void deleteReqs()
Delete all requests that make up this translation.
static PacketPtr createWrite(const RequestPtr &req)
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
ContextID contextId() const override
void wakeup(ThreadID tid) override
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
Fault initiateMemAMO(Addr addr, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
TheISA::PCState pcState() const override
virtual Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const =0
bool switchedOut() const
Determine if the CPU is switched out.
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
bool handleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask)
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
void checkForInterrupts()
Overload hash function for BasicBlockRange type.
This class captures the state of an address translation.
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the slave port by calling its corresponding receive function...
void handleLockedRead(XC *xc, const RequestPtr &req)
bool isInvalidate() const
ThreadContext is the external interface to all thread state for anything outside of the CPU...
virtual Fault initiateAcc(ExecContext *xc, Trace::InstRecord *traceData) const
DrainState
Object drain/handover states.
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >()) override
void completeIfetch(PacketPtr)
RequestPtr req
A pointer to the original request.
DrainState drainState() const
Return the current drain state of an object.
void setupFetchRequest(const RequestPtr &req)
std::vector< ThreadContext * > threadContexts
bool tryCompleteDrain()
Try to complete a drain request.
void buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2, const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req, uint8_t *data, bool read)
PacketPtr buildPacket(const RequestPtr &req, bool read)
Draining buffers pending serialization/handover.
bool isPrefetch() const
Check if this request is a prefetch.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
void schedulePowerGatingEvent()
void sendSplitData(const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req, uint8_t *data, bool read)
virtual void takeOverFrom(BaseCPU *cpu)
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
MasterID dataMasterId() const
Reads this CPU's unique data requestor ID.
uint64_t Tick
Tick count type.
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
bool handleReadPacket(PacketPtr pkt)
FetchTranslation fetchTranslation
void translationFault(const Fault &fault)
void takeOverFrom(BaseCPU *oldCPU) override
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
virtual void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode)=0
void setMem(Addr a, Addr s, unsigned f)
void deschedule(Event &event)
Fault writeMem(uint8_t *data, unsigned size, Addr addr, Request::Flags flags, uint64_t *res, const std::vector< bool > &byte_enable=std::vector< bool >()) override
Cycles syscallRetryLatency
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
static const FlagsType STORE_NO_DATA
void schedule(Event &event, Tick when)
T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
void sendFetch(const Fault &fault, const RequestPtr &req, ThreadContext *tc)
Tick nextCycle() const
Based on the clock of the object, determine the start tick of the first cycle that is at least one cy...
void reschedule(Event &event, Tick when, bool always=false)
StaticInstPtr curMacroStaticInst
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
void printAddr(Addr a)
Inject a PrintReq for the given address to print the state of that address throughout the memory syst...
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
virtual void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
static bool isRomMicroPC(MicroPC upc)
void threadSnoop(PacketPtr pkt, ThreadID sender)
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
EventFunctionWrapper fetchEvent
Addr instAddr() const override
bool isFirstMicroop() const
virtual void switchOut()
Prepare for another CPU to take over execution.
void activateContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now active.
Command responseCommand() const
virtual ~TimingSimpleCPU()
bool scheduled() const
Determine if the current event is scheduled.
int16_t ThreadID
Thread index/ID type.
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
virtual const std::string name() const
unsigned int cacheLineSize() const
Get the cache line size of the system.
The request should not cause a memory access.
virtual void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Declaration of the Packet class.
Fault getFault() const
Determine whether this translation produced a fault.
Trace::InstRecord * traceData
void deschedulePowerGatingEvent()
IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t)
SenderState * senderState
This packet's sender state.
MemCmd cmd
The command field of the packet.
void advanceInst(const Fault &fault)
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
std::vector< SimpleExecContext * > threadInfo
void signalDrainDone() const
Signal that an object is drained.
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
void finishTranslation(WholeTranslationState *state)
Finish a DTB translation.
void handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
void completeDataAccess(PacketPtr pkt)
void setNoFault()
Remove all faults from the translation.
DrainState drain() override
Notify an object that it needs to drain its state.
TimingSimpleCPU(TimingSimpleCPUParams *params)
bool isTimingMode() const
Is the system in timing mode?
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
virtual void recvTimingSnoopReq(PacketPtr pkt)
Snoop a coherence request, we need to check if this causes a wakeup event on a cpu that is monitoring...
GenericISA::DelaySlotPCState< MachInst > PCState
std::shared_ptr< FaultBase > Fault
void drainResume() override
Resume execution after a successful drain.
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
ProbePointArg< PacketInfo > Packet
Packet probe point.