/*
- * Copyright (c) 2011 ARM Limited
+ * Copyright (c) 2011-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
#include <vector>
+// Before we do anything else, check if this build is the NULL ISA,
+// and if so stop here
+#include "config/the_isa.hh"
+#if THE_ISA == NULL_ISA
+#include "arch/null/cpu_dummy.hh"
+#else
#include "arch/interrupts.hh"
#include "arch/isa_traits.hh"
#include "arch/microcode_rom.hh"
#include "base/statistics.hh"
-#include "config/the_isa.hh"
#include "mem/mem_object.hh"
#include "sim/eventq.hh"
#include "sim/full_system.hh"
#include "sim/insttracer.hh"
+#include "sim/system.hh"
struct BaseCPUParams;
-class BranchPred;
class CheckerCPU;
class ThreadContext;
-class System;
class CPUProgressEvent : public Event
{
// therefore no setCpuId() method is provided
int _cpuId;
+ /** Each cpu will have a socket ID that corresponds to its physical location
+ * in the system. This is usually used to bucket cpu cores under single DVFS
+ * domain. This information may also be required by the OS to identify the
+ * cpu core grouping (as in the case of ARM via MPIDR register)
+ */
+ const uint32_t _socketId;
+
/** instruction side request id that must be placed in all requests */
MasterID _instMasterId;
/** data side request id that must be placed in all requests */
MasterID _dataMasterId;
- /**
- * Define a base class for the CPU ports (instruction and data)
- * that is refined in the subclasses. This class handles the
- * common cases, i.e. the functional accesses and the status
- * changes and address range queries. The default behaviour for
- * both atomic and timing access is to panic and the corresponding
- * subclasses have to override these methods.
+ /** An intrenal representation of a task identifier within gem5. This is
+ * used so the CPU can add which taskId (which is an internal representation
+ * of the OS process ID) to each request so components in the memory system
+ * can track which process IDs are ultimately interacting with them
*/
- class CpuPort : public MasterPort
- {
- public:
+ uint32_t _taskId;
- /**
- * Create a CPU port with a name and a structural owner.
- *
- * @param _name port name including the owner
- * @param _name structural owner of this port
- */
- CpuPort(const std::string& _name, MemObject* _owner) :
- MasterPort(_name, _owner)
- { }
+ /** The current OS process ID that is executing on this processor. This is
+ * used to generate a taskId */
+ uint32_t _pid;
- protected:
+ /** Is the CPU switched out or active? */
+ bool _switchedOut;
- virtual bool recvTimingResp(PacketPtr pkt);
-
- virtual void recvRetry();
-
- virtual void recvFunctionalSnoop(PacketPtr pkt);
-
- };
+ /** Cache the cache line size that we get from the system */
+ const unsigned int _cacheLineSize;
public:
*
* @return a reference to the data port
*/
- virtual CpuPort &getDataPort() = 0;
+ virtual MasterPort &getDataPort() = 0;
/**
* Purely virtual method that returns a reference to the instruction
*
* @return a reference to the instruction port
*/
- virtual CpuPort &getInstPort() = 0;
+ virtual MasterPort &getInstPort() = 0;
/** Reads this CPU's ID. */
- int cpuId() { return _cpuId; }
+ int cpuId() const { return _cpuId; }
+
+ /** Reads this CPU's Socket ID. */
+ uint32_t socketId() const { return _socketId; }
/** Reads this CPU's unique data requestor ID */
MasterID dataMasterId() { return _dataMasterId; }
BaseMasterPort &getMasterPort(const std::string &if_name,
PortID idx = InvalidPortID);
+ /** Get cpu task id */
+ uint32_t taskId() const { return _taskId; }
+ /** Set cpu task id */
+ void taskId(uint32_t id) { _taskId = id; }
+
+ uint32_t getPid() const { return _pid; }
+ void setPid(uint32_t pid) { _pid = pid; }
+
inline void workItemBegin() { numWorkItemsStarted++; }
inline void workItemEnd() { numWorkItemsCompleted++; }
// @todo remove me after debugging with legion done
int findContext(ThreadContext *tc);
/// Given a thread num get tho thread context for it
- ThreadContext *getContext(int tn) { return threadContexts[tn]; }
+ virtual ThreadContext *getContext(int tn) { return threadContexts[tn]; }
+
+ /// Get the number of thread contexts available
+ unsigned numContexts() { return threadContexts.size(); }
public:
typedef BaseCPUParams Params;
*/
virtual void takeOverFrom(BaseCPU *cpu);
+ /**
+ * Flush all TLBs in the CPU.
+ *
+ * This method is mainly used to flush stale translations when
+ * switching CPUs. It is also exported to the Python world to
+ * allow it to request a TLB flush after draining the CPU to make
+ * it easier to compare traces when debugging
+ * handover/checkpointing.
+ */
+ void flushTLBs();
+
+ /**
+ * Determine if the CPU is switched out.
+ *
+ * @return True if the CPU is switched out, false otherwise.
+ */
+ bool switchedOut() const { return _switchedOut; }
+
+ /**
+ * Verify that the system is in a memory mode supported by the
+ * CPU.
+ *
+ * Implementations are expected to query the system for the
+ * current memory mode and ensure that it is what the CPU model
+ * expects. If the check fails, the implementation should
+ * terminate the simulation using fatal().
+ */
+ virtual void verifyMemoryMode() const { };
+
/**
* Number of threads we're actually simulating (<= SMT_MAX_THREADS).
* This is a constant for the duration of the simulation.
System *system;
+ /**
+ * Get the cache line size of the system.
+ */
+ inline unsigned int cacheLineSize() const { return _cacheLineSize; }
+
/**
* Serialize this object to the given output stream.
+ *
+ * @note CPU models should normally overload the serializeThread()
+ * method instead of the serialize() method as this provides a
+ * uniform data format for all CPU models and promotes better code
+ * reuse.
+ *
* @param os The stream to serialize to.
*/
virtual void serialize(std::ostream &os);
/**
* Reconstruct the state of this object from a checkpoint.
+ *
+ * @note CPU models should normally overload the
+ * unserializeThread() method instead of the unserialize() method
+ * as this provides a uniform data format for all CPU models and
+ * promotes better code reuse.
+
* @param cp The checkpoint use.
- * @param section The section name of this object
+ * @param section The section name of this object.
*/
virtual void unserialize(Checkpoint *cp, const std::string §ion);
/**
- * Return pointer to CPU's branch predictor (NULL if none).
- * @return Branch predictor pointer.
+ * Serialize a single thread.
+ *
+ * @param os The stream to serialize to.
+ * @param tid ID of the current thread.
+ */
+ virtual void serializeThread(std::ostream &os, ThreadID tid) {};
+
+ /**
+ * Unserialize one thread.
+ *
+ * @param cp The checkpoint use.
+ * @param section The section name of this thread.
+ * @param tid ID of the current thread.
*/
- virtual BranchPred *getBranchPred() { return NULL; };
+ virtual void unserializeThread(Checkpoint *cp, const std::string §ion,
+ ThreadID tid) {};
virtual Counter totalInsts() const = 0;
virtual Counter totalOps() const = 0;
+ /**
+ * Schedule an event that exits the simulation loops after a
+ * predefined number of instructions.
+ *
+ * This method is usually called from the configuration script to
+ * get an exit event some time in the future. It is typically used
+ * when the script wants to simulate for a specific number of
+ * instructions rather than ticks.
+ *
+ * @param tid Thread monitor.
+ * @param insts Number of instructions into the future.
+ * @param cause Cause to signal in the exit event.
+ */
+ void scheduleInstStop(ThreadID tid, Counter insts, const char *cause);
+
+ /**
+ * Schedule an event that exits the simulation loops after a
+ * predefined number of load operations.
+ *
+ * This method is usually called from the configuration script to
+ * get an exit event some time in the future. It is typically used
+ * when the script wants to simulate for a specific number of
+ * loads rather than ticks.
+ *
+ * @param tid Thread monitor.
+ * @param loads Number of load instructions into the future.
+ * @param cause Cause to signal in the exit event.
+ */
+ void scheduleLoadStop(ThreadID tid, Counter loads, const char *cause);
+
// Function tracing
private:
bool functionTracingEnabled;
Stats::Scalar numWorkItemsCompleted;
};
+#endif // THE_ISA == NULL_ISA
+
#endif // __CPU_BASE_HH__