Go to the documentation of this file.
60 #include "debug/Mwait.hh"
61 #include "debug/SyscallVerbose.hh"
62 #include "debug/Thread.hh"
64 #include "params/BaseCPU.hh"
89 :
Event(
Event::Progress_Event_Pri), _interval(ival), lastNumInst(0),
90 cpu(_cpu), _repeatEvent(true)
111 DPRINTFN(
"%s progress event, total committed:%i, progress insts committed: "
116 cprintf(
"%lli: %s progress event, total committed:%i, progress insts "
126 return "CPU Progress";
131 _instRequestorId(
p.
system->getRequestorId(this,
"inst")),
132 _dataRequestorId(
p.
system->getRequestorId(this,
"data")),
133 _taskId(context_switch_task_id::
Unknown), _pid(invldPid),
134 _switchedOut(
p.switched_out), _cacheLineSize(
p.
system->cacheLineSize()),
135 modelResetPort(
p.
name +
".model_reset"),
137 previousCycle(0), previousState(CPU_STATE_SLEEP),
138 functionTraceStream(nullptr), currentFunctionStart(0),
139 currentFunctionEnd(0), functionEntryTick(0),
141 addressMonitor(
p.numThreads),
142 syscallRetryLatency(
p.syscallRetryLatency),
143 pwrGatingLatency(
p.pwr_gating_latency),
144 powerGatingOnIdle(
p.power_gating_on_idle),
149 _cpuId = cpuList.size();
153 cpuList.push_back(
this);
155 DPRINTF(SyscallVerbose,
"Constructing CPU with id %d, socket id %d\n",
161 functionTracingEnabled =
false;
162 if (
p.function_trace) {
163 const std::string fname =
csprintf(
"ftrace.%s",
name());
166 currentFunctionStart = currentFunctionEnd = 0;
167 functionEntryTick =
p.function_trace_start;
169 if (
p.function_trace_start == 0) {
170 functionTracingEnabled =
true;
172 Event *
event =
new EventFunctionWrapper(
173 [
this]{ enableFunctionTrace(); },
name(),
true);
174 schedule(
event,
p.function_trace_start);
178 tracer = params().tracer;
180 if (params().isa.size() != numThreads) {
181 fatal(
"Number of ISAs (%i) assigned to the CPU does not equal number "
182 "of threads (%i).\n", params().isa.size(), numThreads);
185 if (!
FullSystem && params().workload.size() != numThreads) {
186 fatal(
"Number of processes (cpu.workload) (%i) assigned to the CPU "
187 "does not equal number of threads (%i).\n",
188 params().workload.size(), numThreads);
191 modelResetPort.onChange([
this](
const bool &new_val) {
195 fetchStats.reserve(numThreads);
196 executeStats.reserve(numThreads);
197 commitStats.reserve(numThreads);
198 for (
int i = 0;
i < numThreads;
i++) {
200 FetchCPUStats* fetchStatptr =
new FetchCPUStats(
this,
i);
201 fetchStatptr->fetchRate = fetchStatptr->numInsts / baseStats.numCycles;
202 fetchStatptr->branchRate = fetchStatptr->numBranches /
204 fetchStats.emplace_back(fetchStatptr);
207 ExecuteCPUStats* executeStatptr =
new ExecuteCPUStats(
this,
i);
208 executeStatptr->instRate = executeStatptr->numInsts /
210 executeStats.emplace_back(executeStatptr);
213 CommitCPUStats* commitStatptr =
new CommitCPUStats(
this,
i);
214 commitStatptr->ipc = commitStatptr->numInsts / baseStats.numCycles;
215 commitStatptr->cpi = baseStats.numCycles / commitStatptr->numInsts;
216 commitStats.emplace_back(commitStatptr);
247 monitor.
armed =
true;
248 monitor.
vAddr = address;
250 DPRINTF(Mwait,
"[tid:%d] Armed monitor (vAddr=0x%lx)\n", tid, address);
261 uint64_t
mask = ~((uint64_t)(block_size - 1));
263 assert(pkt->
req->hasPaddr());
267 DPRINTF(Mwait,
"[tid:%d] mwait called (vAddr=0x%lx, "
268 "line's paddr=0x%lx)\n", tid, monitor.
vAddr, monitor.
pAddr);
286 uint64_t
mask = ~((uint64_t)(block_size - 1));
287 int size = block_size;
292 if (secondAddr >
addr)
293 size = secondAddr -
addr;
305 DPRINTF(Mwait,
"[tid:%d] mwait called (vAddr=0x%lx, line's paddr=0x%lx)\n",
314 if (
params().max_insts_any_thread != 0) {
322 if (!
params().simpoint_start_insts.empty()) {
326 if (
params().max_insts_all_threads != 0) {
327 std::string cause =
"all threads reached the max instruction count";
332 int *counter =
new int;
341 if (!
params().switched_out) {
351 if (
params().progress_interval) {
409 : statistics::
Group(parent),
410 ADD_STAT(numCycles, statistics::units::Cycle::get(),
411 "Number of cpu cycles simulated"),
412 ADD_STAT(cpi, statistics::units::Rate<
413 statistics::units::Cycle, statistics::units::
Count>::get(),
414 "CPI: cycles per instruction (core level)"),
415 ADD_STAT(ipc, statistics::units::Rate<
416 statistics::units::
Count, statistics::units::Cycle>::get(),
417 "IPC: instructions per cycle (core level)"),
418 ADD_STAT(numWorkItemsStarted, statistics::units::
Count::get(),
419 "Number of work items this cpu started"),
420 ADD_STAT(numWorkItemsCompleted, statistics::units::
Count::get(),
421 "Number of work items this cpu completed")
441 using namespace statistics;
445 for (
int i = 0;
i < size; ++
i) {
446 std::stringstream namestr;
450 }
else if (size == 1)
460 if (if_name ==
"dcache_port")
462 else if (if_name ==
"icache_port")
464 else if (if_name ==
"model_reset")
476 "CPU %s has %i interrupt controllers, but is expecting one "
522 for (
ThreadID tid = 0; tid < size; ++tid) {
533 DPRINTF(Thread,
"CPU in reset, not activating context %d\n",
538 DPRINTF(Thread,
"activate contextId %d\n",
552 DPRINTF(Thread,
"suspend contextId %d\n",
607 assert(oldCPU !=
this);
644 if (old_checker && new_checker) {
676 tc->getIsaPtr()->resetThread();
678 tc->getDecoderPtr()->reset();
680 tc->getMMUPtr()->flushAll();
766 assert(pkt->
req->hasPaddr());
767 if (armed && waiting) {
769 DPRINTF(Mwait,
"pAddr=0x%lx invalidated: waking up core\n",
811 std::string cause =
"simpoint starting point found";
812 for (
size_t i = 0;
i < inst_starts.size(); ++
i) {
820 std::string cause =
"a thread reached the max instruction count";
827 : statistics::
Group(parent),
829 "Number of instructions simulated"),
831 "Number of ops (including micro ops) simulated"),
832 ADD_STAT(hostInstRate, statistics::units::Rate<
833 statistics::units::
Count, statistics::units::Second>::get(),
834 "Simulator instruction rate (inst/s)"),
835 ADD_STAT(hostOpRate, statistics::units::Rate<
836 statistics::units::
Count, statistics::units::Second>::get(),
837 "Simulator op (including micro ops) rate (op/s)")
867 : statistics::
Group(parent,
csprintf(
"fetchStats%i", thread_id).c_str()),
869 "Number of instructions fetched (thread level)"),
871 "Number of ops (including micro ops) fetched (thread level)"),
872 ADD_STAT(fetchRate, statistics::units::Rate<
873 statistics::units::
Count, statistics::units::Cycle>::get(),
874 "Number of inst fetches per cycle"),
876 "Number of branches fetched"),
877 ADD_STAT(branchRate, statistics::units::Ratio::get(),
878 "Number of branch fetches per cycle"),
879 ADD_STAT(icacheStallCycles, statistics::units::Cycle::get(),
880 "ICache total stall cycles"),
882 "Number of times Execute suspended instruction fetching")
902 : statistics::
Group(parent,
csprintf(
"executeStats%i", thread_id).c_str()),
904 "Number of executed instructions"),
906 "Number of nop insts executed"),
908 "Number of branches executed"),
910 "Number of load instructions executed"),
912 "Number of stores executed"),
913 ADD_STAT(instRate, statistics::units::Rate<
914 statistics::units::
Count, statistics::units::Cycle>::get(),
915 "Inst execution rate"),
916 ADD_STAT(dcacheStallCycles, statistics::units::Cycle::get(),
917 "DCache total stall cycles"),
919 "Number of times the CC registers were read"),
921 "Number of times the CC registers were written"),
923 "Number of float alu accesses"),
925 "Number of times the floating registers were read"),
927 "Number of times the floating registers were written"),
929 "Number of integer alu accesses"),
931 "Number of times the integer registers were read"),
933 "Number of times the integer registers were written"),
935 "Number of memory refs"),
937 "Number of times the Misc registers were read"),
939 "Number of times the Misc registers were written"),
941 "Number of vector alu accesses"),
942 ADD_STAT(numVecPredRegReads, statistics::units::
Count::get(),
943 "Number of times the predicate registers were read"),
944 ADD_STAT(numVecPredRegWrites, statistics::units::
Count::get(),
945 "Number of times the predicate registers were written"),
947 "Number of times the vector registers were read"),
949 "Number of times the vector registers were written"),
951 "Number of ops (including micro ops) which were discarded before "
990 : statistics::
Group(parent,
csprintf(
"commitStats%i", thread_id).c_str()),
992 "Number of instructions committed (thread level)"),
994 "Number of ops (including micro ops) committed (thread level)"),
996 "Number of instructions committed excluding NOPs or prefetches"),
998 "Number of Ops (including micro ops) Simulated"),
999 ADD_STAT(cpi, statistics::units::Rate<
1000 statistics::units::Cycle, statistics::units::
Count>::get(),
1001 "CPI: cycles per instruction (thread level)"),
1002 ADD_STAT(ipc, statistics::units::Rate<
1003 statistics::units::
Count, statistics::units::Cycle>::get(),
1004 "IPC: instructions per cycle (thread level)"),
1006 "Number of memory references committed"),
1008 "Number of float instructions"),
1010 "Number of integer instructions"),
1012 "Number of load instructions"),
1014 "Number of store instructions"),
1016 "Number of vector instructions"),
1017 ADD_STAT(committedInstType, statistics::units::
Count::get(),
1018 "Class of committed instruction."),
1020 "Class of control type instructions committed")
1029 .
init(enums::Num_OpClass)
1037 .
init(StaticInstFlags::Flags::Num_Flags)
1040 for (
unsigned i = 0;
i < StaticInstFlags::Flags::Num_Flags;
i++) {
1053 committedControl[gem5::StaticInstFlags::Flags::IsReturn]++;
1055 if (staticInst->
isCall()) {
1056 committedControl[gem5::StaticInstFlags::Flags::IsCall]++;
1059 committedControl[gem5::StaticInstFlags::Flags::IsDirectControl]++;
1063 [gem5::StaticInstFlags::Flags::IsIndirectControl]++;
1066 committedControl[gem5::StaticInstFlags::Flags::IsCondControl]++;
1069 committedControl[gem5::StaticInstFlags::Flags::IsUncondControl]++;
1071 committedControl[gem5::StaticInstFlags::Flags::IsControl]++;
statistics::Scalar numBranches
CPUProgressEvent(BaseCPU *_cpu, Tick ival=0)
statistics::Scalar numInsts
Tick curTick()
The universal simulation clock.
#define fatal(...)
This implements a cprintf based fatal() function.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
void assignThreadContext(ContextID context_id)
statistics::Scalar numVecRegReads
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Addr currentFunctionStart
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
int maxThreadsPerCPU
The maximum number of active threads across all cpus.
const State & state() const
void armMonitor(ThreadID tid, Addr address)
statistics::Scalar dcacheStallCycles
std::ostream * functionTraceStream
constexpr decltype(nullptr) NoFault
bool switchedOut() const
Determine if the CPU is switched out.
std::vector< BaseInterrupts * > interrupts
virtual Port & getInstPort()=0
Purely virtual method that returns a reference to the instruction port.
void scheduleInstStop(ThreadID tid, Counter insts, std::string cause)
Schedule an event that exits the simulation loops after a predefined number of instructions.
void cprintf(const char *format, const Args &...args)
statistics::Scalar numCCRegWrites
void mwaitAtomic(ThreadID tid, ThreadContext *tc, BaseMMU *mmu)
ProbePointArg< bool > * ppSleeping
ProbePoint that signals transitions of threadContexts sets.
void startup() override
startup() is the final initialization call before simulation.
#define UNSERIALIZE_SCALAR(scalar)
BaseCPUStats(statistics::Group *parent)
Static instruction class for unknown (illegal) instructions.
void enableFunctionTrace()
statistics::Scalar numMemRefs
bool isIndirectCtrl() const
virtual void unserializeThread(CheckpointIn &cp, ThreadID tid)
Unserialize one thread.
statistics::Scalar numFpRegReads
statistics::Formula hostOpRate
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
RequestPtr req
A pointer to the original request.
statistics::Formula numStoreInsts
statistics::Scalar numMiscRegReads
probing::PMUUPtr ppRetiredInsts
Instruction commit probe point.
probing::PMUUPtr pmuProbePoint(const char *name)
Helper method to instantiate probe points belonging to this object.
unsigned int cacheLineSize() const
Get the cache line size of the system.
virtual BaseMMU * getMMUPtr()=0
virtual const PCStateBase & pcState() const =0
bool doMonitor(PacketPtr pkt)
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
Global CPU statistics that are merged into the Root object.
const FlagsType nozero
Don't print if this is zero.
BaseCPU(const Params ¶ms, bool is_checker=false)
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
statistics::Scalar numIntAluAccesses
enums::PwrState get() const
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation.
virtual ContextID contextId() const =0
ExecuteCPUStats(statistics::Group *parent, int thread_id)
static std::vector< BaseCPU * > cpuList
Static global cpu list.
static Counter numSimulatedOps()
void schedule(Event &event, Tick when)
void registerThreadContext(ThreadContext *tc)
std::string csprintf(const char *format, const Args &...args)
statistics::Vector committedInstType
void takeOverFrom(Port *old)
A utility function to make it easier to swap out ports.
void schedulePowerGatingEvent()
OutputStream * findOrCreate(const std::string &name, bool binary=false)
SignalSinkPort< bool > modelResetPort
void ccprintf(cp::Print &print)
uint32_t _taskId
An intrenal representation of a task identifier within gem5.
const FlagsType dist
Print the distribution.
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
probing::PMUUPtr ppAllCycles
CPU cycle counter even if any thread Context is suspended.
const FlagsType pdf
Print the percent of the total that this entry represents.
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
virtual void serializeThread(CheckpointOut &cp, ThreadID tid) const
Serialize a single thread.
void regStats() override
Callback to set stat parameters.
probing::PMUUPtr ppRetiredInstsPC
virtual void wakeup(ThreadID tid)=0
virtual Port & getDataPort()=0
Purely virtual method that returns a reference to the data port.
void deschedulePowerGatingEvent()
statistics::Scalar numVecPredRegReads
std::ostream * stream() const
Get the output underlying output stream.
virtual const char * description() const
Return a C string describing the event.
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
CommitCPUStats(statistics::Group *parent, int thread_id)
void registerThreadContexts()
statistics::Scalar numIntRegWrites
statistics::Formula fetchRate
uint32_t taskId() const
Get cpu task id.
statistics::Value simInsts
probing::PMUUPtr ppRetiredStores
Retired store instructions.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual std::string name() const
std::shared_ptr< FaultBase > Fault
void flushTLBs()
Flush all TLBs in the CPU.
const Params & params() const
std::unique_ptr< PMU > PMUUPtr
const Cycles pwrGatingLatency
statistics::Scalar numCCRegReads
@ Suspended
Temporarily inactive.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
statistics::Scalar numCycles
statistics::Scalar numIntRegReads
statistics::Vector committedControl
FetchCPUStats(statistics::Group *parent, int thread_id)
void scheduleSimpointsInstStop(std::vector< Counter > inst_starts)
Schedule simpoint events using the scheduleInstStop function.
uint64_t Tick
Tick count type.
virtual void haltContext(ThreadID thread_num)
Notify the CPU that the indicated context is now halted.
statistics::Formula hostInstRate
void scheduleInstStopAnyThread(Counter max_insts)
Schedule an exit event when any threads in the core reach the max_insts instructions using the schedu...
std::shared_ptr< Request > RequestPtr
void regProbePoints() override
Register probe points for this object.
virtual void setThreadContext(ThreadContext *_tc)
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
const_iterator findNearest(Addr addr, Addr &next_addr) const
Find the nearest symbol equal to or less than the supplied address (e.g., the label for the enclosing...
virtual void setReset(bool state)
Set the reset of the CPU to be either asserted or deasserted.
bool isConnected() const
Is this port currently connected to a peer?
virtual Counter totalOps() const =0
int findContext(ThreadContext *tc)
Given a Thread Context pointer return the thread num.
Derived & functor(const T &func)
virtual void takeOverFrom(ThreadContext *old_context)=0
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
static Counter numSimulatedInsts()
bool isDirectCtrl() const
bool functionTracingEnabled
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
void postInterrupt(ThreadID tid, int int_num, int index)
EventFunctionWrapper enterPwrGatingEvent
virtual void probeInstCommit(const StaticInstPtr &inst, Addr pc)
Helper method to trigger PMU probes for a committed instruction.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
const std::string & name()
bool isLastMicroop() const
#define SERIALIZE_SCALAR(scalar)
virtual void regStats()
Callback to set stat parameters.
Tick instCnt
Instruction count used for SPARC misc register.
statistics::Scalar numVecPredRegWrites
GlobalStats(statistics::Group *parent)
bool is_waiting(ThreadContext *tc)
Determine if the given thread context is currently waiting on a futex wait operation on any of the fu...
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
bool _switchedOut
Is the CPU switched out or active?
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)
statistics::Scalar numLoadInsts
ProbePointArg generates a point for the class of Arg.
virtual Process * getProcessPtr()=0
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
ProbeManager * getProbeManager()
Get the probe manager for this object.
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.
Ports are used to interface objects to each other.
Derived & prereq(const Stat &prereq)
Set the prerequisite stat and marks this stat to print at the end of simulation.
statistics::Scalar numMiscRegWrites
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port on this CPU.
int cpuId() const
Reads this CPU's ID.
statistics::Scalar numInsts
virtual void verifyMemoryMode() const
Verify that the system is in a memory mode supported by the CPU.
probing::PMUUPtr ppRetiredLoads
Retired load instructions.
double Counter
All counters are of 64-bit values.
void traceFunctionsInternal(Addr pc)
virtual void switchOut()
Prepare for another CPU to take over execution.
uint64_t getCurrentInstCount(ThreadID tid)
Get the number of instructions executed by the specified thread on this CPU.
statistics::Scalar numFpAluAccesses
std::ostream CheckpointOut
void replaceThreadContext(ThreadContext *tc, ContextID context_id)
static const OpClass Num_OpClasses
virtual int threadId() const =0
RequestorID dataRequestorId() const
Reads this CPU's unique data requestor ID.
statistics::Scalar numVecRegWrites
ClockedObjectParams Params
Parameters of ClockedObject.
bool isUncondCtrl() const
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
bool mwait(ThreadID tid, PacketPtr pkt)
SymbolTable debugSymbolTable
Global unified debugging symbol table (for target).
virtual BaseISA * getIsaPtr() const =0
probing::PMUUPtr ppActiveCycles
CPU cycle counter, only counts if any thread contexts is active.
virtual 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....
const FlagsType total
Print the total.
Derived & init(size_type size)
Set this vector to have the given size.
void set(enums::PwrState p)
Change the power state of this object to the power state p.
statistics::Value & hostSeconds
statistics::Scalar icacheStallCycles
virtual void takeOverFrom(BaseMMU *old_mmu)
probing::PMUUPtr ppRetiredBranches
Retired branches (any type)
virtual CheckerCPU * getCheckerCpuPtr()=0
uint32_t _pid
The current OS process ID that is executing on this processor.
static Root * root()
Use this function to get a pointer to the single Root object in the simulation.
const bool powerGatingOnIdle
static std::unique_ptr< GlobalStats > globalStats
Pointer to the global stat structure.
void updateComCtrlStats(const StaticInstPtr staticInst)
bool scheduled() const
Determine if the current event is scheduled.
int16_t ThreadID
Thread index/ID type.
std::vector< AddressMonitor > addressMonitor
statistics::Formula branchRate
Generated on Sun Jul 30 2023 01:56:52 for gem5 by doxygen 1.8.17