Go to the documentation of this file.
44 #include "arch/locked_mem.hh"
46 #include "config/the_isa.hh"
49 #include "debug/Drain.hh"
50 #include "debug/ExecFaulting.hh"
51 #include "debug/SimpleCPU.hh"
55 #include "params/AtomicSimpleCPU.hh"
77 tickEvent([this]{
tick(); },
"AtomicSimpleCPU tick",
79 width(
p.width), locked(
false),
80 simulate_data_stalls(
p.simulate_data_stalls),
81 simulate_inst_stalls(
p.simulate_inst_stalls),
82 icachePort(
name() +
".icache_port",
this),
83 dcachePort(
name() +
".dcache_port",
this),
84 dcache_access(
false), dcache_latency(0),
88 ifetch_req = std::make_shared<Request>();
89 data_read_req = std::make_shared<Request>();
90 data_write_req = std::make_shared<Request>();
91 data_amo_req = std::make_shared<Request>();
112 DPRINTF(Drain,
"Requesting drain.\n");
119 DPRINTF(Drain,
"Not executing microcode, no need to drain.\n");
127 DPRINTF(SimpleCPU,
"%s received snoop pkt for addr:%#x %s\n",
149 DPRINTF(SimpleCPU,
"Resume\n");
158 threadInfo[tid]->execContextStats.notIdleFraction = 1;
167 threadInfo[tid]->execContextStats.notIdleFraction = 0;
181 DPRINTF(Drain,
"tryCompleteDrain.\n");
185 DPRINTF(Drain,
"CPU done draining, processing drain event\n");
216 "The atomic CPU requires the memory system to be in "
223 DPRINTF(SimpleCPU,
"ActivateContext %d\n", thread_num);
227 threadInfo[thread_num]->execContextStats.notIdleFraction = 1;
249 DPRINTF(SimpleCPU,
"SuspendContext %d\n", thread_num);
259 threadInfo[thread_num]->execContextStats.notIdleFraction = 0;
281 DPRINTF(SimpleCPU,
"%s received atomic snoop pkt for addr:%#x %s\n",
298 DPRINTF(SimpleCPU,
"received invalidation for addr:%#x\n",
311 DPRINTF(SimpleCPU,
"%s received functional snoop pkt for addr:%#x %s\n",
324 DPRINTF(SimpleCPU,
"received invalidation for addr:%#x\n",
336 int &frag_size,
int &size_left)
const
338 bool predicate =
true;
341 frag_size = std::min(
344 size_left -= frag_size;
347 auto it_start = byte_enable.begin() + (size - (frag_size + size_left));
348 auto it_end = byte_enable.begin() + (size - size_left);
380 int size_left = size;
386 byte_enable, frag_size, size_left);
395 if (predicate && fault ==
NoFault &&
400 if (req->isLocalAccess()) {
416 return req->isPrefetch() ?
NoFault : fault;
419 if (size_left == 0) {
420 if (req->isLockedRMW() && fault ==
NoFault) {
430 frag_addr += frag_size;
444 static uint8_t zero_array[64] = {};
465 int size_left = size;
466 int curr_frag_id = 0;
472 byte_enable, frag_size, size_left);
480 if (predicate && fault ==
NoFault) {
481 bool do_access =
true;
484 assert(curr_frag_id == 0);
488 }
else if (req->isSwap()) {
489 assert(curr_frag_id == 0);
490 if (req->isCondSwap()) {
492 req->setExtraData(*res);
500 if (req->isLocalAccess()) {
502 req->localAccessor(thread->
getTC(), &pkt);
513 assert(res && curr_frag_id == 0);
518 if (res && !req->isSwap()) {
519 *res = req->getExtraData();
525 if (fault !=
NoFault || size_left == 0) {
526 if (req->isLockedRMW() && fault ==
NoFault) {
527 assert(!req->isMasked());
532 return req->isPrefetch() ?
NoFault : fault;
538 frag_addr += frag_size;
572 "AMO request should not access across a cache line boundary.");
578 thread->
pcState().instAddr(), std::move(amo_op));
591 if (req->isLocalAccess()) {
600 assert(!req->isLLSC());
603 if (fault !=
NoFault && req->isPrefetch()) {
665 Tick icache_latency = 0;
666 bool icache_access =
false;
677 icache_access =
true;
684 Tick stall_ticks = 0;
697 std::dynamic_pointer_cast<SyscallRetryFault>(fault)) {
714 stall_ticks += icache_latency;
static MemCmd makeWriteCmd(const RequestPtr &req)
Generate the appropriate write MemCmd based on the Request flags.
Tick curTick()
The universal simulation clock.
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
bool tryCompleteDrain()
Try to complete a drain request.
constexpr decltype(nullptr) NoFault
bool switchedOut() const
Determine if the CPU is switched out.
void regProbePoints() override
Register probe points for this object.
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
std::vector< SimpleExecContext * > threadInfo
void setMem(Addr a, Addr s, unsigned f)
const bool simulate_data_stalls
Trace::InstRecord * traceData
virtual Tick sendPacket(RequestPort &port, const PacketPtr &pkt)
DrainState drainState() const
Return the current drain state of an object.
static bool isRomMicroPC(MicroPC upc)
Fault readMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >()) override
unsigned int cacheLineSize() const
Get the cache line size of the system.
bool doMonitor(PacketPtr pkt)
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
bool isAtomicMode() const
Is the system in atomic mode?
virtual ~AtomicSimpleCPU()
StaticInstPtr curStaticInst
Current instruction.
AtomicCPUDPort dcachePort
Addr addrBlockOffset(Addr addr, Addr block_size)
Calculates the offset of a given address wrt aligned fixed-size blocks.
void schedule(Event &event, Tick when)
bool isDelayedCommit() const
bool isFirstMicroop() const
void schedulePowerGatingEvent()
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
void checkForInterrupts()
virtual Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const =0
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
const bool simulate_inst_stalls
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
Cycles is a wrapper class for representing cycle counts, i.e.
bool handleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask)
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
void deschedulePowerGatingEvent()
DrainState
Object drain/handover states.
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
gem5::BaseCPU::BaseCPUStats baseStats
uint32_t taskId() const
Get cpu task id.
std::shared_ptr< FaultBase > Fault
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...
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
statistics::Scalar numCycles
GenericISA::DelaySlotPCState< 4 > PCState
ProbePointArg< PacketInfo > Packet
Packet probe point.
virtual Tick fetchInstMem()
uint64_t Tick
Tick count type.
EventFunctionWrapper tickEvent
void setupFetchRequest(const RequestPtr &req)
std::shared_ptr< Request > RequestPtr
const T * getConstPtr() const
AtomicSimpleCPU(const AtomicSimpleCPUParams ¶ms)
void regProbePoints() override
Register probe points for this object.
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.
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
std::list< ThreadID > activeThreads
void drainResume() override
Resume execution after a successful drain.
void reschedule(Event &event, Tick when, bool always=false)
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.
static MemCmd makeReadCmd(const RequestPtr &req)
Generate the appropriate read MemCmd based on the Request flags.
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.
TheISA::PCState pcState() const override
@ Drained
Buffers drained, ready for serialization/handover.
void activateContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now active.
bool isCpuDrained() const
Check if a system is in a drained state.
Fault amoMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
AddressMonitor * getCpuAddrMonitor(ThreadID tid)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
const std::string & name()
Tick instCnt
Instruction count used for SPARC misc register.
RequestPtr data_write_req
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...
void deschedule(Event &event)
static constexpr T divCeil(const T &a, const U &b)
ProbePointArg generates a point for the class of Arg.
void signalDrainDone() const
Signal that an object is drained.
Tick nextCycle() const
Based on the clock of the object, determine the start tick of the first cycle that is at least one cy...
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
static const FlagsType STORE_NO_DATA
ProbeManager * getProbeManager()
Get the probe manager for this object.
void switchOut() override
Prepare for another CPU to take over execution.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
std::vector< ThreadContext * > threadContexts
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...
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
void threadSnoop(PacketPtr pkt, ThreadID sender)
Perform snoop for other cpu-local thread contexts.
int ContextID
Globally unique thread context ID.
void serviceInstCountEvents()
virtual void switchOut()
Prepare for another CPU to take over execution.
void handleLockedRead(XC *xc, const RequestPtr &req)
Cycles syscallRetryLatency
void wakeup(ThreadID tid) override
@ NO_ACCESS
The request should not cause a memory access.
void advancePC(const Fault &fault)
ProbePointArg< std::pair< SimpleThread *, const StaticInstPtr > > * ppCommit
Probe Points.
RequestorID dataRequestorId() const
Reads this CPU's unique data requestor ID.
void handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
Cycles ticksToCycles(Tick t) const
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode)
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
virtual Tick recvAtomicSnoop(PacketPtr pkt)
Receive an atomic snoop request packet from our peer.
void printAddr(Addr a)
Inject a PrintReq for the given address to print the state of that address throughout the memory syst...
StaticInstPtr curMacroStaticInst
@ Draining
Draining buffers pending serialization/handover.
bool scheduled() const
Determine if the current event is scheduled.
int16_t ThreadID
Thread index/ID type.
bool isInvalidate() const
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Generated on Tue Sep 7 2021 14:53:45 for gem5 by doxygen 1.8.17