46 #include "arch/locked_mem.hh" 47 #include "arch/mmapped_ipr.hh" 48 #include "arch/utility.hh" 50 #include "config/the_isa.hh" 53 #include "debug/Drain.hh" 54 #include "debug/ExecFaulting.hh" 55 #include "debug/SimpleCPU.hh" 59 #include "params/AtomicSimpleCPU.hh" 72 int cid = threadContexts[0]->contextId();
73 ifetch_req->setContext(cid);
74 data_read_req->setContext(cid);
75 data_write_req->setContext(cid);
76 data_amo_req->setContext(cid);
81 tickEvent([this]{
tick(); },
"AtomicSimpleCPU tick",
116 DPRINTF(Drain,
"Requesting drain.\n");
123 DPRINTF(Drain,
"Not executing microcode, no need to drain.\n");
131 DPRINTF(SimpleCPU,
"received snoop pkt for addr:%#x %s\n", pkt->
getAddr(),
153 DPRINTF(SimpleCPU,
"Resume\n");
185 DPRINTF(Drain,
"tryCompleteDrain.\n");
189 DPRINTF(Drain,
"CPU done draining, processing drain event\n");
220 fatal(
"The atomic CPU requires the memory system to be in " 228 DPRINTF(SimpleCPU,
"ActivateContext %d\n", thread_num);
254 DPRINTF(SimpleCPU,
"SuspendContext %d\n", thread_num);
286 DPRINTF(SimpleCPU,
"received snoop pkt for addr:%#x %s\n", pkt->
getAddr(),
292 for (
ThreadID tid = 0; tid < cpu->numThreads; tid++) {
293 if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
303 DPRINTF(SimpleCPU,
"received invalidation for addr:%#x\n",
305 for (
auto &t_info : cpu->threadInfo) {
316 DPRINTF(SimpleCPU,
"received snoop pkt for addr:%#x %s\n", pkt->
getAddr(),
321 for (
ThreadID tid = 0; tid < cpu->numThreads; tid++) {
322 if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
329 DPRINTF(SimpleCPU,
"received invalidation for addr:%#x\n",
331 for (
auto &t_info : cpu->threadInfo) {
341 int& frag_size,
int& size_left)
const 343 bool predicate =
true;
346 frag_size = std::min(
349 size_left -= frag_size;
351 if (!byte_enable.empty()) {
353 auto it_start = byte_enable.begin() + (size - (frag_size + size_left));
354 auto it_end = byte_enable.begin() + (size - size_left);
356 req->setVirt(0, frag_addr, frag_size, flags,
dataMasterId(),
363 req->setVirt(0, frag_addr, frag_size, flags,
dataMasterId(),
391 int size_left = size;
397 byte_enable, frag_size, size_left);
406 if (predicate && fault ==
NoFault &&
411 if (req->isMmappedIpr()) {
427 if (req->isPrefetch()) {
435 if (size_left == 0) {
436 if (req->isLockedRMW() && fault ==
NoFault) {
446 frag_addr += frag_size;
460 static uint8_t zero_array[64] = {};
481 int size_left = size;
482 int curr_frag_id = 0;
488 byte_enable, frag_size, size_left);
496 if (predicate && fault ==
NoFault) {
497 bool do_access =
true;
500 assert(curr_frag_id == 0);
504 }
else if (req->isSwap()) {
505 assert(curr_frag_id == 0);
506 if (req->isCondSwap()) {
508 req->setExtraData(*res);
516 if (req->isMmappedIpr()) {
529 assert(res && curr_frag_id == 0);
534 if (res && !req->isSwap()) {
535 *res = req->getExtraData();
541 if (fault !=
NoFault || size_left == 0)
543 if (req->isLockedRMW() && fault ==
NoFault) {
544 assert(!req->isMasked());
548 if (fault !=
NoFault && req->isPrefetch()) {
558 frag_addr += frag_size;
591 if (secondAddr > addr) {
592 panic(
"AMO request should not access across a cache line boundary\n");
599 thread->
pcState().instAddr(), std::move(amo_op));
612 if (req->isMmappedIpr())
621 assert(!req->isLLSC());
624 if (fault !=
NoFault && req->isPrefetch()) {
684 Tick icache_latency = 0;
685 bool icache_access =
false;
696 icache_access =
true;
711 Tick stall_ticks = 0;
726 dynamic_pointer_cast<SyscallRetryFault>(fault)) {
742 stall_ticks += icache_latency;
791 AtomicSimpleCPUParams::create()
StaticInstPtr curStaticInst
A MasterPort is a specialisation of a BaseMasterPort, which implements the default protocol for the t...
uint32_t taskId() const
Get cpu task id.
#define panic(...)
This implements a cprintf based panic() function.
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 advancePC(const Fault &fault)
Addr addrBlockOffset(Addr addr, Addr block_size)
Calculates the offset of a given address wrt aligned fixed-size blocks.
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
std::list< ThreadID > activeThreads
decltype(nullptr) constexpr NoFault
Cycles is a wrapper class for representing cycle counts, i.e.
AddressMonitor * getCpuAddrMonitor(ThreadID tid)
#define fatal(...)
This implements a cprintf based fatal() function.
bool isDelayedCommit() const
DrainState
Object drain/handover states.
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
Tick instCnt
Instruction count used for SPARC misc register.
std::shared_ptr< Request > RequestPtr
TheISA::MachInst inst
Current instruction.
EventFunctionWrapper tickEvent
std::unique_ptr< AtomicOpFunctor > AtomicOpFunctorPtr
void wakeup(ThreadID tid) override
Cycles handleIprRead(ThreadContext *, Packet *)
DrainState drainState() const
Return the current drain state of an object.
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
TheISA::PCState pcState() const override
virtual Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const =0
void signalDrainDone() const
Signal that an object is drained.
bool switchedOut() const
Determine if the CPU is switched out.
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
bool handleLockedWrite(XC *xc, const RequestPtr &req, Addr cacheBlockMask)
void checkForInterrupts()
RequestPtr data_write_req
Overload hash function for BasicBlockRange type.
void handleLockedRead(XC *xc, const RequestPtr &req)
void drainResume() override
Resume execution after a successful drain.
static MemCmd makeReadCmd(const RequestPtr &req)
Generate the appropriate read MemCmd based on the Request flags.
bool isInvalidate() const
void deschedule(Event &event)
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
void setupFetchRequest(const RequestPtr &req)
std::vector< ThreadContext * > threadContexts
bool isAtomicMode() const
Is the system in atomic mode?
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.
Tick curTick()
The current simulated tick.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
void schedulePowerGatingEvent()
bool scheduled() const
Determine if the current event is scheduled.
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...
const bool simulate_inst_stalls
MasterID dataMasterId() const
Reads this CPU's unique data requestor ID.
uint64_t Tick
Tick count type.
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
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...
bool doMonitor(PacketPtr pkt)
void setMem(Addr a, Addr s, unsigned f)
virtual Tick sendPacket(MasterPort &port, const PacketPtr &pkt)
Cycles syscallRetryLatency
static const FlagsType STORE_NO_DATA
T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Tick nextCycle() const
Based on the clock of the object, determine the start tick of the first cycle that is at least one cy...
StaticInstPtr curMacroStaticInst
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
ThreadContext * getTC()
Returns the pointer to this SimpleThread's ThreadContext.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
void printAddr(Addr a)
Inject a PrintReq for the given address to print the state of that address throughout the memory syst...
Draining buffers pending serialization/handover.
virtual const std::string name() const
virtual ~AtomicSimpleCPU()
ProbePointArg< std::pair< SimpleThread *, const StaticInstPtr > > * ppCommit
Probe Points.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
static bool isRomMicroPC(MicroPC upc)
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...
DrainState drain() override
Notify an object that it needs to drain its state.
Fault amoMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags, AtomicOpFunctorPtr amo_op) override
bool isFirstMicroop() const
virtual void switchOut()
Prepare for another CPU to take over execution.
static MemCmd makeWriteCmd(const RequestPtr &req)
Generate the appropriate write MemCmd based on the Request flags.
void activateContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now active.
void switchOut() override
Prepare for another CPU to take over execution.
int16_t ThreadID
Thread index/ID type.
void reschedule(Event &event, Tick when, bool always=false)
The request should not cause a memory access.
void threadSnoop(PacketPtr pkt, ThreadID sender)
Perform snoop for other cpu-local thread contexts.
unsigned int cacheLineSize() const
Get the cache line size of the system.
ProbePointArg generates a point for the class of Arg.
void regProbePoints() override
Register probe points for this object.
Cycles ticksToCycles(Tick t) const
Declaration of the Packet class.
bool isCpuDrained() const
Check if a system is in a drained state.
Trace::InstRecord * traceData
void deschedulePowerGatingEvent()
GenericISA::SimplePCState< MachInst > PCState
AtomicSimpleCPU(AtomicSimpleCPUParams *params)
ProbeManager * getProbeManager()
Get the probe manager for this object.
Fault readMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags, const std::vector< bool > &byte_enable=std::vector< bool >()) override
std::vector< SimpleExecContext * > threadInfo
const bool simulate_data_stalls
T divCeil(const T &a, const U &b)
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.
bool tryCompleteDrain()
Try to complete a drain request.
void schedule(Event &event, Tick when)
void verifyMemoryMode() const override
Verify that the system is in a memory mode supported by the CPU.
const T * getConstPtr() const
void handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
Cycles handleIprWrite(ThreadContext *, Packet *)
void regProbePoints() override
Register probe points for this object.
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time...
AtomicCPUDPort dcachePort
std::shared_ptr< FaultBase > Fault
int ContextID
Globally unique thread context ID.
virtual Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode)=0
void suspendContext(ThreadID thread_num) override
Notify the CPU that the indicated context is now suspended.
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
ProbePointArg< PacketInfo > Packet
Packet probe point.
virtual Tick recvAtomicSnoop(PacketPtr pkt)
Receive an atomic snoop request packet from our peer.