/*
+ * Copyright (c) 2011 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* Copyright (c) 2011 Regents of the University of California
* All rights reserved.
#include <vector>
+#include "arch/interrupts.hh"
#include "arch/isa_traits.hh"
#include "arch/microcode_rom.hh"
#include "base/statistics.hh"
-#include "config/full_system.hh"
#include "config/the_isa.hh"
#include "mem/mem_object.hh"
#include "sim/eventq.hh"
+#include "sim/full_system.hh"
#include "sim/insttracer.hh"
-#if FULL_SYSTEM
-#include "arch/interrupts.hh"
-#endif
-
-class BaseCPUParams;
+struct BaseCPUParams;
class BranchPred;
class CheckerCPU;
class ThreadContext;
class System;
-class Port;
-
-namespace TheISA
-{
- class Predecoder;
-}
class CPUProgressEvent : public Event
{
// therefore no setCpuId() method is provided
int _cpuId;
+ /** 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.
+ */
+ class CpuPort : public MasterPort
+ {
+ public:
+
+ /**
+ * 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)
+ { }
+
+ protected:
+
+ virtual bool recvTimingResp(PacketPtr pkt);
+
+ virtual void recvRetry();
+
+ virtual void recvFunctionalSnoop(PacketPtr pkt);
+
+ };
+
public:
+
+ /**
+ * Purely virtual method that returns a reference to the data
+ * port. All subclasses must implement this method.
+ *
+ * @return a reference to the data port
+ */
+ virtual CpuPort &getDataPort() = 0;
+
+ /**
+ * Purely virtual method that returns a reference to the instruction
+ * port. All subclasses must implement this method.
+ *
+ * @return a reference to the instruction port
+ */
+ virtual CpuPort &getInstPort() = 0;
+
/** Reads this CPU's ID. */
int cpuId() { return _cpuId; }
+ /** Reads this CPU's unique data requestor ID */
+ MasterID dataMasterId() { return _dataMasterId; }
+ /** Reads this CPU's unique instruction requestor ID */
+ MasterID instMasterId() { return _instMasterId; }
+
+ /**
+ * Get a master port on this CPU. All CPUs have a data and
+ * instruction port, and this method uses getDataPort and
+ * getInstPort of the subclasses to resolve the two ports.
+ *
+ * @param if_name the port name
+ * @param idx ignored index
+ *
+ * @return a reference to the port with the given name
+ */
+ MasterPort &getMasterPort(const std::string &if_name, int idx = -1);
+
// Tick currentTick;
inline Tick frequency() const { return SimClock::Frequency / clock; }
inline Tick ticks(int numCycles) const { return clock * numCycles; }
TheISA::MicrocodeRom microcodeRom;
-#if FULL_SYSTEM
protected:
TheISA::Interrupts *interrupts;
postInterrupt(int int_num, int index)
{
interrupts->post(int_num, index);
- wakeup();
+ if (FullSystem)
+ wakeup();
}
void
bool
checkInterrupts(ThreadContext *tc) const
{
- return interrupts->checkInterrupts(tc);
+ return FullSystem && interrupts->checkInterrupts(tc);
}
class ProfileEvent : public Event
void process();
};
ProfileEvent *profileEvent;
-#endif
protected:
std::vector<ThreadContext *> threadContexts;
- std::vector<TheISA::Predecoder *> predecoders;
Trace::InstTracer * tracer;
/// Notify the CPU that the indicated context is now active. The
/// delay parameter indicates the number of ticks to wait before
/// executing (typically 0 or 1).
- virtual void activateContext(int thread_num, int delay) {}
+ virtual void activateContext(ThreadID thread_num, int delay) {}
/// Notify the CPU that the indicated context is now suspended.
- virtual void suspendContext(int thread_num) {}
+ virtual void suspendContext(ThreadID thread_num) {}
/// Notify the CPU that the indicated context is now deallocated.
- virtual void deallocateContext(int thread_num) {}
+ virtual void deallocateContext(ThreadID thread_num) {}
/// Notify the CPU that the indicated context is now halted.
- virtual void haltContext(int thread_num) {}
+ virtual void haltContext(ThreadID thread_num) {}
/// Given a Thread Context pointer return the thread num
int findContext(ThreadContext *tc);
typedef BaseCPUParams Params;
const Params *params() const
{ return reinterpret_cast<const Params *>(_params); }
- BaseCPU(Params *params);
+ BaseCPU(Params *params, bool is_checker = false);
virtual ~BaseCPU();
virtual void init();
/// Take over execution from the given CPU. Used for warm-up and
/// sampling.
- virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc);
+ virtual void takeOverFrom(BaseCPU *);
/**
* Number of threads we're actually simulating (<= SMT_MAX_THREADS).
Tick phase;
-#if FULL_SYSTEM
/**
* Serialize this object to the given output stream.
* @param os The stream to serialize to.
*/
virtual void unserialize(Checkpoint *cp, const std::string §ion);
-#endif
-
/**
* Return pointer to CPU's branch predictor (NULL if none).
* @return Branch predictor pointer.
*/
virtual BranchPred *getBranchPred() { return NULL; };
- virtual Counter totalInstructions() const = 0;
+ virtual Counter totalInsts() const = 0;
+
+ virtual Counter totalOps() const = 0;
// Function tracing
private:
void enableFunctionTrace();
void traceFunctionsInternal(Addr pc);
- protected:
+ private:
+ static std::vector<BaseCPU *> cpuList; //!< Static global cpu list
+
+ public:
void traceFunctions(Addr pc)
{
if (functionTracingEnabled)
traceFunctionsInternal(pc);
}
- private:
- static std::vector<BaseCPU *> cpuList; //!< Static global cpu list
-
- public:
static int numSimulatedCPUs() { return cpuList.size(); }
- static Counter numSimulatedInstructions()
+ static Counter numSimulatedInsts()
+ {
+ Counter total = 0;
+
+ int size = cpuList.size();
+ for (int i = 0; i < size; ++i)
+ total += cpuList[i]->totalInsts();
+
+ return total;
+ }
+
+ static Counter numSimulatedOps()
{
Counter total = 0;
int size = cpuList.size();
for (int i = 0; i < size; ++i)
- total += cpuList[i]->totalInstructions();
+ total += cpuList[i]->totalOps();
return total;
}