Go to the documentation of this file.
44 #include "arch/locked_mem.hh"
45 #include "arch/utility.hh"
47 #include "config/the_isa.hh"
50 #include "debug/Drain.hh"
51 #include "debug/ExecFaulting.hh"
52 #include "debug/SimpleCPU.hh"
56 #include "params/AtomicSimpleCPU.hh"
75 tickEvent([this]{
tick(); },
"AtomicSimpleCPU tick",
77 width(
p.width), locked(
false),
78 simulate_data_stalls(
p.simulate_data_stalls),
79 simulate_inst_stalls(
p.simulate_inst_stalls),
80 icachePort(
name() +
".icache_port",
this),
81 dcachePort(
name() +
".dcache_port",
this),
82 dcache_access(
false), dcache_latency(0),
86 ifetch_req = std::make_shared<Request>();
87 data_read_req = std::make_shared<Request>();
88 data_write_req = std::make_shared<Request>();
89 data_amo_req = std::make_shared<Request>();
110 DPRINTF(Drain,
"Requesting drain.\n");
117 DPRINTF(Drain,
"Not executing microcode, no need to drain.\n");
125 DPRINTF(SimpleCPU,
"%s received snoop pkt for addr:%#x %s\n",
147 DPRINTF(SimpleCPU,
"Resume\n");
156 threadInfo[tid]->execContextStats.notIdleFraction = 1;
165 threadInfo[tid]->execContextStats.notIdleFraction = 0;
179 DPRINTF(Drain,
"tryCompleteDrain.\n");
183 DPRINTF(Drain,
"CPU done draining, processing drain event\n");
214 "The atomic CPU requires the memory system to be in "
221 DPRINTF(SimpleCPU,
"ActivateContext %d\n", thread_num);
225 threadInfo[thread_num]->execContextStats.notIdleFraction = 1;
247 DPRINTF(SimpleCPU,
"SuspendContext %d\n", thread_num);
257 threadInfo[thread_num]->execContextStats.notIdleFraction = 0;
279 DPRINTF(SimpleCPU,
"%s received atomic snoop pkt for addr:%#x %s\n",
296 DPRINTF(SimpleCPU,
"received invalidation for addr:%#x\n",
309 DPRINTF(SimpleCPU,
"%s received functional snoop pkt for addr:%#x %s\n",
322 DPRINTF(SimpleCPU,
"received invalidation for addr:%#x\n",
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()) {
414 return req->isPrefetch() ?
NoFault : fault;
417 if (size_left == 0) {
418 if (req->isLockedRMW() && fault ==
NoFault) {
428 frag_addr += frag_size;
442 static uint8_t zero_array[64] = {};
463 int size_left = size;
464 int curr_frag_id = 0;
470 byte_enable, frag_size, size_left);
478 if (predicate && fault ==
NoFault) {
479 bool do_access =
true;
482 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.");
576 thread->
pcState().instAddr(), std::move(amo_op));
589 if (req->isLocalAccess()) {
598 assert(!req->isLLSC());
601 if (fault !=
NoFault && req->isPrefetch()) {
661 Tick icache_latency = 0;
662 bool icache_access =
false;
673 icache_access =
true;
680 Tick stall_ticks = 0;
693 std::dynamic_pointer_cast<SyscallRetryFault>(fault)) {
710 stall_ticks += icache_latency;
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
bool scheduled() const
Determine if the current event is scheduled.
void activateContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now active.
bool handleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask)
T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
TheISA::PCState pcState() const override
Trace::InstRecord * traceData
StaticInstPtr curMacroStaticInst
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
void handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
void reschedule(Event &event, Tick when, bool always=false)
int16_t ThreadID
Thread index/ID type.
virtual Tick sendPacket(RequestPort &port, const PacketPtr &pkt)
ProbePointArg< std::pair< SimpleThread *, const StaticInstPtr > > * ppCommit
Probe Points.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
void drainResume() override
Resume execution after a successful drain.
int ContextID
Globally unique thread context ID.
bool doMonitor(PacketPtr pkt)
unsigned int cacheLineSize() const
Get the cache line size of the system.
ProbePointArg generates a point for the class of Arg.
uint64_t Tick
Tick count type.
AtomicSimpleCPU(const AtomicSimpleCPUParams ¶ms)
static MemCmd makeReadCmd(const RequestPtr &req)
Generate the appropriate read MemCmd based on the Request flags.
Cycles syscallRetryLatency
void setMem(Addr a, Addr s, unsigned f)
void setupFetchRequest(const RequestPtr &req)
bool isInvalidate() const
std::shared_ptr< Request > RequestPtr
EventFunctionWrapper tickEvent
void regProbePoints() override
Register probe points for this object.
void deschedule(Event &event)
BaseCPU::BaseCPUStats baseStats
void deschedulePowerGatingEvent()
std::vector< SimpleExecContext * > threadInfo
void traceFault()
Handler used when encountering a fault; its purpose is to tear down the InstRecord.
Fault readMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >()) override
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
const bool simulate_inst_stalls
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
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.
@ Drained
Buffers drained, ready for serialization/handover.
std::list< ThreadID > activeThreads
DrainState
Object drain/handover states.
bool isCpuDrained() const
Check if a system is in a drained state.
bool isFirstMicroop() const
T divCeil(const T &a, const U &b)
void schedule(Event &event, Tick when)
bool isDelayedCommit() const
void threadSnoop(PacketPtr pkt, ThreadID sender)
Perform snoop for other cpu-local thread contexts.
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
Tick instCnt
Instruction count used for SPARC misc register.
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
std::shared_ptr< FaultBase > Fault
TheISA::MachInst inst
Current instruction.
RequestPtr data_write_req
std::vector< ThreadContext * > threadContexts
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 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...
void suspendContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now suspended.
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, BaseTLB::Mode mode)
void signalDrainDone() const
Signal that an object is drained.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
void checkForInterrupts()
Fault amoMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
AddressMonitor * getCpuAddrMonitor(ThreadID tid)
Addr addrBlockOffset(Addr addr, Addr block_size)
Calculates the offset of a given address wrt aligned fixed-size blocks.
static MemCmd makeWriteCmd(const RequestPtr &req)
Generate the appropriate write MemCmd based on the Request flags.
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
constexpr decltype(nullptr) NoFault
void switchOut() override
Prepare for another CPU to take over execution.
ProbePointArg< PacketInfo > Packet
Packet probe point.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
const std::string & name()
static bool isRomMicroPC(MicroPC upc)
ProbeManager * getProbeManager()
Get the probe manager for this object.
DrainState drainState() const
Return the current drain state of an object.
virtual Tick recvAtomicSnoop(PacketPtr pkt)
Receive an atomic snoop request packet from our peer.
uint32_t taskId() const
Get cpu task id.
void wakeup(ThreadID tid) override
StaticInstPtr curStaticInst
@ NO_ACCESS
The request should not cause a memory access.
void advancePC(const Fault &fault)
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
void handleLockedRead(XC *xc, const RequestPtr &req)
GenericISA::DelaySlotPCState< MachInst > PCState
void schedulePowerGatingEvent()
Cycles ticksToCycles(Tick t) const
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
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...
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
virtual void switchOut()
Prepare for another CPU to take over execution.
void printAddr(Addr a)
Inject a PrintReq for the given address to print the state of that address throughout the memory syst...
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
RequestorID dataRequestorId() const
Reads this CPU's unique data requestor ID.
Cycles is a wrapper class for representing cycle counts, i.e.
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 regProbePoints() override
Register probe points for this object.
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
Tick curTick()
The universal simulation clock.
const bool simulate_data_stalls
virtual Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const =0
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
bool tryCompleteDrain()
Try to complete a drain request.
static const FlagsType STORE_NO_DATA
bool switchedOut() const
Determine if the CPU is switched out.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
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 isAtomicMode() const
Is the system in atomic mode?
const T * getConstPtr() const
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
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
virtual ~AtomicSimpleCPU()
@ Draining
Draining buffers pending serialization/handover.
virtual Tick fetchInstMem()
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
AtomicCPUDPort dcachePort
Generated on Tue Mar 23 2021 19:41:25 for gem5 by doxygen 1.8.17