46 #include "arch/locked_mem.hh"
47 #include "arch/mmapped_ipr.hh"
48 #include "arch/utility.hh"
51 #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"
65 using namespace TheISA;
68 :
Event(CPU_Tick_Pri), cpu(c)
82 return "AtomicSimpleCPU tick";
90 int cid = threadContexts[0]->contextId();
123 DPRINTF(Drain,
"Requesting drain.\n");
130 DPRINTF(Drain,
"Not executing microcode, no need to drain.\n");
138 DPRINTF(SimpleCPU,
"received snoop pkt for addr:%#x %s\n", pkt->
getAddr(),
141 for (
ThreadID tid = 0; tid < numThreads; tid++) {
143 if (getCpuAddrMonitor(tid)->doMonitor(pkt)) {
160 DPRINTF(SimpleCPU,
"Resume\n");
163 assert(!threadContexts.empty());
167 for (
ThreadID tid = 0; tid < numThreads; tid++) {
189 DPRINTF(Drain,
"tryCompleteDrain.\n");
193 DPRINTF(Drain,
"CPU done draining, processing drain event\n");
203 BaseSimpleCPU::switchOut();
223 if (!
system->isAtomicMode()) {
224 fatal(
"The atomic CPU requires the memory system to be in "
232 DPRINTF(SimpleCPU,
"ActivateContext %d\n", thread_num);
234 assert(thread_num < numThreads);
240 ppCycles->notify(delta);
252 BaseCPU::activateContext(thread_num);
259 DPRINTF(SimpleCPU,
"SuspendContext %d\n", thread_num);
261 assert(thread_num < numThreads);
279 BaseCPU::suspendContext(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) {
355 Addr secondAddr =
roundDown(addr + size - 1, cacheLineSize());
357 if (secondAddr > addr)
358 size = secondAddr -
addr;
364 req->
setVirt(0, addr, size, flags, dataMasterId(), thread->
pcState().instAddr());
367 Fault fault = thread->
dtb->translateAtomic(req, thread->
getTC(),
379 system->getPhysMem().access(&pkt);
402 if (secondAddr <= addr)
419 size = addr + fullSize - secondAddr;
429 panic(
"initiateMemRead() is for timing accesses, and should "
430 "never be called on AtomicSimpleCPU.\n");
439 static uint8_t zero_array[64] = {};
459 Addr secondAddr =
roundDown(addr + size - 1, cacheLineSize());
461 if (secondAddr > addr)
462 size = secondAddr -
addr;
468 req->
setVirt(0, addr, size, flags, dataMasterId(), thread->
pcState().instAddr());
476 bool do_access =
true;
481 }
else if (req->
isSwap()) {
498 system->getPhysMem().access(&pkt);
514 if (res && !req->
isSwap()) {
521 if (fault !=
NoFault || secondAddr <= addr)
543 size = addr + fullSize - secondAddr;
559 if (numThreads > 1) {
601 Tick icache_latency = 0;
602 bool icache_access =
false;
613 icache_access =
true;
618 system->getPhysMem().access(&ifetch_pkt);
631 Tick stall_ticks = 0;
645 if (dynamic_pointer_cast<SyscallRetryFault>(fault)) {
649 stall_ticks += clockEdge(syscallRetryLatency) -
curTick();
661 stall_ticks += icache_latency;
670 latency +=
divCeil(stall_ticks, clockPeriod()) *
683 if (latency < clockPeriod())
684 latency = clockPeriod();
693 BaseCPU::regProbePoints();
696 (getProbeManager(),
"Commit");
710 AtomicSimpleCPUParams::create()
StaticInstPtr curStaticInst
void advancePC(const Fault &fault)
MemObject & owner
A reference to the MemObject that owns this port.
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the slave port.
bool isFirstMicroop() const
Fault readMem(Addr addr, uint8_t *data, unsigned size, Request::Flags flags) override
std::list< ThreadID > activeThreads
decltype(nullptr) constexpr NoFault
Cycles is a wrapper class for representing cycle counts, i.e.
Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags) override
const std::string & name()
DrainState
Object drain/handover states.
void setExtraData(uint64_t extraData)
Accessor function for store conditional return value.
bool isDelayedCommit() const
TheISA::MachInst inst
Current instruction.
uint64_t getExtraData() const
Accessor function for store conditional return value.
void wakeup(ThreadID tid) override
bool scheduled() const
Determine if the current event is scheduled.
bool isMmappedIpr() const
bool handleLockedWrite(XC *xc, Request *req, Addr cacheBlockMask)
virtual Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const =0
void setContext(ContextID context_id)
Set up Context numbers.
The SimpleThread object provides a combination of the ThreadState object and the ThreadContext interf...
This is a write that is targeted and zeroing an entire cache block.
void checkForInterrupts()
void drainResume() override
Cycles handleIprRead(ThreadContext *xc, Packet *pkt)
Helper function to handle IPRs when the target architecture doesn't need its own IPR handling...
Cycles handleIprWrite(ThreadContext *xc, Packet *pkt)
Helper function to handle IPRs when the target architecture doesn't need its own IPR handling...
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
bool isDrained()
Check if a system is in a drained state.
void handleLockedSnoop(XC *xc, PacketPtr pkt, Addr cacheBlockMask)
const char * description() const
Return a C string describing the event.
Tick curTick()
The current simulated tick.
const bool simulate_inst_stalls
void takeOverFrom(ThreadContext &ntc, ThreadContext &otc)
Copy state between thread contexts in preparation for CPU handover.
TickEvent(AtomicSimpleCPU *c)
uint64_t Tick
Tick count type.
void printAddr(Addr a)
Print state of address in memory system via PrintReq (for debugging).
void takeOverFrom(BaseCPU *oldCPU) override
void setMem(Addr a, Addr s, unsigned f)
T roundDown(const T &val, const U &align)
static MemCmd makeReadCmd(const RequestPtr req)
Generate the appropriate read MemCmd based on the Request flags.
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 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 ~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)
DrainState drain() override
void activateContext(ThreadID thread_num) override
TheISA::PCState pcState()
void switchOut() override
Flags getFlags()
Accessor for flags.
int16_t ThreadID
Thread index/ID type.
void threadSnoop(PacketPtr pkt, ThreadID sender)
Perform snoop for other cpu-local thread contexts.
ProbePointArg generates a point for the class of Arg.
Declaration of the Packet class.
The request should not cause a memory access.
Trace::InstRecord * traceData
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
GenericISA::SimplePCState< MachInst > PCState
Fault writeMem(uint8_t *data, unsigned size, Addr addr, Request::Flags flags, uint64_t *res) override
AtomicSimpleCPU(AtomicSimpleCPUParams *params)
void setVirt(int asid, Addr vaddr, unsigned size, Flags flags, MasterID mid, Addr pc)
Set up a virtual (e.g., CPU) request in a previously allocated Request object.
std::vector< SimpleExecContext * > threadInfo
const bool simulate_data_stalls
T divCeil(const T &a, const U &b)
bool tryCompleteDrain()
Try to complete a drain request.
void verifyMemoryMode() const override
const T * getConstPtr() const
void regProbePoints() override
bool isInvalidate() const
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
void setupFetchRequest(Request *req)
int ContextID
Globally unique thread context ID.
void handleLockedRead(XC *xc, Request *req)
void suspendContext(ThreadID thread_num) override
ProbePointArg< PacketInfo > Packet
Packet probe point.
virtual Tick recvAtomicSnoop(PacketPtr pkt)
Receive an atomic snoop request packet from the slave port.