58 #include "debug/Mwait.hh"
59 #include "debug/SyscallVerbose.hh"
60 #include "debug/Thread.hh"
62 #include "params/BaseCPU.hh"
87 :
Event(
Event::Progress_Event_Pri), _interval(ival), lastNumInst(0),
88 cpu(_cpu), _repeatEvent(true)
109 DPRINTFN(
"%s progress event, total committed:%i, progress insts committed: "
114 cprintf(
"%lli: %s progress event, total committed:%i, progress insts "
124 return "CPU Progress";
129 _instRequestorId(
p.
system->getRequestorId(this,
"inst")),
130 _dataRequestorId(
p.
system->getRequestorId(this,
"data")),
131 _taskId(context_switch_task_id::
Unknown), _pid(invldPid),
132 _switchedOut(
p.switched_out), _cacheLineSize(
p.
system->cacheLineSize()),
134 previousCycle(0), previousState(CPU_STATE_SLEEP),
135 functionTraceStream(nullptr), currentFunctionStart(0),
136 currentFunctionEnd(0), functionEntryTick(0),
138 addressMonitor(
p.numThreads),
139 syscallRetryLatency(
p.syscallRetryLatency),
140 pwrGatingLatency(
p.pwr_gating_latency),
141 powerGatingOnIdle(
p.power_gating_on_idle),
146 _cpuId = cpuList.size();
150 cpuList.push_back(
this);
152 DPRINTF(SyscallVerbose,
"Constructing CPU with id %d, socket id %d\n",
158 functionTracingEnabled =
false;
159 if (
p.function_trace) {
160 const std::string fname =
csprintf(
"ftrace.%s",
name());
163 currentFunctionStart = currentFunctionEnd = 0;
164 functionEntryTick =
p.function_trace_start;
166 if (
p.function_trace_start == 0) {
167 functionTracingEnabled =
true;
169 Event *
event =
new EventFunctionWrapper(
170 [
this]{ enableFunctionTrace(); },
name(),
true);
171 schedule(
event,
p.function_trace_start);
175 tracer = params().tracer;
177 if (params().isa.size() != numThreads) {
178 fatal(
"Number of ISAs (%i) assigned to the CPU does not equal number "
179 "of threads (%i).\n", params().isa.size(), numThreads);
210 monitor.
armed =
true;
211 monitor.
vAddr = address;
213 DPRINTF(Mwait,
"[tid:%d] Armed monitor (vAddr=0x%lx)\n", tid, address);
224 uint64_t
mask = ~((uint64_t)(block_size - 1));
226 assert(pkt->
req->hasPaddr());
230 DPRINTF(Mwait,
"[tid:%d] mwait called (vAddr=0x%lx, "
231 "line's paddr=0x%lx)\n", tid, monitor.
vAddr, monitor.
pAddr);
249 uint64_t
mask = ~((uint64_t)(block_size - 1));
250 int size = block_size;
255 if (secondAddr >
addr)
256 size = secondAddr -
addr;
268 DPRINTF(Mwait,
"[tid:%d] mwait called (vAddr=0x%lx, line's paddr=0x%lx)\n",
277 if (
params().max_insts_any_thread != 0) {
285 if (!
params().simpoint_start_insts.empty()) {
289 if (
params().max_insts_all_threads != 0) {
290 std::string cause =
"all threads reached the max instruction count";
295 int *counter =
new int;
304 if (!
params().switched_out) {
314 if (
params().progress_interval) {
372 : statistics::
Group(parent),
373 ADD_STAT(numCycles, statistics::units::Cycle::get(),
374 "Number of cpu cycles simulated"),
375 ADD_STAT(numWorkItemsStarted, statistics::units::
Count::get(),
376 "Number of work items this cpu started"),
377 ADD_STAT(numWorkItemsCompleted, statistics::units::
Count::get(),
378 "Number of work items this cpu completed")
393 using namespace statistics;
397 for (
int i = 0;
i < size; ++
i) {
398 std::stringstream namestr;
402 }
else if (size == 1)
412 if (if_name ==
"dcache_port")
414 else if (if_name ==
"icache_port")
426 "CPU %s has %i interrupt controllers, but is expecting one "
472 for (
ThreadID tid = 0; tid < size; ++tid) {
482 DPRINTF(Thread,
"activate contextId %d\n",
496 DPRINTF(Thread,
"suspend contextId %d\n",
551 assert(oldCPU !=
this);
588 if (old_checker && new_checker) {
684 assert(pkt->
req->hasPaddr());
685 if (armed && waiting) {
687 DPRINTF(Mwait,
"pAddr=0x%lx invalidated: waking up core\n",
729 std::string cause =
"simpoint starting point found";
730 for (
size_t i = 0;
i < inst_starts.size(); ++
i) {
738 std::string cause =
"a thread reached the max instruction count";
745 : statistics::
Group(parent),
747 "Number of instructions simulated"),
749 "Number of ops (including micro ops) simulated"),
750 ADD_STAT(hostInstRate, statistics::units::Rate<
751 statistics::units::
Count, statistics::units::Second>::get(),
752 "Simulator instruction rate (inst/s)"),
753 ADD_STAT(hostOpRate, statistics::units::Rate<
754 statistics::units::
Count, statistics::units::Second>::get(),
755 "Simulator op (including micro ops) rate (op/s)")
void regStats() override
Callback to set stat parameters.
int findContext(ThreadContext *tc)
Given a Thread Context pointer return the thread num.
RequestorID dataRequestorId() const
Reads this CPU's unique data requestor ID.
probing::PMUUPtr ppRetiredInsts
Instruction commit probe point.
const Cycles pwrGatingLatency
virtual void serializeThread(CheckpointOut &cp, ThreadID tid) const
Serialize a single thread.
virtual Counter totalOps() const =0
void traceFunctionsInternal(Addr pc)
const bool powerGatingOnIdle
void registerThreadContexts()
virtual Port & getDataPort()=0
Purely virtual method that returns a reference to the data port.
virtual void haltContext(ThreadID thread_num)
Notify the CPU that the indicated context is now halted.
probing::PMUUPtr ppRetiredLoads
Retired load instructions.
Tick instCnt
Instruction count used for SPARC misc register.
probing::PMUUPtr ppAllCycles
CPU cycle counter even if any thread Context is suspended.
probing::PMUUPtr ppRetiredInstsPC
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
void mwaitAtomic(ThreadID tid, ThreadContext *tc, BaseMMU *mmu)
void updateCycleCounters(CPUState state)
base method keeping track of cycle progression
probing::PMUUPtr pmuProbePoint(const char *name)
Helper method to instantiate probe points belonging to this object.
void postInterrupt(ThreadID tid, int int_num, int index)
bool mwait(ThreadID tid, PacketPtr pkt)
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
virtual Port & getInstPort()=0
Purely virtual method that returns a reference to the instruction port.
void scheduleInstStopAnyThread(Counter max_insts)
Schedule an exit event when any threads in the core reach the max_insts instructions using the schedu...
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
probing::PMUUPtr ppRetiredStores
Retired store instructions.
bool _switchedOut
Is the CPU switched out or active?
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port on this CPU.
Addr currentFunctionStart
void schedulePowerGatingEvent()
static std::unique_ptr< GlobalStats > globalStats
Pointer to the global stat structure.
virtual void verifyMemoryMode() const
Verify that the system is in a memory mode supported by the CPU.
void regProbePoints() override
Register probe points for this object.
void scheduleSimpointsInstStop(std::vector< Counter > inst_starts)
Schedule simpoint events using the scheduleInstStop function.
uint32_t taskId() const
Get cpu task id.
virtual void suspendContext(ThreadID thread_num)
Notify the CPU that the indicated context is now suspended.
void enableFunctionTrace()
ThreadID numThreads
Number of threads we're actually simulating (<= SMT_MAX_THREADS).
probing::PMUUPtr ppRetiredBranches
Retired branches (any type)
void deschedulePowerGatingEvent()
virtual void wakeup(ThreadID tid)=0
probing::PMUUPtr ppActiveCycles
CPU cycle counter, only counts if any thread contexts is active.
bool functionTracingEnabled
int cpuId() const
Reads this CPU's ID.
uint32_t _taskId
An intrenal representation of a task identifier within gem5.
std::vector< BaseInterrupts * > interrupts
void startup() override
startup() is the final initialization call before simulation.
virtual void unserializeThread(CheckpointIn &cp, ThreadID tid)
Unserialize one thread.
virtual void switchOut()
Prepare for another CPU to take over execution.
void flushTLBs()
Flush all TLBs in the CPU.
void armMonitor(ThreadID tid, Addr address)
unsigned int cacheLineSize() const
Get the cache line size of the system.
ProbePointArg< bool > * ppSleeping
ProbePoint that signals transitions of threadContexts sets.
static Counter numSimulatedOps()
std::ostream * functionTraceStream
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...
std::vector< AddressMonitor > addressMonitor
std::vector< ThreadContext * > threadContexts
static std::vector< BaseCPU * > cpuList
Static global cpu list.
EventFunctionWrapper enterPwrGatingEvent
void scheduleInstStop(ThreadID tid, Counter insts, std::string cause)
Schedule an event that exits the simulation loops after a predefined number of instructions.
bool switchedOut() const
Determine if the CPU is switched out.
BaseCPU(const Params ¶ms, bool is_checker=false)
uint32_t _pid
The current OS process ID that is executing on this processor.
virtual void probeInstCommit(const StaticInstPtr &inst, Addr pc)
Helper method to trigger PMU probes for a committed instruction.
uint64_t getCurrentInstCount(ThreadID tid)
Get the number of instructions executed by the specified thread on this CPU.
static Counter numSimulatedInsts()
virtual void activateContext(ThreadID thread_num)
Notify the CPU that the indicated context is now active.
virtual void setThreadContext(ThreadContext *_tc)
virtual void takeOverFrom(BaseMMU *old_mmu)
virtual Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode)
CPUProgressEvent(BaseCPU *_cpu, Tick ival=0)
virtual const char * description() const
Return a C string describing the event.
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
ClockedObjectParams Params
Parameters of ClockedObject.
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...
bool is_waiting(ThreadContext *tc)
Determine if the given thread context is currently waiting on a futex wait operation on any of the fu...
virtual std::string name() const
OutputStream * findOrCreate(const std::string &name, bool binary=false)
std::ostream * stream() const
Get the output underlying output stream.
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
RequestPtr req
A pointer to the original request.
Ports are used to interface objects to each other.
void takeOverFrom(Port *old)
A utility function to make it easier to swap out ports.
void set(enums::PwrState p)
Change the power state of this object to the power state p.
enums::PwrState get() const
ProbePointArg generates a point for the class of Arg.
void assignThreadContext(ContextID context_id)
Static instruction class for unknown (illegal) instructions.
static Root * root()
Use this function to get a pointer to the single Root object in the simulation.
bool isLastMicroop() const
void registerThreadContext(ThreadContext *tc)
void replaceThreadContext(ThreadContext *tc, ContextID context_id)
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual const PCStateBase & pcState() const =0
virtual BaseISA * getIsaPtr() const =0
virtual CheckerCPU * getCheckerCpuPtr()=0
virtual void takeOverFrom(ThreadContext *old_context)=0
@ Suspended
Temporarily inactive.
virtual int threadId() const =0
virtual ContextID contextId() const =0
virtual Process * getProcessPtr()=0
virtual BaseMMU * getMMUPtr()=0
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...
Derived & precision(int _precision)
Set the precision and marks this stat to print at the end of simulation.
Derived & functor(const T &func)
ClockedObject declaration and implementation.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
void deschedule(Event &event)
bool scheduled() const
Determine if the current event is scheduled.
void schedule(Event &event, Tick when)
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define fatal(...)
This implements a cprintf based fatal() function.
const Params & params() const
ProbeManager * getProbeManager()
Get the probe manager for this object.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
virtual void regStats()
Callback to set stat parameters.
SymbolTable debugSymbolTable
Global unified debugging symbol table (for target).
std::unique_ptr< PMU > PMUUPtr
double Counter
All counters are of 64-bit values.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
int16_t ThreadID
Thread index/ID type.
std::shared_ptr< Request > RequestPtr
statistics::Value & hostSeconds
void cprintf(const char *format, const Args &...args)
Tick curTick()
The universal simulation clock.
std::ostream CheckpointOut
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
uint64_t Tick
Tick count type.
int maxThreadsPerCPU
The maximum number of active threads across all cpus.
std::string csprintf(const char *format, const Args &...args)
constexpr decltype(nullptr) NoFault
void ccprintf(cp::Print &print)
Declarations of a non-full system Page Table.
#define UNSERIALIZE_SCALAR(scalar)
#define SERIALIZE_SCALAR(scalar)
bool doMonitor(PacketPtr pkt)
BaseCPUStats(statistics::Group *parent)
Global CPU statistics that are merged into the Root object.
statistics::Formula hostInstRate
statistics::Value simInsts
GlobalStats(statistics::Group *parent)
statistics::Formula hostOpRate
const std::string & name()