/*
+ * Copyright (c) 2011-2012,2015 ARM Limited
+ * Copyright (c) 2013 Advanced Micro Devices, Inc.
+ * 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.
*
#ifndef __CPU_SIMPLE_BASE_HH__
#define __CPU_SIMPLE_BASE_HH__
-#include "arch/predecoder.hh"
#include "base/statistics.hh"
#include "config/the_isa.hh"
#include "cpu/base.hh"
-#include "cpu/decode.hh"
+#include "cpu/checker/cpu.hh"
+#include "cpu/exec_context.hh"
#include "cpu/pc_event.hh"
#include "cpu/simple_thread.hh"
#include "cpu/static_inst.hh"
// forward declarations
class Checkpoint;
-class MemObject;
class Process;
class Processor;
class ThreadContext;
{
class DTB;
class ITB;
- class Predecoder;
}
namespace Trace {
class InstRecord;
}
-class BaseSimpleCPUParams;
-
+struct BaseSimpleCPUParams;
+class BPredUnit;
+class SimpleExecContext;
class BaseSimpleCPU : public BaseCPU
{
protected:
- typedef TheISA::MiscReg MiscReg;
- typedef TheISA::FloatReg FloatReg;
- typedef TheISA::FloatRegBits FloatRegBits;
+ ThreadID curThread;
+ BPredUnit *branchPred;
- 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 wakeup();
-
- void zero_fill_64(Addr addr) {
- static int warned = 0;
- if (!warned) {
- warn ("WH64 is not implemented");
- warned = 1;
- }
- };
+ void checkPcEventQueue();
+ void swapActiveThread();
public:
BaseSimpleCPU(BaseSimpleCPUParams *params);
virtual ~BaseSimpleCPU();
-
+ void wakeup(ThreadID tid) override;
+ void init() override;
public:
- /** SimpleThread object, provides all the architectural state. */
- SimpleThread *thread;
+ Trace::InstRecord *traceData;
+ CheckerCPU *checker;
- /** ThreadContext object, provides an interface for external
- * objects to modify this thread's state.
- */
- ThreadContext *tc;
- protected:
+ std::vector<SimpleExecContext*> threadInfo;
+ std::list<ThreadID> activeThreads;
+
+ /** Current instruction */
+ TheISA::MachInst inst;
+ StaticInstPtr curStaticInst;
+ StaticInstPtr curMacroStaticInst;
+ protected:
enum Status {
Idle,
Running,
DcacheRetry,
DcacheWaitResponse,
DcacheWaitSwitch,
- SwitchedOut
};
Status _status;
public:
-
Addr dbg_vtophys(Addr addr);
- bool interval_stats;
-
- // current instruction
- TheISA::MachInst inst;
-
- // The predecoder
- TheISA::Predecoder predecoder;
-
- StaticInstPtr curStaticInst;
- StaticInstPtr curMacroStaticInst;
-
- //This is the offset from the current pc that fetch should be performed at
- Addr fetchOffset;
- //This flag says to stay at the current pc. This is useful for
- //instructions which go beyond MachInst boundaries.
- bool stayAtPC;
void checkForInterrupts();
void setupFetchRequest(Request *req);
void preExecute();
void postExecute();
- void advancePC(Fault fault);
+ void advancePC(const Fault &fault);
- virtual void deallocateContext(int thread_num);
- virtual void haltContext(int thread_num);
+ void haltContext(ThreadID thread_num) override;
// statistics
- virtual void regStats();
- virtual void resetStats();
-
- // number of simulated instructions
- Counter numInst;
- Counter startNumInst;
- Stats::Scalar numInsts;
-
- void countInst()
- {
- numInst++;
- numInsts++;
- system->totalNumInsts++;
- thread->funcExeInst++;
- }
-
- virtual Counter totalInstructions() const
- {
- return numInst - startNumInst;
- }
-
- //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 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::Formula idleFraction;
-
- // number of cycles stalled for I-cache responses
- Stats::Scalar icacheStallCycles;
- Counter lastIcacheStall;
-
- // number of cycles stalled for I-cache retries
- Stats::Scalar icacheRetryCycles;
- Counter lastIcacheRetry;
-
- // number of cycles stalled for D-cache responses
- Stats::Scalar dcacheStallCycles;
- Counter lastDcacheStall;
-
- // number of cycles stalled for D-cache retries
- Stats::Scalar dcacheRetryCycles;
- Counter lastDcacheRetry;
-
- virtual void serialize(std::ostream &os);
- virtual void unserialize(Checkpoint *cp, const std::string §ion);
-
- // 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");
- M5_DUMMY_RETURN}
-
- // 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
- // renaming. We find the architectural register index by indexing
- // into the instruction's own operand index table. Note that a
- // raw pointer to the StaticInst is provided instead of a
- // ref-counted StaticInstPtr to redice overhead. This is fine as
- // long as these methods don't copy the pointer into any long-term
- // storage (which is pretty hard to imagine they would have reason
- // to do).
-
- uint64_t readIntRegOperand(const StaticInst *si, int idx)
- {
- numIntRegReads++;
- return thread->readIntReg(si->srcRegIdx(idx));
- }
-
- 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)
- {
- 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)
- {
- 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)
- {
- numFpRegWrites++;
- int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- thread->setFloatRegBits(reg_idx, 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)
- {
- return thread->readMiscRegNoEffect(misc_reg);
- }
-
- MiscReg readMiscReg(int misc_reg)
- {
- numIntRegReads++;
- return thread->readMiscReg(misc_reg);
- }
-
- void setMiscReg(int misc_reg, const MiscReg &val)
- {
- numIntRegWrites++;
- return thread->setMiscReg(misc_reg, val);
- }
-
- MiscReg readMiscRegOperand(const StaticInst *si, int idx)
- {
- numIntRegReads++;
- int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag;
- return thread->readMiscReg(reg_idx);
- }
-
- 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();
- }
-
- void setStCondFailures(unsigned sc_failures) {
- thread->setStCondFailures(sc_failures);
- }
+ void regStats() override;
+ void resetStats() override;
- MiscReg readRegOtherThread(int regIdx, ThreadID tid = InvalidThreadID)
- {
- panic("Simple CPU models do not support multithreaded "
- "register access.\n");
- }
+ void startup() override;
- void setRegOtherThread(int regIdx, const MiscReg &val,
- ThreadID tid = InvalidThreadID)
- {
- panic("Simple CPU models do not support multithreaded "
- "register access.\n");
- }
+ virtual Fault readMem(Addr addr, uint8_t* data, unsigned size,
+ Request::Flags flags) = 0;
- //Fault CacheOp(uint8_t Op, Addr EA);
+ virtual Fault initiateMemRead(Addr addr, unsigned size,
+ Request::Flags flags) = 0;
- Fault hwrei() { return thread->hwrei(); }
- bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
+ virtual Fault writeMem(uint8_t* data, unsigned size, Addr addr,
+ Request::Flags flags, uint64_t* res) = 0;
- void
- syscall(int64_t callnum)
- {
- if (FullSystem)
- panic("Syscall emulation isn't available in FS mode.\n");
+ void countInst();
+ Counter totalInsts() const override;
+ Counter totalOps() const override;
- thread->syscall(callnum);
- }
+ void serializeThread(CheckpointOut &cp, ThreadID tid) const override;
+ void unserializeThread(CheckpointIn &cp, ThreadID tid) override;
- bool misspeculating() { return thread->misspeculating(); }
- ThreadContext *tcBase() { return tc; }
};
#endif // __CPU_SIMPLE_BASE_HH__