48#include "debug/Drain.hh"
49#include "debug/ExecFaulting.hh"
50#include "debug/SimpleCPU.hh"
54#include "params/BaseAtomicSimpleCPU.hh"
76 tickEvent([this]{
tick(); },
"AtomicSimpleCPU tick",
78 width(
p.width), locked(
false),
79 simulate_data_stalls(
p.simulate_data_stalls),
80 simulate_inst_stalls(
p.simulate_inst_stalls),
81 icachePort(
name() +
".icache_port"),
82 dcachePort(
name() +
".dcache_port",
this),
83 dcache_access(
false), dcache_latency(0),
87 ifetch_req = std::make_shared<Request>();
88 data_read_req = std::make_shared<Request>();
89 data_write_req = std::make_shared<Request>();
90 data_amo_req = std::make_shared<Request>();
111 DPRINTF(Drain,
"Requesting drain.\n");
118 DPRINTF(Drain,
"Not executing microcode, no need to drain.\n");
126 DPRINTF(SimpleCPU,
"%s received snoop pkt for addr:%#x %s\n",
135 threadInfo[tid]->thread->getIsaPtr()->handleLockedSnoop(pkt,
148 DPRINTF(SimpleCPU,
"Resume\n");
157 threadInfo[tid]->execContextStats.notIdleFraction = 1;
166 threadInfo[tid]->execContextStats.notIdleFraction = 0;
180 DPRINTF(Drain,
"tryCompleteDrain.\n");
184 DPRINTF(Drain,
"CPU done draining, processing drain event\n");
215 "The atomic CPU requires the memory system to be in "
222 DPRINTF(SimpleCPU,
"ActivateContext %d\n", thread_num);
226 threadInfo[thread_num]->execContextStats.notIdleFraction = 1;
248 DPRINTF(SimpleCPU,
"SuspendContext %d\n", thread_num);
258 threadInfo[thread_num]->execContextStats.notIdleFraction = 0;
280 DPRINTF(SimpleCPU,
"%s received atomic snoop pkt for addr:%#x %s\n",
295 DPRINTF(SimpleCPU,
"received invalidation for addr:%#x\n",
298 t_info->thread->getIsaPtr()->handleLockedSnoop(pkt,
309 DPRINTF(SimpleCPU,
"%s received functional snoop pkt for addr:%#x %s\n",
313 for (
ThreadID tid = 0; tid < cpu->numThreads; tid++) {
314 if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
321 DPRINTF(SimpleCPU,
"received invalidation for addr:%#x\n",
323 for (
auto &t_info : cpu->threadInfo) {
324 t_info->thread->getIsaPtr()->handleLockedSnoop(pkt,
334 int &frag_size,
int &size_left)
const
336 bool predicate =
true;
339 frag_size = std::min(
342 size_left -= frag_size;
345 auto it_start = byte_enable.begin() + (size - (frag_size + size_left));
346 auto it_end = byte_enable.begin() + (size - size_left);
378 int size_left = size;
384 byte_enable, frag_size, size_left);
393 if (predicate && fault ==
NoFault &&
398 if (req->isLocalAccess()) {
415 return req->isPrefetch() ?
NoFault : fault;
418 if (size_left == 0) {
419 if (req->isLockedRMW() && fault ==
NoFault) {
429 frag_addr += frag_size;
443 static uint8_t zero_array[64] = {};
464 int size_left = size;
465 [[maybe_unused]]
int curr_frag_id = 0;
471 byte_enable, frag_size, size_left);
479 if (predicate && fault ==
NoFault) {
480 bool do_access =
true;
483 assert(curr_frag_id == 0);
486 }
else if (req->isSwap()) {
487 assert(curr_frag_id == 0);
488 if (req->isCondSwap()) {
490 req->setExtraData(*res);
498 if (req->isLocalAccess()) {
500 req->localAccessor(thread->
getTC(), &pkt);
511 assert(res && curr_frag_id == 0);
516 if (res && !req->isSwap()) {
517 *res = req->getExtraData();
523 if (fault !=
NoFault || size_left == 0) {
524 if (req->isLockedRMW() && fault ==
NoFault) {
525 assert(!req->isMasked());
530 return req->isPrefetch() ?
NoFault : fault;
536 frag_addr += frag_size;
570 "AMO request should not access across a cache line boundary.");
589 if (req->isLocalAccess()) {
599 assert(!req->isLLSC());
602 if (fault !=
NoFault && req->isPrefetch()) {
663 Tick icache_latency = 0;
664 bool icache_access =
false;
675 icache_access =
true;
682 Tick stall_ticks = 0;
695 std::dynamic_pointer_cast<SyscallRetryFault>(fault)) {
712 stall_ticks += icache_latency;
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
virtual Tick recvAtomicSnoop(PacketPtr pkt)
Receive an atomic snoop request packet from our peer.
void suspendContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now suspended.
void takeOverFrom(BaseCPU *old_cpu) override
Load the state of a CPU from the previous CPU object, invoked on all new CPUs that are about to be sw...
const bool simulate_data_stalls
void drainResume() override
Resume execution after a successful drain.
void switchOut() override
Prepare for another CPU to take over execution.
bool genMemFragmentRequest(const RequestPtr &req, Addr frag_addr, int size, Request::Flags flags, const std::vector< bool > &byte_enable, int &frag_size, int &size_left) const
Helper function used to set up the request for a single fragment of a memory access.
bool isCpuDrained() const
Check if a system is in a drained state.
void regProbePoints() override
Register probe points for this object.
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
virtual Tick fetchInstMem()
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
AtomicCPUDPort dcachePort
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
ProbePointArg< std::pair< SimpleThread *, const StaticInstPtr > > * ppCommit
Probe Points.
AtomicSimpleCPU(const BaseAtomicSimpleCPUParams ¶ms)
Fault readMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >()) override
Fault amoMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
const bool simulate_inst_stalls
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
void threadSnoop(PacketPtr pkt, ThreadID sender)
Perform snoop for other cpu-local thread contexts.
bool tryCompleteDrain()
Try to complete a drain request.
virtual Tick sendPacket(RequestPort &port, const PacketPtr &pkt)
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
RequestPtr data_write_req
void activateContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now active.
virtual ~AtomicSimpleCPU()
EventFunctionWrapper tickEvent
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()
void regProbePoints() override
Register probe points for this object.
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 Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode)
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()
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 ticksToCycles(Tick t) const
Cycles is a wrapper class for representing cycle counts, i.e.
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....
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
AddrRange getAddrRange() const
Get address range to which this packet belongs.
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
static MemCmd makeWriteCmd(const RequestPtr &req)
Generate the appropriate write MemCmd based on the Request flags.
const T * getConstPtr() const
static MemCmd makeReadCmd(const RequestPtr &req)
Generate the appropriate read MemCmd based on the Request flags.
bool isInvalidate() const
ProbePointArg generates a point for the class of Arg.
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
void printAddr(Addr a)
Inject a PrintReq for the given address to print the state of that address throughout the memory syst...
@ NO_ACCESS
The request should not cause a memory access.
static const FlagsType STORE_NO_DATA
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
const PCStateBase & pcState() const override
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
BaseISA * getIsaPtr() const override
bool isFirstMicroop() const
virtual Fault execute(ExecContext *xc, trace::InstRecord *traceData) const =0
bool isDelayedCommit() const
void setMem(Addr a, Addr s, unsigned f)
std::string to_string() const
Get a string representation of the range.
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
static constexpr T divCeil(const T &a, const U &b)
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)
bool scheduled() const
Determine if the current event is scheduled.
void schedule(Event &event, Tick when)
void reschedule(Event &event, Tick when, bool always=false)
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
ProbeManager * getProbeManager()
Get the probe manager for this object.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::shared_ptr< FaultBase > Fault
int16_t ThreadID
Thread index/ID type.
std::shared_ptr< Request > RequestPtr
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Addr addrBlockOffset(Addr addr, Addr block_size)
Calculates the offset of a given address wrt aligned fixed-size blocks.
uint64_t Tick
Tick count type.
int ContextID
Globally unique thread context ID.
static bool isRomMicroPC(MicroPC upc)
constexpr decltype(nullptr) NoFault
bool isAnyActiveElement(const std::vector< bool >::const_iterator &it_start, const std::vector< bool >::const_iterator &it_end)
Test if there is any active element in an enablement range.
Declaration of the Packet class.
bool doMonitor(PacketPtr pkt)
statistics::Scalar numCycles
const std::string & name()