/*
+ * 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
* All rights reserved.
*
#include "arch/predecoder.hh"
#include "base/statistics.hh"
-#include "config/full_system.hh"
+#include "config/the_isa.hh"
#include "cpu/base.hh"
-#include "cpu/simple_thread.hh"
+#include "cpu/checker/cpu.hh"
+#include "cpu/decode.hh"
#include "cpu/pc_event.hh"
+#include "cpu/simple_thread.hh"
#include "cpu/static_inst.hh"
#include "mem/packet.hh"
#include "mem/port.hh"
#include "mem/request.hh"
#include "sim/eventq.hh"
+#include "sim/full_system.hh"
+#include "sim/system.hh"
// forward declarations
-#if FULL_SYSTEM
-class Processor;
-namespace TheISA
-{
- class ITB;
- class DTB;
-}
-class MemObject;
-
-#else
-
+class Checkpoint;
class Process;
-
-#endif // FULL_SYSTEM
-
-class RemoteGDB;
-class GDBListener;
+class Processor;
+class ThreadContext;
namespace TheISA
{
+ class DTB;
+ class ITB;
class Predecoder;
}
-class ThreadContext;
-class Checkpoint;
namespace Trace {
class InstRecord;
}
+struct BaseSimpleCPUParams;
+
class BaseSimpleCPU : public BaseCPU
{
protected:
Trace::InstRecord *traceData;
+ inline void checkPcEventQueue() {
+ Addr oldpc, pc = thread->instAddr();
+ do {
+ oldpc = pc;
+ system->pcEventQueue.service(tc);
+ pc = thread->instAddr();
+ } while (oldpc != pc);
+ }
+
public:
- void post_interrupt(int int_num, int index);
+ void wakeup();
void zero_fill_64(Addr addr) {
static int warned = 0;
};
public:
- struct Params : public BaseCPU::Params
- {
-#if FULL_SYSTEM
- TheISA::ITB *itb;
- TheISA::DTB *dtb;
-#else
- Process *process;
-#endif
- };
- BaseSimpleCPU(Params *params);
+ BaseSimpleCPU(BaseSimpleCPUParams *params);
virtual ~BaseSimpleCPU();
public:
*/
ThreadContext *tc;
-#if FULL_SYSTEM
+ CheckerCPU *checker;
+
+ protected:
+
+ enum Status {
+ Idle,
+ Running,
+ Faulting,
+ ITBWaitResponse,
+ IcacheRetry,
+ IcacheWaitResponse,
+ IcacheWaitSwitch,
+ DTBWaitResponse,
+ DcacheRetry,
+ DcacheWaitResponse,
+ DcacheWaitSwitch,
+ SwitchedOut
+ };
+
+ Status _status;
+
+ public:
+
Addr dbg_vtophys(Addr addr);
bool interval_stats;
-#endif
// current instruction
TheISA::MachInst inst;
bool stayAtPC;
void checkForInterrupts();
- Fault setupFetchRequest(Request *req);
+ void setupFetchRequest(Request *req);
void preExecute();
void postExecute();
void advancePC(Fault fault);
- virtual void deallocateContext(int thread_num);
- virtual void haltContext(int thread_num);
+ virtual void deallocateContext(ThreadID thread_num);
+ virtual void haltContext(ThreadID thread_num);
// statistics
virtual void regStats();
// number of simulated instructions
Counter numInst;
Counter startNumInst;
- Stats::Scalar<> numInsts;
+ Stats::Scalar numInsts;
+ Counter numOp;
+ Counter startNumOp;
+ Stats::Scalar numOps;
+
+ void countInst()
+ {
+ if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
+ numInst++;
+ numInsts++;
+ }
+ numOp++;
+ numOps++;
+
+ system->totalNumInsts++;
+ thread->funcExeInst++;
+ }
- virtual Counter totalInstructions() const
+ virtual Counter totalInsts() const
{
return numInst - startNumInst;
}
- // Mask to align PCs to MachInst sized boundaries
- static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1);
+ virtual Counter totalOps() const
+ {
+ return numOp - startNumOp;
+ }
+
+ //number of integer alu accesses
+ Stats::Scalar numIntAluAccesses;
+
+ //number of float alu accesses
+ Stats::Scalar numFpAluAccesses;
+
+ //number of function calls/returns
+ Stats::Scalar numCallsReturns;
+
+ //conditional control instructions;
+ Stats::Scalar numCondCtrlInsts;
+
+ //number of int instructions
+ Stats::Scalar numIntInsts;
+
+ //number of float instructions
+ Stats::Scalar numFpInsts;
+
+ //number of integer register file accesses
+ Stats::Scalar numIntRegReads;
+ Stats::Scalar numIntRegWrites;
+
+ //number of float register file accesses
+ Stats::Scalar numFpRegReads;
+ Stats::Scalar numFpRegWrites;
// number of simulated memory references
- Stats::Scalar<> numMemRefs;
+ Stats::Scalar numMemRefs;
+ Stats::Scalar numLoadInsts;
+ Stats::Scalar numStoreInsts;
+
+ // number of idle cycles
+ Stats::Formula numIdleCycles;
+
+ // number of busy cycles
+ Stats::Formula numBusyCycles;
// number of simulated loads
Counter numLoad;
Counter startNumLoad;
// number of idle cycles
- Stats::Average<> notIdleFraction;
+ Stats::Average notIdleFraction;
Stats::Formula idleFraction;
// number of cycles stalled for I-cache responses
- Stats::Scalar<> icacheStallCycles;
+ Stats::Scalar icacheStallCycles;
Counter lastIcacheStall;
// number of cycles stalled for I-cache retries
- Stats::Scalar<> icacheRetryCycles;
+ Stats::Scalar icacheRetryCycles;
Counter lastIcacheRetry;
// number of cycles stalled for D-cache responses
- Stats::Scalar<> dcacheStallCycles;
+ Stats::Scalar dcacheStallCycles;
Counter lastDcacheStall;
// number of cycles stalled for D-cache retries
- Stats::Scalar<> dcacheRetryCycles;
+ Stats::Scalar dcacheRetryCycles;
Counter lastDcacheRetry;
virtual void serialize(std::ostream &os);
// These functions are only used in CPU models that split
// effective address computation from the actual memory access.
void setEA(Addr EA) { panic("BaseSimpleCPU::setEA() not implemented\n"); }
- Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n");
+ Addr getEA() { panic("BaseSimpleCPU::getEA() not implemented\n");
M5_DUMMY_RETURN}
- void prefetch(Addr addr, unsigned flags)
- {
- // need to do this...
- }
-
- void writeHint(Addr addr, int size, unsigned flags)
- {
- // need to do this...
- }
-
-
- Fault copySrcTranslate(Addr src);
-
- Fault copy(Addr dest);
-
// The register accessor methods provide the index of the
// instruction's operand (e.g., 0 or 1), not the architectural
// register index, to simplify the implementation of register
uint64_t readIntRegOperand(const StaticInst *si, int idx)
{
+ numIntRegReads++;
return thread->readIntReg(si->srcRegIdx(idx));
}
- FloatReg readFloatRegOperand(const StaticInst *si, int idx, int width)
- {
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return thread->readFloatReg(reg_idx, width);
- }
-
FloatReg readFloatRegOperand(const StaticInst *si, int idx)
{
+ numFpRegReads++;
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return thread->readFloatReg(reg_idx);
}
- FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx,
- int width)
- {
- int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return thread->readFloatRegBits(reg_idx, width);
- }
-
FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx)
{
+ numFpRegReads++;
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return thread->readFloatRegBits(reg_idx);
}
void setIntRegOperand(const StaticInst *si, int idx, uint64_t val)
{
+ numIntRegWrites++;
thread->setIntReg(si->destRegIdx(idx), val);
}
- void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val,
- int width)
- {
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- thread->setFloatReg(reg_idx, val, width);
- }
-
void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val)
{
+ numFpRegWrites++;
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
thread->setFloatReg(reg_idx, val);
}
- void setFloatRegOperandBits(const StaticInst *si, int idx,
- FloatRegBits val, int width)
- {
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- thread->setFloatRegBits(reg_idx, val, width);
- }
-
void setFloatRegOperandBits(const StaticInst *si, int idx,
FloatRegBits val)
{
+ numFpRegWrites++;
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
thread->setFloatRegBits(reg_idx, val);
}
- uint64_t readPC() { return thread->readPC(); }
- uint64_t readNextPC() { return thread->readNextPC(); }
- uint64_t readNextNPC() { return thread->readNextNPC(); }
-
- void setPC(uint64_t val) { thread->setPC(val); }
- void setNextPC(uint64_t val) { thread->setNextPC(val); }
- void setNextNPC(uint64_t val) { thread->setNextNPC(val); }
+ bool readPredicate() { return thread->readPredicate(); }
+ void setPredicate(bool val)
+ {
+ thread->setPredicate(val);
+ if (traceData) {
+ traceData->setPredicate(val);
+ }
+ }
+ TheISA::PCState pcState() { return thread->pcState(); }
+ void pcState(const TheISA::PCState &val) { thread->pcState(val); }
+ Addr instAddr() { return thread->instAddr(); }
+ Addr nextInstAddr() { return thread->nextInstAddr(); }
+ MicroPC microPC() { return thread->microPC(); }
MiscReg readMiscRegNoEffect(int misc_reg)
{
MiscReg readMiscReg(int misc_reg)
{
+ numIntRegReads++;
return thread->readMiscReg(misc_reg);
}
- void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
- {
- return thread->setMiscRegNoEffect(misc_reg, val);
- }
-
void setMiscReg(int misc_reg, const MiscReg &val)
{
+ numIntRegWrites++;
return thread->setMiscReg(misc_reg, val);
}
- MiscReg readMiscRegOperandNoEffect(const StaticInst *si, int idx)
- {
- int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
- return thread->readMiscRegNoEffect(reg_idx);
- }
-
MiscReg readMiscRegOperand(const StaticInst *si, int idx)
{
+ numIntRegReads++;
int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
return thread->readMiscReg(reg_idx);
}
- void setMiscRegOperandNoEffect(const StaticInst *si, int idx, const MiscReg &val)
- {
- int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
- return thread->setMiscRegNoEffect(reg_idx, val);
- }
-
void setMiscRegOperand(
const StaticInst *si, int idx, const MiscReg &val)
{
+ numIntRegWrites++;
int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
return thread->setMiscReg(reg_idx, val);
}
+ void demapPage(Addr vaddr, uint64_t asn)
+ {
+ thread->demapPage(vaddr, asn);
+ }
+
+ void demapInstPage(Addr vaddr, uint64_t asn)
+ {
+ thread->demapInstPage(vaddr, asn);
+ }
+
+ void demapDataPage(Addr vaddr, uint64_t asn)
+ {
+ thread->demapDataPage(vaddr, asn);
+ }
+
unsigned readStCondFailures() {
return thread->readStCondFailures();
}
thread->setStCondFailures(sc_failures);
}
- MiscReg readRegOtherThread(int regIdx, int tid = -1)
+ MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
{
panic("Simple CPU models do not support multithreaded "
"register access.\n");
}
- void setRegOtherThread(int regIdx, const MiscReg &val, int tid = -1)
+ void setRegOtherThread(int regIdx, const MiscReg &val,
+ ThreadID tid = InvalidThreadID)
{
panic("Simple CPU models do not support multithreaded "
"register access.\n");
}
-#if FULL_SYSTEM
+ //Fault CacheOp(uint8_t Op, Addr EA);
+
Fault hwrei() { return thread->hwrei(); }
- void ev5_trap(Fault fault) { fault->invoke(tc); }
bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
-#else
- void syscall(int64_t callnum) { thread->syscall(callnum); }
-#endif
+
+ void
+ syscall(int64_t callnum)
+ {
+ if (FullSystem)
+ panic("Syscall emulation isn't available in FS mode.\n");
+
+ thread->syscall(callnum);
+ }
bool misspeculating() { return thread->misspeculating(); }
ThreadContext *tcBase() { return tc; }