47#include "debug/Config.hh"
48#include "debug/Drain.hh"
49#include "debug/ExecFaulting.hh"
50#include "debug/HtmCpu.hh"
51#include "debug/Mwait.hh"
52#include "debug/SimpleCPU.hh"
55#include "params/BaseTimingSimpleCPU.hh"
73 cpu->schedule(
this,
t);
101 DPRINTF(Drain,
"No need to drain.\n");
105 DPRINTF(Drain,
"Requesting drain.\n");
124 DPRINTF(SimpleCPU,
"Resume\n");
133 threadInfo[tid]->execContextStats.notIdleFraction = 1;
144 threadInfo[tid]->execContextStats.notIdleFraction = 0;
158 DPRINTF(Drain,
"tryCompleteDrain.\n");
162 DPRINTF(Drain,
"CPU done draining, processing drain event\n");
201 if (!
system->isTimingMode()) {
202 fatal(
"The timing CPU requires the memory system to be in "
210 DPRINTF(SimpleCPU,
"ActivateContext %d\n", thread_num);
214 threadInfo[thread_num]->execContextStats.notIdleFraction = 1;
234 DPRINTF(SimpleCPU,
"SuspendContext %d\n", thread_num);
248 threadInfo[thread_num]->execContextStats.notIdleFraction = 0;
271 if (req->isHTMCmd()) {
272 assert(!req->isLocalAccess());
277 if (pkt->
isRead() && pkt->
req->isLLSC()) {
280 if (req->isLocalAccess()) {
281 Cycles delay = req->localAccessor(thread->
getTC(), pkt);
311 if (is_htm_speculative || req->isHTMAbort()) {
314 if (req->isHTMAbort())
324 bool do_access =
true;
329 }
else if (req->isCondSwap()) {
331 req->setExtraData(*res);
355 assert(!req1->isHTMCmd() && !req2->isHTMCmd());
423 uint8_t *
data,
bool read)
427 assert(!req1->isLocalAccess() && !req2->isLocalAccess());
470 req->setByteEnable(byte_enable);
475 assert(split_addr <=
addr || split_addr -
addr < block_size);
478 if (split_addr >
addr) {
480 assert(!req->isLLSC() && !req->isSwap());
481 req->splitOnVaddr(split_addr, req1, req2);
511 if (req->isLocalAccess()) {
534 uint8_t *newData =
new uint8_t[size];
542 memset(newData, 0, size);
544 memcpy(newData,
data, size);
552 req->setByteEnable(byte_enable);
557 assert(split_addr <=
addr || split_addr -
addr < block_size);
564 if (split_addr >
addr) {
566 assert(!req->isLLSC() && !req->isSwap());
567 req->splitOnVaddr(split_addr, req1, req2);
610 assert(req->hasAtomicOpFunctor());
623 if (split_addr >
addr) {
624 panic(
"AMO requests should not access across a cache line boundary\n");
646 threadInfo[tid]->thread->getIsaPtr()->handleLockedSnoop(pkt,
661 delete [] state->
data;
703 RequestPtr ifetch_req = std::make_shared<Request>();
704 ifetch_req->taskId(
taskId());
705 ifetch_req->setContext(thread->
contextId());
707 DPRINTF(SimpleCPU,
"Translating address %#x\n", ifetch_req->getVaddr());
727 DPRINTF(SimpleCPU,
"Sending fetch for addr %#x(pa: %#x)\n",
728 req->getVaddr(), req->getPaddr());
743 DPRINTF(SimpleCPU,
"Translation of addr %#x faulted\n", req->getVaddr());
767 !std::dynamic_pointer_cast<GenericHtmFailureFault>(fault)) {
768 DPRINTF(HtmCpu,
"fault (%s) occurred - "
769 "replacing with HTM abort fault htmUid=%u\n",
772 Fault tmfault = std::make_shared<GenericHtmFailureFault>(
782 DPRINTF(SimpleCPU,
"Fault occured. Handling the fault\n");
792 DPRINTF(SimpleCPU,
"Scheduling fetch event after the Fault\n");
794 Tick stall = std::dynamic_pointer_cast<SyscallRetryFault>(fault) ?
825 DPRINTF(SimpleCPU,
"Complete ICache Fetch for addr %#x\n", pkt ?
840 pkt->
req->setAccessLatency();
853 DPRINTF(HtmCpu,
"htmTransactionStarts++=%u\n",
913 DPRINTF(SimpleCPU,
"Received fetch response %#x\n", pkt->
getAddr());
919 panic(
"HTM transactional support for"
920 " instruction stream not yet supported\n");
937 assert(
cpu->ifetch_pkt != NULL);
942 cpu->ifetch_pkt = NULL;
952 [[maybe_unused]]
const bool is_htm_speculative =
962 pkt->
req->setAccessLatency();
970 if (pkt->
req->isHTMCmd()) {
971 panic(
"unexpected HTM case");
981 assert(is_htm_speculative);
989 assert(is_htm_speculative);
999 assert(main_send_state);
1007 delete main_send_state;
1026 assert(is_htm_speculative);
1033 DPRINTF(HtmCpu,
"HTM abortion in cache (rc=%s) detected htmUid=%u\n",
1045 fault = std::make_shared<GenericHtmFailureFault>(
1049 fault = std::make_shared<GenericHtmFailureFault>(
1065 DPRINTF(HtmCpu,
"htmTransactionStops++=%u\n",
1095 for (
ThreadID tid = 0; tid <
cpu->numThreads; tid++) {
1096 if (
cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1107 for (
auto &t_info :
cpu->threadInfo) {
1108 t_info->thread->getIsaPtr()->handleLockedSnoop(pkt,
1111 }
else if (pkt->
req && pkt->
req->isTlbiExtSync()) {
1117 cpu->dataRequestorId());
1120 reply_req->setExtraData(pkt->
req->getExtraData());
1125 panic(
"Couldn't send TLBI_EXT_SYNC_COMP message");
1133 for (
ThreadID tid = 0; tid <
cpu->numThreads; tid++) {
1134 if (
cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
1143 DPRINTF(SimpleCPU,
"Received load/store response %#x\n", pkt->
getAddr());
1164 cpu->completeDataAccess(
pkt);
1172 assert(
cpu->dcache_pkt != NULL);
1184 assert(main_send_state);
1191 if (other_index > 0) {
1192 tmp = main_send_state->
fragments[other_index];
1193 cpu->dcache_pkt = tmp;
1194 if ((big_pkt->
isRead() &&
cpu->handleReadPacket(tmp)) ||
1195 (big_pkt->
isWrite() &&
cpu->handleWritePacket())) {
1196 main_send_state->
fragments[other_index] = NULL;
1201 cpu->dcache_pkt = NULL;
1207 cpu->dcache_pkt = NULL;
1215 cpu->schedule(
this,
t);
1221 cpu->completeDataAccess(
pkt);
1227 return "Timing Simple CPU Delay IPR event";
1256 req->setInstCount(t_info.
numInst);
1258 assert(req->isHTMCmd() || req->isTlbiCmd());
1262 uint8_t *
data =
new uint8_t[size];
1264 uint64_t
rc = 0xdeadbeeflu;
1265 memcpy (
data, &
rc, size);
1268 if (req->isHTMCmd()) {
1269 if (req->isHTMStart())
1270 DPRINTF(HtmCpu,
"HTMstart htmUid=%u\n",
1272 else if (req->isHTMCommit())
1273 DPRINTF(HtmCpu,
"HTMcommit htmUid=%u\n",
1275 else if (req->isHTMCancel())
1276 DPRINTF(HtmCpu,
"HTMcancel htmUid=%u\n",
1279 panic(
"initiateMemMgmtCmd: unknown HTM CMD");
1311 req->setInstCount(t_info.
numInst);
1312 req->setHtmAbortCause(cause);
1314 assert(req->isHTMAbort());
1316 uint8_t *
data =
new uint8_t[size];
1319 memcpy (
data, &
rc, size);
RequestorID dataRequestorId() const
Reads this CPU's unique data requestor ID.
Cycles syscallRetryLatency
Tick instCnt
Instruction count used for SPARC misc register.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Addr cacheLineSize() const
Get the cache line size of the system.
AddressMonitor * getCpuAddrMonitor(ThreadID tid)
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
void schedulePowerGatingEvent()
uint32_t taskId() const
Get cpu task id.
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
gem5::BaseCPU::BaseCPUStats baseStats
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
void deschedulePowerGatingEvent()
virtual void switchOut()
Prepare for another CPU to take over execution.
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...
std::vector< ThreadContext * > threadContexts
bool switchedOut() const
Determine if the CPU is switched out.
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
virtual void handleLockedRead(const RequestPtr &req)
virtual bool handleLockedWrite(const RequestPtr &req, Addr cacheBlockMask)
virtual void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode)
BaseSimpleCPU(const BaseSimpleCPUParams ¶ms)
void wakeup(ThreadID tid) override
StaticInstPtr curMacroStaticInst
void checkForInterrupts()
void traceFault()
Handler used when encountering a fault; its purpose is to tear down the InstRecord.
void advancePC(const Fault &fault)
void setupFetchRequest(const RequestPtr &req)
std::list< ThreadID > activeThreads
std::vector< SimpleExecContext * > threadInfo
StaticInstPtr curStaticInst
Current instruction.
trace::InstRecord * traceData
void serviceInstCountEvents()
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
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...
Tick nextCycle() const
Based on the clock of the object, determine the start tick of the first cycle that is at least one cy...
Cycles is a wrapper class for representing cycle counts, i.e.
This class represents part of a data address translation.
Command responseCommand() const
MicroPC microPC() const
Returns the current micropc.
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setHtmTransactionFailedInCache(const HtmCacheFailure ret_code)
Stipulates that this packet/request has returned from the cache hierarchy in a failed transaction.
AddrRange getAddrRange() const
Get address range to which this packet belongs.
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
static PacketPtr createWrite(const RequestPtr &req)
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
SenderState * senderState
This packet's sender state.
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
HtmCacheFailure getHtmTransactionFailedInCacheRC() const
If a 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,...
uint64_t getHtmTransactionUid() const
If a packet/request originates in a CPU executing in transactional mode, i.e.
static PacketPtr createRead(const RequestPtr &req)
Constructor-like methods that return Packets based on Request objects.
RequestPtr req
A pointer to the original request.
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
void setHtmTransactional(uint64_t val)
Stipulates that this packet/request originates in the CPU executing in transactional mode,...
MemCmd cmd
The command field of the packet.
bool isInvalidate() const
bool htmTransactionFailedInCache() const
Returns whether or not this packet/request has returned from the cache hierarchy in a failed transact...
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
static RequestPtr createMemManagement(Flags flags, RequestorID id)
Factory method for creating memory management requests, with unspecified addr and size.
@ STRICT_ORDER
The request is required to be strictly ordered by CPU models and is non-speculative.
@ PHYSICAL
The virtual address is also the physical address.
@ HTM_ABORT
The request aborts a HTM transaction.
@ TLBI_EXT_SYNC_COMP
The Request tells the interconnect that a remote TLB Sync request has completed.
@ NO_ACCESS
The request should not cause a memory access.
static const FlagsType STORE_NO_DATA
gem5::Flags< FlagsType > Flags
Counter numInst
PER-THREAD STATS.
uint64_t newHtmTransactionUid() const override
bool inHtmTransactionalState() const override
uint64_t getHtmTransactionUid() const override
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
int64_t htmTransactionStops
const PCStateBase & pcState() const override
ContextID contextId() const override
int64_t htmTransactionStarts
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
BaseISA * getIsaPtr() const override
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
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...
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
virtual void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
EventFunctionWrapper retryRespEvent
bool tryCompleteDrain()
Try to complete a drain request.
Fault initiateMemMgmtCmd(Request::Flags flags) override
hardware transactional memory & TLBI operations
bool isCpuDrained() const
Check if a system is in a drained state.
void advanceInst(const Fault &fault)
void switchOut() override
Prepare for another CPU to take over execution.
EventFunctionWrapper fetchEvent
DrainState drain() override
Provide a default implementation of the drain interface for objects that don't need draining.
void suspendContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now suspended.
void threadSnoop(PacketPtr pkt, ThreadID sender)
void drainResume() override
Resume execution after a successful drain.
Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >()) override
void htmSendAbortSignal(ThreadID tid, uint64_t htm_uid, HtmFailureFaultCause) override
This function is used to instruct the memory subsystem that a transaction should be aborted and the s...
bool handleReadPacket(PacketPtr pkt)
PacketPtr buildPacket(const RequestPtr &req, bool read)
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
void sendSplitData(const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req, uint8_t *data, bool read)
void translationFault(const Fault &fault)
void sendData(const RequestPtr &req, uint8_t *data, uint64_t *res, bool read)
FetchTranslation fetchTranslation
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
void finishTranslation(WholeTranslationState *state)
Finish a DTB translation.
void activateContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now active.
void completeIfetch(PacketPtr)
TimingSimpleCPU(const BaseTimingSimpleCPUParams ¶ms)
void completeDataAccess(PacketPtr pkt)
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Fault initiateMemAMO(Addr addr, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
void buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2, const RequestPtr &req1, const RequestPtr &req2, const RequestPtr &req, uint8_t *data, bool read)
virtual ~TimingSimpleCPU()
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...
void sendFetch(const Fault &fault, const RequestPtr &req, ThreadContext *tc)
This class captures the state of an address translation.
bool isPrefetch() const
Check if this request is a prefetch.
void deleteReqs()
Delete all requests that make up this translation.
void setNoFault()
Remove all faults from the translation.
Fault getFault() const
Determine whether this translation produced a fault.
std::string to_string() const
Get a string representation of the range.
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
void signalDrainDone() const
Signal that an object is drained.
DrainState drainState() const
Return the current drain state of an object.
DrainState
Object drain/handover states.
@ Draining
Draining buffers pending serialization/handover.
@ Drained
Buffers drained, ready for serialization/handover.
void deschedule(Event &event)
void schedule(Event &event, Tick when)
void reschedule(Event &event, Tick when, bool always=false)
#define panic(...)
This implements a cprintf based panic() function.
#define fatal(...)
This implements a cprintf based fatal() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Copyright (c) 2024 Arm Limited All rights reserved.
std::shared_ptr< FaultBase > Fault
int16_t ThreadID
Thread index/ID type.
std::shared_ptr< Request > RequestPtr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
std::string htmFailureToStr(HtmFailureFaultCause cause)
Convert enum into string to be used for debug purposes.
uint64_t Tick
Tick count type.
static bool isRomMicroPC(MicroPC upc)
constexpr decltype(nullptr) NoFault
Declaration of the Packet class.
virtual const char * description() const
Return a C string describing the event.
IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t)
void schedule(PacketPtr _pkt, Tick t)
const std::string & name()