Reorganization/renaming of CPUExecContext. Now it is called SimpleThread in order to clear up the confusion due to the many ExecContexts. It also derives from a common ThreadState object, which holds various state common to threads across CPU models.

Following with the previous check-in, ExecContext now refers only to the interface provided to the ISA in order to access CPU state.  ThreadContext refers to the interface provided to all objects outside the CPU in order to access thread state.  SimpleThread provides all thread state and the interface to access it, and is suitable for simple execution models such as the SimpleCPU.

src/SConscript:
    Include thread state file.
src/arch/alpha/ev5.cc:
src/cpu/checker/cpu.cc:
src/cpu/checker/cpu.hh:
src/cpu/checker/thread_context.hh:
src/cpu/memtest/memtest.cc:
src/cpu/memtest/memtest.hh:
src/cpu/o3/cpu.cc:
src/cpu/ozone/cpu_impl.hh:
src/cpu/simple/atomic.cc:
src/cpu/simple/base.cc:
src/cpu/simple/base.hh:
src/cpu/simple/timing.cc:
    Rename CPUExecContext to SimpleThread.
src/cpu/base_dyn_inst.hh:
    Make thread member variables protected..
src/cpu/o3/alpha_cpu.hh:
src/cpu/o3/cpu.hh:
    Make various members of ThreadState protected.
src/cpu/o3/alpha_cpu_impl.hh:
    Push generation of TranslatingPort into the CPU itself.
    Make various members of ThreadState protected.
src/cpu/o3/thread_state.hh:
    Pull a lot of common code into the base ThreadState class.
src/cpu/ozone/thread_state.hh:
    Rename CPUExecContext to SimpleThread, move a lot of common code into base ThreadState class.
src/cpu/thread_state.hh:
    Push a lot of common code into base ThreadState class.  This goes along with renaming CPUExecContext to SimpleThread, and making it derive from ThreadState.
src/cpu/simple_thread.cc:
    Rename CPUExecContext to SimpleThread, make it derive from ThreadState.  This helps push a lot of common code/state into a single class that can be used by all CPUs.
src/cpu/simple_thread.hh:
    Rename CPUExecContext to SimpleThread, make it derive from ThreadState.
src/kern/system_events.cc:
    Rename cpu_exec_context to thread_context.
src/sim/process.hh:
    Remove unused forward declaration.

--HG--
rename : src/cpu/cpu_exec_context.cc => src/cpu/simple_thread.cc
rename : src/cpu/cpu_exec_context.hh => src/cpu/simple_thread.hh
extra : convert_revision : 2ed617aa80b64016cb9270f75352607cca032733
This commit is contained in:
Kevin Lim 2006-06-07 15:29:53 -04:00
parent 6915513b97
commit 54d4220b00
25 changed files with 610 additions and 604 deletions

View file

@ -83,7 +83,6 @@ base_sources = Split('''
cpu/activity.cc
cpu/base.cc
cpu/cpu_exec_context.cc
cpu/cpuevent.cc
cpu/exetrace.cc
cpu/op_class.cc
@ -91,6 +90,8 @@ base_sources = Split('''
cpu/quiesce_event.cc
cpu/static_inst.cc
cpu/sampler/sampler.cc
cpu/simple_thread.cc
cpu/thread_state.cc
encumbered/cpu/full/fu_pool.cc

View file

@ -37,7 +37,7 @@
#include "base/stats/events.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "kern/kernel_stats.hh"
#include "sim/debug.hh"
@ -135,12 +135,12 @@ AlphaISA::zeroRegisters(CPU *cpu)
// Insure ISA semantics
// (no longer very clean due to the change in setIntReg() in the
// cpu model. Consider changing later.)
cpu->cpuXC->setIntReg(ZeroReg, 0);
cpu->cpuXC->setFloatReg(ZeroReg, 0.0);
cpu->thread->setIntReg(ZeroReg, 0);
cpu->thread->setFloatReg(ZeroReg, 0.0);
}
Fault
CPUExecContext::hwrei()
SimpleThread::hwrei()
{
if (!inPalMode())
return new UnimplementedOpcodeFault;
@ -562,7 +562,7 @@ AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest)
* If return value is false, actual PAL call will be suppressed.
*/
bool
CPUExecContext::simPalCheck(int palFunc)
SimpleThread::simPalCheck(int palFunc)
{
if (kernelStats)
kernelStats->callpal(palFunc, tc);

View file

@ -650,7 +650,7 @@ BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags)
req = new Request();
req->setVirt(asid, addr, sizeof(T), flags, this->PC);
req->setThreadContext(thread->cpuId, threadNumber);
req->setThreadContext(thread->readCpuId(), threadNumber);
if ((req->getVaddr() & (TheISA::VMPageSize - 1)) + req->getSize() >
TheISA::VMPageSize) {
@ -705,7 +705,7 @@ BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res)
req = new Request();
req->setVirt(asid, addr, sizeof(T), flags, this->PC);
req->setThreadContext(thread->cpuId, threadNumber);
req->setThreadContext(thread->readCpuId(), threadNumber);
if ((req->getVaddr() & (TheISA::VMPageSize - 1)) + req->getSize() >
TheISA::VMPageSize) {

View file

@ -33,7 +33,7 @@
#include "cpu/base.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "cpu/static_inst.hh"
#include "sim/byteswap.hh"
@ -62,7 +62,7 @@ CheckerCPU::init()
}
CheckerCPU::CheckerCPU(Params *p)
: BaseCPU(p), cpuXC(NULL), tc(NULL)
: BaseCPU(p), thread(NULL), tc(NULL)
{
memReq = NULL;
@ -94,21 +94,21 @@ CheckerCPU::setMemory(MemObject *mem)
{
memPtr = mem;
#if !FULL_SYSTEM
cpuXC = new CPUExecContext(this, /* thread_num */ 0, process,
/* asid */ 0, mem);
thread = new SimpleThread(this, /* thread_num */ 0, process,
/* asid */ 0, mem);
cpuXC->setStatus(ThreadContext::Suspended);
tc = cpuXC->getTC();
thread->setStatus(ThreadContext::Suspended);
tc = thread->getTC();
threadContexts.push_back(tc);
#else
if (systemPtr) {
cpuXC = new CPUExecContext(this, 0, systemPtr, itb, dtb, memPtr, false);
thread = new SimpleThread(this, 0, systemPtr, itb, dtb, memPtr, false);
cpuXC->setStatus(ThreadContext::Suspended);
tc = cpuXC->getTC();
thread->setStatus(ThreadContext::Suspended);
tc = thread->getTC();
threadContexts.push_back(tc);
delete cpuXC->kernelStats;
cpuXC->kernelStats = NULL;
delete thread->kernelStats;
thread->kernelStats = NULL;
}
#endif
}
@ -120,13 +120,13 @@ CheckerCPU::setSystem(System *system)
systemPtr = system;
if (memPtr) {
cpuXC = new CPUExecContext(this, 0, systemPtr, itb, dtb, memPtr, false);
thread = new SimpleThread(this, 0, systemPtr, itb, dtb, memPtr, false);
cpuXC->setStatus(ThreadContext::Suspended);
tc = cpuXC->getTC();
thread->setStatus(ThreadContext::Suspended);
tc = thread->getTC();
threadContexts.push_back(tc);
delete cpuXC->kernelStats;
cpuXC->kernelStats = NULL;
delete thread->kernelStats;
thread->kernelStats = NULL;
}
}
#endif
@ -150,7 +150,7 @@ CheckerCPU::serialize(ostream &os)
BaseCPU::serialize(os);
SERIALIZE_SCALAR(inst);
nameOut(os, csprintf("%s.xc", name()));
cpuXC->serialize(os);
thread->serialize(os);
cacheCompletionEvent.serialize(os);
*/
}
@ -161,7 +161,7 @@ CheckerCPU::unserialize(Checkpoint *cp, const string &section)
/*
BaseCPU::unserialize(cp, section);
UNSERIALIZE_SCALAR(inst);
cpuXC->unserialize(cp, csprintf("%s.xc", section));
thread->unserialize(cp, csprintf("%s.xc", section));
*/
}
@ -184,7 +184,7 @@ CheckerCPU::read(Addr addr, T &data, unsigned flags)
// need to fill in CPU & thread IDs here
memReq = new Request();
memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC());
// translate to physical address
translateDataReadReq(memReq);
@ -254,10 +254,10 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
// need to fill in CPU & thread IDs here
memReq = new Request();
memReq->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC());
// translate to physical address
cpuXC->translateDataWriteReq(memReq);
thread->translateDataWriteReq(memReq);
// Can compare the write data and result only if it's cacheable,
// not a store conditional, or is a store conditional that
@ -356,9 +356,9 @@ bool
CheckerCPU::translateInstReq(Request *req)
{
#if FULL_SYSTEM
return (cpuXC->translateInstReq(req) == NoFault);
return (thread->translateInstReq(req) == NoFault);
#else
cpuXC->translateInstReq(req);
thread->translateInstReq(req);
return true;
#endif
}
@ -366,7 +366,7 @@ CheckerCPU::translateInstReq(Request *req)
void
CheckerCPU::translateDataReadReq(Request *req)
{
cpuXC->translateDataReadReq(req);
thread->translateDataReadReq(req);
if (req->getVaddr() != unverifiedReq->getVaddr()) {
warn("%lli: Request virtual addresses do not match! Inst: %#x, "
@ -386,7 +386,7 @@ CheckerCPU::translateDataReadReq(Request *req)
void
CheckerCPU::translateDataWriteReq(Request *req)
{
cpuXC->translateDataWriteReq(req);
thread->translateDataWriteReq(req);
if (req->getVaddr() != unverifiedReq->getVaddr()) {
warn("%lli: Request virtual addresses do not match! Inst: %#x, "
@ -475,9 +475,9 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
Fault fault = NoFault;
// maintain $r0 semantics
cpuXC->setIntReg(ZeroReg, 0);
thread->setIntReg(ZeroReg, 0);
#ifdef TARGET_ALPHA
cpuXC->setFloatRegDouble(ZeroReg, 0.0);
thread->setFloatRegDouble(ZeroReg, 0.0);
#endif // TARGET_ALPHA
// Check if any recent PC changes match up with anything we
@ -485,14 +485,14 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
// PC-based events have occurred in both the checker and CPU.
if (changedPC) {
DPRINTF(Checker, "Changed PC recently to %#x\n",
cpuXC->readPC());
thread->readPC());
if (willChangePC) {
if (newPC == cpuXC->readPC()) {
if (newPC == thread->readPC()) {
DPRINTF(Checker, "Changed PC matches expected PC\n");
} else {
warn("%lli: Changed PC does not match expected PC, "
"changed: %#x, expected: %#x",
curTick, cpuXC->readPC(), newPC);
curTick, thread->readPC(), newPC);
handleError();
}
willChangePC = false;
@ -501,7 +501,7 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
}
if (changedNextPC) {
DPRINTF(Checker, "Changed NextPC recently to %#x\n",
cpuXC->readNextPC());
thread->readNextPC());
changedNextPC = false;
}
@ -513,13 +513,13 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
#define IFETCH_FLAGS(pc) 0
#endif
uint64_t fetch_PC = cpuXC->readPC() & ~3;
uint64_t fetch_PC = thread->readPC() & ~3;
// set up memory request for instruction fetch
memReq = new Request(inst->threadNumber, fetch_PC,
sizeof(uint32_t),
IFETCH_FLAGS(cpuXC->readPC()),
fetch_PC, cpuXC->readCpuId(), inst->threadNumber);
IFETCH_FLAGS(thread->readPC()),
fetch_PC, thread->readCpuId(), inst->threadNumber);
bool succeeded = translateInstReq(memReq);
@ -531,12 +531,12 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
// translate this instruction; in the SMT case it's
// possible that its ITB entry was kicked out.
warn("%lli: Instruction PC %#x was not found in the ITB!",
curTick, cpuXC->readPC());
curTick, thread->readPC());
handleError();
// go to the next instruction
cpuXC->setPC(cpuXC->readNextPC());
cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst));
thread->setPC(thread->readNextPC());
thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
return;
} else {
@ -567,10 +567,10 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
validateInst(inst);
curStaticInst = StaticInst::decode(makeExtMI(machInst,
cpuXC->readPC()));
thread->readPC()));
#if FULL_SYSTEM
cpuXC->setInst(machInst);
thread->setInst(machInst);
#endif // FULL_SYSTEM
fault = inst->getFault();
@ -585,7 +585,7 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
// that the instruction is properly marked as a fault.
if (fault == NoFault) {
cpuXC->func_exe_inst++;
thread->funcExeInst++;
fault = curStaticInst->execute(this, NULL);
@ -601,21 +601,21 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
#if FULL_SYSTEM
fault->invoke(xcProxy);
willChangePC = true;
newPC = cpuXC->readPC();
newPC = thread->readPC();
DPRINTF(Checker, "Fault, PC is now %#x\n", newPC);
#else // !FULL_SYSTEM
fatal("fault (%d) detected @ PC 0x%08p", fault, cpuXC->readPC());
fatal("fault (%d) detected @ PC 0x%08p", fault, thread->readPC());
#endif // FULL_SYSTEM
} else {
#if THE_ISA != MIPS_ISA
// go to the next instruction
cpuXC->setPC(cpuXC->readNextPC());
cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst));
thread->setPC(thread->readNextPC());
thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
#else
// go to the next instruction
cpuXC->setPC(cpuXC->readNextPC());
cpuXC->setNextPC(cpuXC->readNextNPC());
cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst));
thread->setPC(thread->readNextPC());
thread->setNextPC(thread->readNextNPC());
thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
#endif
}
@ -627,13 +627,13 @@ Checker<DynInstPtr>::tick(DynInstPtr &completed_inst)
Addr oldpc;
int count = 0;
do {
oldpc = cpuXC->readPC();
oldpc = thread->readPC();
system->pcEventQueue.service(xcProxy);
count++;
} while (oldpc != cpuXC->readPC());
} while (oldpc != thread->readPC());
if (count > 1) {
willChangePC = true;
newPC = cpuXC->readPC();
newPC = thread->readPC();
DPRINTF(Checker, "PC Event, PC is now %#x\n", newPC);
}
#endif
@ -677,9 +677,9 @@ template <class DynInstPtr>
void
Checker<DynInstPtr>::validateInst(DynInstPtr &inst)
{
if (inst->readPC() != cpuXC->readPC()) {
if (inst->readPC() != thread->readPC()) {
warn("%lli: PCs do not match! Inst: %#x, checker: %#x",
curTick, inst->readPC(), cpuXC->readPC());
curTick, inst->readPC(), thread->readPC());
if (changedPC) {
warn("%lli: Changed PCs recently, may not be an error",
curTick);
@ -710,11 +710,11 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
// instruction and write it to the register.
RegIndex idx = inst->destRegIdx(0);
if (idx < TheISA::FP_Base_DepTag) {
cpuXC->setIntReg(idx, inst->readIntResult());
thread->setIntReg(idx, inst->readIntResult());
} else if (idx < TheISA::Fpcr_DepTag) {
cpuXC->setFloatRegBits(idx, inst->readIntResult());
thread->setFloatRegBits(idx, inst->readIntResult());
} else {
cpuXC->setMiscReg(idx, inst->readIntResult());
thread->setMiscReg(idx, inst->readIntResult());
}
} else if (result.integer != inst->readIntResult()) {
warn("%lli: Instruction results do not match! (Values may not "
@ -724,10 +724,10 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
}
}
if (inst->readNextPC() != cpuXC->readNextPC()) {
if (inst->readNextPC() != thread->readNextPC()) {
warn("%lli: Instruction next PCs do not match! Inst: %#x, "
"checker: %#x",
curTick, inst->readNextPC(), cpuXC->readNextPC());
curTick, inst->readNextPC(), thread->readNextPC());
handleError();
}
@ -741,12 +741,12 @@ Checker<DynInstPtr>::validateExecution(DynInstPtr &inst)
miscRegIdxs.pop();
if (inst->tcBase()->readMiscReg(misc_reg_idx) !=
cpuXC->readMiscReg(misc_reg_idx)) {
thread->readMiscReg(misc_reg_idx)) {
warn("%lli: Misc reg idx %i (side effect) does not match! "
"Inst: %#x, checker: %#x",
curTick, misc_reg_idx,
inst->tcBase()->readMiscReg(misc_reg_idx),
cpuXC->readMiscReg(misc_reg_idx));
thread->readMiscReg(misc_reg_idx));
handleError();
}
}

View file

@ -38,7 +38,7 @@
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/base_dyn_inst.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/simple_thread.hh"
#include "cpu/pc_event.hh"
#include "cpu/static_inst.hh"
#include "sim/eventq.hh"
@ -77,7 +77,7 @@ class Sampler;
* instructions marked as "IsUnverifiable", the checker assumes that
* the value from the main CPU's execution is correct and simply
* copies that value. It provides a CheckerThreadContext (see
* checker/exec_context.hh) that provides hooks for updating the
* checker/thread_context.hh) that provides hooks for updating the
* Checker's state through any ThreadContext accesses. This allows the
* checker to be able to correctly verify instructions, even with
* external accesses to the ThreadContext that change state.
@ -129,8 +129,8 @@ class CheckerCPU : public BaseCPU
Port *dcachePort;
public:
// execution context
CPUExecContext *cpuXC;
// Primary thread being run.
SimpleThread *thread;
ThreadContext *tc;
@ -213,43 +213,43 @@ class CheckerCPU : public BaseCPU
uint64_t readIntReg(const StaticInst *si, int idx)
{
return cpuXC->readIntReg(si->srcRegIdx(idx));
return thread->readIntReg(si->srcRegIdx(idx));
}
FloatReg readFloatReg(const StaticInst *si, int idx, int width)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return cpuXC->readFloatReg(reg_idx, width);
return thread->readFloatReg(reg_idx, width);
}
FloatReg readFloatReg(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return cpuXC->readFloatReg(reg_idx);
return thread->readFloatReg(reg_idx);
}
FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return cpuXC->readFloatRegBits(reg_idx, width);
return thread->readFloatRegBits(reg_idx, width);
}
FloatRegBits readFloatRegBits(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return cpuXC->readFloatRegBits(reg_idx);
return thread->readFloatRegBits(reg_idx);
}
void setIntReg(const StaticInst *si, int idx, uint64_t val)
{
cpuXC->setIntReg(si->destRegIdx(idx), val);
thread->setIntReg(si->destRegIdx(idx), val);
result.integer = val;
}
void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
cpuXC->setFloatReg(reg_idx, val, width);
thread->setFloatReg(reg_idx, val, width);
switch(width) {
case 32:
result.fp = val;
@ -263,7 +263,7 @@ class CheckerCPU : public BaseCPU
void setFloatReg(const StaticInst *si, int idx, FloatReg val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
cpuXC->setFloatReg(reg_idx, val);
thread->setFloatReg(reg_idx, val);
result.fp = val;
}
@ -271,46 +271,46 @@ class CheckerCPU : public BaseCPU
int width)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
cpuXC->setFloatRegBits(reg_idx, val, width);
thread->setFloatRegBits(reg_idx, val, width);
result.integer = val;
}
void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
cpuXC->setFloatRegBits(reg_idx, val);
thread->setFloatRegBits(reg_idx, val);
result.integer = val;
}
uint64_t readPC() { return cpuXC->readPC(); }
uint64_t readPC() { return thread->readPC(); }
uint64_t readNextPC() { return cpuXC->readNextPC(); }
uint64_t readNextPC() { return thread->readNextPC(); }
void setNextPC(uint64_t val) {
cpuXC->setNextPC(val);
thread->setNextPC(val);
}
MiscReg readMiscReg(int misc_reg)
{
return cpuXC->readMiscReg(misc_reg);
return thread->readMiscReg(misc_reg);
}
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
{
return cpuXC->readMiscRegWithEffect(misc_reg, fault);
return thread->readMiscRegWithEffect(misc_reg, fault);
}
Fault setMiscReg(int misc_reg, const MiscReg &val)
{
result.integer = val;
miscRegIdxs.push(misc_reg);
return cpuXC->setMiscReg(misc_reg, val);
return thread->setMiscReg(misc_reg, val);
}
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
miscRegIdxs.push(misc_reg);
return cpuXC->setMiscRegWithEffect(misc_reg, val);
return thread->setMiscRegWithEffect(misc_reg, val);
}
void recordPCChange(uint64_t val) { changedPC = true; }
@ -321,12 +321,12 @@ class CheckerCPU : public BaseCPU
void translateDataReadReq(Request *req);
#if FULL_SYSTEM
Fault hwrei() { return cpuXC->hwrei(); }
int readIntrFlag() { return cpuXC->readIntrFlag(); }
void setIntrFlag(int val) { cpuXC->setIntrFlag(val); }
bool inPalMode() { return cpuXC->inPalMode(); }
Fault hwrei() { return thread->hwrei(); }
int readIntrFlag() { return thread->readIntrFlag(); }
void setIntrFlag(int val) { thread->setIntrFlag(val); }
bool inPalMode() { return thread->inPalMode(); }
void ev5_trap(Fault fault) { fault->invoke(xcProxy); }
bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); }
bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
#else
// Assume that the normal CPU's call to syscall was successful.
// The checker's state would have already been updated by the syscall.
@ -341,7 +341,7 @@ class CheckerCPU : public BaseCPU
bool checkFlags(Request *req);
ThreadContext *tcBase() { return tc; }
CPUExecContext *cpuXCBase() { return cpuXC; }
SimpleThread *threadBase() { return thread; }
Result unverifiedResult;
Request *unverifiedReq;

View file

@ -26,11 +26,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __CPU_CHECKER_EXEC_CONTEXT_HH__
#define __CPU_CHECKER_EXEC_CONTEXT_HH__
#ifndef __CPU_CHECKER_THREAD_CONTEXT_HH__
#define __CPU_CHECKER_THREAD_CONTEXT_HH__
#include "cpu/checker/cpu.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
class EndQuiesceEvent;
@ -41,23 +41,30 @@ namespace Kernel {
/**
* Derived ThreadContext class for use with the Checker. The template
* parameter is the ThreadContext class used by the specific CPU being
* verified. This CheckerThreadContext is then used by the main CPU in
* place of its usual ThreadContext class. It handles updating the
* checker's state any time state is updated through the ThreadContext.
* verified. This CheckerThreadContext is then used by the main CPU
* in place of its usual ThreadContext class. It handles updating the
* checker's state any time state is updated externally through the
* ThreadContext.
*/
template <class TC>
class CheckerThreadContext : public ThreadContext
{
public:
CheckerThreadContext(TC *actual_tc,
CheckerCPU *checker_cpu)
: actualTC(actual_tc), checkerTC(checker_cpu->cpuXC),
CheckerCPU *checker_cpu)
: actualTC(actual_tc), checkerTC(checker_cpu->thread),
checkerCPU(checker_cpu)
{ }
private:
/** The main CPU's ThreadContext, or class that implements the
* ThreadContext interface. */
TC *actualTC;
CPUExecContext *checkerTC;
/** The checker's own SimpleThread. Will be updated any time
* anything uses this ThreadContext to externally update a
* thread's state. */
SimpleThread *checkerTC;
/** Pointer to the checker CPU. */
CheckerCPU *checkerCPU;
public:

View file

@ -38,7 +38,7 @@
#include "base/misc.hh"
#include "base/statistics.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/simple_thread.hh"
#include "cpu/memtest/memtest.hh"
#include "mem/cache/base_cache.hh"
#include "sim/builder.hh"
@ -81,7 +81,7 @@ MemTest::MemTest(const string &name,
vector<string> cmd;
cmd.push_back("/bin/ls");
vector<string> null_vec;
cpuXC = new CPUExecContext(NULL, 0, mainMem, 0);
thread = new SimpleThread(NULL, 0, mainMem, 0);
blockSize = cacheInterface->getBlockSize();
blockAddrMask = blockSize - 1;
@ -271,7 +271,7 @@ MemTest::tick()
req->data = new uint8_t[req->size];
req->paddr &= ~(req->size - 1);
req->time = curTick;
req->xc = cpuXC->getProxy();
req->xc = thread->getProxy();
if (cmd < percentReads) {
// read

View file

@ -86,7 +86,7 @@ class MemTest : public SimObject
MemInterface *cacheInterface;
FunctionalMemory *mainMem;
FunctionalMemory *checkMem;
CPUExecContext *cpuXC;
SimpleThread *thread;
unsigned size; // size of testing memory region

View file

@ -96,7 +96,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
/** Reads this CPU's ID. */
virtual int readCpuId() { return cpu->cpu_id; }
virtual TranslatingPort *getMemPort() { return thread->port; }
virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
#if FULL_SYSTEM
/** Returns a pointer to the system. */
@ -116,7 +116,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
{ return thread->kernelStats; }
#else
/** Returns a pointer to this thread's process. */
virtual Process *getProcessPtr() { return thread->process; }
virtual Process *getProcessPtr() { return thread->getProcessPtr(); }
#endif
/** Returns this thread's status. */
virtual Status status() const { return thread->status(); }
@ -170,7 +170,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
virtual void profileSample();
#endif
/** Returns this thread's ID number. */
virtual int getThreadNum() { return thread->tid; }
virtual int getThreadNum() { return thread->readTid(); }
/** Returns the instruction this thread is currently committing.
* Only used when an instruction faults.
@ -207,14 +207,14 @@ class AlphaFullCPU : public FullO3CPU<Impl>
/** Reads this thread's PC. */
virtual uint64_t readPC()
{ return cpu->readPC(thread->tid); }
{ return cpu->readPC(thread->readTid()); }
/** Sets this thread's PC. */
virtual void setPC(uint64_t val);
/** Reads this thread's next PC. */
virtual uint64_t readNextPC()
{ return cpu->readNextPC(thread->tid); }
{ return cpu->readNextPC(thread->readTid()); }
/** Sets this thread's next PC. */
virtual void setNextPC(uint64_t val);
@ -230,12 +230,12 @@ class AlphaFullCPU : public FullO3CPU<Impl>
/** Reads a miscellaneous register. */
virtual MiscReg readMiscReg(int misc_reg)
{ return cpu->readMiscReg(misc_reg, thread->tid); }
{ return cpu->readMiscReg(misc_reg, thread->readTid()); }
/** Reads a misc. register, including any side-effects the
* read might have as defined by the architecture. */
virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
{ return cpu->readMiscRegWithEffect(misc_reg, fault, thread->tid); }
{ return cpu->readMiscRegWithEffect(misc_reg, fault, thread->readTid()); }
/** Sets a misc. register. */
virtual Fault setMiscReg(int misc_reg, const MiscReg &val);
@ -257,7 +257,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
/** Returns if the thread is currently in PAL mode, based on
* the PC's value. */
virtual bool inPalMode()
{ return TheISA::PcPAL(cpu->readPC(thread->tid)); }
{ return TheISA::PcPAL(cpu->readPC(thread->readTid())); }
#endif
// Only really makes sense for old CPU model. Lots of code
// outside the CPU still checks this function, so it will
@ -279,7 +279,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
/** Executes a syscall in SE mode. */
virtual void syscall(int64_t callnum)
{ return cpu->syscall(callnum, thread->tid); }
{ return cpu->syscall(callnum, thread->readTid()); }
/** Reads the funcExeInst counter. */
virtual Counter readFuncExeInst() { return thread->funcExeInst; }
@ -323,21 +323,21 @@ class AlphaFullCPU : public FullO3CPU<Impl>
Fault translateInstReq(RequestPtr &req)
{
int tid = req->getThreadNum();
return this->thread[tid]->process->pTable->translate(req);
return this->thread[tid]->getProcessPtr()->pTable->translate(req);
}
/** Translates data read request in syscall emulation mode. */
Fault translateDataReadReq(RequestPtr &req)
{
int tid = req->getThreadNum();
return this->thread[tid]->process->pTable->translate(req);
return this->thread[tid]->getProcessPtr()->pTable->translate(req);
}
/** Translates data write request in syscall emulation mode. */
Fault translateDataWriteReq(RequestPtr &req)
{
int tid = req->getThreadNum();
return this->thread[tid]->process->pTable->translate(req);
return this->thread[tid]->getProcessPtr()->pTable->translate(req);
}
#endif
@ -492,14 +492,14 @@ class AlphaFullCPU : public FullO3CPU<Impl>
#if FULL_SYSTEM
// @todo: Fix this LL/SC hack.
if (req->flags & LOCKED) {
if (req->flags & UNCACHEABLE) {
req->result = 2;
if (req->getFlags() & LOCKED) {
if (req->getFlags() & UNCACHEABLE) {
req->setScResult(2);
} else {
if (this->lockFlag) {
req->result = 1;
req->setScResult(1);
} else {
req->result = 0;
req->setScResult(0);
return NoFault;
}
}

View file

@ -32,7 +32,7 @@
#include "base/cprintf.hh"
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "cpu/checker/exec_context.hh"
#include "cpu/checker/thread_context.hh"
#include "sim/sim_events.hh"
#include "sim/stats.hh"
@ -77,6 +77,20 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
i, params->mem);
this->thread[i]->setStatus(ThreadContext::Suspended);
#if !FULL_SYSTEM
/* Use this port to for syscall emulation writes to memory. */
Port *mem_port;
TranslatingPort *trans_port;
trans_port = new TranslatingPort(csprintf("%s-%d-funcport",
name(), i),
params->workload[i]->pTable,
false);
mem_port = params->mem->getPort("functional");
mem_port->setPeer(trans_port);
trans_port->setPeer(mem_port);
this->thread[i]->setMemPort(trans_port);
#endif
//usedTids[i] = true;
//threadMap[i] = i;
} else {
@ -108,10 +122,25 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
#if FULL_SYSTEM
// Setup quiesce event.
this->thread[i]->quiesceEvent =
new EndQuiesceEvent(tc);
this->thread[i]->lastActivate = 0;
this->thread[i]->lastSuspend = 0;
this->thread[i]->quiesceEvent = new EndQuiesceEvent(tc);
Port *mem_port;
FunctionalPort *phys_port;
VirtualPort *virt_port;
phys_port = new FunctionalPort(csprintf("%s-%d-funcport",
cpu->name(), tid));
mem_port = system->physmem->getPort("functional");
mem_port->setPeer(phys_port);
phys_port->setPeer(mem_port);
virt_port = new VirtualPort(csprintf("%s-%d-vport",
cpu->name(), tid));
mem_port = system->physmem->getPort("functional");
mem_port->setPeer(virt_port);
virt_port->setPeer(mem_port);
this->thread[i]->setPhysPort(phys_port);
this->thread[i]->setVirtPort(virt_port);
#endif
// Give the thread the TC.
this->thread[i]->tc = tc;
@ -120,9 +149,8 @@ AlphaFullCPU<Impl>::AlphaFullCPU(Params *params)
this->threadContexts.push_back(tc);
}
for (int i=0; i < this->numThreads; i++) {
this->thread[i]->funcExeInst = 0;
this->thread[i]->setFuncExeInst(0);
}
// Sets CPU pointers. These must be set at this level because the CPU
@ -218,14 +246,14 @@ AlphaFullCPU<Impl>::AlphaTC::activate(int delay)
#endif
if (thread->status() == ThreadContext::Unallocated) {
cpu->activateWhenReady(thread->tid);
cpu->activateWhenReady(thread->readTid());
return;
}
thread->setStatus(ThreadContext::Active);
// status() == Suspended
cpu->activateContext(thread->tid, delay);
cpu->activateContext(thread->readTid(), delay);
}
template <class Impl>
@ -251,7 +279,7 @@ AlphaFullCPU<Impl>::AlphaTC::suspend()
#endif
*/
thread->setStatus(ThreadContext::Suspended);
cpu->suspendContext(thread->tid);
cpu->suspendContext(thread->readTid());
}
template <class Impl>
@ -264,7 +292,7 @@ AlphaFullCPU<Impl>::AlphaTC::deallocate()
return;
thread->setStatus(ThreadContext::Unallocated);
cpu->deallocateContext(thread->tid);
cpu->deallocateContext(thread->readTid());
}
template <class Impl>
@ -277,7 +305,7 @@ AlphaFullCPU<Impl>::AlphaTC::halt()
return;
thread->setStatus(ThreadContext::Halted);
cpu->haltContext(thread->tid);
cpu->haltContext(thread->readTid());
}
template <class Impl>
@ -349,7 +377,7 @@ template <class Impl>
TheISA::MachInst
AlphaFullCPU<Impl>::AlphaTC:: getInst()
{
return thread->inst;
return thread->getInst();
}
template <class Impl>
@ -358,7 +386,7 @@ AlphaFullCPU<Impl>::AlphaTC::copyArchRegs(ThreadContext *tc)
{
// This function will mess things up unless the ROB is empty and
// there are no instructions in the pipeline.
unsigned tid = thread->tid;
unsigned tid = thread->readTid();
PhysRegIndex renamed_reg;
// First loop through the integer registers.
@ -400,7 +428,7 @@ template <class Impl>
uint64_t
AlphaFullCPU<Impl>::AlphaTC::readIntReg(int reg_idx)
{
return cpu->readArchIntReg(reg_idx, thread->tid);
return cpu->readArchIntReg(reg_idx, thread->readTid());
}
template <class Impl>
@ -409,9 +437,9 @@ AlphaFullCPU<Impl>::AlphaTC::readFloatReg(int reg_idx, int width)
{
switch(width) {
case 32:
return cpu->readArchFloatRegSingle(reg_idx, thread->tid);
return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
case 64:
return cpu->readArchFloatRegDouble(reg_idx, thread->tid);
return cpu->readArchFloatRegDouble(reg_idx, thread->readTid());
default:
panic("Unsupported width!");
return 0;
@ -422,7 +450,7 @@ template <class Impl>
FloatReg
AlphaFullCPU<Impl>::AlphaTC::readFloatReg(int reg_idx)
{
return cpu->readArchFloatRegSingle(reg_idx, thread->tid);
return cpu->readArchFloatRegSingle(reg_idx, thread->readTid());
}
template <class Impl>
@ -430,25 +458,25 @@ FloatRegBits
AlphaFullCPU<Impl>::AlphaTC::readFloatRegBits(int reg_idx, int width)
{
DPRINTF(Fault, "Reading floatint register through the TC!\n");
return cpu->readArchFloatRegInt(reg_idx, thread->tid);
return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
}
template <class Impl>
FloatRegBits
AlphaFullCPU<Impl>::AlphaTC::readFloatRegBits(int reg_idx)
{
return cpu->readArchFloatRegInt(reg_idx, thread->tid);
return cpu->readArchFloatRegInt(reg_idx, thread->readTid());
}
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setIntReg(int reg_idx, uint64_t val)
{
cpu->setArchIntReg(reg_idx, val, thread->tid);
cpu->setArchIntReg(reg_idx, val, thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
cpu->squashFromTC(thread->tid);
cpu->squashFromTC(thread->readTid());
}
}
@ -458,16 +486,16 @@ AlphaFullCPU<Impl>::AlphaTC::setFloatReg(int reg_idx, FloatReg val, int width)
{
switch(width) {
case 32:
cpu->setArchFloatRegSingle(reg_idx, val, thread->tid);
cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
break;
case 64:
cpu->setArchFloatRegDouble(reg_idx, val, thread->tid);
cpu->setArchFloatRegDouble(reg_idx, val, thread->readTid());
break;
}
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
cpu->squashFromTC(thread->tid);
cpu->squashFromTC(thread->readTid());
}
}
@ -475,10 +503,10 @@ template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setFloatReg(int reg_idx, FloatReg val)
{
cpu->setArchFloatRegSingle(reg_idx, val, thread->tid);
cpu->setArchFloatRegSingle(reg_idx, val, thread->readTid());
if (!thread->trapPending && !thread->inSyscall) {
cpu->squashFromTC(thread->tid);
cpu->squashFromTC(thread->readTid());
}
}
@ -488,11 +516,11 @@ AlphaFullCPU<Impl>::AlphaTC::setFloatRegBits(int reg_idx, FloatRegBits val,
int width)
{
DPRINTF(Fault, "Setting floatint register through the TC!\n");
cpu->setArchFloatRegInt(reg_idx, val, thread->tid);
cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
cpu->squashFromTC(thread->tid);
cpu->squashFromTC(thread->readTid());
}
}
@ -500,11 +528,11 @@ template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setFloatRegBits(int reg_idx, FloatRegBits val)
{
cpu->setArchFloatRegInt(reg_idx, val, thread->tid);
cpu->setArchFloatRegInt(reg_idx, val, thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
cpu->squashFromTC(thread->tid);
cpu->squashFromTC(thread->readTid());
}
}
@ -512,11 +540,11 @@ template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setPC(uint64_t val)
{
cpu->setPC(val, thread->tid);
cpu->setPC(val, thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
cpu->squashFromTC(thread->tid);
cpu->squashFromTC(thread->readTid());
}
}
@ -524,11 +552,11 @@ template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setNextPC(uint64_t val)
{
cpu->setNextPC(val, thread->tid);
cpu->setNextPC(val, thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
cpu->squashFromTC(thread->tid);
cpu->squashFromTC(thread->readTid());
}
}
@ -536,11 +564,11 @@ template <class Impl>
Fault
AlphaFullCPU<Impl>::AlphaTC::setMiscReg(int misc_reg, const MiscReg &val)
{
Fault ret_fault = cpu->setMiscReg(misc_reg, val, thread->tid);
Fault ret_fault = cpu->setMiscReg(misc_reg, val, thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
cpu->squashFromTC(thread->tid);
cpu->squashFromTC(thread->readTid());
}
return ret_fault;
@ -551,11 +579,12 @@ Fault
AlphaFullCPU<Impl>::AlphaTC::setMiscRegWithEffect(int misc_reg,
const MiscReg &val)
{
Fault ret_fault = cpu->setMiscRegWithEffect(misc_reg, val, thread->tid);
Fault ret_fault = cpu->setMiscRegWithEffect(misc_reg, val,
thread->readTid());
// Squash if we're not already in a state update mode.
if (!thread->trapPending && !thread->inSyscall) {
cpu->squashFromTC(thread->tid);
cpu->squashFromTC(thread->readTid());
}
return ret_fault;
@ -567,21 +596,21 @@ template <class Impl>
TheISA::IntReg
AlphaFullCPU<Impl>::AlphaTC::getSyscallArg(int i)
{
return cpu->getSyscallArg(i, thread->tid);
return cpu->getSyscallArg(i, thread->readTid());
}
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setSyscallArg(int i, IntReg val)
{
cpu->setSyscallArg(i, val, thread->tid);
cpu->setSyscallArg(i, val, thread->readTid());
}
template <class Impl>
void
AlphaFullCPU<Impl>::AlphaTC::setSyscallReturn(SyscallReturn return_value)
{
cpu->setSyscallReturn(return_value, thread->tid);
cpu->setSyscallReturn(return_value, thread->readTid());
}
#endif // FULL_SYSTEM
@ -749,8 +778,8 @@ AlphaFullCPU<Impl>::processInterrupts()
this->setMiscReg(IPR_INTID, ipl, 0);
// Checker needs to know these two registers were updated.
if (this->checker) {
this->checker->cpuXCBase()->setMiscReg(IPR_ISR, summary);
this->checker->cpuXCBase()->setMiscReg(IPR_INTID, ipl);
this->checker->threadBase()->setMiscReg(IPR_ISR, summary);
this->checker->threadBase()->setMiscReg(IPR_INTID, ipl);
}
this->trap(Fault(new InterruptFault), 0);
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",

View file

@ -38,7 +38,7 @@
#include "cpu/activity.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "cpu/o3/alpha_dyn_inst.hh"
#include "cpu/o3/alpha_impl.hh"
@ -245,12 +245,6 @@ FullO3CPU<Impl>::FullO3CPU(Params *params)
}
rename.setFreeList(&freeList);
// Setup the page table for whichever stages need it.
#if !FULL_SYSTEM
// fetch.setPageTable(pTable);
// iew.setPageTable(pTable);
#endif
// Setup the ROB for whichever stages need it.
commit.setROB(&rob);
@ -427,12 +421,12 @@ FullO3CPU<Impl>::insertThread(unsigned tid)
{
DPRINTF(FullCPU,"[tid:%i] Initializing thread data");
// Will change now that the PC and thread state is internal to the CPU
// and not in the CPUExecContext.
// and not in the ThreadContext.
#if 0
#if FULL_SYSTEM
ThreadContext *src_tc = system->threadContexts[tid];
#else
CPUExecContext *src_tc = thread[tid];
ThreadContext *src_tc = thread[tid];
#endif
//Bind Int Regs to Rename Map

View file

@ -43,7 +43,7 @@
#include "config/full_system.hh"
#include "cpu/activity.hh"
#include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/simple_thread.hh"
#include "cpu/o3/comm.hh"
#include "cpu/o3/cpu_policy.hh"
#include "cpu/o3/scoreboard.hh"
@ -237,11 +237,11 @@ class FullO3CPU : public BaseFullCPU
#else
/** Get instruction asid. */
int getInstAsid(unsigned tid)
{ return thread[tid]->asid; }
{ return thread[tid]->getInstAsid(); }
/** Get data asid. */
int getDataAsid(unsigned tid)
{ return thread[tid]->asid; }
{ return thread[tid]->getDataAsid(); }
#endif

View file

@ -58,14 +58,6 @@ struct O3ThreadState : public ThreadState {
typedef ThreadContext::Status Status;
typedef typename Impl::FullCPU FullCPU;
/** Current status of the thread. */
Status _status;
/** Current instruction the thread is committing. Only set and
* used for DTB faults currently.
*/
TheISA::MachInst inst;
private:
/** Pointer to the CPU. */
FullCPU *cpu;
@ -81,8 +73,8 @@ struct O3ThreadState : public ThreadState {
bool trapPending;
#if FULL_SYSTEM
O3ThreadState(FullCPU *_cpu, int _thread_num, FunctionalMemory *_mem)
: ThreadState(-1, _thread_num, _mem),
O3ThreadState(FullCPU *_cpu, int _thread_num, )
: ThreadState(-1, _thread_num),
inSyscall(0), trapPending(0)
{ }
#else
@ -99,25 +91,6 @@ struct O3ThreadState : public ThreadState {
/** Returns a pointer to the TC of this thread. */
ThreadContext *getTC() { return tc; }
/** Returns the status of this thread. */
Status status() const { return _status; }
/** Sets the status of this thread. */
void setStatus(Status new_status) { _status = new_status; }
/** Sets the current instruction being committed. */
void setInst(TheISA::MachInst _inst) { inst = _inst; }
/** Reads the number of instructions functionally executed and
* committed.
*/
Counter readFuncExeInst() { return funcExeInst; }
/** Sets the total number of instructions functionally executed
* and committed.
*/
void setFuncExeInst(Counter new_val) { funcExeInst = new_val; }
#if !FULL_SYSTEM
/** Handles the syscall. */
void syscall(int64_t callnum) { process->syscall(callnum, tc); }

View file

@ -36,7 +36,7 @@
#include "base/trace.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/checker/exec_context.hh"
#include "cpu/checker/thread_context.hh"
#include "cpu/thread_context.hh"
#include "cpu/exetrace.hh"
#include "cpu/ozone/cpu.hh"
@ -670,8 +670,8 @@ OzoneCPU<Impl>::processInterrupts()
thread.setMiscReg(IPR_INTID, ipl);
// @todo: Make this more transparent
if (checker) {
checker->cpuXCBase()->setMiscReg(IPR_ISR, summary);
checker->cpuXCBase()->setMiscReg(IPR_INTID, ipl);
checker->threadBase()->setMiscReg(IPR_ISR, summary);
checker->threadBase()->setMiscReg(IPR_INTID, ipl);
}
Fault fault = new InterruptFault;
fault->invoke(thread.getTC());

View file

@ -49,7 +49,7 @@ class FunctionalMemory;
// Maybe this ozone thread state should only really have committed state?
// I need to think about why I'm using this and what it's useful for. Clearly
// has benefits for SMT; basically serves same use as CPUExecContext.
// has benefits for SMT; basically serves same use as SimpleThread.
// Makes the ExecContext proxy easier. Gives organization/central access point
// to state of a thread that can be accessed normally (i.e. not in-flight
// stuff within a OoO processor). Does this need an TC proxy within it?
@ -83,18 +83,11 @@ struct OzoneThreadState : public ThreadState {
}
#endif
Status _status;
Status status() const { return _status; }
void setStatus(Status new_status) { _status = new_status; }
RenameTable<Impl> renameTable;
Addr PC;
Addr nextPC;
// Current instruction
TheISA::MachInst inst;
Addr PC;
Addr nextPC;
TheISA::RegFile regs;
@ -169,14 +162,6 @@ struct OzoneThreadState : public ThreadState {
void setNextPC(uint64_t val)
{ nextPC = val; }
bool misspeculating() { return false; }
void setInst(TheISA::MachInst _inst) { inst = _inst; }
Counter readFuncExeInst() { return funcExeInst; }
void setFuncExeInst(Counter new_val) { funcExeInst = new_val; }
};
#endif // __CPU_OZONE_THREAD_STATE_HH__

View file

@ -196,7 +196,7 @@ void
AtomicSimpleCPU::activateContext(int thread_num, int delay)
{
assert(thread_num == 0);
assert(cpuXC);
assert(thread);
assert(_status == Idle);
assert(!tickEvent.scheduled());
@ -211,7 +211,7 @@ void
AtomicSimpleCPU::suspendContext(int thread_num)
{
assert(thread_num == 0);
assert(cpuXC);
assert(thread);
assert(_status == Running);
@ -229,14 +229,14 @@ template <class T>
Fault
AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
{
data_read_req->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
data_read_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
if (traceData) {
traceData->setAddr(addr);
}
// translate to physical address
Fault fault = cpuXC->translateDataReadReq(data_read_req);
Fault fault = thread->translateDataReadReq(data_read_req);
// Now do the access.
if (fault == NoFault) {
@ -304,14 +304,14 @@ template <class T>
Fault
AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
data_write_req->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
data_write_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
if (traceData) {
traceData->setAddr(addr);
}
// translate to physical address
Fault fault = cpuXC->translateDataWriteReq(data_write_req);
Fault fault = thread->translateDataWriteReq(data_write_req);
// Now do the access.
if (fault == NoFault) {

View file

@ -38,18 +38,18 @@
#include "base/stats/events.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/thread_context.hh"
#include "cpu/exetrace.hh"
#include "cpu/profile.hh"
#include "cpu/sampler/sampler.hh"
#include "cpu/simple/base.hh"
#include "cpu/simple_thread.hh"
#include "cpu/smt.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "kern/kernel_stats.hh"
#include "mem/packet_impl.hh"
#include "sim/byteswap.hh"
#include "sim/builder.hh"
#include "sim/byteswap.hh"
#include "sim/debug.hh"
#include "sim/host.hh"
#include "sim/sim_events.hh"
@ -70,18 +70,18 @@ using namespace std;
using namespace TheISA;
BaseSimpleCPU::BaseSimpleCPU(Params *p)
: BaseCPU(p), mem(p->mem), cpuXC(NULL)
: BaseCPU(p), mem(p->mem), thread(NULL)
{
#if FULL_SYSTEM
cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb);
thread = new SimpleThread(this, 0, p->system, p->itb, p->dtb);
#else
cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process,
thread = new SimpleThread(this, /* thread_num */ 0, p->process,
/* asid */ 0, mem);
#endif // !FULL_SYSTEM
cpuXC->setStatus(ThreadContext::Suspended);
thread->setStatus(ThreadContext::Suspended);
tc = cpuXC->getTC();
tc = thread->getTC();
numInst = 0;
startNumInst = 0;
@ -180,7 +180,7 @@ BaseSimpleCPU::serialize(ostream &os)
BaseCPU::serialize(os);
SERIALIZE_SCALAR(inst);
nameOut(os, csprintf("%s.xc", name()));
cpuXC->serialize(os);
thread->serialize(os);
}
void
@ -188,7 +188,7 @@ BaseSimpleCPU::unserialize(Checkpoint *cp, const string &section)
{
BaseCPU::unserialize(cp, section);
UNSERIALIZE_SCALAR(inst);
cpuXC->unserialize(cp, csprintf("%s.xc", section));
thread->unserialize(cp, csprintf("%s.xc", section));
}
void
@ -217,16 +217,16 @@ BaseSimpleCPU::copySrcTranslate(Addr src)
memReq->reset(src & ~(blk_size - 1), blk_size);
// translate to physical address
Fault fault = cpuXC->translateDataReadReq(req);
Fault fault = thread->translateDataReadReq(req);
if (fault == NoFault) {
cpuXC->copySrcAddr = src;
cpuXC->copySrcPhysAddr = memReq->paddr + offset;
thread->copySrcAddr = src;
thread->copySrcPhysAddr = memReq->paddr + offset;
} else {
assert(!fault->isAlignmentFault());
cpuXC->copySrcAddr = 0;
cpuXC->copySrcPhysAddr = 0;
thread->copySrcAddr = 0;
thread->copySrcPhysAddr = 0;
}
return fault;
#else
@ -243,7 +243,7 @@ BaseSimpleCPU::copy(Addr dest)
// Only support block sizes of 64 atm.
assert(blk_size == 64);
uint8_t data[blk_size];
//assert(cpuXC->copySrcAddr);
//assert(thread->copySrcAddr);
int offset = dest & (blk_size - 1);
// Make sure block doesn't span page
@ -256,19 +256,19 @@ BaseSimpleCPU::copy(Addr dest)
memReq->reset(dest & ~(blk_size -1), blk_size);
// translate to physical address
Fault fault = cpuXC->translateDataWriteReq(req);
Fault fault = thread->translateDataWriteReq(req);
if (fault == NoFault) {
Addr dest_addr = memReq->paddr + offset;
// Need to read straight from memory since we have more than 8 bytes.
memReq->paddr = cpuXC->copySrcPhysAddr;
cpuXC->mem->read(memReq, data);
memReq->paddr = thread->copySrcPhysAddr;
thread->mem->read(memReq, data);
memReq->paddr = dest_addr;
cpuXC->mem->write(memReq, data);
thread->mem->write(memReq, data);
if (dcacheInterface) {
memReq->cmd = Copy;
memReq->completionEvent = NULL;
memReq->paddr = cpuXC->copySrcPhysAddr;
memReq->paddr = thread->copySrcPhysAddr;
memReq->dest = dest_addr;
memReq->size = 64;
memReq->time = curTick;
@ -300,9 +300,9 @@ BaseSimpleCPU::post_interrupt(int int_num, int index)
{
BaseCPU::post_interrupt(int_num, index);
if (cpuXC->status() == ThreadContext::Suspended) {
if (thread->status() == ThreadContext::Suspended) {
DPRINTF(IPI,"Suspended Processor awoke\n");
cpuXC->activate();
thread->activate();
}
}
#endif // FULL_SYSTEM
@ -311,15 +311,15 @@ void
BaseSimpleCPU::checkForInterrupts()
{
#if FULL_SYSTEM
if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode()) {
if (checkInterrupts && check_interrupts() && !thread->inPalMode()) {
int ipl = 0;
int summary = 0;
checkInterrupts = false;
if (cpuXC->readMiscReg(IPR_SIRR)) {
if (thread->readMiscReg(IPR_SIRR)) {
for (int i = INTLEVEL_SOFTWARE_MIN;
i < INTLEVEL_SOFTWARE_MAX; i++) {
if (cpuXC->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
if (thread->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
summary |= (ULL(1) << i);
@ -327,7 +327,7 @@ BaseSimpleCPU::checkForInterrupts()
}
}
uint64_t interrupts = cpuXC->cpu->intr_status();
uint64_t interrupts = thread->cpu->intr_status();
for (int i = INTLEVEL_EXTERNAL_MIN;
i < INTLEVEL_EXTERNAL_MAX; i++) {
if (interrupts & (ULL(1) << i)) {
@ -337,17 +337,17 @@ BaseSimpleCPU::checkForInterrupts()
}
}
if (cpuXC->readMiscReg(IPR_ASTRR))
if (thread->readMiscReg(IPR_ASTRR))
panic("asynchronous traps not implemented\n");
if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) {
cpuXC->setMiscReg(IPR_ISR, summary);
cpuXC->setMiscReg(IPR_INTID, ipl);
if (ipl && ipl > thread->readMiscReg(IPR_IPLR)) {
thread->setMiscReg(IPR_ISR, summary);
thread->setMiscReg(IPR_INTID, ipl);
Fault(new InterruptFault)->invoke(tc);
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
cpuXC->readMiscReg(IPR_IPLR), ipl, summary);
thread->readMiscReg(IPR_IPLR), ipl, summary);
}
}
#endif
@ -358,14 +358,14 @@ Fault
BaseSimpleCPU::setupFetchRequest(Request *req)
{
// set up memory request for instruction fetch
DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",cpuXC->readPC(),
cpuXC->readNextPC(),cpuXC->readNextNPC());
DPRINTF(Fetch,"Fetch: PC:%08p NPC:%08p NNPC:%08p\n",thread->readPC(),
thread->readNextPC(),thread->readNextNPC());
req->setVirt(0, cpuXC->readPC() & ~3, sizeof(MachInst),
(FULL_SYSTEM && (cpuXC->readPC() & 1)) ? PHYSICAL : 0,
cpuXC->readPC());
req->setVirt(0, thread->readPC() & ~3, sizeof(MachInst),
(FULL_SYSTEM && (thread->readPC() & 1)) ? PHYSICAL : 0,
thread->readPC());
Fault fault = cpuXC->translateInstReq(req);
Fault fault = thread->translateInstReq(req);
return fault;
}
@ -375,33 +375,33 @@ void
BaseSimpleCPU::preExecute()
{
// maintain $r0 semantics
cpuXC->setIntReg(ZeroReg, 0);
thread->setIntReg(ZeroReg, 0);
#if THE_ISA == ALPHA_ISA
cpuXC->setFloatReg(ZeroReg, 0.0);
thread->setFloatReg(ZeroReg, 0.0);
#endif // ALPHA_ISA
// keep an instruction count
numInst++;
numInsts++;
cpuXC->func_exe_inst++;
thread->funcExeInst++;
// check for instruction-count-based events
comInstEventQueue[0]->serviceEvents(numInst);
// decode the instruction
inst = gtoh(inst);
curStaticInst = StaticInst::decode(makeExtMI(inst, cpuXC->readPC()));
curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC()));
traceData = Trace::getInstRecord(curTick, tc, this, curStaticInst,
cpuXC->readPC());
thread->readPC());
DPRINTF(Decode,"Decode: Decoded %s instruction (opcode: 0x%x): 0x%x\n",
curStaticInst->getName(), curStaticInst->getOpcode(),
curStaticInst->machInst);
#if FULL_SYSTEM
cpuXC->setInst(inst);
thread->setInst(inst);
#endif // FULL_SYSTEM
}
@ -410,17 +410,17 @@ BaseSimpleCPU::postExecute()
{
#if FULL_SYSTEM
if (system->kernelBinning->fnbin) {
assert(cpuXC->getKernelStats());
assert(thread->getKernelStats());
system->kernelBinning->execute(tc, inst);
}
if (cpuXC->profile) {
if (thread->profile) {
bool usermode =
(cpuXC->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
cpuXC->profilePC = usermode ? 1 : cpuXC->readPC();
ProfileNode *node = cpuXC->profile->consume(tc, inst);
(thread->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
thread->profilePC = usermode ? 1 : thread->readPC();
ProfileNode *node = thread->profile->consume(tc, inst);
if (node)
cpuXC->profileNode = node;
thread->profileNode = node;
}
#endif
@ -433,7 +433,7 @@ BaseSimpleCPU::postExecute()
comLoadEventQueue[0]->serviceEvents(numLoad);
}
traceFunctions(cpuXC->readPC());
traceFunctions(thread->readPC());
if (traceData) {
traceData->finalize();
@ -448,17 +448,17 @@ BaseSimpleCPU::advancePC(Fault fault)
#if FULL_SYSTEM
fault->invoke(tc);
#else // !FULL_SYSTEM
fatal("fault (%s) detected @ PC %08p", fault->name(), cpuXC->readPC());
fatal("fault (%s) detected @ PC %08p", fault->name(), thread->readPC());
#endif // FULL_SYSTEM
}
else {
// go to the next instruction
cpuXC->setPC(cpuXC->readNextPC());
thread->setPC(thread->readNextPC());
#if THE_ISA == ALPHA_ISA
cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst));
thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
#else
cpuXC->setNextPC(cpuXC->readNextNPC());
cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst));
thread->setNextPC(thread->readNextNPC());
thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
#endif
}
@ -466,9 +466,9 @@ BaseSimpleCPU::advancePC(Fault fault)
#if FULL_SYSTEM
Addr oldpc;
do {
oldpc = cpuXC->readPC();
oldpc = thread->readPC();
system->pcEventQueue.service(tc);
} while (oldpc != cpuXC->readPC());
} while (oldpc != thread->readPC());
#endif
}

View file

@ -36,7 +36,7 @@
#include "base/statistics.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/simple_thread.hh"
#include "cpu/pc_event.hh"
#include "cpu/sampler/sampler.hh"
#include "cpu/static_inst.hh"
@ -108,9 +108,12 @@ class BaseSimpleCPU : public BaseCPU
virtual ~BaseSimpleCPU();
public:
// execution context
CPUExecContext *cpuXC;
/** SimpleThread object, provides all the architectural state. */
SimpleThread *thread;
/** ThreadContext object, provides an interface for external
* objects to modify this thread's state.
*/
ThreadContext *tc;
#if FULL_SYSTEM
@ -217,103 +220,103 @@ class BaseSimpleCPU : public BaseCPU
uint64_t readIntReg(const StaticInst *si, int idx)
{
return cpuXC->readIntReg(si->srcRegIdx(idx));
return thread->readIntReg(si->srcRegIdx(idx));
}
FloatReg readFloatReg(const StaticInst *si, int idx, int width)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return cpuXC->readFloatReg(reg_idx, width);
return thread->readFloatReg(reg_idx, width);
}
FloatReg readFloatReg(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return cpuXC->readFloatReg(reg_idx);
return thread->readFloatReg(reg_idx);
}
FloatRegBits readFloatRegBits(const StaticInst *si, int idx, int width)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return cpuXC->readFloatRegBits(reg_idx, width);
return thread->readFloatRegBits(reg_idx, width);
}
FloatRegBits readFloatRegBits(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return cpuXC->readFloatRegBits(reg_idx);
return thread->readFloatRegBits(reg_idx);
}
void setIntReg(const StaticInst *si, int idx, uint64_t val)
{
cpuXC->setIntReg(si->destRegIdx(idx), val);
thread->setIntReg(si->destRegIdx(idx), val);
}
void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
cpuXC->setFloatReg(reg_idx, val, width);
thread->setFloatReg(reg_idx, val, width);
}
void setFloatReg(const StaticInst *si, int idx, FloatReg val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
cpuXC->setFloatReg(reg_idx, val);
thread->setFloatReg(reg_idx, val);
}
void setFloatRegBits(const StaticInst *si, int idx,
FloatRegBits val, int width)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
cpuXC->setFloatRegBits(reg_idx, val, width);
thread->setFloatRegBits(reg_idx, val, width);
}
void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
cpuXC->setFloatRegBits(reg_idx, val);
thread->setFloatRegBits(reg_idx, val);
}
uint64_t readPC() { return cpuXC->readPC(); }
uint64_t readNextPC() { return cpuXC->readNextPC(); }
uint64_t readNextNPC() { return cpuXC->readNextNPC(); }
uint64_t readPC() { return thread->readPC(); }
uint64_t readNextPC() { return thread->readNextPC(); }
uint64_t readNextNPC() { return thread->readNextNPC(); }
void setPC(uint64_t val) { cpuXC->setPC(val); }
void setNextPC(uint64_t val) { cpuXC->setNextPC(val); }
void setNextNPC(uint64_t val) { cpuXC->setNextNPC(val); }
void setPC(uint64_t val) { thread->setPC(val); }
void setNextPC(uint64_t val) { thread->setNextPC(val); }
void setNextNPC(uint64_t val) { thread->setNextNPC(val); }
MiscReg readMiscReg(int misc_reg)
{
return cpuXC->readMiscReg(misc_reg);
return thread->readMiscReg(misc_reg);
}
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
{
return cpuXC->readMiscRegWithEffect(misc_reg, fault);
return thread->readMiscRegWithEffect(misc_reg, fault);
}
Fault setMiscReg(int misc_reg, const MiscReg &val)
{
return cpuXC->setMiscReg(misc_reg, val);
return thread->setMiscReg(misc_reg, val);
}
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
return cpuXC->setMiscRegWithEffect(misc_reg, val);
return thread->setMiscRegWithEffect(misc_reg, val);
}
#if FULL_SYSTEM
Fault hwrei() { return cpuXC->hwrei(); }
int readIntrFlag() { return cpuXC->readIntrFlag(); }
void setIntrFlag(int val) { cpuXC->setIntrFlag(val); }
bool inPalMode() { return cpuXC->inPalMode(); }
Fault hwrei() { return thread->hwrei(); }
int readIntrFlag() { return thread->readIntrFlag(); }
void setIntrFlag(int val) { thread->setIntrFlag(val); }
bool inPalMode() { return thread->inPalMode(); }
void ev5_trap(Fault fault) { fault->invoke(tc); }
bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); }
bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
#else
void syscall(int64_t callnum) { cpuXC->syscall(callnum); }
void syscall(int64_t callnum) { thread->syscall(callnum); }
#endif
bool misspeculating() { return cpuXC->misspeculating(); }
bool misspeculating() { return thread->misspeculating(); }
ThreadContext *tcBase() { return tc; }
};

View file

@ -141,7 +141,7 @@ void
TimingSimpleCPU::activateContext(int thread_num, int delay)
{
assert(thread_num == 0);
assert(cpuXC);
assert(thread);
assert(_status == Idle);
@ -158,7 +158,7 @@ void
TimingSimpleCPU::suspendContext(int thread_num)
{
assert(thread_num == 0);
assert(cpuXC);
assert(thread);
assert(_status == Running);
@ -177,14 +177,14 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
// need to fill in CPU & thread IDs here
Request *data_read_req = new Request();
data_read_req->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
data_read_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
if (traceData) {
traceData->setAddr(data_read_req->getVaddr());
}
// translate to physical address
Fault fault = cpuXC->translateDataReadReq(data_read_req);
Fault fault = thread->translateDataReadReq(data_read_req);
// Now do the access.
if (fault == NoFault) {
@ -257,10 +257,10 @@ TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
// need to fill in CPU & thread IDs here
Request *data_write_req = new Request();
data_write_req->setVirt(0, addr, sizeof(T), flags, cpuXC->readPC());
data_write_req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
// translate to physical address
Fault fault = cpuXC->translateDataWriteReq(data_write_req);
Fault fault = thread->translateDataWriteReq(data_write_req);
// Now do the access.
if (fault == NoFault) {
Packet *data_write_pkt =

View file

@ -35,7 +35,7 @@
#include "arch/isa_traits.hh"
#include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#if FULL_SYSTEM
@ -59,15 +59,14 @@ using namespace std;
// constructor
#if FULL_SYSTEM
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
AlphaITB *_itb, AlphaDTB *_dtb,
bool use_kernel_stats)
: _status(ThreadContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
cpu_id(-1), lastActivate(0), lastSuspend(0), system(_sys), itb(_itb),
dtb(_dtb), profile(NULL), func_exe_inst(0), storeCondFailures(0)
SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
AlphaITB *_itb, AlphaDTB *_dtb,
bool use_kernel_stats)
: ThreadState(-1, _thread_num), cpu(_cpu), system(_sys), itb(_itb),
dtb(_dtb)
{
tc = new ProxyThreadContext<CPUExecContext>(this);
tc = new ProxyThreadContext<SimpleThread>(this);
quiesceEvent = new EndQuiesceEvent(tc);
@ -76,8 +75,8 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
if (cpu->params->profile) {
profile = new FunctionProfile(system->kernelSymtab);
Callback *cb =
new MakeCallback<CPUExecContext,
&CPUExecContext::dumpFuncProfile>(this);
new MakeCallback<SimpleThread,
&SimpleThread::dumpFuncProfile>(this);
registerExitCallback(cb);
}
@ -87,7 +86,6 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
profileNode = &dummyNode;
profilePC = 3;
if (use_kernel_stats) {
kernelStats = new Kernel::Statistics(system);
} else {
@ -95,79 +93,52 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
}
Port *mem_port;
physPort = new FunctionalPort(csprintf("%s-%d-funcport",
cpu->name(), thread_num));
cpu->name(), tid));
mem_port = system->physmem->getPort("functional");
mem_port->setPeer(physPort);
physPort->setPeer(mem_port);
virtPort = new VirtualPort(csprintf("%s-%d-vport",
cpu->name(), thread_num));
cpu->name(), tid));
mem_port = system->physmem->getPort("functional");
mem_port->setPeer(virtPort);
virtPort->setPeer(mem_port);
}
#else
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num,
Process *_process, int _asid, MemObject* memobj)
: _status(ThreadContext::Unallocated),
cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0),
lastSuspend(0), process(_process), asid(_asid),
func_exe_inst(0), storeCondFailures(0)
: ThreadState(-1, _thread_num, memobj, _process, _asid),
cpu(_cpu)
{
/* Use this port to for syscall emulation writes to memory. */
Port *mem_port;
port = new TranslatingPort(csprintf("%s-%d-funcport",
cpu->name(), thread_num),
cpu->name(), tid),
process->pTable, false);
mem_port = memobj->getPort("functional");
mem_port->setPeer(port);
port->setPeer(mem_port);
regs.clear();
tc = new ProxyThreadContext<CPUExecContext>(this);
tc = new ProxyThreadContext<SimpleThread>(this);
}
CPUExecContext::CPUExecContext(RegFile *regFile)
: cpu(NULL), thread_num(-1), process(NULL), asid(-1),
func_exe_inst(0), storeCondFailures(0)
SimpleThread::SimpleThread(RegFile *regFile)
: ThreadState(-1, -1, NULL, NULL, -1), cpu(NULL)
{
regs = *regFile;
tc = new ProxyThreadContext<CPUExecContext>(this);
tc = new ProxyThreadContext<SimpleThread>(this);
}
#endif
CPUExecContext::~CPUExecContext()
SimpleThread::~SimpleThread()
{
delete tc;
}
#if FULL_SYSTEM
void
CPUExecContext::dumpFuncProfile()
{
std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
profile->dump(tc, *os);
}
void
CPUExecContext::profileClear()
{
if (profile)
profile->clear();
}
void
CPUExecContext::profileSample()
{
if (profile)
profile->sample(profileNode, profilePC);
}
#endif
void
CPUExecContext::takeOverFrom(ThreadContext *oldContext)
SimpleThread::takeOverFrom(ThreadContext *oldContext)
{
// some things should already be set up
#if FULL_SYSTEM
@ -179,9 +150,9 @@ CPUExecContext::takeOverFrom(ThreadContext *oldContext)
// copy over functional state
_status = oldContext->status();
copyArchRegs(oldContext);
cpu_id = oldContext->readCpuId();
cpuId = oldContext->readCpuId();
#if !FULL_SYSTEM
func_exe_inst = oldContext->readFuncExeInst();
funcExeInst = oldContext->readFuncExeInst();
#else
EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
if (quiesce) {
@ -200,12 +171,12 @@ CPUExecContext::takeOverFrom(ThreadContext *oldContext)
}
void
CPUExecContext::serialize(ostream &os)
SimpleThread::serialize(ostream &os)
{
SERIALIZE_ENUM(_status);
regs.serialize(os);
// thread_num and cpu_id are deterministic from the config
SERIALIZE_SCALAR(func_exe_inst);
SERIALIZE_SCALAR(funcExeInst);
SERIALIZE_SCALAR(inst);
#if FULL_SYSTEM
@ -220,12 +191,12 @@ CPUExecContext::serialize(ostream &os)
void
CPUExecContext::unserialize(Checkpoint *cp, const std::string &section)
SimpleThread::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ENUM(_status);
regs.unserialize(cp, section);
// thread_num and cpu_id are deterministic from the config
UNSERIALIZE_SCALAR(func_exe_inst);
UNSERIALIZE_SCALAR(funcExeInst);
UNSERIALIZE_SCALAR(inst);
#if FULL_SYSTEM
@ -238,9 +209,17 @@ CPUExecContext::unserialize(Checkpoint *cp, const std::string &section)
#endif
}
#if FULL_SYSTEM
void
SimpleThread::dumpFuncProfile()
{
std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
profile->dump(tc, *os);
}
#endif
void
CPUExecContext::activate(int delay)
SimpleThread::activate(int delay)
{
if (status() == ThreadContext::Active)
return;
@ -248,18 +227,18 @@ CPUExecContext::activate(int delay)
lastActivate = curTick;
if (status() == ThreadContext::Unallocated) {
cpu->activateWhenReady(thread_num);
cpu->activateWhenReady(tid);
return;
}
_status = ThreadContext::Active;
// status() == Suspended
cpu->activateContext(thread_num, delay);
cpu->activateContext(tid, delay);
}
void
CPUExecContext::suspend()
SimpleThread::suspend()
{
if (status() == ThreadContext::Suspended)
return;
@ -276,32 +255,32 @@ CPUExecContext::suspend()
#endif
*/
_status = ThreadContext::Suspended;
cpu->suspendContext(thread_num);
cpu->suspendContext(tid);
}
void
CPUExecContext::deallocate()
SimpleThread::deallocate()
{
if (status() == ThreadContext::Unallocated)
return;
_status = ThreadContext::Unallocated;
cpu->deallocateContext(thread_num);
cpu->deallocateContext(tid);
}
void
CPUExecContext::halt()
SimpleThread::halt()
{
if (status() == ThreadContext::Halted)
return;
_status = ThreadContext::Halted;
cpu->haltContext(thread_num);
cpu->haltContext(tid);
}
void
CPUExecContext::regStats(const string &name)
SimpleThread::regStats(const string &name)
{
#if FULL_SYSTEM
if (kernelStats)
@ -310,14 +289,14 @@ CPUExecContext::regStats(const string &name)
}
void
CPUExecContext::copyArchRegs(ThreadContext *src_tc)
SimpleThread::copyArchRegs(ThreadContext *src_tc)
{
TheISA::copyRegs(src_tc, tc);
}
#if FULL_SYSTEM
VirtualPort*
CPUExecContext::getVirtPort(ThreadContext *src_tc)
SimpleThread::getVirtPort(ThreadContext *src_tc)
{
if (!src_tc)
return virtPort;
@ -333,7 +312,7 @@ CPUExecContext::getVirtPort(ThreadContext *src_tc)
}
void
CPUExecContext::delVirtPort(VirtualPort *vp)
SimpleThread::delVirtPort(VirtualPort *vp)
{
// assert(!vp->nullThreadContext());
delete vp->getPeer();

View file

@ -29,12 +29,13 @@
* Nathan Binkert
*/
#ifndef __CPU_CPU_EXEC_CONTEXT_HH__
#define __CPU_CPU_EXEC_CONTEXT_HH__
#ifndef __CPU_SIMPLE_THREAD_HH__
#define __CPU_SIMPLE_THREAD_HH__
#include "arch/isa_traits.hh"
#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
#include "mem/physical.hh"
#include "mem/request.hh"
#include "sim/byteswap.hh"
@ -54,7 +55,6 @@ class ProfileNode;
class FunctionalPort;
class PhysicalPort;
namespace Kernel {
class Statistics;
};
@ -65,16 +65,25 @@ namespace Kernel {
#include "mem/page_table.hh"
class TranslatingPort;
#endif // FULL_SYSTEM
//
// The CPUExecContext object represents a functional context for
// instruction execution. It incorporates everything required for
// architecture-level functional simulation of a single thread.
//
/**
* The SimpleThread object provides a combination of the ThreadState
* object and the ThreadContext interface. It implements the
* ThreadContext interface so that a ProxyThreadContext class can be
* made using SimpleThread as the template parameter (see
* thread_context.hh). It adds to the ThreadState object by adding all
* the objects needed for simple functional execution, including a
* simple architectural register file, and pointers to the ITB and DTB
* in full system mode. For CPU models that do not need more advanced
* ways to hold state (i.e. a separate physical register file, or
* separate fetch and commit PC's), this SimpleThread class provides
* all the necessary state for full architecture-level functional
* simulation. See the AtomicSimpleCPU or TimingSimpleCPU for
* examples.
*/
class CPUExecContext
class SimpleThread : public ThreadState
{
protected:
typedef TheISA::RegFile RegFile;
@ -86,134 +95,35 @@ class CPUExecContext
public:
typedef ThreadContext::Status Status;
private:
Status _status;
public:
Status status() const { return _status; }
void setStatus(Status newStatus) { _status = newStatus; }
/// Set the status to Active. Optional delay indicates number of
/// cycles to wait before beginning execution.
void activate(int delay = 1);
/// Set the status to Suspended.
void suspend();
/// Set the status to Unallocated.
void deallocate();
/// Set the status to Halted.
void halt();
protected:
RegFile regs; // correct-path register context
public:
// pointer to CPU associated with this context
// pointer to CPU associated with this SimpleThread
BaseCPU *cpu;
ProxyThreadContext<CPUExecContext> *tc;
// Current instruction
MachInst inst;
// Index of hardware thread context on the CPU that this represents.
int thread_num;
// ID of this context w.r.t. the System or Process object to which
// it belongs. For full-system mode, this is the system CPU ID.
int cpu_id;
Tick lastActivate;
Tick lastSuspend;
ProxyThreadContext<SimpleThread> *tc;
System *system;
#if FULL_SYSTEM
AlphaITB *itb;
AlphaDTB *dtb;
/** A functional port outgoing only for functional accesses to physical
* addresses.*/
FunctionalPort *physPort;
/** A functional port, outgoing only, for functional accesse to virtual
* addresses. That doen't require execution context information */
VirtualPort *virtPort;
FunctionProfile *profile;
ProfileNode *profileNode;
Addr profilePC;
void dumpFuncProfile();
EndQuiesceEvent *quiesceEvent;
EndQuiesceEvent *getQuiesceEvent() { return quiesceEvent; }
Tick readLastActivate() { return lastActivate; }
Tick readLastSuspend() { return lastSuspend; }
void profileClear();
void profileSample();
Kernel::Statistics *getKernelStats() { return kernelStats; }
Kernel::Statistics *kernelStats;
#else
/// Port that syscalls can use to access memory (provides translation step).
TranslatingPort *port;
Process *process;
// Address space ID. Note that this is used for TIMING cache
// simulation only; all functional memory accesses should use
// one of the FunctionalMemory pointers above.
short asid;
#endif
/**
* Temporary storage to pass the source address from copy_load to
* copy_store.
* @todo Remove this temporary when we have a better way to do it.
*/
Addr copySrcAddr;
/**
* Temp storage for the physical source address of a copy.
* @todo Remove this temporary when we have a better way to do it.
*/
Addr copySrcPhysAddr;
/*
* number of executed instructions, for matching with syscall trace
* points in EIO files.
*/
Counter func_exe_inst;
//
// Count failed store conditionals so we can warn of apparent
// application deadlock situations.
unsigned storeCondFailures;
// constructor: initialize context from given process structure
// constructor: initialize SimpleThread from given process structure
#if FULL_SYSTEM
CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
AlphaITB *_itb, AlphaDTB *_dtb,
bool use_kernel_stats = true);
SimpleThread(BaseCPU *_cpu, int _thread_num, System *_system,
AlphaITB *_itb, AlphaDTB *_dtb,
bool use_kernel_stats = true);
#else
CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid,
MemObject *memobj);
// Constructor to use XC to pass reg file around. Not used for anything
// else.
CPUExecContext(RegFile *regFile);
SimpleThread(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid,
MemObject *memobj);
// Constructor to use SimpleThread to pass reg file around. Not
// used for anything else.
SimpleThread(RegFile *regFile);
#endif
virtual ~CPUExecContext();
virtual ~SimpleThread();
virtual void takeOverFrom(ThreadContext *oldContext);
@ -222,19 +132,18 @@ class CPUExecContext
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
BaseCPU *getCpuPtr() { return cpu; }
/***************************************************************
* SimpleThread functions to provide CPU with access to various
* state, and to provide address translation methods.
**************************************************************/
/** Returns the pointer to this SimpleThread's ThreadContext. Used
* when a ThreadContext must be passed to objects outside of the
* CPU.
*/
ThreadContext *getTC() { return tc; }
int getThreadNum() { return thread_num; }
#if FULL_SYSTEM
System *getSystemPtr() { return system; }
AlphaITB *getITBPtr() { return itb; }
AlphaDTB *getDTBPtr() { return dtb; }
int getInstAsid() { return regs.instAsid(); }
int getDataAsid() { return regs.dataAsid(); }
@ -253,23 +162,14 @@ class CPUExecContext
return dtb->translate(req, tc, true);
}
FunctionalPort *getPhysPort() { return physPort; }
void dumpFuncProfile();
/** Return a virtual port. If no thread context is specified then a static
* port is returned. Otherwise a port is created and returned. It must be
* deleted by deleteVirtPort(). */
VirtualPort *getVirtPort(ThreadContext *tc);
void delVirtPort(VirtualPort *vp);
int readIntrFlag() { return regs.intrflag; }
void setIntrFlag(int val) { regs.intrflag = val; }
Fault hwrei();
bool simPalCheck(int palFunc);
#else
TranslatingPort *getMemPort() { return port; }
Process *getProcessPtr() { return process; }
int getInstAsid() { return asid; }
int getDataAsid() { return asid; }
Fault translateInstReq(RequestPtr &req)
{
return process->pTable->translate(req);
@ -284,9 +184,50 @@ class CPUExecContext
{
return process->pTable->translate(req);
}
#endif
/*******************************************
* ThreadContext interface functions.
******************************************/
BaseCPU *getCpuPtr() { return cpu; }
int getThreadNum() { return tid; }
#if FULL_SYSTEM
System *getSystemPtr() { return system; }
AlphaITB *getITBPtr() { return itb; }
AlphaDTB *getDTBPtr() { return dtb; }
FunctionalPort *getPhysPort() { return physPort; }
/** Return a virtual port. If no thread context is specified then a static
* port is returned. Otherwise a port is created and returned. It must be
* deleted by deleteVirtPort(). */
VirtualPort *getVirtPort(ThreadContext *tc);
void delVirtPort(VirtualPort *vp);
#endif
Status status() const { return _status; }
void setStatus(Status newStatus) { _status = newStatus; }
/// Set the status to Active. Optional delay indicates number of
/// cycles to wait before beginning execution.
void activate(int delay = 1);
/// Set the status to Suspended.
void suspend();
/// Set the status to Unallocated.
void deallocate();
/// Set the status to Halted.
void halt();
/*
template <class T>
Fault read(RequestPtr &req, T &data)
@ -358,14 +299,6 @@ class CPUExecContext
*/
virtual bool misspeculating();
MachInst getInst() { return inst; }
void setInst(MachInst new_inst)
{
inst = new_inst;
}
Fault instRead(RequestPtr &req)
{
panic("instRead not implemented");
@ -373,12 +306,10 @@ class CPUExecContext
return NoFault;
}
void setCpuId(int id) { cpu_id = id; }
int readCpuId() { return cpu_id; }
void copyArchRegs(ThreadContext *tc);
void clearArchRegs() { regs.clear(); }
//
// New accessors for new decoder.
//
@ -462,7 +393,6 @@ class CPUExecContext
regs.setNextNPC(val);
}
MiscReg readMiscReg(int misc_reg)
{
return regs.readMiscReg(misc_reg);
@ -488,14 +418,8 @@ class CPUExecContext
void setStCondFailures(unsigned sc_failures)
{ storeCondFailures = sc_failures; }
void clearArchRegs() { regs.clear(); }
#if FULL_SYSTEM
int readIntrFlag() { return regs.intrflag; }
void setIntrFlag(int val) { regs.intrflag = val; }
Fault hwrei();
bool inPalMode() { return AlphaISA::PcPAL(regs.readPC()); }
bool simPalCheck(int palFunc);
#endif
#if !FULL_SYSTEM
@ -519,10 +443,6 @@ class CPUExecContext
{
process->syscall(callnum, tc);
}
Counter readFuncExeInst() { return func_exe_inst; }
void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; }
#endif
void changeRegFileContext(RegFile::ContextParam param,
@ -535,7 +455,7 @@ class CPUExecContext
// for non-speculative execution context, spec_mode is always false
inline bool
CPUExecContext::misspeculating()
SimpleThread::misspeculating()
{
return false;
}

46
src/cpu/thread_state.cc Normal file
View file

@ -0,0 +1,46 @@
#include "base/output.hh"
#include "cpu/profile.hh"
#include "cpu/thread_state.hh"
#if FULL_SYSTEM
ThreadState::ThreadState(int _cpuId, int _tid)
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
funcExeInst(0), storeCondFailures(0)
#else
ThreadState::ThreadState(int _cpuId, int _tid, MemObject *mem,
Process *_process, short _asid)
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
process(_process), asid(_asid),
funcExeInst(0), storeCondFailures(0)
#endif
{
#if !FULL_SYSTEM
/* Use this port to for syscall emulation writes to memory. */
Port *mem_port;
port = new TranslatingPort(csprintf("%d-funcport",
tid),
process->pTable, false);
mem_port = mem->getPort("functional");
mem_port->setPeer(port);
port->setPeer(mem_port);
#endif
}
#if FULL_SYSTEM
void
ThreadState::profileClear()
{
if (profile)
profile->clear();
}
void
ThreadState::profileSample()
{
if (profile)
profile->sample(profileNode, profilePC);
}
#endif

View file

@ -29,10 +29,13 @@
#ifndef __CPU_THREAD_STATE_HH__
#define __CPU_THREAD_STATE_HH__
#include "arch/isa_traits.hh"
#include "cpu/thread_context.hh"
#if !FULL_SYSTEM
#include "mem/mem_object.hh"
#include "mem/translating_port.hh"
#include "sim/process.hh"
#endif
#if FULL_SYSTEM
@ -42,9 +45,6 @@ class ProfileNode;
namespace Kernel {
class Statistics;
};
#else
class FunctionalMemory;
class Process;
#endif
/**
@ -54,56 +54,121 @@ class Process;
* to hold more thread-specific stats within it.
*/
struct ThreadState {
typedef ThreadContext::Status Status;
#if FULL_SYSTEM
ThreadState(int _cpuId, int _tid)
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL)
ThreadState(int _cpuId, int _tid);
#else
ThreadState(int _cpuId, int _tid, MemObject *mem,
Process *_process, short _asid)
: cpuId(_cpuId), tid(_tid), process(_process), asid(_asid)
Process *_process, short _asid);
#endif
{
funcExeInst = 0;
storeCondFailures = 0;
#if !FULL_SYSTEM
/* Use this port to for syscall emulation writes to memory. */
Port *mem_port;
port = new TranslatingPort(csprintf("%d-funcport",
tid),
process->pTable, false);
mem_port = mem->getPort("functional");
mem_port->setPeer(port);
port->setPeer(mem_port);
void setCpuId(int id) { cpuId = id; }
int readCpuId() { return cpuId; }
void setTid(int id) { tid = id; }
int readTid() { return tid; }
Tick readLastActivate() { return lastActivate; }
Tick readLastSuspend() { return lastSuspend; }
#if FULL_SYSTEM
void dumpFuncProfile();
EndQuiesceEvent *getQuiesceEvent() { return quiesceEvent; }
void profileClear();
void profileSample();
Kernel::Statistics *getKernelStats() { return kernelStats; }
void setPhysPort(FunctionalPort *port) { physPort = port; }
void setVirtPort(VirtualPort *port) { virtPort = port; }
#else
Process *getProcessPtr() { return process; }
TranslatingPort *getMemPort() { return port; }
void setMemPort(TranslatingPort *_port) { port = _port; }
int getInstAsid() { return asid; }
int getDataAsid() { return asid; }
#endif
}
ThreadContext::Status status;
/** Sets the current instruction being committed. */
void setInst(TheISA::MachInst _inst) { inst = _inst; }
/** Returns the current instruction being committed. */
TheISA::MachInst getInst() { return inst; }
/** Reads the number of instructions functionally executed and
* committed.
*/
Counter readFuncExeInst() { return funcExeInst; }
/** Sets the total number of instructions functionally executed
* and committed.
*/
void setFuncExeInst(Counter new_val) { funcExeInst = new_val; }
/** Returns the status of this thread. */
Status status() const { return _status; }
/** Sets the status of this thread. */
void setStatus(Status new_status) { _status = new_status; }
/** Number of instructions committed. */
Counter numInst;
/** Stat for number instructions committed. */
Stats::Scalar<> numInsts;
/** Stat for number of memory references. */
Stats::Scalar<> numMemRefs;
/** Number of simulated loads, used for tracking events based on
* the number of loads committed.
*/
Counter numLoad;
/** The number of simulated loads committed prior to this run. */
Counter startNumLoad;
protected:
ThreadContext::Status _status;
// ID of this context w.r.t. the System or Process object to which
// it belongs. For full-system mode, this is the system CPU ID.
int cpuId;
// Index of hardware thread context on the CPU that this represents.
int tid;
Counter numInst;
Stats::Scalar<> numInsts;
Stats::Scalar<> numMemRefs;
// number of simulated loads
Counter numLoad;
Counter startNumLoad;
#if FULL_SYSTEM
/** Last time activate was called on this thread. */
Tick lastActivate;
/** Last time suspend was called on this thread. */
Tick lastSuspend;
#if FULL_SYSTEM
public:
FunctionProfile *profile;
ProfileNode *profileNode;
Addr profilePC;
EndQuiesceEvent *quiesceEvent;
Kernel::Statistics *kernelStats;
protected:
/** A functional port outgoing only for functional accesses to physical
* addresses.*/
FunctionalPort *physPort;
/** A functional port, outgoing only, for functional accesse to virtual
* addresses. That doen't require execution context information */
VirtualPort *virtPort;
#else
TranslatingPort *port;
@ -113,9 +178,13 @@ struct ThreadState {
// simulation only; all functional memory accesses should use
// one of the FunctionalMemory pointers above.
short asid;
#endif
/** Current instruction the thread is committing. Only set and
* used for DTB faults currently.
*/
TheISA::MachInst inst;
/**
* Temporary storage to pass the source address from copy_load to
* copy_store.
@ -128,6 +197,7 @@ struct ThreadState {
*/
Addr copySrcPhysAddr;
public:
/*
* number of executed instructions, for matching with syscall trace
* points in EIO files.

View file

@ -30,7 +30,7 @@
*/
#include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/thread_context.hh"
#include "kern/kernel_stats.hh"
#include "kern/system_events.hh"
#include "sim/system.hh"

View file

@ -46,7 +46,6 @@
#include "base/statistics.hh"
#include "sim/sim_object.hh"
class CPUExecContext;
class ThreadContext;
class SyscallDesc;
class PageTable;