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" 69 int cid = threadContexts[0]->contextId();
70 ifetch_req->setContext(cid);
71 data_read_req->setContext(cid);
72 data_write_req->setContext(cid);
73 data_amo_req->setContext(cid);
78 tickEvent([this]{
tick(); },
"AtomicSimpleCPU tick",
113 DPRINTF(Drain,
"Requesting drain.\n");
120 DPRINTF(Drain,
"Not executing microcode, no need to drain.\n");
128 DPRINTF(SimpleCPU,
"received snoop pkt for addr:%#x %s\n", pkt->
getAddr(),
150 DPRINTF(SimpleCPU,
"Resume\n");
182 DPRINTF(Drain,
"tryCompleteDrain.\n");
186 DPRINTF(Drain,
"CPU done draining, processing drain event\n");
217 fatal(
"The atomic CPU requires the memory system to be in " 225 DPRINTF(SimpleCPU,
"ActivateContext %d\n", thread_num);
251 DPRINTF(SimpleCPU,
"SuspendContext %d\n", thread_num);
283 DPRINTF(SimpleCPU,
"received snoop pkt for addr:%#x %s\n", pkt->
getAddr(),
289 for (
ThreadID tid = 0; tid < cpu->numThreads; tid++) {
290 if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
300 DPRINTF(SimpleCPU,
"received invalidation for addr:%#x\n",
302 for (
auto &t_info : cpu->threadInfo) {
313 DPRINTF(SimpleCPU,
"received snoop pkt for addr:%#x %s\n", pkt->
getAddr(),
318 for (
ThreadID tid = 0; tid < cpu->numThreads; tid++) {
319 if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) {
326 DPRINTF(SimpleCPU,
"received invalidation for addr:%#x\n",
328 for (
auto &t_info : cpu->threadInfo) {
338 int& frag_size,
int& size_left)
const 340 bool predicate =
true;
343 frag_size = std::min(
346 size_left -= frag_size;
348 if (!byte_enable.empty()) {
350 auto it_start = byte_enable.begin() + (size - (frag_size + size_left));
351 auto it_end = byte_enable.begin() + (size - size_left);
353 req->setVirt(frag_addr, frag_size, flags,
dataMasterId(),
360 req->setVirt(frag_addr, frag_size, flags,
dataMasterId(),
388 int size_left = size;
394 byte_enable, frag_size, size_left);
403 if (predicate && fault ==
NoFault &&
408 if (req->isLocalAccess()) {
424 if (req->isPrefetch()) {
432 if (size_left == 0) {
433 if (req->isLockedRMW() && fault ==
NoFault) {
443 frag_addr += frag_size;
457 static uint8_t zero_array[64] = {};
478 int size_left = size;
479 int curr_frag_id = 0;
485 byte_enable, frag_size, size_left);
493 if (predicate && fault ==
NoFault) {
494 bool do_access =
true;
497 assert(curr_frag_id == 0);
501 }
else if (req->isSwap()) {
502 assert(curr_frag_id == 0);
503 if (req->isCondSwap()) {
505 req->setExtraData(*res);
513 if (req->isLocalAccess()) {
515 req->localAccessor(thread->
getTC(), &pkt);
526 assert(res && curr_frag_id == 0);
531 if (res && !req->isSwap()) {
532 *res = req->getExtraData();
538 if (fault !=
NoFault || size_left == 0)
540 if (req->isLockedRMW() && fault ==
NoFault) {
541 assert(!req->isMasked());
545 if (fault !=
NoFault && req->isPrefetch()) {
555 frag_addr += frag_size;
588 if (secondAddr > addr) {
589 panic(
"AMO request should not access across a cache line boundary\n");
596 thread->
pcState().instAddr(), std::move(amo_op));
609 if (req->isLocalAccess())
618 assert(!req->isLLSC());
621 if (fault !=
NoFault && req->isPrefetch()) {
681 Tick icache_latency = 0;
682 bool icache_access =
false;
693 icache_access =
true;
708 Tick stall_ticks = 0;
723 dynamic_pointer_cast<SyscallRetryFault>(fault)) {
739 stall_ticks += icache_latency;
788 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
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
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
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
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
DrainState
Object drain/handover states.
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
DrainState drainState() const
Return the current drain state of an object.
void setupFetchRequest(const RequestPtr &req)
std::vector< ThreadContext * > threadContexts
Draining buffers pending serialization/handover.
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()
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)
void deschedule(Event &event)
Cycles syscallRetryLatency
static const Priority CPU_Tick_Pri
CPU ticks must come after other associated CPU events (such as writebacks).
static const FlagsType STORE_NO_DATA
void schedule(Event &event, Tick when)
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...
void reschedule(Event &event, Tick when, bool always=false)
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...
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.
bool scheduled() const
Determine if the current event is scheduled.
ProbeManager * getProbeManager()
Get the probe manager for this object.
int16_t ThreadID
Thread index/ID type.
void threadSnoop(PacketPtr pkt, ThreadID sender)
Perform snoop for other cpu-local thread contexts.
virtual const std::string name() const
unsigned int cacheLineSize() const
Get the cache line size of the system.
ProbePointArg generates a point for the class of Arg.
The request should not cause a memory access.
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()
AtomicSimpleCPU(AtomicSimpleCPUParams *params)
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
void signalDrainDone() const
Signal that an object is drained.
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 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)
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...
GenericISA::DelaySlotPCState< MachInst > PCState
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.