Go to the documentation of this file.
46 #include "config/the_isa.hh"
48 #include "debug/Config.hh"
49 #include "debug/Drain.hh"
50 #include "debug/ExecFaulting.hh"
51 #include "debug/HtmCpu.hh"
52 #include "debug/Mwait.hh"
53 #include "debug/SimpleCPU.hh"
56 #include "params/BaseTimingSimpleCPU.hh"
74 cpu->schedule(
this,
t);
95 deschedulePowerGatingEvent();
102 DPRINTF(Drain,
"No need to drain.\n");
106 DPRINTF(Drain,
"Requesting drain.\n");
125 DPRINTF(SimpleCPU,
"Resume\n");
128 assert(!threadContexts.empty());
132 for (
ThreadID tid = 0; tid < numThreads; tid++) {
134 threadInfo[tid]->execContextStats.notIdleFraction = 1;
145 threadInfo[tid]->execContextStats.notIdleFraction = 0;
150 schedulePowerGatingEvent();
159 DPRINTF(Drain,
"tryCompleteDrain.\n");
163 DPRINTF(Drain,
"CPU done draining, processing drain event\n");
179 BaseSimpleCPU::switchOut();
187 updateCycleCounters(BaseCPU::CPU_STATE_ON);
202 if (!
system->isTimingMode()) {
203 fatal(
"The timing CPU requires the memory system to be in "
211 DPRINTF(SimpleCPU,
"ActivateContext %d\n", thread_num);
213 assert(thread_num < numThreads);
215 threadInfo[thread_num]->execContextStats.notIdleFraction = 1;
228 BaseCPU::activateContext(thread_num);
235 DPRINTF(SimpleCPU,
"SuspendContext %d\n", thread_num);
237 assert(thread_num < numThreads);
249 threadInfo[thread_num]->execContextStats.notIdleFraction = 0;
259 BaseCPU::suspendContext(thread_num);
272 if (req->isHTMCmd()) {
273 assert(!req->isLocalAccess());
278 if (pkt->
isRead() && pkt->
req->isLLSC()) {
281 if (req->isLocalAccess()) {
282 Cycles delay = req->localAccessor(thread->
getTC(), pkt);
283 new IprEvent(pkt,
this, clockEdge(delay));
312 if (is_htm_speculative || req->isHTMAbort()) {
315 if (req->isHTMAbort())
325 bool do_access =
true;
330 }
else if (req->isCondSwap()) {
332 req->setExtraData(*res);
356 assert(!req1->isHTMCmd() && !req2->isHTMCmd());
402 updateCycleCounters(BaseCPU::CPU_STATE_ON);
422 uint8_t *
data,
bool read)
426 assert(!req1->isLocalAccess() && !req2->isLocalAccess());
444 main_send_state->fragments[0] = pkt1;
445 main_send_state->fragments[1] = pkt2;
446 main_send_state->outstanding = 2;
461 unsigned block_size = cacheLineSize();
469 req->setByteEnable(byte_enable);
471 req->taskId(taskId());
474 assert(split_addr <=
addr || split_addr -
addr < block_size);
477 if (split_addr >
addr) {
479 assert(!req->isLLSC() && !req->isSwap());
480 req->splitOnVaddr(split_addr, req1, req2);
510 if (req->isLocalAccess()) {
533 uint8_t *newData =
new uint8_t[size];
535 unsigned block_size = cacheLineSize();
541 memset(newData, 0, size);
543 memcpy(newData,
data, size);
551 req->setByteEnable(byte_enable);
553 req->taskId(taskId());
556 assert(split_addr <=
addr || split_addr -
addr < block_size);
563 if (split_addr >
addr) {
565 assert(!req->isLLSC() && !req->isSwap());
566 req->splitOnVaddr(split_addr, req1, req2);
599 unsigned block_size = cacheLineSize();
609 assert(req->hasAtomicOpFunctor());
611 req->taskId(taskId());
622 if (split_addr >
addr) {
623 panic(
"AMO requests should not access across a cache line boundary\n");
640 for (
ThreadID tid = 0; tid < numThreads; tid++) {
642 if (getCpuAddrMonitor(tid)->doMonitor(pkt)) {
645 threadInfo[tid]->thread->getIsaPtr()->handleLockedSnoop(pkt,
657 if (
state->isPrefetch()) {
660 delete []
state->data;
664 if (!
state->isSplit) {
702 RequestPtr ifetch_req = std::make_shared<Request>();
703 ifetch_req->taskId(taskId());
704 ifetch_req->setContext(thread->
contextId());
706 DPRINTF(SimpleCPU,
"Translating address %#x\n", ifetch_req->getVaddr());
714 updateCycleCounters(BaseCPU::CPU_STATE_ON);
726 DPRINTF(SimpleCPU,
"Sending fetch for addr %#x(pa: %#x)\n",
727 req->getVaddr(), req->getPaddr());
742 DPRINTF(SimpleCPU,
"Translation of addr %#x faulted\n", req->getVaddr());
749 updateCycleCounters(BaseCPU::CPU_STATE_ON);
766 !std::dynamic_pointer_cast<GenericHtmFailureFault>(fault)) {
767 DPRINTF(HtmCpu,
"fault (%s) occurred - "
768 "replacing with HTM abort fault htmUid=%u\n",
771 Fault tmfault = std::make_shared<GenericHtmFailureFault>(
781 DPRINTF(SimpleCPU,
"Fault occured. Handling the fault\n");
791 DPRINTF(SimpleCPU,
"Scheduling fetch event after the Fault\n");
793 Tick stall = std::dynamic_pointer_cast<SyscallRetryFault>(fault) ?
794 clockEdge(syscallRetryLatency) : clockEdge();
824 DPRINTF(SimpleCPU,
"Complete ICache Fetch for addr %#x\n", pkt ?
836 updateCycleCounters(BaseCPU::CPU_STATE_ON);
839 pkt->
req->setAccessLatency();
852 DPRINTF(HtmCpu,
"htmTransactionStarts++=%u\n",
910 DPRINTF(SimpleCPU,
"Received fetch response %#x\n", pkt->
getAddr());
916 panic(
"HTM transactional support for"
917 " instruction stream not yet supported\n");
949 [[maybe_unused]]
const bool is_htm_speculative =
959 pkt->
req->setAccessLatency();
962 updateCycleCounters(BaseCPU::CPU_STATE_ON);
967 if (pkt->
req->isHTMCmd()) {
968 panic(
"unexpected HTM case");
978 assert(is_htm_speculative);
986 assert(is_htm_speculative);
996 assert(main_send_state);
1004 delete main_send_state;
1023 assert(is_htm_speculative);
1030 DPRINTF(HtmCpu,
"HTM abortion in cache (rc=%s) detected htmUid=%u\n",
1042 fault = std::make_shared<GenericHtmFailureFault>(
1046 fault = std::make_shared<GenericHtmFailureFault>(
1062 DPRINTF(HtmCpu,
"htmTransactionStops++=%u\n",
1085 baseStats.numCycles += delta;
1093 for (
ThreadID tid = 0; tid <
cpu->numThreads; tid++) {
1094 if (
cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1106 t_info->thread->getIsaPtr()->handleLockedSnoop(pkt,
1109 }
else if (pkt->
req && pkt->
req->isTlbiExtSync()) {
1115 cpu->dataRequestorId());
1118 reply_req->setExtraData(pkt->
req->getExtraData());
1123 panic(
"Couldn't send TLBI_EXT_SYNC_COMP message");
1131 for (
ThreadID tid = 0; tid <
cpu->numThreads; tid++) {
1132 if (
cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1141 DPRINTF(SimpleCPU,
"Received load/store response %#x\n", pkt->
getAddr());
1182 assert(main_send_state);
1189 if (other_index > 0) {
1190 tmp = main_send_state->
fragments[other_index];
1194 main_send_state->
fragments[other_index] = NULL;
1211 : pkt(_pkt),
cpu(_cpu)
1213 cpu->schedule(
this,
t);
1219 cpu->completeDataAccess(pkt);
1225 return "Timing Simple CPU Delay IPR event";
1253 req->taskId(taskId());
1254 req->setInstCount(t_info.
numInst);
1256 assert(req->isHTMCmd() || req->isTlbiCmd());
1260 uint8_t *
data =
new uint8_t[size];
1262 uint64_t
rc = 0xdeadbeeflu;
1263 memcpy (
data, &
rc, size);
1266 if (req->isHTMCmd()) {
1267 if (req->isHTMStart())
1268 DPRINTF(HtmCpu,
"HTMstart htmUid=%u\n",
1270 else if (req->isHTMCommit())
1271 DPRINTF(HtmCpu,
"HTMcommit htmUid=%u\n",
1273 else if (req->isHTMCancel())
1274 DPRINTF(HtmCpu,
"HTMcancel htmUid=%u\n",
1277 panic(
"initiateMemMgmtCmd: unknown HTM CMD");
1308 req->taskId(taskId());
1309 req->setInstCount(t_info.
numInst);
1310 req->setHtmAbortCause(cause);
1312 assert(req->isHTMAbort());
1314 uint8_t *
data =
new uint8_t[size];
1317 memcpy (
data, &
rc, size);
#define fatal(...)
This implements a cprintf based fatal() function.
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
std::string to_string() const
Get a string representation of the range.
virtual void handleLockedRead(const RequestPtr &req)
constexpr decltype(nullptr) NoFault
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
void htmSendAbortSignal(ThreadID tid, uint64_t htm_uid, HtmFailureFaultCause) override
void sendData(const RequestPtr &req, uint8_t *data, uint64_t *res, bool read)
int64_t htmTransactionStops
std::vector< SimpleExecContext * > threadInfo
void setMem(Addr a, Addr s, unsigned f)
Trace::InstRecord * traceData
EventFunctionWrapper retryRespEvent
static bool isRomMicroPC(MicroPC upc)
DrainState drain() override
RequestPtr req
A pointer to the original request.
Command responseCommand() const
void buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2, const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req, uint8_t *data, bool read)
@ HTM_ABORT
The request aborts a HTM transaction.
@ PHYSICAL
The virtual address is also the physical address.
@ NO_ACCESS
The request should not cause a memory access.
virtual bool handleLockedWrite(const RequestPtr &req, Addr cacheBlockMask)
void setHtmTransactional(uint64_t val)
Stipulates that this packet/request originates in the CPU executing in transactional mode,...
StaticInstPtr curStaticInst
Current instruction.
PacketPtr buildPacket(const RequestPtr &req, bool read)
uint64_t newHtmTransactionUid() const override
void verifyMemoryMode() const override
static PacketPtr createWrite(const RequestPtr &req)
MicroPC microPC() const
Returns the current micropc.
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...
bool isDelayedCommit() const
void sendFetch(const Fault &fault, const RequestPtr &req, ThreadContext *tc)
virtual void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
bool isFirstMicroop() const
int64_t htmTransactionStarts
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
void completeDataAccess(PacketPtr pkt)
static RequestPtr createMemManagement(Flags flags, RequestorID id)
Factory method for creating memory management requests, with unspecified addr and size.
void checkForInterrupts()
virtual Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const =0
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
void takeOverFrom(ThreadContext &ntc, ThreadContext &otc)
Copy state between thread contexts in preparation for CPU handover.
Fault initiateMemMgmtCmd(Request::Flags flags) override
hardware transactional memory & TLBI operations
Cycles is a wrapper class for representing cycle counts, i.e.
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
DrainState
Object drain/handover states.
void switchOut() override
ThreadContext is the external interface to all thread state for anything outside of the CPU.
std::shared_ptr< FaultBase > Fault
This class represents part of a data address translation.
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
bool inHtmTransactionalState() const override
Fault initiateMemAMO(Addr addr, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
EventFunctionWrapper fetchEvent
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
bool htmTransactionFailedInCache() const
Returns whether or not this packet/request has returned from the cache hierarchy in a failed transact...
virtual ~TimingSimpleCPU()
ProbePointArg< PacketInfo > Packet
Packet probe point.
uint64_t Tick
Tick count type.
void setupFetchRequest(const RequestPtr &req)
std::shared_ptr< Request > RequestPtr
uint64_t getHtmTransactionUid() const
If a packet/request originates in a CPU executing in transactional mode, i.e.
void activateContext(ThreadID thread_num) override
IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t)
void completeIfetch(PacketPtr)
std::list< ThreadID > activeThreads
Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >()) override
@ TLBI_EXT_SYNC_COMP
The Request tells the interconnect that a remote TLB Sync request has completed.
void advanceInst(const Fault &fault)
HtmCacheFailure getHtmTransactionFailedInCacheRC() const
If a packet/request has returned from the cache hierarchy in a failed transaction,...
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
void traceFault()
Handler used when encountering a fault; its purpose is to tear down the InstRecord.
Counter numInst
PER-THREAD STATS.
@ Drained
Buffers drained, ready for serialization/handover.
MemCmd cmd
The command field of the packet.
const PCStateBase & pcState() const override
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
void threadSnoop(PacketPtr pkt, ThreadID sender)
SenderState * senderState
This packet's sender state.
const std::string & name()
BaseISA * getIsaPtr() const override
virtual void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode)
virtual void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
ContextID contextId() const override
@ STRICT_ORDER
The request is required to be strictly ordered by CPU models and is non-speculative.
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
static const FlagsType STORE_NO_DATA
void takeOverFrom(BaseCPU *oldCPU) override
void finishTranslation(WholeTranslationState *state)
Finish a DTB translation.
bool tryCompleteDrain()
Try to complete a drain request.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
void drainResume() override
virtual Fault completeAcc(Packet *pkt, ExecContext *xc, Trace::InstRecord *trace_data) const
void translationFault(const Fault &fault)
std::string htmFailureToStr(HtmFailureFaultCause cause)
Convert enum into string to be used for debug purposes.
This class captures the state of an address translation.
virtual Fault initiateAcc(ExecContext *xc, Trace::InstRecord *traceData) const
bool handleReadPacket(PacketPtr pkt)
void suspendContext(ThreadID thread_num) override
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
virtual const char * description() const
Return a C string describing the event.
void serviceInstCountEvents()
void wakeup(ThreadID tid) override
void advancePC(const Fault &fault)
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
const FlagsType init
This Stat is Initialized.
void schedule(PacketPtr _pkt, Tick t)
void setHtmTransactionFailedInCache(const HtmCacheFailure ret_code)
Stipulates that this packet/request has returned from the cache hierarchy in a failed transaction.
bool isHtmTransactional() const
Returns whether or not this packet/request originates in the CPU executing in transactional mode,...
void sendSplitData(const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req, uint8_t *data, bool read)
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
FetchTranslation fetchTranslation
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
AddrRange getAddrRange() const
Get address range to which this packet belongs.
uint64_t getHtmTransactionUid() const override
void printAddr(Addr a)
Inject a PrintReq for the given address to print the state of that address throughout the memory syst...
StaticInstPtr curMacroStaticInst
bool isCpuDrained() const
Check if a system is in a drained state.
@ Draining
Draining buffers pending serialization/handover.
bool scheduled() const
Determine if the current event is scheduled.
int16_t ThreadID
Thread index/ID type.
TimingSimpleCPU(const BaseTimingSimpleCPUParams ¶ms)
bool isInvalidate() const
#define panic(...)
This implements a cprintf based panic() function.
Generated on Wed Jul 13 2022 10:39:17 for gem5 by doxygen 1.8.17