summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConscript2
-rw-r--r--arch/SConscript3
-rw-r--r--arch/alpha/arguments.cc8
-rw-r--r--arch/alpha/ev5.cc87
-rw-r--r--arch/alpha/faults.cc6
-rw-r--r--arch/alpha/freebsd/system.cc8
-rw-r--r--arch/alpha/isa/decoder.isa2
-rw-r--r--arch/alpha/isa_traits.hh156
-rw-r--r--arch/alpha/linux/process.cc7
-rw-r--r--arch/alpha/linux/system.cc4
-rw-r--r--arch/alpha/linux/threadinfo.hh2
-rw-r--r--arch/alpha/stacktrace.cc30
-rw-r--r--arch/alpha/tlb.cc3
-rw-r--r--arch/alpha/tru64/process.cc16
-rw-r--r--arch/alpha/vtophys.cc27
-rw-r--r--arch/mips/faults.cc2
-rw-r--r--arch/mips/faults.hh66
-rw-r--r--arch/mips/isa/base.isa11
-rw-r--r--arch/mips/isa/bitfields.isa5
-rw-r--r--arch/mips/isa/decoder.isa323
-rw-r--r--arch/mips/isa/formats.isa3
-rw-r--r--arch/mips/isa/formats/basic.isa4
-rw-r--r--arch/mips/isa/formats/branch.isa81
-rw-r--r--arch/mips/isa/formats/fp.isa41
-rw-r--r--arch/mips/isa/formats/int.isa63
-rw-r--r--arch/mips/isa/formats/mem.isa9
-rw-r--r--arch/mips/isa/formats/noop.isa10
-rw-r--r--arch/mips/isa/formats/trap.isa11
-rw-r--r--arch/mips/isa/formats/unimp.isa4
-rw-r--r--arch/mips/isa/formats/unknown.isa2
-rw-r--r--arch/mips/isa/formats/util.isa69
-rw-r--r--arch/mips/isa/operands.isa11
-rw-r--r--arch/mips/isa_traits.cc276
-rw-r--r--arch/mips/isa_traits.hh291
-rw-r--r--arch/mips/linux_process.cc4
-rw-r--r--arch/mips/stacktrace.hh119
-rw-r--r--arch/sparc/isa_traits.hh234
-rw-r--r--arch/sparc/linux/process.cc1
-rw-r--r--arch/sparc/stacktrace.hh119
-rw-r--r--base/loader/exec_aout.h3
-rw-r--r--base/loader/exec_ecoff.h3
-rw-r--r--base/remote_gdb.cc22
-rw-r--r--cpu/base.cc46
-rw-r--r--cpu/base.hh5
-rw-r--r--cpu/base_dyn_inst.cc32
-rw-r--r--cpu/base_dyn_inst.hh8
-rw-r--r--cpu/cpu_exec_context.cc (renamed from cpu/exec_context.cc)143
-rw-r--r--cpu/cpu_exec_context.hh530
-rw-r--r--cpu/exec_context.hh568
-rw-r--r--cpu/exetrace.cc1
-rw-r--r--cpu/intr_control.cc9
-rw-r--r--cpu/intr_control.hh1
-rw-r--r--cpu/memtest/memtest.cc6
-rw-r--r--cpu/memtest/memtest.hh2
-rw-r--r--cpu/o3/alpha_cpu.hh47
-rw-r--r--cpu/o3/alpha_cpu_builder.cc1
-rw-r--r--cpu/o3/alpha_cpu_impl.hh72
-rw-r--r--cpu/o3/cpu.cc33
-rw-r--r--cpu/o3/cpu.hh30
-rw-r--r--cpu/o3/regfile.hh3
-rw-r--r--cpu/pc_event.cc7
-rw-r--r--cpu/profile.cc1
-rw-r--r--cpu/profile.hh2
-rw-r--r--cpu/simple/cpu.cc147
-rw-r--r--cpu/simple/cpu.hh53
-rw-r--r--dev/alpha_console.hh1
-rw-r--r--dev/baddev.hh2
-rw-r--r--dev/isa_fake.hh2
-rw-r--r--dev/tsunami_cchip.cc3
-rw-r--r--dev/uart.hh1
-rw-r--r--dev/uart8250.hh1
-rw-r--r--kern/kernel_stats.cc31
-rw-r--r--kern/kernel_stats.hh13
-rw-r--r--kern/linux/events.cc3
-rw-r--r--kern/system_events.cc21
-rw-r--r--kern/tru64/dump_mbuf.cc4
-rw-r--r--kern/tru64/tru64.hh79
-rw-r--r--kern/tru64/tru64_events.cc12
-rw-r--r--sim/faults.cc4
-rw-r--r--sim/process.cc7
-rw-r--r--sim/process.hh2
-rw-r--r--sim/pseudo_inst.cc34
-rw-r--r--sim/syscall_emul.cc20
-rw-r--r--sim/syscall_emul.hh40
84 files changed, 2748 insertions, 1427 deletions
diff --git a/SConscript b/SConscript
index ce95b28fe..8afac510b 100644
--- a/SConscript
+++ b/SConscript
@@ -82,7 +82,7 @@ base_sources = Split('''
cpu/base.cc
cpu/base_dyn_inst.cc
- cpu/exec_context.cc
+ cpu/cpu_exec_context.cc
cpu/exetrace.cc
cpu/pc_event.cc
cpu/static_inst.cc
diff --git a/arch/SConscript b/arch/SConscript
index b4b7a1ddb..0533261a2 100644
--- a/arch/SConscript
+++ b/arch/SConscript
@@ -48,13 +48,10 @@ isa_switch_hdrs = Split('''
isa_traits.hh
tlb.hh
process.hh
- aout_machdep.h
- ecoff_machdep.h
arguments.hh
stacktrace.hh
vtophys.hh
faults.hh
- ev5.hh
''')
# Generate the header. target[0] is the full path of the output
diff --git a/arch/alpha/arguments.cc b/arch/alpha/arguments.cc
index 4e8190cbc..019390aeb 100644
--- a/arch/alpha/arguments.cc
+++ b/arch/alpha/arguments.cc
@@ -54,13 +54,13 @@ AlphaArguments::getArg(bool fp)
{
if (number < 6) {
if (fp)
- return xc->regs.floatRegFile.q[16 + number];
+ return xc->readFloatRegInt(16 + number);
else
- return xc->regs.intRegFile[16 + number];
+ return xc->readIntReg(16 + number);
} else {
- Addr sp = xc->regs.intRegFile[30];
+ Addr sp = xc->readIntReg(30);
Addr paddr = vtophys(xc, sp + (number-6) * sizeof(uint64_t));
- return xc->physmem->phys_read_qword(paddr);
+ return xc->getPhysMemPtr()->phys_read_qword(paddr);
}
}
diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc
index e313c1a1c..019e83dd4 100644
--- a/arch/alpha/ev5.cc
+++ b/arch/alpha/ev5.cc
@@ -34,6 +34,7 @@
#include "base/stats/events.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
+#include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh"
#include "cpu/fast/cpu.hh"
#include "kern/kernel_stats.hh"
@@ -49,15 +50,15 @@ using namespace EV5;
// Machine dependent functions
//
void
-AlphaISA::initCPU(RegFile *regs, int cpuId)
+AlphaISA::initCPU(ExecContext *xc, int cpuId)
{
- initIPRs(&regs->miscRegs, cpuId);
+ initIPRs(xc, cpuId);
- regs->intRegFile[16] = cpuId;
- regs->intRegFile[0] = cpuId;
+ xc->setIntReg(16, cpuId);
+ xc->setIntReg(0, cpuId);
- regs->pc = regs->miscRegs.readReg(IPR_PAL_BASE) + (new ResetFault)->vect();
- regs->npc = regs->pc + sizeof(MachInst);
+ xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + (new ResetFault)->vect());
+ xc->setNextPC(xc->readPC() + sizeof(MachInst));
}
////////////////////////////////////////////////////////////////////////
@@ -65,13 +66,15 @@ AlphaISA::initCPU(RegFile *regs, int cpuId)
//
//
void
-AlphaISA::initIPRs(MiscRegFile *miscRegs, int cpuId)
+AlphaISA::initIPRs(ExecContext *xc, int cpuId)
{
- miscRegs->clearIprs();
+ for (int i = 0; i < NumInternalProcRegs; ++i) {
+ xc->setMiscReg(i, 0);
+ }
- miscRegs->setReg(IPR_PAL_BASE, PalBase);
- miscRegs->setReg(IPR_MCSR, 0x6);
- miscRegs->setReg(IPR_PALtemp16, cpuId);
+ xc->setMiscReg(IPR_PAL_BASE, PalBase);
+ xc->setMiscReg(IPR_MCSR, 0x6);
+ xc->setMiscReg(IPR_PALtemp16, cpuId);
}
@@ -130,12 +133,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->xc->setIntReg(ZeroReg, 0);
- cpu->xc->setFloatRegDouble(ZeroReg, 0.0);
+ cpu->cpuXC->setIntReg(ZeroReg, 0);
+ cpu->cpuXC->setFloatRegDouble(ZeroReg, 0.0);
}
Fault
-ExecContext::hwrei()
+CPUExecContext::hwrei()
{
if (!inPalMode())
return new UnimplementedOpcodeFault;
@@ -143,7 +146,7 @@ ExecContext::hwrei()
setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR));
if (!misspeculating()) {
- kernelStats->hwrei();
+ cpu->kernelStats->hwrei();
cpu->checkInterrupts = true;
}
@@ -152,10 +155,16 @@ ExecContext::hwrei()
return NoFault;
}
-void
-AlphaISA::MiscRegFile::clearIprs()
+int
+AlphaISA::MiscRegFile::getInstAsid()
+{
+ return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
+}
+
+int
+AlphaISA::MiscRegFile::getDataAsid()
{
- bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg));
+ return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
}
AlphaISA::MiscReg
@@ -213,7 +222,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc)
case AlphaISA::IPR_CC:
retval |= ipr[idx] & ULL(0xffffffff00000000);
- retval |= xc->cpu->curCycle() & ULL(0x00000000ffffffff);
+ retval |= xc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff);
break;
case AlphaISA::IPR_VA:
@@ -230,7 +239,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc)
case AlphaISA::IPR_DTB_PTE:
{
- AlphaISA::PTE &pte = xc->dtb->index(!xc->misspeculating());
+ AlphaISA::PTE &pte = xc->getDTBPtr()->index(!xc->misspeculating());
retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32;
retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8;
@@ -327,7 +336,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// write entire quad w/ no side-effect
old = ipr[idx];
ipr[idx] = val;
- xc->kernelStats->context(old, val);
+ xc->getCpuPtr()->kernelStats->context(old, val, xc);
break;
case AlphaISA::IPR_DTB_PTE:
@@ -354,14 +363,14 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// only write least significant five bits - interrupt level
ipr[idx] = val & 0x1f;
- xc->kernelStats->swpipl(ipr[idx]);
+ xc->getCpuPtr()->kernelStats->swpipl(ipr[idx]);
break;
case AlphaISA::IPR_DTB_CM:
if (val & 0x18)
- xc->kernelStats->mode(Kernel::user);
+ xc->getCpuPtr()->kernelStats->mode(Kernel::user, xc);
else
- xc->kernelStats->mode(Kernel::kernel);
+ xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc);
case AlphaISA::IPR_ICM:
// only write two mode bits - processor mode
@@ -435,21 +444,22 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// really a control write
ipr[idx] = 0;
- xc->dtb->flushAll();
+ xc->getDTBPtr()->flushAll();
break;
case AlphaISA::IPR_DTB_IAP:
// really a control write
ipr[idx] = 0;
- xc->dtb->flushProcesses();
+ xc->getDTBPtr()->flushProcesses();
break;
case AlphaISA::IPR_DTB_IS:
// really a control write
ipr[idx] = val;
- xc->dtb->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
+ xc->getDTBPtr()->flushAddr(val,
+ DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
break;
case AlphaISA::IPR_DTB_TAG: {
@@ -472,7 +482,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]);
// insert new TAG/PTE value into data TLB
- xc->dtb->insert(val, pte);
+ xc->getDTBPtr()->insert(val, pte);
}
break;
@@ -496,7 +506,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]);
// insert new TAG/PTE value into data TLB
- xc->itb->insert(ipr[AlphaISA::IPR_ITB_TAG], pte);
+ xc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte);
}
break;
@@ -504,21 +514,22 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// really a control write
ipr[idx] = 0;
- xc->itb->flushAll();
+ xc->getITBPtr()->flushAll();
break;
case AlphaISA::IPR_ITB_IAP:
// really a control write
ipr[idx] = 0;
- xc->itb->flushProcesses();
+ xc->getITBPtr()->flushProcesses();
break;
case AlphaISA::IPR_ITB_IS:
// really a control write
ipr[idx] = val;
- xc->itb->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]));
+ xc->getITBPtr()->flushAddr(val,
+ ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]));
break;
default:
@@ -530,14 +541,22 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
return NoFault;
}
+void
+AlphaISA::MiscRegFile::copyIprs(ExecContext *xc)
+{
+ for (int i = IPR_Base_DepTag; i < NumInternalProcRegs; ++i) {
+ ipr[i] = xc->readMiscReg(i);
+ }
+}
+
/**
* Check for special simulator handling of specific PAL calls.
* If return value is false, actual PAL call will be suppressed.
*/
bool
-ExecContext::simPalCheck(int palFunc)
+CPUExecContext::simPalCheck(int palFunc)
{
- kernelStats->callpal(palFunc);
+ cpu->kernelStats->callpal(palFunc, proxy);
switch (palFunc) {
case PAL::halt:
diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc
index 75165eece..e0918da21 100644
--- a/arch/alpha/faults.cc
+++ b/arch/alpha/faults.cc
@@ -107,7 +107,7 @@ void AlphaFault::invoke(ExecContext * xc)
// exception restart address
if (setRestartAddress() || !xc->inPalMode())
- xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc);
+ xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->readPC());
if (skipFaultingInstruction()) {
// traps... skip faulting instruction.
@@ -115,8 +115,8 @@ void AlphaFault::invoke(ExecContext * xc)
xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
}
- xc->regs.pc = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect();
- xc->regs.npc = xc->regs.pc + sizeof(MachInst);
+ xc->setPC(xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect());
+ xc->setNextPC(xc->readPC() + sizeof(MachInst));
}
void ArithmeticFault::invoke(ExecContext * xc)
diff --git a/arch/alpha/freebsd/system.cc b/arch/alpha/freebsd/system.cc
index 681d4ad46..e32053afd 100644
--- a/arch/alpha/freebsd/system.cc
+++ b/arch/alpha/freebsd/system.cc
@@ -39,8 +39,8 @@
#include "cpu/exec_context.hh"
#include "mem/functional/memory_control.hh"
#include "mem/functional/physical.hh"
-#include "sim/builder.hh"
#include "arch/isa_traits.hh"
+#include "sim/builder.hh"
#include "sim/byteswap.hh"
#include "arch/vtophys.hh"
@@ -77,8 +77,8 @@ FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc)
Addr ppc_paddr = 0;
Addr timer_paddr = 0;
- ppc_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg1];
- timer_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg2];
+ ppc_vaddr = (Addr)xc->readIntReg(ArgumentReg1);
+ timer_vaddr = (Addr)xc->readIntReg(ArgumentReg2);
ppc_paddr = vtophys(physmem, ppc_vaddr);
timer_paddr = vtophys(physmem, timer_vaddr);
@@ -95,7 +95,7 @@ void
FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ExecContext *xc)
{
SkipFuncEvent::process(xc);
- ((FreebsdAlphaSystem *)xc->system)->doCalibrateClocks(xc);
+ ((FreebsdAlphaSystem *)xc->getSystemPtr())->doCalibrateClocks(xc);
}
diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa
index 54bc97920..e09673269 100644
--- a/arch/alpha/isa/decoder.isa
+++ b/arch/alpha/isa/decoder.isa
@@ -784,7 +784,7 @@ decode OPCODE default Unknown::unknown() {
0x21: m5exit({{
AlphaPseudo::m5exit(xc->xcBase(), R16);
}}, No_OpClass, IsNonSpeculative);
- 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }});
+ 0x30: initparam({{ Ra = xc->xcBase()->getCpuPtr()->system->init_param; }});
0x40: resetstats({{
AlphaPseudo::resetstats(xc->xcBase(), R16, R17);
}}, IsNonSpeculative);
diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh
index 198473918..6f6b11e62 100644
--- a/arch/alpha/isa_traits.hh
+++ b/arch/alpha/isa_traits.hh
@@ -98,57 +98,49 @@ namespace AlphaISA
typedef uint64_t ExtMachInst;
typedef uint8_t RegIndex;
- enum {
- MemoryEnd = 0xffffffffffffffffULL,
-
- NumIntArchRegs = 32,
- NumPALShadowRegs = 8,
- NumFloatArchRegs = 32,
- // @todo: Figure out what this number really should be.
- NumMiscArchRegs = 32,
-
- MaxRegsOfAnyType = 32,
- // Static instruction parameters
- MaxInstSrcRegs = 3,
- MaxInstDestRegs = 2,
-
- // semantically meaningful register indices
- ZeroReg = 31, // architecturally meaningful
- // the rest of these depend on the ABI
- StackPointerReg = 30,
- GlobalPointerReg = 29,
- ProcedureValueReg = 27,
- ReturnAddressReg = 26,
- ReturnValueReg = 0,
- SyscallNumReg = 0,
- FramePointerReg = 15,
- ArgumentReg0 = 16,
- ArgumentReg1 = 17,
- ArgumentReg2 = 18,
- ArgumentReg3 = 19,
- ArgumentReg4 = 20,
- ArgumentReg5 = 21,
- SyscallSuccessReg = 19,
- // Some OS use a second register (o1) to return a second value
- // for some syscalls
- SyscallPseudoReturnReg = ArgumentReg4,
-
- LogVMPageSize = 13, // 8K bytes
- VMPageSize = (1 << LogVMPageSize),
-
- BranchPredAddrShiftAmt = 2, // instructions are 4-byte aligned
-
- WordBytes = 4,
- HalfwordBytes = 2,
- ByteBytes = 1,
- DepNA = 0,
- };
-
- enum {
- NumIntRegs = NumIntArchRegs + NumPALShadowRegs,
- NumFloatRegs = NumFloatArchRegs,
- NumMiscRegs = NumMiscArchRegs
- };
+ const int NumIntArchRegs = 32;
+ const int NumPALShadowRegs = 8;
+ const int NumFloatArchRegs = 32;
+ // @todo: Figure out what this number really should be.
+ const int NumMiscArchRegs = 32;
+
+ // Static instruction parameters
+ const int MaxInstSrcRegs = 3;
+ const int MaxInstDestRegs = 2;
+
+ // semantically meaningful register indices
+ const int ZeroReg = 31; // architecturally meaningful
+ // the rest of these depend on the ABI
+ const int StackPointerReg = 30;
+ const int GlobalPointerReg = 29;
+ const int ProcedureValueReg = 27;
+ const int ReturnAddressReg = 26;
+ const int ReturnValueReg = 0;
+ const int FramePointerReg = 15;
+ const int ArgumentReg0 = 16;
+ const int ArgumentReg1 = 17;
+ const int ArgumentReg2 = 18;
+ const int ArgumentReg3 = 19;
+ const int ArgumentReg4 = 20;
+ const int ArgumentReg5 = 21;
+ const int SyscallNumReg = ReturnValueReg;
+ const int SyscallPseudoReturnReg = ArgumentReg4;
+
+
+
+ const int LogVMPageSize = 13; // 8K bytes
+ const int VMPageSize = (1 << LogVMPageSize);
+
+ const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
+
+ const int WordBytes = 4;
+ const int HalfwordBytes = 2;
+ const int ByteBytes = 1;
+
+
+ const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
+ const int NumFloatRegs = NumFloatArchRegs;
+ const int NumMiscRegs = NumMiscArchRegs;
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
@@ -192,9 +184,7 @@ extern const int reg_redir[NumIntRegs];
#include "arch/alpha/isa_fullsys_traits.hh"
#else
- enum {
- NumInternalProcRegs = 0
- };
+ const int NumInternalProcRegs = 0;
#endif
// control register file contents
@@ -209,6 +199,11 @@ extern const int reg_redir[NumIntRegs];
public:
MiscReg readReg(int misc_reg);
+ //These functions should be removed once the simplescalar cpu model
+ //has been replaced.
+ int getInstAsid();
+ int getDataAsid();
+
MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc);
Fault setReg(int misc_reg, const MiscReg &val);
@@ -216,9 +211,9 @@ extern const int reg_redir[NumIntRegs];
Fault setRegWithEffect(int misc_reg, const MiscReg &val,
ExecContext *xc);
-#if FULL_SYSTEM
- void clearIprs();
+ void copyMiscRegs(ExecContext *xc);
+#if FULL_SYSTEM
protected:
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
@@ -226,18 +221,16 @@ extern const int reg_redir[NumIntRegs];
MiscReg readIpr(int idx, Fault &fault, ExecContext *xc);
Fault setIpr(int idx, uint64_t val, ExecContext *xc);
+
+ void copyIprs(ExecContext *xc);
#endif
friend class RegFile;
};
- enum {
- TotalNumRegs =
- NumIntRegs + NumFloatRegs + NumMiscRegs + NumInternalProcRegs
- };
+ const int TotalNumRegs = NumIntRegs + NumFloatRegs +
+ NumMiscRegs + NumInternalProcRegs;
- enum {
- TotalDataRegs = NumIntRegs + NumFloatRegs
- };
+ const int TotalDataRegs = NumIntRegs + NumFloatRegs;
typedef union {
IntReg intreg;
@@ -251,6 +244,8 @@ extern const int reg_redir[NumIntRegs];
MiscRegFile miscRegs; // control register file
Addr pc; // program counter
Addr npc; // next-cycle program counter
+ Addr nnpc;
+
#if FULL_SYSTEM
int intrflag; // interrupt flag
inline int instAsid()
@@ -362,38 +357,6 @@ extern const int reg_redir[NumIntRegs];
}
}
-//typedef AlphaISA TheISA;
-
-//typedef TheISA::MachInst MachInst;
-//typedef TheISA::Addr Addr;
-//typedef TheISA::RegIndex RegIndex;
-//typedef TheISA::IntReg IntReg;
-//typedef TheISA::IntRegFile IntRegFile;
-//typedef TheISA::FloatReg FloatReg;
-//typedef TheISA::FloatRegFile FloatRegFile;
-//typedef TheISA::MiscReg MiscReg;
-//typedef TheISA::MiscRegFile MiscRegFile;
-//typedef TheISA::AnyReg AnyReg;
-//typedef TheISA::RegFile RegFile;
-
-//const int NumIntRegs = TheISA::NumIntRegs;
-//const int NumFloatRegs = TheISA::NumFloatRegs;
-//const int NumMiscRegs = TheISA::NumMiscRegs;
-//const int TotalNumRegs = TheISA::TotalNumRegs;
-//const int VMPageSize = TheISA::VMPageSize;
-//const int LogVMPageSize = TheISA::LogVMPageSize;
-//const int ZeroReg = TheISA::ZeroReg;
-//const int StackPointerReg = TheISA::StackPointerReg;
-//const int GlobalPointerReg = TheISA::GlobalPointerReg;
-//const int ReturnAddressReg = TheISA::ReturnAddressReg;
-//const int ReturnValueReg = TheISA::ReturnValueReg;
-//const int ArgumentReg0 = TheISA::ArgumentReg0;
-//const int ArgumentReg1 = TheISA::ArgumentReg1;
-//const int ArgumentReg2 = TheISA::ArgumentReg2;
-//const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt;
-const Addr MaxAddr = (Addr)-1;
-};
-
static inline AlphaISA::ExtMachInst
AlphaISA::makeExtMI(AlphaISA::MachInst inst, const uint64_t &pc) {
#if FULL_SYSTEM
@@ -408,9 +371,6 @@ AlphaISA::makeExtMI(AlphaISA::MachInst inst, const uint64_t &pc) {
}
#if FULL_SYSTEM
-//typedef TheISA::InternalProcReg InternalProcReg;
-//const int NumInternalProcRegs = TheISA::NumInternalProcRegs;
-//const int NumInterruptLevels = TheISA::NumInterruptLevels;
#include "arch/alpha/ev5.hh"
#endif
diff --git a/arch/alpha/linux/process.cc b/arch/alpha/linux/process.cc
index 2ebdbfc0f..1c911bc50 100644
--- a/arch/alpha/linux/process.cc
+++ b/arch/alpha/linux/process.cc
@@ -42,7 +42,6 @@ using namespace AlphaISA;
-
/// Target uname() handler.
static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, Process *process,
@@ -56,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "alpha");
- name.copyOut(xc->mem);
+ name.copyOut(xc->getMemPtr());
return 0;
}
@@ -76,7 +75,7 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
- fpcr.copyOut(xc->mem);
+ fpcr.copyOut(xc->getMemPtr());
return 0;
}
@@ -102,7 +101,7 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
case 14: { // SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
// I don't think this exactly matches the HW FPCR
- fpcr.copyIn(xc->mem);
+ fpcr.copyIn(xc->getMemPtr());
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
return 0;
diff --git a/arch/alpha/linux/system.cc b/arch/alpha/linux/system.cc
index 6a820d14f..f9275d15e 100644
--- a/arch/alpha/linux/system.cc
+++ b/arch/alpha/linux/system.cc
@@ -195,7 +195,7 @@ LinuxAlphaSystem::setDelayLoop(ExecContext *xc)
uint8_t *loops_per_jiffy =
physmem->dma_addr(paddr, sizeof(uint32_t));
- Tick cpuFreq = xc->cpu->frequency();
+ Tick cpuFreq = xc->getCpuPtr()->frequency();
Tick intrFreq = platform->intrFrequency();
*(uint32_t *)loops_per_jiffy =
(uint32_t)((cpuFreq / intrFreq) * 0.9988);
@@ -208,7 +208,7 @@ LinuxAlphaSystem::SkipDelayLoopEvent::process(ExecContext *xc)
{
SkipFuncEvent::process(xc);
// calculate and set loops_per_jiffy
- ((LinuxAlphaSystem *)xc->system)->setDelayLoop(xc);
+ ((LinuxAlphaSystem *)xc->getSystemPtr())->setDelayLoop(xc);
}
void
diff --git a/arch/alpha/linux/threadinfo.hh b/arch/alpha/linux/threadinfo.hh
index bdb8e1e4c..8f03c9314 100644
--- a/arch/alpha/linux/threadinfo.hh
+++ b/arch/alpha/linux/threadinfo.hh
@@ -54,7 +54,7 @@ class ThreadInfo
* thread_info struct. So we can get the address by masking off
* the lower 14 bits.
*/
- current = xc->regs.intRegFile[TheISA::StackPointerReg] & ~0x3fff;
+ current = xc->readIntReg(TheISA::StackPointerReg) & ~0x3fff;
return VPtr<thread_info>(xc, current);
}
diff --git a/arch/alpha/stacktrace.cc b/arch/alpha/stacktrace.cc
index 89b6b73a9..26656ab5c 100644
--- a/arch/alpha/stacktrace.cc
+++ b/arch/alpha/stacktrace.cc
@@ -35,6 +35,7 @@
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/exec_context.hh"
+#include "sim/system.hh"
using namespace std;
using namespace AlphaISA;
@@ -44,23 +45,23 @@ ProcessInfo::ProcessInfo(ExecContext *_xc)
{
Addr addr = 0;
- if (!xc->system->kernelSymtab->findAddress("thread_info_size", addr))
+ if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
panic("thread info not compiled into kernel\n");
thread_info_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
- if (!xc->system->kernelSymtab->findAddress("task_struct_size", addr))
+ if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
panic("thread info not compiled into kernel\n");
task_struct_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
- if (!xc->system->kernelSymtab->findAddress("thread_info_task", addr))
+ if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
panic("thread info not compiled into kernel\n");
task_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
- if (!xc->system->kernelSymtab->findAddress("task_struct_pid", addr))
+ if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
panic("thread info not compiled into kernel\n");
pid_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
- if (!xc->system->kernelSymtab->findAddress("task_struct_comm", addr))
+ if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
panic("thread info not compiled into kernel\n");
name_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
}
@@ -126,8 +127,9 @@ StackTrace::trace(ExecContext *_xc, bool is_call)
bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
- Addr pc = xc->regs.npc;
- bool kernel = xc->system->kernelStart <= pc && pc <= xc->system->kernelEnd;
+ Addr pc = xc->readNextPC();
+ bool kernel = xc->getSystemPtr()->kernelStart <= pc &&
+ pc <= xc->getSystemPtr()->kernelEnd;
if (usermode) {
stack.push_back(user);
@@ -139,8 +141,8 @@ StackTrace::trace(ExecContext *_xc, bool is_call)
return;
}
- SymbolTable *symtab = xc->system->kernelSymtab;
- Addr ksp = xc->regs.intRegFile[TheISA::StackPointerReg];
+ SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab;
+ Addr ksp = xc->readIntReg(TheISA::StackPointerReg);
Addr bottom = ksp & ~0x3fff;
Addr addr;
@@ -149,7 +151,7 @@ StackTrace::trace(ExecContext *_xc, bool is_call)
panic("could not find address %#x", pc);
stack.push_back(addr);
- pc = xc->regs.pc;
+ pc = xc->readPC();
}
Addr ra;
@@ -181,8 +183,8 @@ StackTrace::trace(ExecContext *_xc, bool is_call)
return;
}
- bool kernel = xc->system->kernelStart <= pc &&
- pc <= xc->system->kernelEnd;
+ bool kernel = xc->getSystemPtr()->kernelStart <= pc &&
+ pc <= xc->getSystemPtr()->kernelEnd;
if (!kernel)
return;
@@ -323,8 +325,8 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
void
StackTrace::dump()
{
- StringWrap name(xc->cpu->name());
- SymbolTable *symtab = xc->system->kernelSymtab;
+ StringWrap name(xc->getCpuPtr()->name());
+ SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab;
DPRINTFN("------ Stack ------\n");
diff --git a/arch/alpha/tlb.cc b/arch/alpha/tlb.cc
index 0f2cedc83..e30a8e595 100644
--- a/arch/alpha/tlb.cc
+++ b/arch/alpha/tlb.cc
@@ -496,9 +496,8 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const
Fault
AlphaDTB::translate(MemReqPtr &req, bool write) const
{
- RegFile *regs = &req->xc->regs;
ExecContext *xc = req->xc;
- Addr pc = regs->pc;
+ Addr pc = xc->readPC();
AlphaISA::mode_type mode =
(AlphaISA::mode_type)DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM));
diff --git a/arch/alpha/tru64/process.cc b/arch/alpha/tru64/process.cc
index 16621a8e2..c3a203587 100644
--- a/arch/alpha/tru64/process.cc
+++ b/arch/alpha/tru64/process.cc
@@ -51,7 +51,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
strcpy(name->version, "732");
strcpy(name->machine, "alpha");
- name.copyOut(xc->mem);
+ name.copyOut(xc->getMemPtr());
return 0;
}
@@ -68,21 +68,21 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
case Tru64::GSI_MAX_CPU: {
TypedBufferArg<uint32_t> max_cpu(xc->getSyscallArg(1));
*max_cpu = htog((uint32_t)process->numCpus());
- max_cpu.copyOut(xc->mem);
+ max_cpu.copyOut(xc->getMemPtr());
return 1;
}
case Tru64::GSI_CPUS_IN_BOX: {
TypedBufferArg<uint32_t> cpus_in_box(xc->getSyscallArg(1));
*cpus_in_box = htog((uint32_t)process->numCpus());
- cpus_in_box.copyOut(xc->mem);
+ cpus_in_box.copyOut(xc->getMemPtr());
return 1;
}
case Tru64::GSI_PHYSMEM: {
TypedBufferArg<uint64_t> physmem(xc->getSyscallArg(1));
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
- physmem.copyOut(xc->mem);
+ physmem.copyOut(xc->getMemPtr());
return 1;
}
@@ -99,14 +99,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
infop->cpu_ex_binding = htog(0);
infop->mhz = htog(667);
- infop.copyOut(xc->mem);
+ infop.copyOut(xc->getMemPtr());
return 1;
}
case Tru64::GSI_PROC_TYPE: {
TypedBufferArg<uint64_t> proc_type(xc->getSyscallArg(1));
*proc_type = htog((uint64_t)11);
- proc_type.copyOut(xc->mem);
+ proc_type.copyOut(xc->getMemPtr());
return 1;
}
@@ -115,14 +115,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
strncpy((char *)bufArg.bufferPtr(),
"COMPAQ Professional Workstation XP1000",
nbytes);
- bufArg.copyOut(xc->mem);
+ bufArg.copyOut(xc->getMemPtr());
return 1;
}
case Tru64::GSI_CLK_TCK: {
TypedBufferArg<uint64_t> clk_hz(xc->getSyscallArg(1));
*clk_hz = htog((uint64_t)1024);
- clk_hz.copyOut(xc->mem);
+ clk_hz.copyOut(xc->getMemPtr());
return 1;
}
diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc
index 1d70196c5..40261426d 100644
--- a/arch/alpha/vtophys.cc
+++ b/arch/alpha/vtophys.cc
@@ -95,7 +95,7 @@ vtophys(ExecContext *xc, Addr addr)
paddr = vaddr;
} else {
AlphaISA::PageTableEntry pte =
- kernel_pte_lookup(xc->physmem, ptbr, vaddr);
+ kernel_pte_lookup(xc->getPhysMemPtr(), ptbr, vaddr);
if (pte.valid())
paddr = pte.paddr() | vaddr.offset();
}
@@ -110,14 +110,14 @@ vtophys(ExecContext *xc, Addr addr)
uint8_t *
ptomem(ExecContext *xc, Addr paddr, size_t len)
{
- return xc->physmem->dma_addr(paddr, len);
+ return xc->getPhysMemPtr()->dma_addr(paddr, len);
}
uint8_t *
vtomem(ExecContext *xc, Addr vaddr, size_t len)
{
Addr paddr = vtophys(xc, vaddr);
- return xc->physmem->dma_addr(paddr, len);
+ return xc->getPhysMemPtr()->dma_addr(paddr, len);
}
void
@@ -131,7 +131,7 @@ CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen)
paddr = vtophys(xc, src);
len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)),
(int)cplen);
- dmaaddr = (char *)xc->physmem->dma_addr(paddr, len);
+ dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len);
assert(dmaaddr);
memcpy(dst, dmaaddr, len);
@@ -144,7 +144,8 @@ CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen)
while (cplen > AlphaISA::PageBytes) {
paddr = vtophys(xc, src);
- dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes);
+ dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr,
+ AlphaISA::PageBytes);
assert(dmaaddr);
memcpy(dst, dmaaddr, AlphaISA::PageBytes);
@@ -155,7 +156,7 @@ CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen)
if (cplen > 0) {
paddr = vtophys(xc, src);
- dmaaddr = (char *)xc->physmem->dma_addr(paddr, cplen);
+ dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen);
assert(dmaaddr);
memcpy(dst, dmaaddr, cplen);
@@ -173,7 +174,7 @@ CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen)
paddr = vtophys(xc, dest);
len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)),
(int)cplen);
- dmaaddr = (char *)xc->physmem->dma_addr(paddr, len);
+ dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len);
assert(dmaaddr);
memcpy(dmaaddr, src, len);
@@ -186,7 +187,8 @@ CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen)
while (cplen > AlphaISA::PageBytes) {
paddr = vtophys(xc, dest);
- dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes);
+ dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr,
+ AlphaISA::PageBytes);
assert(dmaaddr);
memcpy(dmaaddr, src, AlphaISA::PageBytes);
@@ -197,7 +199,7 @@ CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen)
if (cplen > 0) {
paddr = vtophys(xc, dest);
- dmaaddr = (char *)xc->physmem->dma_addr(paddr, cplen);
+ dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen);
assert(dmaaddr);
memcpy(dmaaddr, src, cplen);
@@ -214,7 +216,7 @@ CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen)
paddr = vtophys(xc, vaddr);
len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)),
(int)maxlen);
- dmaaddr = (char *)xc->physmem->dma_addr(paddr, len);
+ dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len);
assert(dmaaddr);
char *term = (char *)memchr(dmaaddr, 0, len);
@@ -232,7 +234,8 @@ CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen)
while (maxlen > AlphaISA::PageBytes) {
paddr = vtophys(xc, vaddr);
- dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes);
+ dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr,
+ AlphaISA::PageBytes);
assert(dmaaddr);
char *term = (char *)memchr(dmaaddr, 0, AlphaISA::PageBytes);
@@ -249,7 +252,7 @@ CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen)
if (maxlen > 0) {
paddr = vtophys(xc, vaddr);
- dmaaddr = (char *)xc->physmem->dma_addr(paddr, maxlen);
+ dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, maxlen);
assert(dmaaddr);
char *term = (char *)memchr(dmaaddr, 0, maxlen);
diff --git a/arch/mips/faults.cc b/arch/mips/faults.cc
index e05b3fe59..142dfe0a4 100644
--- a/arch/mips/faults.cc
+++ b/arch/mips/faults.cc
@@ -26,7 +26,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "arch/alpha/faults.hh"
+#include "arch/mips/faults.hh"
ResetFaultType * const ResetFault =
new ResetFaultType("reset", 1, 0x0001);
diff --git a/arch/mips/faults.hh b/arch/mips/faults.hh
index 60c9e735c..c1cb956b0 100644
--- a/arch/mips/faults.hh
+++ b/arch/mips/faults.hh
@@ -26,131 +26,131 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __ALPHA_FAULTS_HH__
-#define __ALPHA_FAULTS_HH__
+#ifndef __MIPS_FAULTS_HH__
+#define __MIPS_FAULTS_HH__
#include "sim/faults.hh"
#include "arch/isa_traits.hh" //For the Addr type
-class AlphaFault : public Fault
+class MipsFault : public FaultBase
{
public:
- AlphaFault(char * newName, int newId, Addr newVect)
- : Fault(newName, newId), vect(newVect)
+ MipsFault(char * newName, int newId, Addr newVect)
+ : FaultBase(newName, newId), vect(newVect)
{;}
Addr vect;
};
-extern class ResetFaultType : public AlphaFault
+extern class ResetFaultType : public MipsFault
{
public:
ResetFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const ResetFault;
-extern class ArithmeticFaultType : public AlphaFault
+extern class ArithmeticFaultType : public MipsFault
{
public:
ArithmeticFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const ArithmeticFault;
-extern class InterruptFaultType : public AlphaFault
+extern class InterruptFaultType : public MipsFault
{
public:
InterruptFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const InterruptFault;
-extern class NDtbMissFaultType : public AlphaFault
+extern class NDtbMissFaultType : public MipsFault
{
public:
NDtbMissFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const NDtbMissFault;
-extern class PDtbMissFaultType : public AlphaFault
+extern class PDtbMissFaultType : public MipsFault
{
public:
PDtbMissFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const PDtbMissFault;
-extern class DtbPageFaultType : public AlphaFault
+extern class DtbPageFaultType : public MipsFault
{
public:
DtbPageFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const DtbPageFault;
-extern class DtbAcvFaultType : public AlphaFault
+extern class DtbAcvFaultType : public MipsFault
{
public:
DtbAcvFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const DtbAcvFault;
-extern class ItbMissFaultType : public AlphaFault
+extern class ItbMissFaultType : public MipsFault
{
public:
ItbMissFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const ItbMissFault;
-extern class ItbPageFaultType : public AlphaFault
+extern class ItbPageFaultType : public MipsFault
{
public:
ItbPageFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const ItbPageFault;
-extern class ItbAcvFaultType : public AlphaFault
+extern class ItbAcvFaultType : public MipsFault
{
public:
ItbAcvFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const ItbAcvFault;
-extern class UnimplementedOpcodeFaultType : public AlphaFault
+extern class UnimplementedOpcodeFaultType : public MipsFault
{
public:
UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const UnimplementedOpcodeFault;
-extern class FloatEnableFaultType : public AlphaFault
+extern class FloatEnableFaultType : public MipsFault
{
public:
FloatEnableFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const FloatEnableFault;
-extern class PalFaultType : public AlphaFault
+extern class PalFaultType : public MipsFault
{
public:
PalFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const PalFault;
-extern class IntegerOverflowFaultType : public AlphaFault
+extern class IntegerOverflowFaultType : public MipsFault
{
public:
IntegerOverflowFaultType(char * newName, int newId, Addr newVect)
- : AlphaFault(newName, newId, newVect)
+ : MipsFault(newName, newId, newVect)
{;}
} * const IntegerOverflowFault;
diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa
index 7600632d3..4125b5101 100644
--- a/arch/mips/isa/base.isa
+++ b/arch/mips/isa/base.isa
@@ -7,7 +7,13 @@
//Outputs to decoder.hh
output header {{
+
#define R31 31
+#include "arch/mips/faults.hh"
+#include "arch/mips/isa_traits.hh"
+
+ using namespace MipsISA;
+
/**
* Base class for all MIPS static instructions.
@@ -19,12 +25,12 @@ output header {{
/// Make MipsISA register dependence tags directly visible in
/// this class and derived classes. Maybe these should really
/// live here and not in the MipsISA namespace.
- enum DependenceTags {
+ /*enum DependenceTags {
FP_Base_DepTag = MipsISA::FP_Base_DepTag,
Fpcr_DepTag = MipsISA::Fpcr_DepTag,
Uniq_DepTag = MipsISA::Uniq_DepTag,
IPR_Base_DepTag = MipsISA::IPR_Base_DepTag
- };
+ };*/
// Constructor
MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
@@ -67,6 +73,7 @@ output decoder {{
{
printReg(ss, _srcRegIdx[0]);
}
+
if(_numSrcRegs > 1)
{
ss << ",";
diff --git a/arch/mips/isa/bitfields.isa b/arch/mips/isa/bitfields.isa
index 3a01b64ee..58d487ad2 100644
--- a/arch/mips/isa/bitfields.isa
+++ b/arch/mips/isa/bitfields.isa
@@ -33,10 +33,12 @@ def bitfield INTIMM <15: 0>; // integer immediate (literal)
// Floating-point operate format
def bitfield FMT <25:21>;
+def bitfield FR <25:21>;
def bitfield FT <20:16>;
def bitfield FS <15:11>;
def bitfield FD <10:6>;
+def bitfield CC <20:18>;
def bitfield ND <17:17>;
def bitfield TF <16:16>;
def bitfield MOVCI <16:16>;
@@ -45,6 +47,9 @@ def bitfield SRL <21:21>;
def bitfield SRLV < 6: 6>;
def bitfield SA <10: 6>;
+// CP0 Register Select
+def bitfield SEL < 2: 0>;
+
// Interrupts
def bitfield SC < 5: 5>;
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa
index f16da7f87..3f054f6a5 100644
--- a/arch/mips/isa/decoder.isa
+++ b/arch/mips/isa/decoder.isa
@@ -20,8 +20,8 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode FUNCTION_LO {
0x1: decode MOVCI {
format BasicOp {
- 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}});
- 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}});
+ 0: movf({{ if (xc->readMiscReg(FPCR,0) != CC) Rd = Rs}});
+ 1: movt({{ if (xc->readMiscReg(FPCR,0) == CC) Rd = Rs}});
}
}
@@ -30,7 +30,17 @@ decode OPCODE_HI default Unknown::unknown() {
//Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
//are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
- 0x0: sll({{ Rd = Rt.uw << SA; }});
+ 0x0: decode RS {
+ 0x0: decode RT default BasicOp::sll({{ Rd = Rt.uw << SA; }}) {
+ 0x0: decode RD{
+ 0x0: decode HINT {
+ 0x0:nop({{}}); //really sll r0,r0,0
+ 0x1:ssnop({{}});//really sll r0,r0,1
+ 0x3:ehb({{}}); //really sll r0,r0,3
+ }
+ }
+ }
+ }
0x2: decode SRL {
0: srl({{ Rd = Rt.uw >> SA; }});
@@ -60,9 +70,9 @@ decode OPCODE_HI default Unknown::unknown() {
//to distinguish JR from JR.HB and JALR from JALR.HB"
format Jump {
0x0: decode HINT {
- 0:jr({{ NNPC = Rs; }},IsReturn);
+ 0:jr({{ NNPC = Rs & ~1; }},IsReturn);
- 1:jr_hb({{ NNPC = Rs; clear_exe_inst_hazards(); }},IsReturn);
+ 1:jr_hb({{ NNPC = Rs & ~1; clear_exe_inst_hazards(); }},IsReturn);
}
0x1: decode HINT {
@@ -86,10 +96,10 @@ decode OPCODE_HI default Unknown::unknown() {
0x2: decode FUNCTION_LO {
format BasicOp {
- 0x0: mfhi({{ Rd = xc->miscRegs.hi; }});
- 0x1: mthi({{ xc->miscRegs.hi = Rs; }});
- 0x2: mflo({{ Rd = xc->miscRegs.lo; }});
- 0x3: mtlo({{ xc->miscRegs.lo = Rs; }});
+ 0x0: mfhi({{ Rd = xc->readMiscReg(Hi); }});
+ 0x1: mthi({{ xc->setMiscReg(Hi,Rs); }});
+ 0x2: mflo({{ Rd = xc->readMiscReg(Lo); }});
+ 0x3: mtlo({{ xc->setMiscReg(Lo,Rs); }});
}
}
@@ -97,39 +107,38 @@ decode OPCODE_HI default Unknown::unknown() {
format IntOp {
0x0: mult({{
int64_t temp1 = Rs.sw * Rt.sw;
- xc->miscRegs.hi->temp1<63:32>;
- xc->miscRegs.lo->temp1<31:0>;
+ xc->setMiscReg(Hi,temp1<63:32>);
+ xc->setMiscReg(Lo,temp1<31:0>);
}});
0x1: multu({{
int64_t temp1 = Rs.uw * Rt.uw;
- xc->miscRegs.hi->temp1<63:32>;
- xc->miscRegs.lo->temp1<31:0>
- Rd.sw = Rs.uw * Rt.uw;
+ xc->setMiscReg(Hi,temp1<63:32>);
+ xc->setMiscReg(Lo,temp1<31:0>);
}});
0x2: div({{
- xc->miscRegs.hi = Rs.sw % Rt.sw;
- xc->miscRegs.lo = Rs.sw / Rt.sw;
+ xc->setMiscReg(Hi,Rs.sw % Rt.sw);
+ xc->setMiscReg(Lo,Rs.sw / Rt.sw);
}});
0x3: divu({{
- xc->miscRegs.hi = Rs.uw % Rt.uw;
- xc->miscRegs.lo = Rs.uw / Rt.uw;
+ xc->setMiscReg(Hi,Rs.uw % Rt.uw);
+ xc->setMiscReg(Lo,Rs.uw / Rt.uw);
}});
}
}
0x4: decode FUNCTION_LO {
format IntOp {
- 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;}});
- 0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}});
- 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}});
- 0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}});
- 0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}});
- 0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}});
- 0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}});
- 0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}});
+ 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;/*Trap on Overflow*/}});
+ 0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}});
+ 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}});
+ 0x3: subu({{ Rd.sw = Rs.sw - Rt.uw;}});
+ 0x4: and({{ Rd = Rs & Rt;}});
+ 0x5: or({{ Rd = Rs | Rt;}});
+ 0x6: xor({{ Rd = Rs ^ Rt;}});
+ 0x7: nor({{ Rd = ~(Rs | Rt);}});
}
}
@@ -141,8 +150,8 @@ decode OPCODE_HI default Unknown::unknown() {
}
0x6: decode FUNCTION_LO {
- format BasicOp {
- 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }});
+ format Trap {
+ 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }});
0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }});
@@ -167,7 +176,7 @@ decode OPCODE_HI default Unknown::unknown() {
}
0x1: decode REGIMM_LO {
- format BasicOp {
+ format Trap {
0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }});
0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }});
0x2: tlti( {{ cond = (Rs.sw < INTIMM); }});
@@ -198,14 +207,14 @@ decode OPCODE_HI default Unknown::unknown() {
}
format Jump {
- 0x2: j({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}});
+ 0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}});
- 0x3: jal({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}},IsCall,IsReturn);
+ 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},IsCall,IsReturn);
}
format Branch {
- 0x4: beq({{ cond = (Rs.sw == 0); }});
- 0x5: bne({{ cond = (Rs.sw != 0); }});
+ 0x4: beq({{ cond = (Rs.sw == Rt.sw); }});
+ 0x5: bne({{ cond = (Rs.sw != Rt.sw); }});
0x6: blez({{ cond = (Rs.sw <= 0); }});
0x7: bgtz({{ cond = (Rs.sw > 0); }});
}
@@ -213,10 +222,10 @@ decode OPCODE_HI default Unknown::unknown() {
0x1: decode OPCODE_LO {
format IntOp {
- 0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }});
- 0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}});
- 0x2: slti({{ Rt.sw = ( Rs.sw < INTIMM ) ? 1 : 0 }});
- 0x3: sltiu({{ Rt.uw = ( Rs.uw < INTIMM ) ? 1 : 0 }});
+ 0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}});
+ 0x1: addiu({{ Rt.sw = Rs.sw + imm;}});
+ 0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }});
+ 0x3: sltiu({{ Rt.sw = ( Rs.sw < imm ) ? 1 : 0 }});
0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}});
0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}});
0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}});
@@ -229,33 +238,17 @@ decode OPCODE_HI default Unknown::unknown() {
//Table A-11 MIPS32 COP0 Encoding of rs Field
0x0: decode RS_MSB {
0x0: decode RS {
- format BasicOp {
+ format System {
0x0: mfc0({{
- //The contents of the coprocessor 0 register specified by the
- //combination of rd and sel are loaded into general register
- //rt. Note that not all coprocessor 0 registers support the
- //sel field. In those instances, the sel field must be zero.
+ //uint64_t reg_num = Rd.uw;
- if (SEL > 0)
- panic("Can't Handle Cop0 with register select yet\n");
-
- uint64_t reg_num = Rd.uw;
-
- Rt = xc->miscRegs.cop0[reg_num];
+ Rt = xc->readMiscReg(RD << 5 | SEL);
}});
0x4: mtc0({{
- //The contents of the coprocessor 0 register specified by the
- //combination of rd and sel are loaded into general register
- //rt. Note that not all coprocessor 0 registers support the
- //sel field. In those instances, the sel field must be zero.
+ //uint64_t reg_num = Rd.uw;
- if (SEL > 0)
- panic("Can't Handle Cop0 with register select yet\n");
-
- uint64_t reg_num = Rd.uw;
-
- xc->miscRegs.cop0[reg_num] = Rt;
+ xc->setMiscReg(RD << 5 | SEL,Rt);
}});
0x8: mftr({{
@@ -279,64 +272,84 @@ decode OPCODE_HI default Unknown::unknown() {
0xA: rdpgpr({{
//Accessing Previous Shadow Set Register Number
- uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
- uint64_t reg_num = Rt.uw;
+ //uint64_t prev = xc->readMiscReg(SRSCtl)/*[PSS]*/;
+ //uint64_t reg_num = Rt.uw;
- Rd = xc->shadowIntRegFile[prev][reg_num];
+ //Rd = xc->regs.IntRegFile[prev];
+ //Rd = xc->shadowIntRegFile[prev][reg_num];
}});
0xB: decode RD {
0x0: decode SC {
0x0: dvpe({{
- Rt.sw = xc->miscRegs.cop0.MVPControl;
- xc->miscRegs.cop0.MVPControl[EVP] = 0;
+ int idx;
+ int sel;
+ getMiscRegIdx(MVPControl,idx,sel);
+ Rt.sw = xc->readMiscReg(idx,sel);
+ xc->setMiscReg(idx,sel);
}});
0x1: evpe({{
- Rt.sw = xc->miscRegs.cop0.MVPControl;
- xc->miscRegs.cop0.MVPControl[EVP] = 1;
+ int idx;
+ int sel;
+ getMiscRegIdx(MVPControl,idx,sel);
+ Rt.sw = xc->readMiscReg(idx,sel);
+ xc->setMiscReg(idx,sel,1);
}});
}
0x1: decode SC {
0x0: dmt({{
- Rt.sw = xc->miscRegs.cop0.VPEControl;
- xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0;
+ int idx;
+ int sel;
+ getMiscRegIdx(VPEControl,idx,sel);
+ Rt.sw = xc->readMiscReg(idx,sel);
+ xc->setMiscReg(idx,sel);
}});
0x1: emt({{
- Rt.sw = xc->miscRegs.cop0.VPEControl;
- xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1;
+ int idx;
+ int sel;
+ getMiscRegIdx(VPEControl,idx,sel);
+ Rt.sw = xc->readMiscReg(idx,sel);
+ xc->setMiscReg(idx,sel,1);
}});
}
0xC: decode SC {
0x0: di({{
- Rt.sw = xc->miscRegs.cop0.Status;
- xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0;
+ int idx;
+ int sel;
+ getMiscRegIdx(Status,idx,sel);
+ Rt.sw = xc->readMiscReg(idx,sel);
+ xc->setMiscReg(idx,sel);
}});
0x1: ei({{
- Rt.sw = xc->miscRegs.cop0.Status;
- xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1;
+ int idx;
+ int sel;
+ getMiscRegIdx(Status,idx,sel);
+ Rt.sw = xc->readMiscReg(idx,sel);
+ xc->setMiscReg(idx,sel,1);
}});
}
}
0xE: wrpgpr({{
//Accessing Previous Shadow Set Register Number
- uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
- uint64_t reg_num = Rd.uw;
+ //uint64_t prev = xc->readMiscReg(SRSCtl/*[PSS]*/);
+ //uint64_t reg_num = Rd.uw;
- xc->shadowIntRegFile[prev][reg_num] = Rt;
+ //xc->regs.IntRegFile[prev];
+ //xc->shadowIntRegFile[prev][reg_num] = Rt;
}});
}
}
//Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
0x1: decode FUNCTION {
- format BasicOp {
+ format System {
0x01: tlbr({{ }});
0x02: tlbwi({{ }});
0x06: tlbwr({{ }});
@@ -357,27 +370,27 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode RS_HI {
0x0: decode RS_LO {
format FloatOp {
- 0x0: mfc1({{ Rt = Fs<31:0>; }});
- 0x2: cfc1({{ Rt = xc->miscRegs.fpcr[Fs];}});
- 0x3: mfhc1({{ Rt = Fs<63:32>;}});
- 0x4: mtc1({{ Fs<31:0> = Rt}});
- 0x6: ctc1({{ xc->miscRegs.fpcr[Fs] = Rt;}});
- 0x7: mftc1({{ Fs<63:32> = Rt}});
+ 0x0: mfc1({{ /*Rt.uw = Fs.ud<31:0>;*/ }});
+ 0x2: cfc1({{ /*Rt.uw = xc->readMiscReg(FPCR[Fs]);*/}});
+ 0x3: mfhc1({{ /*Rt.uw = Fs.ud<63:32>*/;}});
+ 0x4: mtc1({{ /*Fs = Rt.uw*/}});
+ 0x6: ctc1({{ /*xc->setMiscReg(FPCR[Fs],Rt);*/}});
+ 0x7: mthc1({{ /*Fs<63:32> = Rt.uw*/}});
}
}
0x1: decode ND {
0x0: decode TF {
format Branch {
- 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }});
- 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }});
+ 0x0: bc1f({{ cond = (xc->readMiscReg(FPCR) == 0); }});
+ 0x1: bc1t({{ cond = (xc->readMiscReg(FPCR) == 1); }});
}
}
0x1: decode TF {
format BranchLikely {
- 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }});
- 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }});
+ 0x0: bc1fl({{ cond = (xc->readMiscReg(FPCR) == 0); }});
+ 0x1: bc1tl({{ cond = (xc->readMiscReg(FPCR) == 1); }});
}
}
}
@@ -396,7 +409,7 @@ decode OPCODE_HI default Unknown::unknown() {
0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}});
0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}});
0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}});
- 0x5: abss({{ Fd.sf = abs(Fs.sf);}});
+ 0x5: abss({{ Fd.sf = fabs(Fs.sf);}});
0x6: movs({{ Fd.sf = Fs.sf;}});
0x7: negs({{ Fd.sf = -1 * Fs.sf;}});
}
@@ -422,8 +435,8 @@ decode OPCODE_HI default Unknown::unknown() {
0x2: decode RS_LO {
0x1: decode MOVCF {
format FloatOp {
- 0x0: movfs({{ if ( FPConditionCode(CC) == 0 ) Fd = Fs; }});
- 0x1: movts({{ if ( FPConditionCode(CC) == 1 ) Fd = Fs;}});
+ 0x0: movfs({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }});
+ 0x1: movts({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}});
}
}
@@ -434,29 +447,29 @@ decode OPCODE_HI default Unknown::unknown() {
format Float64Op {
0x5: recips({{ Fd = 1 / Fs; }});
- 0x6: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}});
+ 0x6: rsqrts({{ Fd = 1 / sqrt((double)Fs.ud);}});
}
}
0x4: decode RS_LO {
format FloatOp {
- 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr;
+ 0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE);
}});
- 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr;
+ 0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE);
}});
}
//only legal for 64 bit
format Float64Op {
- 0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr;
+ 0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE);
}});
- 0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }});
+ 0x6: cvt_ps_s({{ /*Fd.df = Fs.df<31:0> | Ft.df<31:0>;*/ }});
}
}
}
@@ -470,7 +483,7 @@ decode OPCODE_HI default Unknown::unknown() {
0x2: muld({{ Fd.df = Fs.df * Ft.df;}});
0x3: divd({{ Fd.df = Fs.df / Ft.df;}});
0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}});
- 0x5: absd({{ Fd.df = abs(Fs.df);}});
+ 0x5: absd({{ Fd.df = fabs(Fs.df);}});
0x6: movd({{ Fd.df = Fs.df;}});
0x7: negd({{ Fd.df = -1 * Fs.df;}});
}
@@ -496,8 +509,8 @@ decode OPCODE_HI default Unknown::unknown() {
0x2: decode RS_LO {
0x1: decode MOVCF {
format FloatOp {
- 0x0: movfd({{ if (FPConditionCode(CC) == 0) Fd.df = Fs.df; }});
- 0x1: movtd({{ if (FPConditionCode(CC) == 1) Fd.df = Fs.df; }});
+ 0x0: movfd({{if (xc->readMiscReg(FPCR) != CC) Fd.df = Fs.df; }});
+ 0x1: movtd({{if (xc->readMiscReg(FPCR) == CC) Fd.df = Fs.df; }});
}
}
@@ -515,12 +528,12 @@ decode OPCODE_HI default Unknown::unknown() {
0x4: decode RS_LO {
format FloatOp {
0x0: cvt_s_d({{
- int rnd_mode = xc->miscRegs.fcsr;
+ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
}});
0x4: cvt_w_d({{
- int rnd_mode = xc->miscRegs.fcsr;
+ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
}});
}
@@ -528,7 +541,7 @@ decode OPCODE_HI default Unknown::unknown() {
//only legal for 64 bit
format Float64Op {
0x5: cvt_l_d({{
- int rnd_mode = xc->miscRegs.fcsr;
+ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
}});
}
@@ -539,12 +552,12 @@ decode OPCODE_HI default Unknown::unknown() {
0x4: decode FUNCTION {
format FloatOp {
0x20: cvt_s({{
- int rnd_mode = xc->miscRegs.fcsr;
+ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD);
}});
0x21: cvt_d({{
- int rnd_mode = xc->miscRegs.fcsr;
+ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD);
}});
}
@@ -556,12 +569,12 @@ decode OPCODE_HI default Unknown::unknown() {
0x5: decode FUNCTION_HI {
format FloatOp {
0x10: cvt_s_l({{
- int rnd_mode = xc->miscRegs.fcsr;
+ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG);
}});
0x11: cvt_d_l({{
- int rnd_mode = xc->miscRegs.fcsr;
+ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG);
}});
}
@@ -590,12 +603,12 @@ decode OPCODE_HI default Unknown::unknown() {
0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
//Lower Halves Independently but we take simulator shortcut
- Fd.df = abs(Fs.df);
+ Fd.df = fabs(Fs.df);
}});
0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
//Lower Halves Independently but we take simulator shortcut
- Fd.df = Fs<31:0> | Ft<31:0>;
+ //Fd.df = Fs<31:0> | Ft<31:0>;
}});
0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
@@ -608,21 +621,21 @@ decode OPCODE_HI default Unknown::unknown() {
0x2: decode RS_LO {
0x1: decode MOVCF {
format Float64Op {
- 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}});
- 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}});
+ 0x0: movfps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs;}});
+ 0x1: movtps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}});
}
}
format BasicOp {
- 0x2: movzps({{ if ( FPConditionCode(CC) == 0) Fd = Fs; }});
- 0x3: movnps({{ if ( FPConditionCode(CC) == 0) Fd = Fs; }});
+ 0x2: movzps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }});
+ 0x3: movnps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs; }});
}
}
0x4: decode RS_LO {
0x0: Float64Op::cvt_s_pu({{
- int rnd_mode = xc->miscRegs.fcsr;
+ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI);
}});
}
@@ -630,13 +643,13 @@ decode OPCODE_HI default Unknown::unknown() {
0x5: decode RS_LO {
format Float64Op {
0x0: cvt_s_pl({{
- int rnd_mode = xc->miscRegs.fcsr;
+ int rnd_mode = xc->readMiscReg(FCSR);
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO);
}});
- 0x4: pll({{ Fd.df = Fs<31:0> | Ft<31:0>}});
- 0x5: plu({{ Fd.df = Fs<31:0> | Ft<63:32>}});
- 0x6: pul({{ Fd.df = Fs<63:32> | Ft<31:0>}});
- 0x7: puu({{ Fd.df = Fs<63:32 | Ft<63:32>}});
+ 0x4: pll({{ /*Fd.df = Fs<31:0> | Ft<31:0>*/}});
+ 0x5: plu({{ /*Fd.df = Fs<31:0> | Ft<63:32>*/}});
+ 0x6: pul({{ /*Fd.df = Fs<63:32> | Ft<31:0>*/}});
+ 0x7: puu({{ /*Fd.df = Fs<63:32 | Ft<63:32>*/}});
}
}
}
@@ -682,23 +695,23 @@ decode OPCODE_HI default Unknown::unknown() {
0x3: decode FUNCTION_HI {
0x0: decode FUNCTION_LO {
format LoadMemory2 {
- 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.sf; }});
- 0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }});
+ 0x0: lwxc1({{ EA = Rs + Rt; }},{{ /*F_t<31:0> = Mem.sf; */}});
+ 0x1: ldxc1({{ EA = Rs + Rt; }},{{ /*F_t<63:0> = Mem.df;*/ }});
0x5: luxc1({{ //Need to make EA<2:0> = 0
EA = Rs + Rt;
}},
- {{ Ft<31:0> = Mem.df; }});
+ {{ /*F_t<31:0> = Mem.df; */}});
}
}
0x1: decode FUNCTION_LO {
format StoreMemory2 {
- 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.sf = Ft<31:0>; }});
- 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.df = Ft<63:0>}});
+ 0x0: swxc1({{ EA = Rs + Rt; }},{{ /*Mem.sf = Ft<31:0>; */}});
+ 0x1: sdxc1({{ EA = Rs + Rt; }},{{ /*Mem.df = Ft<63:0> */}});
0x5: suxc1({{ //Need to make EA<2:0> = 0
EA = Rs + Rt;
}},
- {{ Mem.df = Ft<63:0>;}});
+ {{ /*Mem.df = F_t<63:0>;*/}});
}
0x7: WarnUnimpl::prefx();
@@ -768,33 +781,33 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode FUNCTION_LO {
format IntOp {
0x0: madd({{
- int64_t temp1 = Hi.sw << 32 | Lo.sw >> 32;
+ int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
temp1 = temp1 + (Rs.sw * Rt.sw);
- xc->miscRegs.hi->temp1<63:32>;
- xc->miscRegs.lo->temp1<31:0>
+ xc->setMiscReg(Hi,temp1<63:32>);
+ xc->setMiscReg(Lo,temp1<31:0>);
}});
0x1: maddu({{
- int64_t temp1 = Hi.uw << 32 | Lo.uw >> 32;
+ int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
temp1 = temp1 + (Rs.uw * Rt.uw);
- xc->miscRegs.hi->temp1<63:32>;
- xc->miscRegs.lo->temp1<31:0>
+ xc->setMiscReg(Hi,temp1<63:32>);
+ xc->setMiscReg(Lo,temp1<31:0>);
}});
- 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }});
+ 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }});
0x4: msub({{
- int64_t temp1 = Hi.sw << 32 | Lo.sw >> 32;
+ int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
temp1 = temp1 - (Rs.sw * Rt.sw);
- xc->miscRegs.hi->temp1<63:32>;
- xc->miscRegs.lo->temp1<31:0>
+ xc->setMiscReg(Hi,temp1<63:32>);
+ xc->setMiscReg(Lo,temp1<31:0>);
}});
0x5: msubu({{
- int64_t temp1 = Hi.uw << 32 | Lo.uw >> 32;
+ int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
temp1 = temp1 - (Rs.uw * Rt.uw);
- xc->miscRegs.hi->temp1<63:32>;
- xc->miscRegs.lo->temp1<31:0>
+ xc->setMiscReg(Hi,temp1<63:32>);
+ xc->setMiscReg(Lo,temp1<31:0>);
}});
}
}
@@ -802,25 +815,25 @@ decode OPCODE_HI default Unknown::unknown() {
0x4: decode FUNCTION_LO {
format BasicOp {
0x0: clz({{
- int cnt = 0;
+ /*int cnt = 0;
int idx = 0;
- while ( Rs.uw<idx>!= 1) {
+ while ( Rs.uw<idx> != 1) {
cnt++;
idx--;
}
- Rd.uw = cnt;
+ Rd.uw = cnt;*/
}});
0x1: clo({{
- int cnt = 0;
+ /*int cnt = 0;
int idx = 0;
- while ( Rs.uw<idx>!= 0) {
+ while ( Rs.uw<idx> != 0) {
cnt++;
idx--;
}
- Rd.uw = cnt;
+ Rd.uw = cnt;*/
}});
}
}
@@ -860,20 +873,20 @@ decode OPCODE_HI default Unknown::unknown() {
}
0x6: decode FUNCTION_LO {
- 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}});
+ 0x7: BasicOp::rdhwr({{ /*Rt = xc->hwRegs[RD];*/ }});
}
}
}
0x4: decode OPCODE_LO default FailUnimpl::reserved() {
format LoadMemory {
- 0x0: lb({{ Rb.sw = Mem.sb; }});
- 0x1: lh({{ Rb.sw = Mem.sh; }});
- 0x2: lwl({{ Rb.sw = Mem.sw; }});//, WordAlign);
- 0x3: lw({{ Rb.uq = Mem.sb; }});
- 0x4: lbu({{ Rb.uw = Mem.ub; }});
- 0x5: lhu({{ Rb.uw = Mem.uh; }});
- 0x6: lwr({{ Rb.uw = Mem.uw; }});//, WordAlign);
+ 0x0: lb({{ Rt.sw = Mem.sb; }});
+ 0x1: lh({{ Rt.sw = Mem.sh; }});
+ 0x2: lwl({{ Rt.sw = Mem.sw; }});//, WordAlign);
+ 0x3: lw({{ Rt.sw = Mem.sb; }});
+ 0x4: lbu({{ Rt.uw = Mem.ub; }});
+ 0x5: lhu({{ Rt.uw = Mem.uh; }});
+ 0x6: lwr({{ Rt.uw = Mem.uw; }});//, WordAlign);
}
0x7: FailUnimpl::reserved();
@@ -898,19 +911,19 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: WarnUnimpl::ll();
format LoadMemory {
- 0x1: lwc1({{ Ft<31:0> = Mem.sf; }});
- 0x5: ldc1({{ Ft<63:0> = Mem.df; }});
+ 0x1: lwc1({{ /*F_t<31:0> = Mem.sf; */}});
+ 0x5: ldc1({{ /*F_t<63:0> = Mem.df; */}});
}
}
+
0x7: decode OPCODE_LO default FailUnimpl::reserved() {
0x0: WarnUnimpl::sc();
format StoreMemory {
- 0x1: swc1({{ Mem.sf = Ft<31:0>; }});
- 0x5: sdc1({{ Mem.df = Ft<63:0>; }});
+ 0x1: swc1({{ //Mem.sf = Ft<31:0>; }});
+ 0x5: sdc1({{ //Mem.df = Ft<63:0>; }});
}
-
}
}
diff --git a/arch/mips/isa/formats.isa b/arch/mips/isa/formats.isa
index a6aec9437..f7a9e4ce2 100644
--- a/arch/mips/isa/formats.isa
+++ b/arch/mips/isa/formats.isa
@@ -10,6 +10,9 @@
//Include utility formats/functions
##include "m5/arch/mips/isa/formats/util.isa"
+//Include the cop0 formats
+##include "m5/arch/mips/isa/formats/cop0.isa"
+
//Include the integer formats
##include "m5/arch/mips/isa/formats/int.isa"
diff --git a/arch/mips/isa/formats/basic.isa b/arch/mips/isa/formats/basic.isa
index 3b62aa5c3..c02af7ddc 100644
--- a/arch/mips/isa/formats/basic.isa
+++ b/arch/mips/isa/formats/basic.isa
@@ -31,14 +31,14 @@ def template BasicConstructor {{
def template BasicExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
- Fault fault = No_Fault;
+ Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
- if(fault == No_Fault)
+ if(fault == NoFault)
{
%(op_wb)s;
}
diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa
index c896e9b2d..0d2ad7855 100644
--- a/arch/mips/isa/formats/branch.isa
+++ b/arch/mips/isa/formats/branch.isa
@@ -7,6 +7,9 @@
output header {{
+#include <iostream>
+ using namespace std;
+
/**
* Base class for instructions whose disassembly is not purely a
* function of the machine instruction (i.e., it depends on the
@@ -52,6 +55,10 @@ output header {{
: PCDependentDisassembly(mnem, _machInst, __opClass),
disp(OFFSET << 2)
{
+ //If Bit 17 is 1 then Sign Extend
+ if ( (disp & 0x00020000) > 0 ) {
+ disp |= 0xFFFE0000;
+ }
}
Addr branchTarget(Addr branchPC) const;
@@ -74,6 +81,7 @@ output header {{
: PCDependentDisassembly(mnem, _machInst, __opClass),
disp(OFFSET << 2)
{
+
}
Addr branchTarget(Addr branchPC) const;
@@ -93,11 +101,13 @@ output header {{
/// Displacement to target address (signed).
int32_t disp;
+ uint32_t target;
+
public:
/// Constructor
Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
- disp(OFFSET)
+ disp(JMPTARG << 2)
{
}
@@ -159,23 +169,17 @@ output decoder {{
// either a source (the condition for conditional
// branches) or a destination (the link reg for
// unconditional branches)
- if (_numSrcRegs > 0) {
+ if (_numSrcRegs == 1) {
printReg(ss, _srcRegIdx[0]);
ss << ",";
- }
- else if (_numDestRegs > 0) {
- printReg(ss, _destRegIdx[0]);
+ } else if(_numSrcRegs == 2) {
+ printReg(ss, _srcRegIdx[0]);
ss << ",";
- }
-
-#ifdef SS_COMPATIBLE_DISASSEMBLY
- if (_numSrcRegs == 0 && _numDestRegs == 0) {
- printReg(ss, 31);
+ printReg(ss, _srcRegIdx[1]);
ss << ",";
}
-#endif
- Addr target = pc + 4 + disp;
+ Addr target = pc + 8 + disp;
std::string str;
if (symtab && symtab->findSymbol(target, str))
@@ -206,13 +210,6 @@ output decoder {{
ss << ",";
}
-#ifdef SS_COMPATIBLE_DISASSEMBLY
- if (_numSrcRegs == 0 && _numDestRegs == 0) {
- printReg(ss, 31);
- ss << ",";
- }
-#endif
-
Addr target = pc + 4 + disp;
std::string str;
@@ -231,20 +228,25 @@ output decoder {{
ccprintf(ss, "%-10s ", mnemonic);
-#ifdef SS_COMPATIBLE_DISASSEMBLY
- if (_numDestRegs == 0) {
- printReg(ss, 31);
- ss << ",";
- }
-#endif
-
- if (_numDestRegs > 0) {
- printReg(ss, _destRegIdx[0]);
+ if ( mnemonic == "jal" ) {
+ Addr npc = pc + 4;
+ ccprintf(ss,"0x%x",(npc & 0xF0000000) | disp);
+ } else if (_numSrcRegs == 0) {
+ std::string str;
+ if (symtab && symtab->findSymbol(disp, str))
+ ss << str;
+ else
+ ccprintf(ss, "0x%x", disp);
+ } else if (_numSrcRegs == 1) {
+ printReg(ss, _srcRegIdx[0]);
+ } else if(_numSrcRegs == 2) {
+ printReg(ss, _srcRegIdx[0]);
ss << ",";
+ printReg(ss, _srcRegIdx[1]);
+ } else {
+ panic(">= 3 Source Registers!!!");
}
- ccprintf(ss, "(r%d)", RT);
-
return ss.str();
}
}};
@@ -253,16 +255,18 @@ def format Branch(code,*flags) {{
#Add Link Code if Link instruction
strlen = len(name)
if name[strlen-2:] == 'al':
- code += 'R31 = NNPC;\n'
+ code += 'r31 = NNPC;\n'
#Condition code
code = 'bool cond;\n' + code
code += 'if (cond) {\n'
- #code += '//NPC=NPC: just placeholder to force parser to writeback NPC\n'
- #code += ' NPC = NPC; \n'
code += ' NNPC = NPC + disp;\n'
+ code += '} else {\n'
+ code += ' NNPC = NNPC;\n'
code += '} \n'
+ code += 'cout << hex << "NPC: " << NPC << " + " << disp << " = " << NNPC << endl;'
+
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
('IsDirectControl', 'IsCondControl'))
@@ -277,13 +281,11 @@ def format BranchLikely(code,*flags) {{
#Add Link Code if Link instruction
strlen = len(name)
if name[strlen-3:] == 'all':
- code += 'R31 = NNPC;\n'
+ code += 'r31 = NNPC;\n'
#Condition code
code = 'bool cond;\n' + code
code += 'if (cond) {'
- #code += '//NPC=NPC: just placeholder to force parser to writeback NPC\n'
- #code += 'NPC = NPC; \n'
code += 'NNPC = NPC + disp;\n'
code += '} \n'
@@ -300,8 +302,11 @@ def format BranchLikely(code,*flags) {{
def format Jump(code,*flags) {{
#Add Link Code if Link instruction
strlen = len(name)
- if strlen >= 3 and name[2:3] == 'al':
- code = 'R31 = NNPC;\n' + code
+ if strlen > 1 and name[1:] == 'al':
+ code = 'r31 = NNPC;\n' + code
+
+ #code += 'if(NNPC == 0x80000638) { NNPC = r31; cout << "SKIPPING JUMP TO SIM_GET_MEM_CONF" << endl;}'
+ #code += 'target = NNPC;'
iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\
('IsIndirectControl', 'IsUncondControl'))
diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa
index 7dd1e8442..34b71acf7 100644
--- a/arch/mips/isa/formats/fp.isa
+++ b/arch/mips/isa/formats/fp.isa
@@ -29,47 +29,6 @@ output decoder {{
}
}};
-def template FloatingPointExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
- {
- //These are set to constants when the execute method
- //is generated
- bool useCc = ;
- bool checkPriv = ;
-
- //Attempt to execute the instruction
- try
- {
- checkPriv;
-
- %(op_decl)s;
- %(op_rd)s;
- %(code)s;
- }
- //If we have an exception for some reason,
- //deal with it
- catch(MipsException except)
- {
- //Deal with exception
- return No_Fault;
- }
-
- //Write the resulting state to the execution context
- %(op_wb)s;
- if(useCc)
- {
- xc->regs.miscRegFile.ccrFields.iccFields.n = Rd & (1 << 63);
- xc->regs.miscRegFile.ccrFields.iccFields.z = (Rd == 0);
- xc->regs.miscRegFile.ccrFields.iccFields.v = ivValue;
- xc->regs.miscRegFile.ccrFields.iccFields.c = icValue;
- xc->regs.miscRegFile.ccrFields.xccFields.n = Rd & (1 << 31);
- xc->regs.miscRegFile.ccrFields.xccFields.z = ((Rd & 0xFFFFFFFF) == 0);
- xc->regs.miscRegFile.ccrFields.xccFields.v = xvValue;
- xc->regs.miscRegFile.ccrFields.xccFields.c = xcValue;
- }
- return No_Fault;
- }
-}};
// Primary format for integer operate instructions:
def format FloatOp(code, *flags) {{
diff --git a/arch/mips/isa/formats/int.isa b/arch/mips/isa/formats/int.isa
index cf06741a1..a47844bee 100644
--- a/arch/mips/isa/formats/int.isa
+++ b/arch/mips/isa/formats/int.isa
@@ -7,6 +7,8 @@
//Outputs to decoder.hh
output header {{
+#include <iostream>
+ using namespace std;
/**
* Base class for integer operations.
*/
@@ -26,15 +28,24 @@ output header {{
class IntImmOp : public MipsStaticInst
{
protected:
- uint16_t imm;
+
+ int32_t imm;
/// Constructor
IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM)
{
+ //If Bit 15 is 1 then Sign Extend
+ int32_t temp = imm & 0x00008000;
+
+ if (temp > 0 && mnemonic != "lui") {
+ imm |= 0xFFFF0000;
+ }
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+
};
}};
@@ -43,15 +54,59 @@ output header {{
output decoder {{
std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
- return "Disassembly of integer instruction\n";
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // just print the first dest... if there's a second one,
+ // it's generally implicit
+ if (_numDestRegs > 0) {
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ ss << ",";
+
+ // just print the first two source regs... if there's
+ // a third one, it's a read-modify-write dest (Rc),
+ // e.g. for CMOVxx
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ if (_numSrcRegs > 1) {
+ ss << ",";
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ return ss.str();
}
std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
- return "Disassembly of integer immediate instruction\n";
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ if (_numDestRegs > 0) {
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ ss << ",";
+
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ ss << ",";
+ }
+
+ if( mnemonic == "lui")
+ ccprintf(ss, "%08p ", imm);
+ else
+ ss << (int) imm;
+
+ return ss.str();
}
-}};
+}};
//Used by decoder.isa
def format IntOp(code, *opt_flags) {{
diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa
index fcdb577c6..8a07e63d4 100644
--- a/arch/mips/isa/formats/mem.isa
+++ b/arch/mips/isa/formats/mem.isa
@@ -40,6 +40,7 @@ output header {{
const StaticInstPtr eaCompPtr;
/// Pointer to MemAcc object.
const StaticInstPtr memAccPtr;
+
/// Displacement for EA calculation (signed).
int32_t disp;
@@ -51,6 +52,12 @@ output header {{
memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
disp(OFFSET)
{
+ //If Bit 15 is 1 then Sign Extend
+ int32_t temp = disp & 0x00008000;
+
+ if (temp > 0) {
+ disp |= 0xFFFF0000;
+ }
}
std::string
@@ -70,7 +77,7 @@ output decoder {{
Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
- flags[IsFloating] ? 'f' : 'r', RS, JMPTARG, RT);
+ flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
}
}};
diff --git a/arch/mips/isa/formats/noop.isa b/arch/mips/isa/formats/noop.isa
index 05c5ac10f..d35179005 100644
--- a/arch/mips/isa/formats/noop.isa
+++ b/arch/mips/isa/formats/noop.isa
@@ -59,7 +59,7 @@ output exec {{
Fault
Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
- return No_Fault;
+ return NoFault;
}
}};
@@ -68,9 +68,11 @@ output exec {{
def template OperateNopCheckDecode {{
{
MipsStaticInst *i = new %(class_name)s(machInst);
- if (RD == 0) {
- i = makeNop(i);
- }
+
+ //if (RD == 0) {
+ // i = makeNop(i);
+ //}
+
return i;
}
}};
diff --git a/arch/mips/isa/formats/trap.isa b/arch/mips/isa/formats/trap.isa
index 78f8d87b0..6884d4fa8 100644
--- a/arch/mips/isa/formats/trap.isa
+++ b/arch/mips/isa/formats/trap.isa
@@ -42,12 +42,11 @@ def template TrapExecute {{
}};
// Primary format for integer operate instructions:
-def format Trap(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
+def format Trap(code, *flags) {{
+ code = 'bool cond;\n' + code;
+ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = TrapExecute.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
}};
diff --git a/arch/mips/isa/formats/unimp.isa b/arch/mips/isa/formats/unimp.isa
index a7a71c681..adbd5b5b1 100644
--- a/arch/mips/isa/formats/unimp.isa
+++ b/arch/mips/isa/formats/unimp.isa
@@ -111,7 +111,7 @@ output exec {{
{
panic("attempt to execute unimplemented instruction '%s' "
"(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE);
- return Unimplemented_Opcode_Fault;
+ return UnimplementedOpcodeFault;
}
Fault
@@ -123,7 +123,7 @@ output exec {{
warned = true;
}
- return No_Fault;
+ return NoFault;
}
}};
diff --git a/arch/mips/isa/formats/unknown.isa b/arch/mips/isa/formats/unknown.isa
index 6eba5b4f9..4601b3684 100644
--- a/arch/mips/isa/formats/unknown.isa
+++ b/arch/mips/isa/formats/unknown.isa
@@ -42,7 +42,7 @@ output exec {{
{
panic("attempt to execute unknown instruction "
"(inst 0x%08x, opcode 0x%x)", machInst, OPCODE);
- return Unimplemented_Opcode_Fault;
+ return UnimplementedOpcodeFault;
}
}};
diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa
index c06877b35..db4bf204a 100644
--- a/arch/mips/isa/formats/util.isa
+++ b/arch/mips/isa/formats/util.isa
@@ -1,29 +1,6 @@
// -*- mode:c++ -*-
let {{
-def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
- # Declare basic control transfer w/o link (i.e. link reg is R31)
- nolink_code = 'NPC = %s;\n' % npc_expr
- nolink_iop = InstObjParams(name, Name, base_class,
- CodeBlock(nolink_code), flags)
- header_output = BasicDeclare.subst(nolink_iop)
- decoder_output = BasicConstructor.subst(nolink_iop)
- exec_output = BasicExecute.subst(nolink_iop)
-
- # Generate declaration of '*AndLink' version, append to decls
- link_code = 'Ra = NPC & ~3;\n' + nolink_code
- link_iop = InstObjParams(name, Name + 'AndLink', base_class,
- CodeBlock(link_code), flags)
- header_output += BasicDeclare.subst(link_iop)
- decoder_output += BasicConstructor.subst(link_iop)
- exec_output += BasicExecute.subst(link_iop)
-
- # need to use link_iop for the decode template since it is expecting
- # the shorter version of class_name (w/o "AndLink")
-
- return (header_output, decoder_output,
- JumpOrBranchDecode.subst(nolink_iop), exec_output)
-
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
postacc_code = '', base_class = 'Memory',
decode_template = BasicDecode, exec_template_base = ''):
@@ -116,10 +93,56 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
output exec {{
+using namespace MipsISA;
+
+
/// CLEAR ALL CPU INST/EXE HAZARDS
inline void
clear_exe_inst_hazards()
{
//CODE HERE
}
+
+
+ /// Check "FP enabled" machine status bit. Called when executing any FP
+ /// instruction in full-system mode.
+ /// @retval Full-system mode: NoFault if FP is enabled, FenFault
+ /// if not. Non-full-system mode: always returns NoFault.
+#if FULL_SYSTEM
+ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
+ {
+ Fault fault = NoFault; // dummy... this ipr access should not fault
+ if (!Mips34k::ICSR_FPE(xc->readIpr(MipsISA::IPR_ICSR, fault))) {
+ fault = FloatEnableFault;
+ }
+ return fault;
+ }
+#else
+ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
+ {
+ return NoFault;
+ }
+#endif
+
+ double convert_and_round(float w, int x, int y, int z)
+ {
+ double temp = .34000;
+
+ return temp;
+ }
+
+ enum FPTypes{
+ FP_SINGLE,
+ FP_DOUBLE,
+ FP_LONG,
+ FP_PS_LO,
+ FP_PS_HI,
+ FP_WORD,
+ RND_NEAREST,
+ RND_ZERO,
+ RND_UP,
+ RND_DOWN
+ };
}};
+
+
diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa
index 65ef2245f..13870337b 100644
--- a/arch/mips/isa/operands.isa
+++ b/arch/mips/isa/operands.isa
@@ -16,21 +16,18 @@ def operands {{
'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1),
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2),
'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3),
- 'R31': ('IntReg', 'uw','R31','IsInteger', 4),
+ 'r31': ('IntReg', 'uw','R31','IsInteger', 4),
+ 'R0': ('IntReg', 'uw','R0', 'IsInteger', 5),
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
- 'Sa': ('IntReg', 'uw', 'SA', 'IsInteger', 4),
'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1),
'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2),
'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
+ 'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3),
'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4),
- 'NNPC': ('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4)
- #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
- #'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1),
- # The next two are hacks for non-full-system call-pal emulation
- #'R0': ('IntReg', 'uq', '0', None, 1),
+ 'NNPC':('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4)
}};
diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc
index 02a857af7..d01fa6bd4 100644
--- a/arch/mips/isa_traits.cc
+++ b/arch/mips/isa_traits.cc
@@ -33,6 +33,259 @@
using namespace MipsISA;
+
+//Function now Obsolete in current state.
+//If anyting this should return the correct miscreg index
+//but that is handled implicitly with enums anyway
+void
+MipsISA::getMiscRegIdx(int reg_name,int &idx, int &sel)
+{
+ switch(reg_name)
+ {
+ case Index: idx = 0; sel = 0; break; //0-0 Index into the TLB array
+ case MVPControl: idx = 0; sel = 1; break; //0-1 Per-processor register containing global
+ case MVPConf0: idx = 0; sel = 2; break; //0-2 Per-processor register containing global
+ case MVPConf1: idx = 0; sel = 3; break; //0-3 Per-processor register containing global
+ case Random: idx = 1; sel = 3; break; //1-0 Randomly generated index into the TLB array
+ case VPEControl: idx = 1; sel = 1; break; //1-1 Per-VPE register containing relatively volatile
+ //thread configuration data
+ case VPEConf0: idx = 1; sel = 2; break; //1-2 Per-VPE multi-thread configuration
+ //information
+ case VPEConf1: idx = 1; sel = 3; break; //1-3 Per-VPE multi-thread configuration
+ //information
+ case YQMask: idx = 1; sel = 4; break; //Per-VPE register defining which YIELD
+ //qualifier bits may be used without generating
+ //an exception
+ case VPESchedule: idx = 1; sel = 5; break;
+ case VPEScheFBack: idx = 1; sel = 6; break;
+ case VPEOpt: idx = 1; sel = 7; break;
+ case EntryLo0: idx = 1; sel = 5; break;
+ case TCStatus: idx = 1; sel = 5; break;
+ case TCBind: idx = 1; sel = 5; break;
+ case TCRestart: idx = 1; sel = 5; break;
+ case TCHalt: idx = 1; sel = 5; break;
+ case TCContext: idx = 1; sel = 5; break;
+ case TCSchedule: idx = 1; sel = 5; break;
+ case TCScheFBack: panic("Accessing Unimplemented CP0 Register"); break;
+ case EntryLo1: panic("Accessing Unimplemented CP0 Register"); break;
+ case Context: panic("Accessing Unimplemented CP0 Register"); break;
+ case ContextConfig: panic("Accessing Unimplemented CP0 Register"); break;
+ //case PageMask: panic("Accessing Unimplemented CP0 Register"); break;
+ case PageGrain: panic("Accessing Unimplemented CP0 Register"); break;
+ case Wired: panic("Accessing Unimplemented CP0 Register"); break;
+ case SRSConf0: panic("Accessing Unimplemented CP0 Register"); break;
+ case SRSConf1: panic("Accessing Unimplemented CP0 Register"); break;
+ case SRSConf2: panic("Accessing Unimplemented CP0 Register"); break;
+ case SRSConf3: panic("Accessing Unimplemented CP0 Register"); break;
+ case SRSConf4: panic("Accessing Unimplemented CP0 Register"); break;
+ case BadVAddr: panic("Accessing Unimplemented CP0 Register"); break;
+ case Count: panic("Accessing Unimplemented CP0 Register"); break;
+ case EntryHi: panic("Accessing Unimplemented CP0 Register"); break;
+ case Compare: panic("Accessing Unimplemented CP0 Register"); break;
+ case Status: idx = 12; sel = 0; break; //12-0 Processor status and control
+ case IntCtl: idx = 12; sel = 1; break; //12-1 Interrupt system status and control
+ case SRSCtl: idx = 12; sel = 2; break; //12-2 Shadow register set status and control
+ case SRSMap: idx = 12; sel = 3; break; //12-3 Shadow set IPL mapping
+ case Cause: idx = 13; sel = 0; break; //13-0 Cause of last general exception
+ case EPC: idx = 14; sel = 0; break; //14-0 Program counter at last exception
+ case PrId: idx = 15; sel = 0; break; //15-0 Processor identification and revision
+ case EBase: idx = 15; sel = 1; break; //15-1 Exception vector base register
+ case Config: panic("Accessing Unimplemented CP0 Register"); break;
+ case Config1: panic("Accessing Unimplemented CP0 Register"); break;
+ case Config2: panic("Accessing Unimplemented CP0 Register"); break;
+ case Config3: panic("Accessing Unimplemented CP0 Register"); break;
+ case LLAddr: panic("Accessing Unimplemented CP0 Register"); break;
+ case WatchLo: panic("Accessing Unimplemented CP0 Register"); break;
+ case WatchHi: panic("Accessing Unimplemented CP0 Register"); break;
+ case Debug: panic("Accessing Unimplemented CP0 Register"); break;
+ case TraceControl1: panic("Accessing Unimplemented CP0 Register"); break;
+ case TraceControl2: panic("Accessing Unimplemented CP0 Register"); break;
+ case UserTraceData: panic("Accessing Unimplemented CP0 Register"); break;
+ case TraceBPC: panic("Accessing Unimplemented CP0 Register"); break;
+ case DEPC: panic("Accessing Unimplemented CP0 Register"); break;
+ case PerfCnt: panic("Accessing Unimplemented CP0 Register"); break;
+ case ErrCtl: panic("Accessing Unimplemented CP0 Register"); break;
+ case CacheErr0: panic("Accessing Unimplemented CP0 Register"); break;
+ case CacheErr1: panic("Accessing Unimplemented CP0 Register"); break;
+ case CacheErr2: panic("Accessing Unimplemented CP0 Register"); break;
+ case CacheErr3: panic("Accessing Unimplemented CP0 Register"); break;
+ case TagLo: panic("Accessing Unimplemented CP0 Register"); break;
+ case DataLo: panic("Accessing Unimplemented CP0 Register"); break;
+ case TagHi: panic("Accessing Unimplemented CP0 Register"); break;
+ case DataHi: panic("Accessing Unimplemented CP0 Register"); break;
+ case ErrorEPC: panic("Accessing Unimplemented CP0 Register"); break;
+
+ default:
+ panic("Accessing Unimplemented Misc. Register");
+ }
+}
+
+void RegFile::coldReset()
+{
+ //CP0 Random Reg:
+ //Randomly generated index into the TLB array
+ miscRegs[Random] = 0x0000003f;
+
+ //CP0 Wired Reg.
+ miscRegs[Wired] = 0x0000000;
+
+ //CP0 HWRENA
+ miscRegs[HWRena] = 0x0000000;
+
+ //CP0 Status Reg.
+ miscRegs[Status] = 0x0400004;
+
+ //CP0 INTCNTL
+ miscRegs[IntCtl] = 0xfc00000;
+
+ //CP0 SRSCNTL
+ miscRegs[SRSCtl] = 0x0c00000;
+
+ //CP0 SRSMAP
+ miscRegs[SRSMap] = 0x0000000;
+
+ //CP0 Cause
+ miscRegs[Cause] = 0x0000000;
+
+ //CP0 Processor ID
+ miscRegs[PrId] = 0x0019300;
+
+ //CP0 EBASE
+ miscRegs[EBase] = 0x8000000;
+
+ //CP0 Config Reg.
+ miscRegs[Config] = 0x80040482;
+
+ //CP0 Config 1 Reg.
+ miscRegs[Config1] = 0xfee3719e;
+
+ //CP0 Config 2 Reg.
+ miscRegs[Config2] = 0x8000000;
+
+ //CP0 Config 3 Reg.
+ miscRegs[Config3] = 0x0000020;
+
+ //CP0 Config 7 Reg.
+ miscRegs[Config7] = 0x0000000;
+
+ //CP0 Debug
+ miscRegs[Debug] = 0x0201800;
+
+ //CP0 PERFCNTL1
+ miscRegs[PerfCnt0] = 0x0000000;
+
+ //CP0 PERFCNTL2
+ miscRegs[PerfCnt1] = 0x0000000;
+
+}
+
+void RegFile::createCP0Regs()
+{
+//Resize Coprocessor Register Banks to
+// the number specified in MIPS32K VOL.III
+// Chapter 8
+ /*
+ //Cop-0 Regs. Bank 0: Index,
+ miscRegs[0].resize(4);
+
+ //Cop-0 Regs. Bank 1:
+ miscRegs[1].resize(8);
+
+ //Cop-0 Regs. Bank 2:
+ miscRegs[2].resize(8);
+
+ //Cop-0 Regs. Bank 3:
+ miscRegs[3].resize(1);
+
+ //Cop-0 Regs. Bank 4:
+ miscRegs[4].resize(2);
+
+ //Cop-0 Regs. Bank 5:
+ miscRegs[5].resize(2);
+
+ //Cop-0 Regs. Bank 6:
+ miscRegs[6].resize(6);
+
+ //Cop-0 Regs. Bank 7:
+ miscRegs[7].resize(1);
+
+ //Cop-0 Regs. Bank 8:
+ miscRegs[8].resize(1);
+
+ //Cop-0 Regs. Bank 9:
+ miscRegs[9].resize(1);
+
+ //Cop-0 Regs. Bank 10:
+ miscRegs[10].resize(1);
+
+ //Cop-0 Regs. Bank 11:
+ miscRegs[11].resize(1);
+
+ //Cop-0 Regs. Bank 12:
+ miscRegs[12].resize(4);
+
+ //Cop-0 Regs. Bank 13:
+ miscRegs[13].resize(1);
+
+ //Cop-0 Regs. Bank 14:
+ miscRegs[14].resize(1);
+
+ //Cop-0 Regs. Bank 15:
+ miscRegs[15].resize(2);
+
+ //Cop-0 Regs. Bank 16:
+ miscRegs[16].resize(4);
+
+ //Cop-0 Regs. Bank 17:
+ miscRegs[17].resize(1);
+
+ //Cop-0 Regs. Bank 18:
+ miscRegs[18].resize(8);
+
+ //Cop-0 Regs. Bank 19:
+ miscRegs[19].resize(8);
+
+ //Cop-0 Regs. Bank 20:
+ miscRegs[20].resize(1);
+
+ //Cop-0 Regs. Bank 21:
+ //miscRegs[21].resize(1);
+ //Reserved for future extensions
+
+ //Cop-0 Regs. Bank 22:
+ //miscRegs[22].resize(4);
+ //Available for implementation dependent use
+
+ //Cop-0 Regs. Bank 23:
+ miscRegs[23].resize(5);
+
+ //Cop-0 Regs. Bank 24:
+ miscRegs[24].resize(1);
+
+ //Cop-0 Regs. Bank 25:
+ miscRegs[25].resize(8);
+
+ //Cop-0 Regs. Bank 26:
+ miscRegs[26].resize(1);
+
+ //Cop-0 Regs. Bank 27:
+ miscRegs[27].resize(4);
+
+ //Cop-0 Regs. Bank 28:
+ miscRegs[28].resize(8);
+
+ //Cop-0 Regs. Bank 29:
+ miscRegs[29].resize(8);
+
+ //Cop-0 Regs. Bank 30:
+ miscRegs[30].resize(1);
+
+ //Cop-0 Regs. Bank 31:
+ miscRegs[31].resize(1);*/
+
+}
+
+
const Addr MipsISA::PageShift = 13;
const Addr MipsISA::PageBytes = ULL(1) << PageShift;
const Addr MipsISA::PageMask = ~(PageBytes - 1);
@@ -64,8 +317,8 @@ const Addr MipsISA::K1SegEnd = ULL(0xffffffffffffffff);
#endif
-// Mips UNOP (ldq_u r31,0(r0))
-const MachInst MipsISA::NoopMachInst = 0x2ffe0000;
+// Mips UNOP (sll r0,r0,r0)
+const MachInst MipsISA::NoopMachInst = 0x00000000;
static inline Addr
TruncPage(Addr addr)
@@ -74,17 +327,19 @@ TruncPage(Addr addr)
static inline Addr
RoundPage(Addr addr)
{ return (addr + MipsISA::PageBytes - 1) & ~(MipsISA::PageBytes - 1); }
+
void
RegFile::serialize(std::ostream &os)
{
SERIALIZE_ARRAY(intRegFile, NumIntRegs);
SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
- SERIALIZE_SCALAR(miscRegs.fpcr);
- SERIALIZE_SCALAR(miscRegs.uniq);
- SERIALIZE_SCALAR(miscRegs.lock_flag);
- SERIALIZE_SCALAR(miscRegs.lock_addr);
+ //SERIALIZE_SCALAR(miscRegs.fpcr);
+ //SERIALIZE_SCALAR(miscRegs.uniq);
+ //SERIALIZE_SCALAR(miscRegs.lock_flag);
+ //SERIALIZE_SCALAR(miscRegs.lock_addr);
SERIALIZE_SCALAR(pc);
SERIALIZE_SCALAR(npc);
+ SERIALIZE_SCALAR(nnpc);
#if FULL_SYSTEM
SERIALIZE_ARRAY(palregs, NumIntRegs);
SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
@@ -99,12 +354,13 @@ RegFile::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(intRegFile, NumIntRegs);
UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
- UNSERIALIZE_SCALAR(miscRegs.fpcr);
- UNSERIALIZE_SCALAR(miscRegs.uniq);
- UNSERIALIZE_SCALAR(miscRegs.lock_flag);
- UNSERIALIZE_SCALAR(miscRegs.lock_addr);
+ //UNSERIALIZE_SCALAR(miscRegs.fpcr);
+ //UNSERIALIZE_SCALAR(miscRegs.uniq);
+ //UNSERIALIZE_SCALAR(miscRegs.lock_flag);
+ //UNSERIALIZE_SCALAR(miscRegs.lock_addr);
UNSERIALIZE_SCALAR(pc);
UNSERIALIZE_SCALAR(npc);
+ UNSERIALIZE_SCALAR(nnpc);
#if FULL_SYSTEM
UNSERIALIZE_ARRAY(palregs, NumIntRegs);
UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh
index 71da82ffa..1dfa0dc7a 100644
--- a/arch/mips/isa_traits.hh
+++ b/arch/mips/isa_traits.hh
@@ -29,19 +29,21 @@
#ifndef __ARCH_MIPS_ISA_TRAITS_HH__
#define __ARCH_MIPS_ISA_TRAITS_HH__
-namespace LittleEndianGuest {}
-using namespace LittleEndianGuest;
-
-//#include "arch/mips/faults.hh"
+//#include "arch/mips/misc_regfile.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
#include "sim/faults.hh"
+#include <vector>
+
class FastCPU;
class FullCPU;
class Checkpoint;
+namespace LittleEndianGuest {};
+using namespace LittleEndianGuest;
+
#define TARGET_MIPS
class StaticInst;
@@ -50,11 +52,10 @@ class StaticInstPtr;
namespace MIPS34K {
int DTB_ASN_ASN(uint64_t reg);
int ITB_ASN_ASN(uint64_t reg);
-}
+};
namespace MipsISA
{
-
typedef uint32_t MachInst;
// typedef uint64_t Addr;
typedef uint8_t RegIndex;
@@ -64,7 +65,7 @@ namespace MipsISA
NumIntRegs = 32,
NumFloatRegs = 32,
- NumMiscRegs = 32,
+ NumMiscRegs = 258, //account for hi,lo regs
MaxRegsOfAnyType = 32,
// Static instruction parameters
@@ -72,7 +73,7 @@ namespace MipsISA
MaxInstDestRegs = 2,
// semantically meaningful register indices
- ZeroReg = 31, // architecturally meaningful
+ ZeroReg = 0, // architecturally meaningful
// the rest of these depend on the ABI
StackPointerReg = 30,
GlobalPointerReg = 29,
@@ -106,7 +107,8 @@ namespace MipsISA
Ctrl_Base_DepTag = 64,
Fpcr_DepTag = 64, // floating point control register
Uniq_DepTag = 65,
- IPR_Base_DepTag = 66
+ IPR_Base_DepTag = 66,
+ MiscReg_DepTag = 67
};
typedef uint64_t IntReg;
@@ -123,14 +125,226 @@ namespace MipsISA
double d[NumFloatRegs]; // double-precision floating point view
} FloatRegFile;
- // control register file contents
+ // cop-0/cop-1 system control register file
typedef uint64_t MiscReg;
- typedef struct {
+//typedef MiscReg MiscRegFile[NumMiscRegs];
+ class MiscRegFile {
+ public:
+ MiscReg
+ protected:
uint64_t fpcr; // floating point condition codes
uint64_t uniq; // process-unique register
bool lock_flag; // lock flag for LL/SC
Addr lock_addr; // lock address for LL/SC
- } MiscRegFile;
+
+ MiscReg miscRegFile[NumMiscRegs];
+
+ public:
+ //These functions should be removed once the simplescalar cpu model
+ //has been replaced.
+ int getInstAsid();
+ int getDataAsid();
+
+ MiscReg readReg(int misc_reg)
+ { return miscRegFile[misc_reg]; }
+
+ MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc)
+ { return miscRegFile[misc_reg];}
+
+ Fault setReg(int misc_reg, const MiscReg &val)
+ { miscRegFile[misc_reg] = val; return NoFault; }
+
+ Fault setRegWithEffect(int misc_reg, const MiscReg &val,
+ ExecContext *xc)
+ { miscRegFile[misc_reg] = val; return NoFault; }
+
+#if FULL_SYSTEM
+ void clearIprs() { };
+
+ protected:
+ InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
+
+ private:
+ MiscReg readIpr(int idx, Fault &fault, ExecContext *xc) { }
+
+ Fault setIpr(int idx, uint64_t val, ExecContext *xc) { }
+#endif
+ friend class RegFile;
+ };
+
+ enum MiscRegTags {
+ //Coprocessor 0 Registers
+ //Reference MIPS32 Arch. for Programmers, Vol. III, Ch.8
+ //(Register Number-Register Select) Summary of Register
+ //------------------------------------------------------
+ Index = 0, //0-0 Index into the TLB array
+
+ MVPControl = 1, //0-1 Per-processor register containing global
+ //MIPS® MT configuration data
+
+ MVPConf0 = 2, //0-2 Per-processor register containing global
+ //MIPS® MT configuration data
+
+ MVPConf1 = 3, //0-3 Per-processor register containing global
+ //MIPS® MT configuration data
+
+ Random = 8, //1-0 Randomly generated index into the TLB array
+
+ VPEControl = 9, //1-1 Per-VPE register containing relatively volatile
+ //thread configuration data
+
+ VPEConf0 = 10, //1-2 Per-VPE multi-thread configuration
+ //information
+
+
+ VPEConf1 = 11, //1-2 Per-VPE multi-thread configuration
+ //information
+
+ YQMask = 12, //Per-VPE register defining which YIELD
+ //qualifier bits may be used without generating
+ //an exception
+
+ VPESchedule = 13,
+ VPEScheFBack = 14,
+ VPEOpt = 15,
+ EntryLo0 = 16, // Bank 3: 16 - 23
+ TCStatus = 17,
+ TCBind = 18,
+ TCRestart = 19,
+ TCHalt = 20,
+ TCContext = 21,
+ TCSchedule = 22,
+ TCScheFBack = 23,
+
+ EntryLo1 = 24,// Bank 4: 24 - 31
+
+ Context = 32, // Bank 5: 32 - 39
+ ContextConfig = 33,
+
+ //PageMask = 40, //Bank 6: 40 - 47
+ PageGrain = 41,
+
+ Wired = 48, //Bank 7:48 - 55
+ SRSConf0 = 49,
+ SRSConf1 = 50,
+ SRSConf2 = 51,
+ SRSConf3 = 52,
+ SRSConf4 = 53,
+ BadVAddr = 54,
+
+ HWRena = 56,//Bank 8:56 - 63
+
+ Count = 64, //Bank 9:64 - 71
+
+ EntryHi = 72,//Bank 10:72 - 79
+
+ Compare = 80,//Bank 11:80 - 87
+
+ Status = 88,//Bank 12:88 - 96 //12-0 Processor status and control
+ IntCtl = 89, //12-1 Interrupt system status and control
+ SRSCtl = 90, //12-2 Shadow register set status and control
+ SRSMap = 91, //12-3 Shadow set IPL mapping
+
+ Cause = 97,//97-104 //13-0 Cause of last general exception
+
+ EPC = 105,//105-112 //14-0 Program counter at last exception
+
+ PRId = 113//113-120, //15-0 Processor identification and revision
+ EBase = 114, //15-1 Exception vector base register
+
+ Config = 121,//Bank 16: 121-128
+ Config1 = 122,
+ Config2 = 123,
+ Config3 = 124,
+ Config6 = 127,
+ Config7 = 128,
+
+
+ LLAddr = 129,//Bank 17: 129-136
+
+ WatchLo0 = 137,//Bank 18: 137-144
+ WatchLo1 = 138,
+ WatchLo2 = 139,
+ WatchLo3 = 140,
+ WatchLo4 = 141,
+ WatchLo5 = 142,
+ WatchLo6 = 143,
+ WatchLo7 = 144,
+
+ WatchHi0 = 145,//Bank 19: 145-152
+ WatchHi1 = 146,
+ WatchHi2 = 147,
+ WatchHi3 = 148,
+ WatchHi4 = 149,
+ WatchHi5 = 150,
+ WatchHi6 = 151,
+ WatchHi7 = 152,
+
+ XCContext64 = 153,//Bank 20: 153-160
+
+ //Bank 21: 161-168
+
+ //Bank 22: 169-176
+
+ Debug = 177, //Bank 23: 177-184
+ TraceControl1 = 178,
+ TraceControl2 = 179,
+ UserTraceData = 180,
+ TraceBPC = 181,
+
+ DEPC = 185,//Bank 24: 185-192
+
+ PerfCnt0 = 193,//Bank 25: 193 - 200
+ PerfCnt1 = 194,
+ PerfCnt2 = 195,
+ PerfCnt3 = 196,
+ PerfCnt4 = 197,
+ PerfCnt5 = 198,
+ PerfCnt6 = 199,
+ PerfCnt7 = 200,
+
+ ErrCtl = 201, //Bank 26: 201 - 208
+
+ CacheErr0 = 209, //Bank 27: 209 - 216
+ CacheErr1 = 210,
+ CacheErr2 = 211,
+ CacheErr3 = 212,
+
+ TagLo0 = 217,//Bank 28: 217 - 224
+ DataLo1 = 218,
+ TagLo2 = 219,
+ DataLo3 = 220,
+ TagLo4 = 221,
+ DataLo5 = 222,
+ TagLo6 = 223,
+ DataLo7 = 234,
+
+ TagHi0 = 233,//Bank 29: 233 - 240
+ DataHi1 = 234,
+ TagHi2 = 235,
+ DataHi3 = 236,
+ TagHi4 = 237,
+ DataHi5 = 238,
+ TagHi6 = 239,
+ DataHi7 = 240,
+
+
+ ErrorEPC = 249,//Bank 30: 241 - 248
+
+ DESAVE = 257,//Bank 31: 249-256
+
+ //More Misc. Regs
+ Hi,
+ Lo,
+ FCSR,
+ FPCR,
+
+ //Alpha Regs, but here now, for
+ //compiling sake
+ UNIQ,
+ LockAddr,
+ LockFlag
+ };
extern const Addr PageShift;
extern const Addr PageBytes;
@@ -168,19 +382,33 @@ extern const Addr PageOffset;
IntRegFile intRegFile; // (signed) integer register file
FloatRegFile floatRegFile; // floating point register file
MiscRegFile miscRegs; // control register file
+
+
Addr pc; // program counter
Addr npc; // next-cycle program counter
+ Addr nnpc; // next-next-cycle program counter
+ // used to implement branch delay slot
+ // not real register
+
+ MiscReg hi; // MIPS HI Register
+ MiscReg lo; // MIPS LO Register
+
+
#if FULL_SYSTEM
IntReg palregs[NumIntRegs]; // PAL shadow registers
InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs
int intrflag; // interrupt flag
bool pal_shadow; // using pal_shadow registers
- inline int instAsid() { return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); }
- inline int dataAsid() { return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); }
+ inline int instAsid() { return MIPS34K::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); }
+ inline int dataAsid() { return MIPS34K::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); }
#endif // FULL_SYSTEM
+ //void initCP0Regs();
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
+
+ void createCP0Regs();
+ void coldReset();
};
StaticInstPtr decodeInst(MachInst);
@@ -194,6 +422,9 @@ extern const Addr PageOffset;
ITOUCH_ANNOTE = 0xffffffff,
};
+ void getMiscRegIdx(int reg_name,int &idx, int &sel);
+
+
static inline bool isCallerSaveIntegerRegister(unsigned int reg) {
panic("register classification not implemented");
return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27);
@@ -264,37 +495,7 @@ extern const Addr PageOffset;
template <class XC>
void zeroRegisters(XC *xc);
-
-//typedef MipsISA TheISA;
-
-//typedef TheISA::MachInst MachInst;
-//typedef TheISA::Addr Addr;
-//typedef TheISA::RegIndex RegIndex;
-//typedef TheISA::IntReg IntReg;
-//typedef TheISA::IntRegFile IntRegFile;
-//typedef TheISA::FloatReg FloatReg;
-//typedef TheISA::FloatRegFile FloatRegFile;
-//typedef TheISA::MiscReg MiscReg;
-//typedef TheISA::MiscRegFile MiscRegFile;
-//typedef TheISA::AnyReg AnyReg;
-//typedef TheISA::RegFile RegFile;
-
-//const int NumIntRegs = TheISA::NumIntRegs;
-//const int NumFloatRegs = TheISA::NumFloatRegs;
-//const int NumMiscRegs = TheISA::NumMiscRegs;
-//const int TotalNumRegs = TheISA::TotalNumRegs;
-//const int VMPageSize = TheISA::VMPageSize;
-//const int LogVMPageSize = TheISA::LogVMPageSize;
-//const int ZeroReg = TheISA::ZeroReg;
-//const int StackPointerReg = TheISA::StackPointerReg;
-//const int GlobalPointerReg = TheISA::GlobalPointerReg;
-//const int ReturnAddressReg = TheISA::ReturnAddressReg;
-//const int ReturnValueReg = TheISA::ReturnValueReg;
-//const int ArgumentReg0 = TheISA::ArgumentReg0;
-//const int ArgumentReg1 = TheISA::ArgumentReg1;
-//const int ArgumentReg2 = TheISA::ArgumentReg2;
-//const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt;
-const Addr MaxAddr = (Addr)-1;
+ const Addr MaxAddr = (Addr)-1;
};
#if !FULL_SYSTEM
diff --git a/arch/mips/linux_process.cc b/arch/mips/linux_process.cc
index d3aca15bc..1d4f62350 100644
--- a/arch/mips/linux_process.cc
+++ b/arch/mips/linux_process.cc
@@ -26,8 +26,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "arch/mips/mips_common_syscall_emul.hh"
-#include "arch/mips/mips_linux_process.hh"
+#include "arch/mips/common_syscall_emul.hh"
+#include "arch/mips/linux_process.hh"
#include "arch/mips/isa_traits.hh"
#include "base/trace.hh"
diff --git a/arch/mips/stacktrace.hh b/arch/mips/stacktrace.hh
new file mode 100644
index 000000000..1d8d97a79
--- /dev/null
+++ b/arch/mips/stacktrace.hh
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ARCH_ALPHA_STACKTRACE_HH__
+#define __ARCH_ALPHA_STACKTRACE_HH__
+
+#include "base/trace.hh"
+#include "cpu/static_inst.hh"
+
+class ExecContext;
+class StackTrace;
+
+class ProcessInfo
+{
+ private:
+ ExecContext *xc;
+
+ int thread_info_size;
+ int task_struct_size;
+ int task_off;
+ int pid_off;
+ int name_off;
+
+ public:
+ ProcessInfo(ExecContext *_xc);
+
+ Addr task(Addr ksp) const;
+ int pid(Addr ksp) const;
+ std::string name(Addr ksp) const;
+};
+
+class StackTrace
+{
+ protected:
+ typedef TheISA::MachInst MachInst;
+ private:
+ ExecContext *xc;
+ std::vector<Addr> stack;
+
+ private:
+ bool isEntry(Addr addr);
+ bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
+ bool decodeSave(MachInst inst, int &reg, int &disp);
+ bool decodeStack(MachInst inst, int &disp);
+
+ void trace(ExecContext *xc, bool is_call);
+
+ public:
+ StackTrace();
+ StackTrace(ExecContext *xc, StaticInstPtr inst);
+ ~StackTrace();
+
+ void clear()
+ {
+ xc = 0;
+ stack.clear();
+ }
+
+ bool valid() const { return xc != NULL; }
+ bool trace(ExecContext *xc, StaticInstPtr inst);
+
+ public:
+ const std::vector<Addr> &getstack() const { return stack; }
+
+ static const int user = 1;
+ static const int console = 2;
+ static const int unknown = 3;
+
+#if TRACING_ON
+ private:
+ void dump();
+
+ public:
+ void dprintf() { if (DTRACE(Stack)) dump(); }
+#else
+ public:
+ void dprintf() {}
+#endif
+};
+
+inline bool
+StackTrace::trace(ExecContext *xc, StaticInstPtr inst)
+{
+ if (!inst->isCall() && !inst->isReturn())
+ return false;
+
+ if (valid())
+ clear();
+
+ trace(xc, !inst->isReturn());
+ return true;
+}
+
+#endif // __ARCH_ALPHA_STACKTRACE_HH__
diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh
index 7f654e33b..bd3c35beb 100644
--- a/arch/sparc/isa_traits.hh
+++ b/arch/sparc/isa_traits.hh
@@ -57,42 +57,59 @@ class StaticInstPtr;
namespace SparcISA
{
typedef uint32_t MachInst;
- typedef uint64_t Addr;
+ typedef uint64_t ExtMachInst;
typedef uint8_t RegIndex;
- enum
- {
- MemoryEnd = 0xffffffffffffffffULL,
-
- NumFloatRegs = 32,
- NumMiscRegs = 32,
-
- MaxRegsOfAnyType = 32,
- // Static instruction parameters
- MaxInstSrcRegs = 3,
- MaxInstDestRegs = 2,
-
- // Maximum trap level
- MaxTL = 4,
-
- // semantically meaningful register indices
- ZeroReg = 0 // architecturally meaningful
- // the rest of these depend on the ABI
- SyscallNumReg = 1,
- ArgumentReg0 = 8,
- ArgumentReg1 = 9,
- ArgumentReg2 = 10,
- ArgumentReg3 = 11,
- ArgumentReg4 = 12,
- ArgumentReg5 = 13,
- StackPoniterReg = 14,
- ReturnAddressReg = 31, // Post Call, precall, 15
- ReturnValueReg = 8, // Post return, 24 is pre-return.
- // Some OS use a second register (o1) to return a second value
- // for some syscalls
- SyscallPseudoReturnReg = 9,
- FramePointerReg = 30
-};
+ const int NumFloatRegs = 32;
+ const int NumMiscRegs = 32;
+
+ const int // Maximum trap level
+ const int MaxTL = 4;
+ const int
+ const int // semantically meaningful register indices
+ const int ZeroReg = 0; // architecturally meaningful
+ const int // the rest of these depend on the ABI
+ const int StackPointerReg = 14;
+ const int ReturnAddressReg = 31; // post call, precall is 15
+ const int ReturnValueReg = 8; // Post return, 24 is pre-return.
+ const int FramePointerReg = 30;
+ const int ArgumentReg0 = 8;
+ const int ArgumentReg1 = 9;
+ const int ArgumentReg2 = 10;
+ const int ArgumentReg3 = 11;
+ const int ArgumentReg4 = 12;
+ const int ArgumentReg5 = 13;
+ // Some OS syscall sue a second register (o1) to return a second value
+ const int SyscallPseudoReturnReg = ArgumentReg1;
+
+
+ //8K. This value is implmentation specific; and should probably
+ //be somewhere else.
+ const int LogVMPageSize = 13;
+ const int VMPageSize = (1 << LogVMPageSize);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
typedef uint64_t IntReg;
class IntRegFile
@@ -113,6 +130,12 @@ namespace SparcISA
void unserialize(Checkpoint *cp, const std::string &section);
+ typedef float float32_t;
+ typedef double float64_t;
+ //FIXME This actually usually refers to a 10 byte float, rather than a
+ //16 byte float as required. This data type may have to be emulated.
+ typedef long double float128_t;
+
class FloatRegFile
{
private:
@@ -120,7 +143,7 @@ namespace SparcISA
//is aligned correctly in memory
union
{
- long double rawRegs[16];
+ float128_t rawRegs[16];
uint64_t regDump[32];
};
class QuadRegs
@@ -129,7 +152,7 @@ namespace SparcISA
FloatRegFile * parent;
public:
QuadRegs(FloatRegFile * p) : parent(p) {;}
- long double & operator [] (RegIndex index)
+ float128_t & operator [] (RegIndex index)
{
//Quad floats are index by the single
//precision register the start on,
@@ -144,13 +167,13 @@ namespace SparcISA
FloatRegFile * parent;
public:
DoubleRegs(FloatRegFile * p) : parent(p) {;}
- double & operator [] (RegIndex index)
+ float64_t & operator [] (RegIndex index)
{
//Double floats are index by the single
//precision register the start on,
//and only 32 should be accessed
index = (index >> 1) & 0x1F;
- return ((double *)parent->rawRegs)[index];
+ return ((float64_t *)parent->rawRegs)[index];
}
};
class SingleRegs
@@ -159,11 +182,11 @@ namespace SparcISA
FloatRegFile * parent;
public:
SingleRegs(FloatRegFile * p) : parent(p) {;}
- float & operator [] (RegIndex index)
+ float32_t & operator [] (RegIndex index)
{
//Only 32 single floats should be accessed
index &= 0x1F;
- return ((float *)parent->rawRegs)[index];
+ return ((float32_t *)parent->rawRegs)[index];
}
};
public:
@@ -183,7 +206,7 @@ namespace SparcISA
// The control registers, broken out into fields
class MiscRegFile
{
- public:
+ private:
union
{
uint16_t pstate; // Process State Register
@@ -207,7 +230,7 @@ namespace SparcISA
struct
{
uint64_t value:32; // The actual value stored in y
- const uint64_t :32; // reserved bits
+ uint64_t :32; // reserved bits
} yFields;
};
uint8_t pil; // Process Interrupt Register
@@ -228,8 +251,8 @@ namespace SparcISA
uint8_t v:1; // Overflow
uint8_t z:1; // Zero
uint8_t n:1; // Negative
- } iccFields:4;
- } :4;
+ } iccFields;
+ };
union
{
uint8_t xcc:4; // 64-bit condition codes
@@ -239,8 +262,8 @@ namespace SparcISA
uint8_t v:1; // Overflow
uint8_t z:1; // Zero
uint8_t n:1; // Negative
- } xccFields:4;
- } :4;
+ } xccFields;
+ };
} ccrFields;
};
uint8_t asi; // Address Space Identifier
@@ -256,9 +279,9 @@ namespace SparcISA
{
//Values are from previous trap level
uint64_t cwp:5; // Current Window Pointer
- const uint64_t :2; // Reserved bits
+ uint64_t :2; // Reserved bits
uint64_t pstate:10; // Process State
- const uint64_t :6; // Reserved bits
+ uint64_t :6; // Reserved bits
uint64_t asi:8; // Address Space Identifier
uint64_t ccr:8; // Condition Code Register
} tstateFields[MaxTL];
@@ -271,7 +294,7 @@ namespace SparcISA
uint64_t counter:63; // Clock-tick count
uint64_t npt:1; // Non-priveleged trap
} tickFields;
- }
+ };
uint8_t cansave; // Savable windows
uint8_t canrestore; // Restorable windows
uint8_t otherwin; // Other windows
@@ -293,9 +316,9 @@ namespace SparcISA
struct
{
uint64_t maxwin:5; // Max CWP value
- const uint64_t :2; // Reserved bits
+ uint64_t :2; // Reserved bits
uint64_t maxtl:8; // Maximum trap level
- const uint64_t :8; // Reserved bits
+ uint64_t :8; // Reserved bits
uint64_t mask:8; // Processor mask set revision number
uint64_t impl:16; // Implementation identification number
uint64_t manuf:16; // Manufacturer code
@@ -316,8 +339,8 @@ namespace SparcISA
uint64_t ufc:1; // Underflow
uint64_t ofc:1; // Overflow
uint64_t nvc:1; // Invalid operand
- } cexecFields:5;
- } :5;
+ } cexecFields;
+ };
union
{
uint64_t aexc:5; // Accrued exception
@@ -328,15 +351,15 @@ namespace SparcISA
uint64_t ufc:1; // Underflow
uint64_t ofc:1; // Overflow
uint64_t nvc:1; // Invalid operand
- } aexecFields:5;
- } :5;
+ } aexecFields;
+ };
uint64_t fcc0:2; // Floating-Point condtion codes
- const uint64_t :1; // Reserved bits
+ uint64_t :1; // Reserved bits
uint64_t qne:1; // Deferred trap queue not empty
// with no queue, it should read 0
uint64_t ftt:3; // Floating-Point trap type
uint64_t ver:3; // Version (of the FPU)
- const uint64_t :2; // Reserved bits
+ uint64_t :2; // Reserved bits
uint64_t ns:1; // Nonstandard floating point
union
{
@@ -348,16 +371,16 @@ namespace SparcISA
uint64_t ufm:1; // Underflow
uint64_t ofm:1; // Overflow
uint64_t nvm:1; // Invalid operand
- } temFields:5;
- } :5;
- const uint64_t :2; // Reserved bits
+ } temFields;
+ };
+ uint64_t :2; // Reserved bits
uint64_t rd:2; // Rounding direction
uint64_t fcc1:2; // Floating-Point condition codes
uint64_t fcc2:2; // Floating-Point condition codes
uint64_t fcc3:2; // Floating-Point condition codes
- const uint64_t :26; // Reserved bits
+ uint64_t :26; // Reserved bits
} fsrFields;
- }
+ };
union
{
uint8_t fprs; // Floating-Point Register State
@@ -365,63 +388,34 @@ namespace SparcISA
{
uint8_t dl:1; // Dirty lower
uint8_t du:1; // Dirty upper
- fef:1; // FPRS enable floating-Point
+ uint8_t fef:1; // FPRS enable floating-Point
} fprsFields;
};
- void serialize(std::ostream & os)
- {
- SERIALIZE_SCALAR(pstate);
- SERIAlIZE_SCALAR(tba);
- SERIALIZE_SCALAR(y);
- SERIALIZE_SCALAR(pil);
- SERIALIZE_SCALAR(cwp);
- SERIALIZE_ARRAY(tt, MaxTL);
- SERIALIZE_SCALAR(ccr);
- SERIALIZE_SCALAR(asi);
- SERIALIZE_SCALAR(tl);
- SERIALIZE_SCALAR(tpc);
- SERIALIZE_SCALAR(tnpc);
- SERIALIZE_ARRAY(tstate, MaxTL);
- SERIALIZE_SCALAR(tick);
- SERIALIZE_SCALAR(cansave);
- SERIALIZE_SCALAR(canrestore);
- SERIALIZE_SCALAR(otherwin);
- SERIALIZE_SCALAR(cleanwin);
- SERIALIZE_SCALAR(wstate);
- SERIALIZE_SCALAR(ver);
- SERIALIZE_SCALAR(fsr);
- SERIALIZE_SCALAR(fprs);
- }
+ public:
+ MiscReg readReg(int misc_reg);
- void unserialize(Checkpoint &* cp, std::string & section)
- {
- UNSERIALIZE_SCALAR(pstate);
- UNSERIAlIZE_SCALAR(tba);
- UNSERIALIZE_SCALAR(y);
- UNSERIALIZE_SCALAR(pil);
- UNSERIALIZE_SCALAR(cwp);
- UNSERIALIZE_ARRAY(tt, MaxTL);
- UNSERIALIZE_SCALAR(ccr);
- UNSERIALIZE_SCALAR(asi);
- UNSERIALIZE_SCALAR(tl);
- UNSERIALIZE_SCALAR(tpc);
- UNSERIALIZE_SCALAR(tnpc);
- UNSERIALIZE_ARRAY(tstate, MaxTL);
- UNSERIALIZE_SCALAR(tick);
- UNSERIALIZE_SCALAR(cansave);
- UNSERIALIZE_SCALAR(canrestore);
- UNSERIALIZE_SCALAR(otherwin);
- UNSERIALIZE_SCALAR(cleanwin);
- UNSERIALIZE_SCALAR(wstate);
- UNSERIALIZE_SCALAR(ver);
- UNSERIALIZE_SCALAR(fsr);
- UNSERIALIZE_SCALAR(fprs);
- }
+ MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc);
+
+ Fault setReg(int misc_reg, const MiscReg &val);
+
+ Fault setRegWithEffect(int misc_reg, const MiscReg &val,
+ ExecContext *xc);
+
+ void serialize(std::ostream & os);
+
+ void unserialize(Checkpoint * cp, std::string & section);
};
typedef union
{
+ float32_t singReg;
+ float64_t doubReg;
+ float128_t quadReg;
+ } FloatReg;
+
+ typedef union
+ {
IntReg intreg;
FloatReg fpreg;
MiscReg ctrlreg;
@@ -435,30 +429,31 @@ namespace SparcISA
Addr pc; // Program Counter
Addr npc; // Next Program Counter
+ Addr nnpc;
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};
- static StaticInstPtr decodeInst(MachInst);
+ StaticInstPtr decodeInst(MachInst);
// return a no-op instruction... used for instruction fetch faults
- static const MachInst NoopMachInst;
+ extern const MachInst NoopMachInst;
// Instruction address compression hooks
- static inline Addr realPCToFetchPC(const Addr &addr)
+ inline Addr realPCToFetchPC(const Addr &addr)
{
return addr;
}
- static inline Addr fetchPCToRealPC(const Addr &addr)
+ inline Addr fetchPCToRealPC(const Addr &addr)
{
return addr;
}
// the size of "fetched" instructions (not necessarily the size
// of real instructions for PISA)
- static inline size_t fetchInstSize()
+ inline size_t fetchInstSize()
{
return sizeof(MachInst);
}
@@ -468,7 +463,6 @@ namespace SparcISA
* @param xc The execution context.
*/
template <class XC>
- static void zeroRegisters(XC *xc);
static inline setSyscallReturn(SyscallReturn return_value, RegFile *regs)
{
@@ -487,12 +481,6 @@ namespace SparcISA
}
};
-const int VMPageSize = TheISA::VMPageSize;
-const int LogVMPageSize = TheISA::LogVMPageSize;
-const int ZeroReg = TheISA::ZeroReg;
-const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt;
-const int MaxAddr = (Addr)-1;
-
#if !FULL_SYSTEM
class SyscallReturn
{
diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc
index 456f99b32..5965e6da9 100644
--- a/arch/sparc/linux/process.cc
+++ b/arch/sparc/linux/process.cc
@@ -62,7 +62,6 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 0 */ SyscallDesc("restart_syscall", unimplimentedFunc);
/* 1 */ SyscallDesc("exit", exitFunc);
- /* 2 */ SyscallDesc("fork", unimplimentedFunc);
/* 3 */ SyscallDesc("read", readFunc);
/* 4 */ SyscallDesc("write", writeFunc);
/* 5 */ SyscallDesc("open", openFunc<Linux>);
diff --git a/arch/sparc/stacktrace.hh b/arch/sparc/stacktrace.hh
new file mode 100644
index 000000000..1d8d97a79
--- /dev/null
+++ b/arch/sparc/stacktrace.hh
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ARCH_ALPHA_STACKTRACE_HH__
+#define __ARCH_ALPHA_STACKTRACE_HH__
+
+#include "base/trace.hh"
+#include "cpu/static_inst.hh"
+
+class ExecContext;
+class StackTrace;
+
+class ProcessInfo
+{
+ private:
+ ExecContext *xc;
+
+ int thread_info_size;
+ int task_struct_size;
+ int task_off;
+ int pid_off;
+ int name_off;
+
+ public:
+ ProcessInfo(ExecContext *_xc);
+
+ Addr task(Addr ksp) const;
+ int pid(Addr ksp) const;
+ std::string name(Addr ksp) const;
+};
+
+class StackTrace
+{
+ protected:
+ typedef TheISA::MachInst MachInst;
+ private:
+ ExecContext *xc;
+ std::vector<Addr> stack;
+
+ private:
+ bool isEntry(Addr addr);
+ bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
+ bool decodeSave(MachInst inst, int &reg, int &disp);
+ bool decodeStack(MachInst inst, int &disp);
+
+ void trace(ExecContext *xc, bool is_call);
+
+ public:
+ StackTrace();
+ StackTrace(ExecContext *xc, StaticInstPtr inst);
+ ~StackTrace();
+
+ void clear()
+ {
+ xc = 0;
+ stack.clear();
+ }
+
+ bool valid() const { return xc != NULL; }
+ bool trace(ExecContext *xc, StaticInstPtr inst);
+
+ public:
+ const std::vector<Addr> &getstack() const { return stack; }
+
+ static const int user = 1;
+ static const int console = 2;
+ static const int unknown = 3;
+
+#if TRACING_ON
+ private:
+ void dump();
+
+ public:
+ void dprintf() { if (DTRACE(Stack)) dump(); }
+#else
+ public:
+ void dprintf() {}
+#endif
+};
+
+inline bool
+StackTrace::trace(ExecContext *xc, StaticInstPtr inst)
+{
+ if (!inst->isCall() && !inst->isReturn())
+ return false;
+
+ if (valid())
+ clear();
+
+ trace(xc, !inst->isReturn());
+ return true;
+}
+
+#endif // __ARCH_ALPHA_STACKTRACE_HH__
diff --git a/base/loader/exec_aout.h b/base/loader/exec_aout.h
index 3863a92fb..eed44baee 100644
--- a/base/loader/exec_aout.h
+++ b/base/loader/exec_aout.h
@@ -55,6 +55,7 @@
(N_GETMAGIC(ex) != NMAGIC && N_GETMAGIC(ex) != OMAGIC && \
N_GETMAGIC(ex) != ZMAGIC)
-#include "arch/aout_machdep.h"
+//Only alpha will be able to load aout for now
+#include "arch/alpha/aout_machdep.h"
#endif /* !_SYS_EXEC_AOUT_H_ */
diff --git a/base/loader/exec_ecoff.h b/base/loader/exec_ecoff.h
index 79cd22a6e..555589806 100644
--- a/base/loader/exec_ecoff.h
+++ b/base/loader/exec_ecoff.h
@@ -37,7 +37,8 @@
#ifndef _SYS_EXEC_ECOFF_H_
#define _SYS_EXEC_ECOFF_H_
-#include "arch/ecoff_machdep.h"
+//Only alpha will be able to load ecoff files for now
+#include "arch/alpha/ecoff_machdep.h"
struct ecoff_filehdr {
coff_ushort f_magic; /* magic number */
diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc
index 57a179719..84093459c 100644
--- a/base/remote_gdb.cc
+++ b/base/remote_gdb.cc
@@ -470,7 +470,7 @@ RemoteGDB::setregs()
context->setFloatRegInt(i, gdbregs[i + KGDB_REG_F0]);
}
#endif
- context->regs.pc = gdbregs[KGDB_REG_PC];
+ context->setPC(gdbregs[KGDB_REG_PC]);
}
void
@@ -509,7 +509,7 @@ RemoteGDB::clearSingleStep()
void
RemoteGDB::setSingleStep()
{
- Addr pc = context->regs.pc;
+ Addr pc = context->readPC();
Addr npc, bpc;
bool set_bt = false;
@@ -858,7 +858,7 @@ RemoteGDB::trap(int type)
return false;
DPRINTF(GDBMisc, "trap: PC=%#x NPC=%#x\n",
- context->regs.pc, context->regs.npc);
+ context->readPC(), context->readNextPC());
clearSingleStep();
@@ -1013,8 +1013,8 @@ RemoteGDB::trap(int type)
subcmd = hex2i(&p);
if (*p++ == ';') {
val = hex2i(&p);
- context->regs.pc = val;
- context->regs.npc = val + sizeof(MachInst);
+ context->setPC(val);
+ context->setNextPC(val + sizeof(MachInst));
}
clearSingleStep();
goto out;
@@ -1022,8 +1022,8 @@ RemoteGDB::trap(int type)
case KGDB_CONT:
if (p - data < datalen) {
val = hex2i(&p);
- context->regs.pc = val;
- context->regs.npc = val + sizeof(MachInst);
+ context->setPC(val);
+ context->setNextPC(val + sizeof(MachInst));
}
clearSingleStep();
goto out;
@@ -1032,8 +1032,8 @@ RemoteGDB::trap(int type)
subcmd = hex2i(&p);
if (*p++ == ';') {
val = hex2i(&p);
- context->regs.pc = val;
- context->regs.npc = val + sizeof(MachInst);
+ context->setPC(val);
+ context->setNextPC(val + sizeof(MachInst));
}
setSingleStep();
goto out;
@@ -1041,8 +1041,8 @@ RemoteGDB::trap(int type)
case KGDB_STEP:
if (p - data < datalen) {
val = hex2i(&p);
- context->regs.pc = val;
- context->regs.npc = val + sizeof(MachInst);
+ context->setPC(val);
+ context->setNextPC(val + sizeof(MachInst));
}
setSingleStep();
goto out;
diff --git a/cpu/base.cc b/cpu/base.cc
index 5a7ecf152..2eb5f7fd3 100644
--- a/cpu/base.cc
+++ b/cpu/base.cc
@@ -39,10 +39,16 @@
#include "cpu/profile.hh"
#include "cpu/sampler/sampler.hh"
#include "sim/param.hh"
+#include "sim/process.hh"
#include "sim/sim_events.hh"
+#include "sim/system.hh"
#include "base/trace.hh"
+#if FULL_SYSTEM
+#include "kern/kernel_stats.hh"
+#endif
+
using namespace std;
vector<BaseCPU *> BaseCPU::cpuList;
@@ -147,7 +153,10 @@ BaseCPU::BaseCPU(Params *p)
profileEvent = NULL;
if (params->profile)
profileEvent = new ProfileEvent(this, params->profile);
+
+ kernelStats = new Kernel::Statistics(system);
#endif
+
}
BaseCPU::Params::Params()
@@ -165,6 +174,10 @@ BaseCPU::enableFunctionTrace()
BaseCPU::~BaseCPU()
{
+#if FULL_SYSTEM
+ if (kernelStats)
+ delete kernelStats;
+#endif
}
void
@@ -203,6 +216,11 @@ BaseCPU::regStats()
}
} else if (size == 1)
execContexts[0]->regStats(name());
+
+#if FULL_SYSTEM
+ if (kernelStats)
+ kernelStats->regStats(name() + ".kern");
+#endif
}
@@ -216,9 +234,9 @@ BaseCPU::registerExecContexts()
if (id != -1)
id += i;
- xc->cpu_id = system->registerExecContext(xc, id);
+ xc->setCpuId(system->registerExecContext(xc, id));
#else
- xc->cpu_id = xc->process->registerExecContext(xc);
+ xc->setCpuId(xc->getProcessPtr()->registerExecContext(xc));
#endif
}
}
@@ -240,12 +258,12 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
ExecContext *oldXC = oldCPU->execContexts[i];
newXC->takeOverFrom(oldXC);
- assert(newXC->cpu_id == oldXC->cpu_id);
+ assert(newXC->readCpuId() == oldXC->readCpuId());
#if FULL_SYSTEM
- system->replaceExecContext(newXC, newXC->cpu_id);
+ system->replaceExecContext(newXC, newXC->readCpuId());
#else
- assert(newXC->process == oldXC->process);
- newXC->process->replaceExecContext(newXC, newXC->cpu_id);
+ assert(newXC->getProcessPtr() == oldXC->getProcessPtr());
+ newXC->getProcessPtr()->replaceExecContext(newXC, newXC->readCpuId());
#endif
}
@@ -255,8 +273,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
intstatus = oldCPU->intstatus;
for (int i = 0; i < execContexts.size(); ++i)
- if (execContexts[i]->profile)
- execContexts[i]->profile->clear();
+ execContexts[i]->profileClear();
if (profileEvent)
profileEvent->schedule(curTick);
@@ -274,7 +291,7 @@ BaseCPU::ProfileEvent::process()
{
for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) {
ExecContext *xc = cpu->execContexts[i];
- xc->profile->sample(xc->profileNode, xc->profilePC);
+ xc->profileSample();
}
schedule(curTick + interval);
@@ -327,6 +344,12 @@ BaseCPU::serialize(std::ostream &os)
{
SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
SERIALIZE_SCALAR(intstatus);
+
+#if FULL_SYSTEM
+ if (kernelStats)
+ kernelStats->serialize(os);
+#endif
+
}
void
@@ -334,6 +357,11 @@ BaseCPU::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
UNSERIALIZE_SCALAR(intstatus);
+
+#if FULL_SYSTEM
+ if (kernelStats)
+ kernelStats->unserialize(cp, section);
+#endif
}
#endif // FULL_SYSTEM
diff --git a/cpu/base.hh b/cpu/base.hh
index d5764d495..d9d5d2b88 100644
--- a/cpu/base.hh
+++ b/cpu/base.hh
@@ -40,6 +40,7 @@
#if FULL_SYSTEM
class System;
+namespace Kernel { class Statistics; }
#endif
class BranchPred;
@@ -234,6 +235,10 @@ class BaseCPU : public SimObject
public:
// Number of CPU cycles simulated
Stats::Scalar<> numCycles;
+
+#if FULL_SYSTEM
+ Kernel::Statistics *kernelStats;
+#endif
};
#endif // __CPU_BASE_HH__
diff --git a/cpu/base_dyn_inst.cc b/cpu/base_dyn_inst.cc
index 5905cdad2..bf7c35cad 100644
--- a/cpu/base_dyn_inst.cc
+++ b/cpu/base_dyn_inst.cc
@@ -68,7 +68,7 @@ template <class Impl>
BaseDynInst<Impl>::BaseDynInst(MachInst machInst, Addr inst_PC,
Addr pred_PC, InstSeqNum seq_num,
FullCPU *cpu)
- : staticInst(machInst), traceData(NULL), cpu(cpu), xc(cpu->xcBase())
+ : staticInst(machInst), traceData(NULL), cpu(cpu), cpuXC(cpu->cpuXCBase())
{
seqNum = seq_num;
@@ -139,14 +139,14 @@ BaseDynInst<Impl>::prefetch(Addr addr, unsigned flags)
// state.
// Generate a MemReq so we can translate the effective address.
- MemReqPtr req = new MemReq(addr, xc, 1, flags);
+ MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), 1, flags);
req->asid = asid;
// Prefetches never cause faults.
fault = NoFault;
// note this is a local, not BaseDynInst::fault
- Fault trans_fault = xc->translateDataReadReq(req);
+ Fault trans_fault = cpuXC->translateDataReadReq(req);
if (trans_fault == NoFault && !(req->flags & UNCACHEABLE)) {
// It's a valid address to cacheable space. Record key MemReq
@@ -184,10 +184,10 @@ BaseDynInst<Impl>::writeHint(Addr addr, int size, unsigned flags)
// will casue a TLB miss trap if necessary... not sure whether
// that's the best thing to do or not. We don't really need the
// MemReq otherwise, since wh64 has no functional effect.
- MemReqPtr req = new MemReq(addr, xc, size, flags);
+ MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), size, flags);
req->asid = asid;
- fault = xc->translateDataWriteReq(req);
+ fault = cpuXC->translateDataWriteReq(req);
if (fault == NoFault && !(req->flags & UNCACHEABLE)) {
// Record key MemReq parameters so we can generate another one
@@ -212,18 +212,18 @@ template <class Impl>
Fault
BaseDynInst<Impl>::copySrcTranslate(Addr src)
{
- MemReqPtr req = new MemReq(src, xc, 64);
+ MemReqPtr req = new MemReq(src, cpuXC->getProxy(), 64);
req->asid = asid;
// translate to physical address
- Fault fault = xc->translateDataReadReq(req);
+ Fault fault = cpuXC->translateDataReadReq(req);
if (fault == NoFault) {
- xc->copySrcAddr = src;
- xc->copySrcPhysAddr = req->paddr;
+ cpuXC->copySrcAddr = src;
+ cpuXC->copySrcPhysAddr = req->paddr;
} else {
- xc->copySrcAddr = 0;
- xc->copySrcPhysAddr = 0;
+ cpuXC->copySrcAddr = 0;
+ cpuXC->copySrcPhysAddr = 0;
}
return fault;
}
@@ -236,18 +236,18 @@ Fault
BaseDynInst<Impl>::copy(Addr dest)
{
uint8_t data[64];
- FunctionalMemory *mem = xc->mem;
- assert(xc->copySrcPhysAddr || xc->misspeculating());
- MemReqPtr req = new MemReq(dest, xc, 64);
+ FunctionalMemory *mem = cpuXC->mem;
+ assert(cpuXC->copySrcPhysAddr || cpuXC->misspeculating());
+ MemReqPtr req = new MemReq(dest, cpuXC->getProxy(), 64);
req->asid = asid;
// translate to physical address
- Fault fault = xc->translateDataWriteReq(req);
+ Fault fault = cpuXC->translateDataWriteReq(req);
if (fault == NoFault) {
Addr dest_addr = req->paddr;
// Need to read straight from memory since we have more than 8 bytes.
- req->paddr = xc->copySrcPhysAddr;
+ req->paddr = cpuXC->copySrcPhysAddr;
mem->read(req, data);
req->paddr = dest_addr;
mem->write(req, data);
diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh
index e94c44151..3a7852f79 100644
--- a/cpu/base_dyn_inst.hh
+++ b/cpu/base_dyn_inst.hh
@@ -145,7 +145,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
FullCPU *cpu;
/** Pointer to the exec context. Will not exist in the final version. */
- ExecContext *xc;
+ CPUExecContext *cpuXC;
/** The kind of fault this instruction has generated. */
Fault fault;
@@ -406,7 +406,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** Returns the exec context.
* @todo: Remove this once the ExecContext is no longer used.
*/
- ExecContext *xcBase() { return xc; }
+ ExecContext *xcBase() { return cpuXC->getProxy(); }
private:
/** Instruction effective address.
@@ -444,7 +444,7 @@ template<class T>
inline Fault
BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags)
{
- MemReqPtr req = new MemReq(addr, xc, sizeof(T), flags);
+ MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), sizeof(T), flags);
req->asid = asid;
fault = cpu->translateDataReadReq(req);
@@ -492,7 +492,7 @@ BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res)
traceData->setData(data);
}
- MemReqPtr req = new MemReq(addr, xc, sizeof(T), flags);
+ MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), sizeof(T), flags);
req->asid = asid;
diff --git a/cpu/exec_context.cc b/cpu/cpu_exec_context.cc
index e0ab1007f..b7238e73a 100644
--- a/cpu/exec_context.cc
+++ b/cpu/cpu_exec_context.cc
@@ -29,6 +29,7 @@
#include <string>
#include "cpu/base.hh"
+#include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh"
#if FULL_SYSTEM
@@ -50,23 +51,23 @@ using namespace std;
// constructor
#if FULL_SYSTEM
-ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
+CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
AlphaITB *_itb, AlphaDTB *_dtb,
FunctionalMemory *_mem)
: _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
cpu_id(-1), lastActivate(0), lastSuspend(0), mem(_mem), itb(_itb),
dtb(_dtb), system(_sys), memctrl(_sys->memctrl), physmem(_sys->physmem),
- kernelBinning(system->kernelBinning), bin(kernelBinning->bin),
- fnbin(kernelBinning->fnbin), profile(NULL), quiesceEvent(this),
- func_exe_inst(0), storeCondFailures(0)
+ profile(NULL), quiesceEvent(this), func_exe_inst(0), storeCondFailures(0)
{
- kernelStats = new Kernel::Statistics(this);
+ proxy = new ProxyExecContext<CPUExecContext>(this);
+
memset(&regs, 0, sizeof(RegFile));
if (cpu->params->profile) {
profile = new FunctionProfile(system->kernelSymtab);
Callback *cb =
- new MakeCallback<ExecContext, &ExecContext::dumpFuncProfile>(this);
+ new MakeCallback<CPUExecContext,
+ &CPUExecContext::dumpFuncProfile>(this);
registerExitCallback(cb);
}
@@ -77,7 +78,7 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
profilePC = 3;
}
#else
-ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
+CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
Process *_process, int _asid)
: _status(ExecContext::Unallocated),
cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0),
@@ -85,74 +86,100 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
func_exe_inst(0), storeCondFailures(0)
{
memset(&regs, 0, sizeof(RegFile));
+ proxy = new ProxyExecContext<CPUExecContext>(this);
}
-ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
+CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
FunctionalMemory *_mem, int _asid)
: cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid),
func_exe_inst(0), storeCondFailures(0)
{
memset(&regs, 0, sizeof(RegFile));
+ proxy = new ProxyExecContext<CPUExecContext>(this);
}
-#endif
-ExecContext::~ExecContext()
+CPUExecContext::CPUExecContext(RegFile *regFile)
+ : cpu(NULL), thread_num(-1), process(NULL), mem(NULL), asid(-1),
+ func_exe_inst(0), storeCondFailures(0)
{
-#if FULL_SYSTEM
- delete kernelStats;
+ regs = *regFile;
+ proxy = new ProxyExecContext<CPUExecContext>(this);
+}
+
#endif
+
+CPUExecContext::~CPUExecContext()
+{
+ delete proxy;
}
#if FULL_SYSTEM
void
-ExecContext::dumpFuncProfile()
+CPUExecContext::dumpFuncProfile()
{
std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
- profile->dump(this, *os);
+ profile->dump(proxy, *os);
}
-ExecContext::EndQuiesceEvent::EndQuiesceEvent(ExecContext *_xc)
- : Event(&mainEventQueue), xc(_xc)
+CPUExecContext::EndQuiesceEvent::EndQuiesceEvent(CPUExecContext *_cpuXC)
+ : Event(&mainEventQueue), cpuXC(_cpuXC)
{
}
void
-ExecContext::EndQuiesceEvent::process()
+CPUExecContext::EndQuiesceEvent::process()
{
- xc->activate();
+ cpuXC->activate();
}
const char*
-ExecContext::EndQuiesceEvent::description()
+CPUExecContext::EndQuiesceEvent::description()
{
return "End Quiesce Event.";
}
+
+void
+CPUExecContext::profileClear()
+{
+ if (profile)
+ profile->clear();
+}
+
+void
+CPUExecContext::profileSample()
+{
+ if (profile)
+ profile->sample(profileNode, profilePC);
+}
+
#endif
void
-ExecContext::takeOverFrom(ExecContext *oldContext)
+CPUExecContext::takeOverFrom(ExecContext *oldContext)
{
// some things should already be set up
- assert(mem == oldContext->mem);
+ assert(mem == oldContext->getMemPtr());
#if FULL_SYSTEM
- assert(system == oldContext->system);
+ assert(system == oldContext->getSystemPtr());
#else
- assert(process == oldContext->process);
+ assert(process == oldContext->getProcessPtr());
#endif
// copy over functional state
- _status = oldContext->_status;
- regs = oldContext->regs;
- cpu_id = oldContext->cpu_id;
- func_exe_inst = oldContext->func_exe_inst;
+ _status = oldContext->status();
+ copyArchRegs(oldContext);
+ cpu_id = oldContext->readCpuId();
+#if !FULL_SYSTEM
+ func_exe_inst = oldContext->readFuncExeInst();
+#endif
storeCondFailures = 0;
- oldContext->_status = ExecContext::Unallocated;
+ oldContext->setStatus(ExecContext::Unallocated);
}
void
-ExecContext::serialize(ostream &os)
+CPUExecContext::serialize(ostream &os)
{
SERIALIZE_ENUM(_status);
regs.serialize(os);
@@ -165,14 +192,13 @@ ExecContext::serialize(ostream &os)
if (quiesceEvent.scheduled())
quiesceEndTick = quiesceEvent.when();
SERIALIZE_SCALAR(quiesceEndTick);
- kernelStats->serialize(os);
#endif
}
void
-ExecContext::unserialize(Checkpoint *cp, const std::string &section)
+CPUExecContext::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ENUM(_status);
regs.unserialize(cp, section);
@@ -185,28 +211,26 @@ ExecContext::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(quiesceEndTick);
if (quiesceEndTick)
quiesceEvent.schedule(quiesceEndTick);
-
- kernelStats->unserialize(cp, section);
#endif
}
void
-ExecContext::activate(int delay)
+CPUExecContext::activate(int delay)
{
- if (status() == Active)
+ if (status() == ExecContext::Active)
return;
lastActivate = curTick;
- _status = Active;
+ _status = ExecContext::Active;
cpu->activateContext(thread_num, delay);
}
void
-ExecContext::suspend()
+CPUExecContext::suspend()
{
- if (status() == Suspended)
+ if (status() == ExecContext::Suspended)
return;
lastActivate = curTick;
@@ -215,41 +239,60 @@ ExecContext::suspend()
#if FULL_SYSTEM
// Don't change the status from active if there are pending interrupts
if (cpu->check_interrupts()) {
- assert(status() == Active);
+ assert(status() == ExecContext::Active);
return;
}
#endif
*/
- _status = Suspended;
+ _status = ExecContext::Suspended;
cpu->suspendContext(thread_num);
}
void
-ExecContext::deallocate()
+CPUExecContext::deallocate()
{
- if (status() == Unallocated)
+ if (status() == ExecContext::Unallocated)
return;
- _status = Unallocated;
+ _status = ExecContext::Unallocated;
cpu->deallocateContext(thread_num);
}
void
-ExecContext::halt()
+CPUExecContext::halt()
{
- if (status() == Halted)
+ if (status() == ExecContext::Halted)
return;
- _status = Halted;
+ _status = ExecContext::Halted;
cpu->haltContext(thread_num);
}
void
-ExecContext::regStats(const string &name)
+CPUExecContext::regStats(const string &name)
{
-#if FULL_SYSTEM
- kernelStats->regStats(name + ".kern");
-#endif
+}
+
+void
+CPUExecContext::copyArchRegs(ExecContext *xc)
+{
+ // First loop through the integer registers.
+ for (int i = 0; i < AlphaISA::NumIntRegs; ++i) {
+ setIntReg(i, xc->readIntReg(i));
+ }
+
+ // Then loop through the floating point registers.
+ for (int i = 0; i < AlphaISA::NumFloatRegs; ++i) {
+ setFloatRegDouble(i, xc->readFloatRegDouble(i));
+ setFloatRegInt(i, xc->readFloatRegInt(i));
+ }
+
+ // Copy misc. registers
+ regs.miscRegs.copyMiscRegs(xc);
+
+ // Lastly copy PC/NPC
+ setPC(xc->readPC());
+ setNextPC(xc->readNextPC());
}
diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh
new file mode 100644
index 000000000..beaf67352
--- /dev/null
+++ b/cpu/cpu_exec_context.hh
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2001-2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __CPU_CPU_EXEC_CONTEXT_HH__
+#define __CPU_CPU_EXEC_CONTEXT_HH__
+
+#include "arch/isa_traits.hh"
+#include "config/full_system.hh"
+#include "cpu/exec_context.hh"
+#include "mem/functional/functional.hh"
+#include "mem/mem_req.hh"
+#include "sim/byteswap.hh"
+#include "sim/eventq.hh"
+#include "sim/host.hh"
+#include "sim/serialize.hh"
+
+// forward declaration: see functional_memory.hh
+class FunctionalMemory;
+class PhysicalMemory;
+class BaseCPU;
+
+#if FULL_SYSTEM
+
+#include "sim/system.hh"
+#include "arch/tlb.hh"
+
+class FunctionProfile;
+class ProfileNode;
+class MemoryController;
+
+#else // !FULL_SYSTEM
+
+#include "sim/process.hh"
+
+#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.
+//
+
+class CPUExecContext
+{
+ protected:
+ typedef TheISA::RegFile RegFile;
+ typedef TheISA::MachInst MachInst;
+ typedef TheISA::MiscRegFile MiscRegFile;
+ typedef TheISA::MiscReg MiscReg;
+ public:
+ typedef ExecContext::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
+ BaseCPU *cpu;
+
+ ProxyExecContext<CPUExecContext> *proxy;
+
+ // 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;
+
+#if FULL_SYSTEM
+ FunctionalMemory *mem;
+ AlphaITB *itb;
+ AlphaDTB *dtb;
+ System *system;
+
+ // the following two fields are redundant, since we can always
+ // look them up through the system pointer, but we'll leave them
+ // here for now for convenience
+ MemoryController *memctrl;
+ PhysicalMemory *physmem;
+
+ FunctionProfile *profile;
+ ProfileNode *profileNode;
+ Addr profilePC;
+ void dumpFuncProfile();
+
+ /** Event for timing out quiesce instruction */
+ struct EndQuiesceEvent : public Event
+ {
+ /** A pointer to the execution context that is quiesced */
+ CPUExecContext *cpuXC;
+
+ EndQuiesceEvent(CPUExecContext *_cpuXC);
+
+ /** Event process to occur at interrupt*/
+ virtual void process();
+
+ /** Event description */
+ virtual const char *description();
+ };
+ EndQuiesceEvent quiesceEvent;
+
+ Event *getQuiesceEvent() { return &quiesceEvent; }
+
+ Tick readLastActivate() { return lastActivate; }
+
+ Tick readLastSuspend() { return lastSuspend; }
+
+ void profileClear();
+
+ void profileSample();
+
+#else
+ Process *process;
+
+ FunctionalMemory *mem; // functional storage for process address space
+
+ // 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
+#if FULL_SYSTEM
+ CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
+ AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem);
+#else
+ CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
+ CPUExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
+ int _asid);
+ // Constructor to use XC to pass reg file around. Not used for anything
+ // else.
+ CPUExecContext(RegFile *regFile);
+#endif
+ virtual ~CPUExecContext();
+
+ virtual void takeOverFrom(ExecContext *oldContext);
+
+ void regStats(const std::string &name);
+
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ BaseCPU *getCpuPtr() { return cpu; }
+
+ ExecContext *getProxy() { return proxy; }
+
+ int getThreadNum() { return thread_num; }
+
+#if FULL_SYSTEM
+ System *getSystemPtr() { return system; }
+
+ PhysicalMemory *getPhysMemPtr() { return physmem; }
+
+ AlphaITB *getITBPtr() { return itb; }
+
+ AlphaDTB *getDTBPtr() { return dtb; }
+
+ bool validInstAddr(Addr addr) { return true; }
+ bool validDataAddr(Addr addr) { return true; }
+ int getInstAsid() { return regs.instAsid(); }
+ int getDataAsid() { return regs.dataAsid(); }
+
+ Fault translateInstReq(MemReqPtr &req)
+ {
+ return itb->translate(req);
+ }
+
+ Fault translateDataReadReq(MemReqPtr &req)
+ {
+ return dtb->translate(req, false);
+ }
+
+ Fault translateDataWriteReq(MemReqPtr &req)
+ {
+ return dtb->translate(req, true);
+ }
+
+#else
+ Process *getProcessPtr() { return process; }
+
+ bool validInstAddr(Addr addr)
+ { return process->validInstAddr(addr); }
+
+ bool validDataAddr(Addr addr)
+ { return process->validDataAddr(addr); }
+
+ int getInstAsid() { return asid; }
+ int getDataAsid() { return asid; }
+
+ Fault dummyTranslation(MemReqPtr &req)
+ {
+#if 0
+ assert((req->vaddr >> 48 & 0xffff) == 0);
+#endif
+
+ // put the asid in the upper 16 bits of the paddr
+ req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
+ req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
+ return NoFault;
+ }
+ Fault translateInstReq(MemReqPtr &req)
+ {
+ return dummyTranslation(req);
+ }
+ Fault translateDataReadReq(MemReqPtr &req)
+ {
+ return dummyTranslation(req);
+ }
+ Fault translateDataWriteReq(MemReqPtr &req)
+ {
+ return dummyTranslation(req);
+ }
+
+#endif
+
+ template <class T>
+ Fault read(MemReqPtr &req, T &data)
+ {
+#if FULL_SYSTEM && defined(TARGET_ALPHA)
+ if (req->flags & LOCKED) {
+ req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
+ req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
+ }
+#endif
+
+ Fault error;
+ error = mem->read(req, data);
+ data = LittleEndianGuest::gtoh(data);
+ return error;
+ }
+
+ template <class T>
+ Fault write(MemReqPtr &req, T &data)
+ {
+#if FULL_SYSTEM && defined(TARGET_ALPHA)
+ ExecContext *xc;
+
+ // If this is a store conditional, act appropriately
+ if (req->flags & LOCKED) {
+ xc = req->xc;
+
+ if (req->flags & UNCACHEABLE) {
+ // Don't update result register (see stq_c in isa_desc)
+ req->result = 2;
+ xc->setStCondFailures(0);//Needed? [RGD]
+ } else {
+ bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag);
+ Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag);
+ req->result = lock_flag;
+ if (!lock_flag ||
+ ((lock_addr & ~0xf) != (req->paddr & ~0xf))) {
+ xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
+ xc->setStCondFailures(xc->readStCondFailures() + 1);
+ if (((xc->readStCondFailures()) % 100000) == 0) {
+ std::cerr << "Warning: "
+ << xc->readStCondFailures()
+ << " consecutive store conditional failures "
+ << "on cpu " << req->xc->readCpuId()
+ << std::endl;
+ }
+ return NoFault;
+ }
+ else xc->setStCondFailures(0);
+ }
+ }
+
+ // Need to clear any locked flags on other proccessors for
+ // this address. Only do this for succsful Store Conditionals
+ // and all other stores (WH64?). Unsuccessful Store
+ // Conditionals would have returned above, and wouldn't fall
+ // through.
+ for (int i = 0; i < system->execContexts.size(); i++){
+ xc = system->execContexts[i];
+ if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
+ (req->paddr & ~0xf)) {
+ xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
+ }
+ }
+
+#endif
+ return mem->write(req, (T)LittleEndianGuest::htog(data));
+ }
+
+ virtual bool misspeculating();
+
+
+ MachInst getInst() { return inst; }
+
+ void setInst(MachInst new_inst)
+ {
+ inst = new_inst;
+ }
+
+ Fault instRead(MemReqPtr &req)
+ {
+ return mem->read(req, inst);
+ }
+
+ void setCpuId(int id) { cpu_id = id; }
+
+ int readCpuId() { return cpu_id; }
+
+ FunctionalMemory *getMemPtr() { return mem; }
+
+ void copyArchRegs(ExecContext *xc);
+
+ //
+ // New accessors for new decoder.
+ //
+ uint64_t readIntReg(int reg_idx)
+ {
+ return regs.intRegFile[reg_idx];
+ }
+
+ float readFloatRegSingle(int reg_idx)
+ {
+ return (float)regs.floatRegFile.d[reg_idx];
+ }
+
+ double readFloatRegDouble(int reg_idx)
+ {
+ return regs.floatRegFile.d[reg_idx];
+ }
+
+ uint64_t readFloatRegInt(int reg_idx)
+ {
+ return regs.floatRegFile.q[reg_idx];
+ }
+
+ void setIntReg(int reg_idx, uint64_t val)
+ {
+ regs.intRegFile[reg_idx] = val;
+ }
+
+ void setFloatRegSingle(int reg_idx, float val)
+ {
+ regs.floatRegFile.d[reg_idx] = (double)val;
+ }
+
+ void setFloatRegDouble(int reg_idx, double val)
+ {
+ regs.floatRegFile.d[reg_idx] = val;
+ }
+
+ void setFloatRegInt(int reg_idx, uint64_t val)
+ {
+ regs.floatRegFile.q[reg_idx] = val;
+ }
+
+ uint64_t readPC()
+ {
+ return regs.pc;
+ }
+
+ void setPC(uint64_t val)
+ {
+ regs.pc = val;
+ }
+
+ uint64_t readNextPC()
+ {
+ return regs.npc;
+ }
+
+ void setNextPC(uint64_t val)
+ {
+ regs.npc = val;
+ }
+
+ uint64_t readNextNPC()
+ {
+ return regs.nnpc;
+ }
+
+ void setNextNPC(uint64_t val)
+ {
+ regs.nnpc = val;
+ }
+
+
+ MiscReg readMiscReg(int misc_reg)
+ {
+ return regs.miscRegs.readReg(misc_reg);
+ }
+
+ MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
+ {
+ return regs.miscRegs.readRegWithEffect(misc_reg, fault, proxy);
+ }
+
+ Fault setMiscReg(int misc_reg, const MiscReg &val)
+ {
+ return regs.miscRegs.setReg(misc_reg, val);
+ }
+
+ Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
+ {
+ return regs.miscRegs.setRegWithEffect(misc_reg, val, proxy);
+ }
+
+ unsigned readStCondFailures() { return storeCondFailures; }
+
+ void setStCondFailures(unsigned sc_failures)
+ { storeCondFailures = sc_failures; }
+
+ void clearArchRegs() { memset(&regs, 0, sizeof(regs)); }
+
+#if FULL_SYSTEM
+ int readIntrFlag() { return regs.intrflag; }
+ void setIntrFlag(int val) { regs.intrflag = val; }
+ Fault hwrei();
+ bool inPalMode() { return AlphaISA::PcPAL(regs.pc); }
+ bool simPalCheck(int palFunc);
+#endif
+
+#if !FULL_SYSTEM
+ TheISA::IntReg getSyscallArg(int i)
+ {
+ return regs.intRegFile[TheISA::ArgumentReg0 + i];
+ }
+
+ // used to shift args for indirect syscall
+ void setSyscallArg(int i, TheISA::IntReg val)
+ {
+ regs.intRegFile[TheISA::ArgumentReg0 + i] = val;
+ }
+
+ void setSyscallReturn(SyscallReturn return_value)
+ {
+ TheISA::setSyscallReturn(return_value, &regs);
+ }
+
+ void syscall()
+ {
+ process->syscall(proxy);
+ }
+
+ Counter readFuncExeInst() { return func_exe_inst; }
+
+ void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; }
+#endif
+};
+
+
+// for non-speculative execution context, spec_mode is always false
+inline bool
+CPUExecContext::misspeculating()
+{
+ return false;
+}
+
+#endif // __CPU_CPU_EXEC_CONTEXT_HH__
diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh
index 97bfc5f0d..2b6c41bd7 100644
--- a/cpu/exec_context.hh
+++ b/cpu/exec_context.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001-2006 The Regents of The University of Michigan
+ * Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,47 +30,30 @@
#define __CPU_EXEC_CONTEXT_HH__
#include "config/full_system.hh"
-#include "mem/functional/functional.hh"
#include "mem/mem_req.hh"
-#include "sim/eventq.hh"
+#include "sim/faults.hh"
#include "sim/host.hh"
#include "sim/serialize.hh"
-#include "arch/isa_traits.hh"
-//#include "arch/isa_registers.hh"
#include "sim/byteswap.hh"
// forward declaration: see functional_memory.hh
+// @todo: Figure out a more architecture independent way to obtain the ITB and
+// DTB pointers.
+class AlphaDTB;
+class AlphaITB;
+class BaseCPU;
+class Event;
class FunctionalMemory;
class PhysicalMemory;
-class BaseCPU;
-
-#if FULL_SYSTEM
-
-#include "sim/system.hh"
-#include "arch/tlb.hh"
-
-class FunctionProfile;
-class ProfileNode;
-class MemoryController;
-namespace Kernel { class Binning; class Statistics; }
-
-#else // !FULL_SYSTEM
-
-#include "sim/process.hh"
-
-#endif // FULL_SYSTEM
-
-//
-// The ExecContext object represents a functional context for
-// instruction execution. It incorporates everything required for
-// architecture-level functional simulation of a single thread.
-//
+class Process;
+class System;
class ExecContext
{
protected:
typedef TheISA::RegFile RegFile;
typedef TheISA::MachInst MachInst;
+ typedef TheISA::IntReg IntReg;
typedef TheISA::MiscRegFile MiscRegFile;
typedef TheISA::MiscReg MiscReg;
public:
@@ -87,7 +70,7 @@ class ExecContext
Active,
/// Temporarily inactive. Entered while waiting for
- /// initialization,synchronization, etc.
+ /// synchronization, etc.
Suspended,
/// Permanently shut down. Entered when target executes
@@ -96,390 +79,339 @@ class ExecContext
Halted
};
- private:
- Status _status;
+ virtual ~ExecContext() { };
- public:
- Status status() const { return _status; }
+ virtual BaseCPU *getCpuPtr() = 0;
+
+ virtual void setCpuId(int id) = 0;
+
+ virtual int readCpuId() = 0;
+
+ virtual FunctionalMemory *getMemPtr() = 0;
+
+#if FULL_SYSTEM
+ virtual System *getSystemPtr() = 0;
+
+ virtual PhysicalMemory *getPhysMemPtr() = 0;
- void setStatus(Status newStatus) { _status = newStatus; }
+ virtual AlphaITB *getITBPtr() = 0;
+
+ virtual AlphaDTB * getDTBPtr() = 0;
+#else
+ virtual Process *getProcessPtr() = 0;
+#endif
+
+ virtual Status status() const = 0;
+
+ virtual void setStatus(Status new_status) = 0;
/// Set the status to Active. Optional delay indicates number of
/// cycles to wait before beginning execution.
- void activate(int delay = 1);
+ virtual void activate(int delay = 1) = 0;
/// Set the status to Suspended.
- void suspend();
+ virtual void suspend() = 0;
/// Set the status to Unallocated.
- void deallocate();
+ virtual void deallocate() = 0;
/// Set the status to Halted.
- void halt();
+ virtual void halt() = 0;
- public:
- RegFile regs; // correct-path register context
+#if FULL_SYSTEM
+ virtual void dumpFuncProfile() = 0;
+#endif
- // pointer to CPU associated with this context
- BaseCPU *cpu;
+ virtual void takeOverFrom(ExecContext *old_context) = 0;
- // Current instruction
- MachInst inst;
+ virtual void regStats(const std::string &name) = 0;
- // Index of hardware thread context on the CPU that this represents.
- int thread_num;
+ virtual void serialize(std::ostream &os) = 0;
+ virtual void unserialize(Checkpoint *cp, const std::string &section) = 0;
- // 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;
+#if FULL_SYSTEM
+ virtual Event *getQuiesceEvent() = 0;
- Tick lastActivate;
- Tick lastSuspend;
+ // Not necessarily the best location for these...
+ // Having an extra function just to read these is obnoxious
+ virtual Tick readLastActivate() = 0;
+ virtual Tick readLastSuspend() = 0;
-#if FULL_SYSTEM
- FunctionalMemory *mem;
- AlphaITB *itb;
- AlphaDTB *dtb;
- System *system;
-
- // the following two fields are redundant, since we can always
- // look them up through the system pointer, but we'll leave them
- // here for now for convenience
- MemoryController *memctrl;
- PhysicalMemory *physmem;
-
- Kernel::Binning *kernelBinning;
- Kernel::Statistics *kernelStats;
- bool bin;
- bool fnbin;
-
- FunctionProfile *profile;
- ProfileNode *profileNode;
- Addr profilePC;
- void dumpFuncProfile();
-
- /** Event for timing out quiesce instruction */
- struct EndQuiesceEvent : public Event
- {
- /** A pointer to the execution context that is quiesced */
- ExecContext *xc;
+ virtual void profileClear() = 0;
+ virtual void profileSample() = 0;
+#endif
- EndQuiesceEvent(ExecContext *_xc);
+ virtual int getThreadNum() = 0;
- /** Event process to occur at interrupt*/
- virtual void process();
+ virtual bool validInstAddr(Addr addr) = 0;
+ virtual bool validDataAddr(Addr addr) = 0;
+ virtual int getInstAsid() = 0;
+ virtual int getDataAsid() = 0;
- /** Event description */
- virtual const char *description();
- };
- EndQuiesceEvent quiesceEvent;
+ virtual Fault translateInstReq(MemReqPtr &req) = 0;
-#else
- Process *process;
+ virtual Fault translateDataReadReq(MemReqPtr &req) = 0;
- FunctionalMemory *mem; // functional storage for process address space
+ virtual Fault translateDataWriteReq(MemReqPtr &req) = 0;
- // 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;
+ // Also somewhat obnoxious. Really only used for the TLB fault.
+ // However, may be quite useful in SPARC.
+ virtual TheISA::MachInst getInst() = 0;
-#endif
+ virtual void copyArchRegs(ExecContext *xc) = 0;
- /**
- * 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;
+ virtual void clearArchRegs() = 0;
//
- // Count failed store conditionals so we can warn of apparent
- // application deadlock situations.
- unsigned storeCondFailures;
+ // New accessors for new decoder.
+ //
+ virtual uint64_t readIntReg(int reg_idx) = 0;
- // constructor: initialize context from given process structure
-#if FULL_SYSTEM
- ExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
- AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem);
-#else
- ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
- ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
- int _asid);
-#endif
- virtual ~ExecContext();
+ virtual float readFloatRegSingle(int reg_idx) = 0;
+
+ virtual double readFloatRegDouble(int reg_idx) = 0;
+
+ virtual uint64_t readFloatRegInt(int reg_idx) = 0;
+
+ virtual void setIntReg(int reg_idx, uint64_t val) = 0;
+
+ virtual void setFloatRegSingle(int reg_idx, float val) = 0;
+
+ virtual void setFloatRegDouble(int reg_idx, double val) = 0;
+
+ virtual void setFloatRegInt(int reg_idx, uint64_t val) = 0;
+
+ virtual uint64_t readPC() = 0;
- virtual void takeOverFrom(ExecContext *oldContext);
+ virtual void setPC(uint64_t val) = 0;
- void regStats(const std::string &name);
+ virtual uint64_t readNextPC() = 0;
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ virtual void setNextPC(uint64_t val) = 0;
+
+ virtual MiscReg readMiscReg(int misc_reg) = 0;
+
+ virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) = 0;
+
+ virtual Fault setMiscReg(int misc_reg, const MiscReg &val) = 0;
+
+ virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0;
+
+ // Also not necessarily the best location for these two. Hopefully will go
+ // away once we decide upon where st cond failures goes.
+ virtual unsigned readStCondFailures() = 0;
+
+ virtual void setStCondFailures(unsigned sc_failures) = 0;
#if FULL_SYSTEM
- bool validInstAddr(Addr addr) { return true; }
- bool validDataAddr(Addr addr) { return true; }
- int getInstAsid() { return regs.instAsid(); }
- int getDataAsid() { return regs.dataAsid(); }
+ virtual int readIntrFlag() = 0;
+ virtual void setIntrFlag(int val) = 0;
+ virtual Fault hwrei() = 0;
+ virtual bool inPalMode() = 0;
+ virtual bool simPalCheck(int palFunc) = 0;
+#endif
- Fault translateInstReq(MemReqPtr &req)
- {
- return itb->translate(req);
- }
+ // Only really makes sense for old CPU model. Still could be useful though.
+ virtual bool misspeculating() = 0;
- Fault translateDataReadReq(MemReqPtr &req)
- {
- return dtb->translate(req, false);
- }
+#if !FULL_SYSTEM
+ virtual IntReg getSyscallArg(int i) = 0;
- Fault translateDataWriteReq(MemReqPtr &req)
- {
- return dtb->translate(req, true);
- }
+ // used to shift args for indirect syscall
+ virtual void setSyscallArg(int i, IntReg val) = 0;
-#else
- bool validInstAddr(Addr addr)
- { return process->validInstAddr(addr); }
+ virtual void setSyscallReturn(SyscallReturn return_value) = 0;
- bool validDataAddr(Addr addr)
- { return process->validDataAddr(addr); }
+ virtual void syscall() = 0;
- int getInstAsid() { return asid; }
- int getDataAsid() { return asid; }
+ // Same with st cond failures.
+ virtual Counter readFuncExeInst() = 0;
- Fault dummyTranslation(MemReqPtr &req)
- {
-#if 0
- assert((req->vaddr >> 48 & 0xffff) == 0);
+ virtual void setFuncExeInst(Counter new_val) = 0;
#endif
+};
- // put the asid in the upper 16 bits of the paddr
- req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
- req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
- return NoFault;
- }
- Fault translateInstReq(MemReqPtr &req)
- {
- return dummyTranslation(req);
- }
- Fault translateDataReadReq(MemReqPtr &req)
- {
- return dummyTranslation(req);
- }
- Fault translateDataWriteReq(MemReqPtr &req)
- {
- return dummyTranslation(req);
- }
+template <class XC>
+class ProxyExecContext : public ExecContext
+{
+ public:
+ ProxyExecContext(XC *actual_xc)
+ { actualXC = actual_xc; }
+ private:
+ XC *actualXC;
+
+ public:
+
+ BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); }
+
+ void setCpuId(int id) { actualXC->setCpuId(id); }
+
+ int readCpuId() { return actualXC->readCpuId(); }
+
+ FunctionalMemory *getMemPtr() { return actualXC->getMemPtr(); }
+
+#if FULL_SYSTEM
+ System *getSystemPtr() { return actualXC->getSystemPtr(); }
+
+ PhysicalMemory *getPhysMemPtr() { return actualXC->getPhysMemPtr(); }
+
+ AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
+
+ AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
+#else
+ Process *getProcessPtr() { return actualXC->getProcessPtr(); }
#endif
- template <class T>
- Fault read(MemReqPtr &req, T &data)
- {
-#if FULL_SYSTEM && defined(TARGET_ALPHA)
- if (req->flags & LOCKED) {
- MiscRegFile *cregs = &req->xc->regs.miscRegs;
- cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr);
- cregs->setReg(TheISA::Lock_Flag_DepTag, true);
- }
+ Status status() const { return actualXC->status(); }
+
+ void setStatus(Status new_status) { actualXC->setStatus(new_status); }
+
+ /// Set the status to Active. Optional delay indicates number of
+ /// cycles to wait before beginning execution.
+ void activate(int delay = 1) { actualXC->activate(delay); }
+
+ /// Set the status to Suspended.
+ void suspend() { actualXC->suspend(); }
+
+ /// Set the status to Unallocated.
+ void deallocate() { actualXC->deallocate(); }
+
+ /// Set the status to Halted.
+ void halt() { actualXC->halt(); }
+
+#if FULL_SYSTEM
+ void dumpFuncProfile() { actualXC->dumpFuncProfile(); }
#endif
- Fault error;
- error = mem->read(req, data);
- data = LittleEndianGuest::gtoh(data);
- return error;
- }
+ void takeOverFrom(ExecContext *oldContext)
+ { actualXC->takeOverFrom(oldContext); }
- template <class T>
- Fault write(MemReqPtr &req, T &data)
- {
-#if FULL_SYSTEM && defined(TARGET_ALPHA)
-
- MiscRegFile *cregs;
-
- // If this is a store conditional, act appropriately
- if (req->flags & LOCKED) {
- cregs = &req->xc->regs.miscRegs;
-
- if (req->flags & UNCACHEABLE) {
- // Don't update result register (see stq_c in isa_desc)
- req->result = 2;
- req->xc->storeCondFailures = 0;//Needed? [RGD]
- } else {
- bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag);
- Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag);
- req->result = lock_flag;
- if (!lock_flag ||
- ((lock_addr & ~0xf) != (req->paddr & ~0xf))) {
- cregs->setReg(TheISA::Lock_Flag_DepTag, false);
- if (((++req->xc->storeCondFailures) % 100000) == 0) {
- std::cerr << "Warning: "
- << req->xc->storeCondFailures
- << " consecutive store conditional failures "
- << "on cpu " << req->xc->cpu_id
- << std::endl;
- }
- return NoFault;
- }
- else req->xc->storeCondFailures = 0;
- }
- }
-
- // Need to clear any locked flags on other proccessors for
- // this address. Only do this for succsful Store Conditionals
- // and all other stores (WH64?). Unsuccessful Store
- // Conditionals would have returned above, and wouldn't fall
- // through.
- for (int i = 0; i < system->execContexts.size(); i++){
- cregs = &system->execContexts[i]->regs.miscRegs;
- if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
- (req->paddr & ~0xf)) {
- cregs->setReg(TheISA::Lock_Flag_DepTag, false);
- }
- }
+ void regStats(const std::string &name) { actualXC->regStats(name); }
+
+ void serialize(std::ostream &os) { actualXC->serialize(os); }
+ void unserialize(Checkpoint *cp, const std::string &section)
+ { actualXC->unserialize(cp, section); }
+#if FULL_SYSTEM
+ Event *getQuiesceEvent() { return actualXC->getQuiesceEvent(); }
+
+ Tick readLastActivate() { return actualXC->readLastActivate(); }
+ Tick readLastSuspend() { return actualXC->readLastSuspend(); }
+
+ void profileClear() { return actualXC->profileClear(); }
+ void profileSample() { return actualXC->profileSample(); }
#endif
- return mem->write(req, (T)LittleEndianGuest::htog(data));
- }
- virtual bool misspeculating();
+ int getThreadNum() { return actualXC->getThreadNum(); }
+ bool validInstAddr(Addr addr) { return actualXC->validInstAddr(addr); }
+ bool validDataAddr(Addr addr) { return actualXC->validDataAddr(addr); }
+ int getInstAsid() { return actualXC->getInstAsid(); }
+ int getDataAsid() { return actualXC->getDataAsid(); }
- MachInst getInst() { return inst; }
+ Fault translateInstReq(MemReqPtr &req)
+ { return actualXC->translateInstReq(req); }
- void setInst(MachInst new_inst)
- {
- inst = new_inst;
- }
+ Fault translateDataReadReq(MemReqPtr &req)
+ { return actualXC->translateDataReadReq(req); }
- Fault instRead(MemReqPtr &req)
- {
- return mem->read(req, inst);
- }
+ Fault translateDataWriteReq(MemReqPtr &req)
+ { return actualXC->translateDataWriteReq(req); }
+
+ // @todo: Do I need this?
+ MachInst getInst() { return actualXC->getInst(); }
+
+ // @todo: Do I need this?
+ void copyArchRegs(ExecContext *xc) { actualXC->copyArchRegs(xc); }
+
+ void clearArchRegs() { actualXC->clearArchRegs(); }
//
// New accessors for new decoder.
//
uint64_t readIntReg(int reg_idx)
- {
- return regs.intRegFile[reg_idx];
- }
+ { return actualXC->readIntReg(reg_idx); }
float readFloatRegSingle(int reg_idx)
- {
- return (float)regs.floatRegFile.d[reg_idx];
- }
+ { return actualXC->readFloatRegSingle(reg_idx); }
double readFloatRegDouble(int reg_idx)
- {
- return regs.floatRegFile.d[reg_idx];
- }
+ { return actualXC->readFloatRegDouble(reg_idx); }
uint64_t readFloatRegInt(int reg_idx)
- {
- return regs.floatRegFile.q[reg_idx];
- }
+ { return actualXC->readFloatRegInt(reg_idx); }
void setIntReg(int reg_idx, uint64_t val)
- {
- regs.intRegFile[reg_idx] = val;
- }
+ { actualXC->setIntReg(reg_idx, val); }
void setFloatRegSingle(int reg_idx, float val)
- {
- regs.floatRegFile.d[reg_idx] = (double)val;
- }
+ { actualXC->setFloatRegSingle(reg_idx, val); }
void setFloatRegDouble(int reg_idx, double val)
- {
- regs.floatRegFile.d[reg_idx] = val;
- }
+ { actualXC->setFloatRegDouble(reg_idx, val); }
void setFloatRegInt(int reg_idx, uint64_t val)
- {
- regs.floatRegFile.q[reg_idx] = val;
- }
+ { actualXC->setFloatRegInt(reg_idx, val); }
- uint64_t readPC()
- {
- return regs.pc;
- }
+ uint64_t readPC() { return actualXC->readPC(); }
- void setNextPC(uint64_t val)
- {
- regs.npc = val;
- }
+ void setPC(uint64_t val) { actualXC->setPC(val); }
+
+ uint64_t readNextPC() { return actualXC->readNextPC(); }
+
+ void setNextPC(uint64_t val) { actualXC->setNextPC(val); }
MiscReg readMiscReg(int misc_reg)
- {
- return regs.miscRegs.readReg(misc_reg);
- }
+ { return actualXC->readMiscReg(misc_reg); }
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
- {
- return regs.miscRegs.readRegWithEffect(misc_reg, fault, this);
- }
+ { return actualXC->readMiscRegWithEffect(misc_reg, fault); }
Fault setMiscReg(int misc_reg, const MiscReg &val)
- {
- return regs.miscRegs.setReg(misc_reg, val);
- }
+ { return actualXC->setMiscReg(misc_reg, val); }
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
- {
- return regs.miscRegs.setRegWithEffect(misc_reg, val, this);
- }
+ { return actualXC->setMiscRegWithEffect(misc_reg, val); }
+
+ unsigned readStCondFailures()
+ { return actualXC->readStCondFailures(); }
+
+ void setStCondFailures(unsigned sc_failures)
+ { actualXC->setStCondFailures(sc_failures); }
#if FULL_SYSTEM
- int readIntrFlag() { return regs.intrflag; }
- void setIntrFlag(int val) { regs.intrflag = val; }
- Fault hwrei();
- bool inPalMode() { return AlphaISA::PcPAL(regs.pc); }
- bool simPalCheck(int palFunc);
+ int readIntrFlag() { return actualXC->readIntrFlag(); }
+
+ void setIntrFlag(int val) { actualXC->setIntrFlag(val); }
+
+ Fault hwrei() { return actualXC->hwrei(); }
+
+ bool inPalMode() { return actualXC->inPalMode(); }
+
+ bool simPalCheck(int palFunc) { return actualXC->simPalCheck(palFunc); }
#endif
+ // @todo: Fix this!
+ bool misspeculating() { return actualXC->misspeculating(); }
+
#if !FULL_SYSTEM
- TheISA::IntReg getSyscallArg(int i)
- {
- return regs.intRegFile[TheISA::ArgumentReg0 + i];
- }
+ IntReg getSyscallArg(int i) { return actualXC->getSyscallArg(i); }
// used to shift args for indirect syscall
- void setSyscallArg(int i, TheISA::IntReg val)
- {
- regs.intRegFile[TheISA::ArgumentReg0 + i] = val;
- }
+ void setSyscallArg(int i, IntReg val)
+ { actualXC->setSyscallArg(i, val); }
void setSyscallReturn(SyscallReturn return_value)
- {
- TheISA::setSyscallReturn(return_value, &regs);
- }
+ { actualXC->setSyscallReturn(return_value); }
- void syscall()
- {
- process->syscall(this);
- }
-#endif
-};
+ void syscall() { actualXC->syscall(); }
+ Counter readFuncExeInst() { return actualXC->readFuncExeInst(); }
-// for non-speculative execution context, spec_mode is always false
-inline bool
-ExecContext::misspeculating()
-{
- return false;
-}
+ void setFuncExeInst(Counter new_val)
+ { return actualXC->setFuncExeInst(new_val); }
+#endif
+};
-#endif // __CPU_EXEC_CONTEXT_HH__
+#endif
diff --git a/cpu/exetrace.cc b/cpu/exetrace.cc
index 8393a1b85..84b5eacf7 100644
--- a/cpu/exetrace.cc
+++ b/cpu/exetrace.cc
@@ -34,7 +34,6 @@
#include "encumbered/cpu/full/spec_state.hh"
#include "encumbered/cpu/full/issue.hh"
#include "cpu/exetrace.hh"
-#include "cpu/exec_context.hh"
#include "base/loader/symtab.hh"
#include "cpu/base.hh"
#include "cpu/static_inst.hh"
diff --git a/cpu/intr_control.cc b/cpu/intr_control.cc
index 5f17c7212..43e7f654c 100644
--- a/cpu/intr_control.cc
+++ b/cpu/intr_control.cc
@@ -30,6 +30,7 @@
#include <vector>
#include "cpu/base.hh"
+#include "cpu/exec_context.hh"
#include "cpu/intr_control.hh"
#include "sim/builder.hh"
#include "sim/sim_object.hh"
@@ -48,7 +49,7 @@ void
IntrControl::post(int int_num, int index)
{
std::vector<ExecContext *> &xcvec = cpu->system->execContexts;
- BaseCPU *temp = xcvec[0]->cpu;
+ BaseCPU *temp = xcvec[0]->getCpuPtr();
temp->post_interrupt(int_num, index);
}
@@ -56,7 +57,7 @@ void
IntrControl::post(int cpu_id, int int_num, int index)
{
std::vector<ExecContext *> &xcvec = cpu->system->execContexts;
- BaseCPU *temp = xcvec[cpu_id]->cpu;
+ BaseCPU *temp = xcvec[cpu_id]->getCpuPtr();
temp->post_interrupt(int_num, index);
}
@@ -64,7 +65,7 @@ void
IntrControl::clear(int int_num, int index)
{
std::vector<ExecContext *> &xcvec = cpu->system->execContexts;
- BaseCPU *temp = xcvec[0]->cpu;
+ BaseCPU *temp = xcvec[0]->getCpuPtr();
temp->clear_interrupt(int_num, index);
}
@@ -72,7 +73,7 @@ void
IntrControl::clear(int cpu_id, int int_num, int index)
{
std::vector<ExecContext *> &xcvec = cpu->system->execContexts;
- BaseCPU *temp = xcvec[cpu_id]->cpu;
+ BaseCPU *temp = xcvec[cpu_id]->getCpuPtr();
temp->clear_interrupt(int_num, index);
}
diff --git a/cpu/intr_control.hh b/cpu/intr_control.hh
index 2a57a8dfc..5ec4e14cb 100644
--- a/cpu/intr_control.hh
+++ b/cpu/intr_control.hh
@@ -34,7 +34,6 @@
#include "cpu/base.hh"
#include "sim/sim_object.hh"
#include "sim/system.hh"
-#include "cpu/exec_context.hh"
class IntrControl : public SimObject
diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc
index 5a4024587..94b66b70b 100644
--- a/cpu/memtest/memtest.cc
+++ b/cpu/memtest/memtest.cc
@@ -36,7 +36,7 @@
#include "base/misc.hh"
#include "base/statistics.hh"
-#include "cpu/exec_context.hh"
+#include "cpu/cpu_exec_context.hh"
#include "cpu/memtest/memtest.hh"
#include "mem/cache/base_cache.hh"
#include "sim/builder.hh"
@@ -79,7 +79,7 @@ MemTest::MemTest(const string &name,
vector<string> cmd;
cmd.push_back("/bin/ls");
vector<string> null_vec;
- xc = new ExecContext(NULL, 0, mainMem, 0);
+ cpuXC = new CPUExecContext(NULL, 0, mainMem, 0);
blockSize = cacheInterface->getBlockSize();
blockAddrMask = blockSize - 1;
@@ -269,7 +269,7 @@ MemTest::tick()
req->data = new uint8_t[req->size];
req->paddr &= ~(req->size - 1);
req->time = curTick;
- req->xc = xc;
+ req->xc = cpuXC->getProxy();
if (cmd < percentReads) {
// read
diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh
index 7abcf017a..cdb40a26a 100644
--- a/cpu/memtest/memtest.hh
+++ b/cpu/memtest/memtest.hh
@@ -83,7 +83,7 @@ class MemTest : public SimObject
MemInterface *cacheInterface;
FunctionalMemory *mainMem;
FunctionalMemory *checkMem;
- ExecContext *xc;
+ CPUExecContext *cpuXC;
unsigned size; // size of testing memory region
diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh
index 38c00a3a9..0352e9972 100644
--- a/cpu/o3/alpha_cpu.hh
+++ b/cpu/o3/alpha_cpu.hh
@@ -42,6 +42,8 @@ class AlphaFullCPU : public FullO3CPU<Impl>
protected:
typedef TheISA::IntReg IntReg;
typedef TheISA::MiscReg MiscReg;
+ typedef TheISA::RegFile RegFile;
+ typedef TheISA::MiscRegFile MiscRegFile;
public:
typedef typename Impl::Params Params;
@@ -152,13 +154,13 @@ class AlphaFullCPU : public FullO3CPU<Impl>
// set the register.
IntReg getSyscallArg(int i)
{
- return this->xc->regs.intRegFile[AlphaISA::ArgumentReg0 + i];
+ return this->cpuXC->readIntReg(AlphaISA::ArgumentReg0 + i);
}
// used to shift args for indirect syscall
void setSyscallArg(int i, IntReg val)
{
- this->xc->regs.intRegFile[AlphaISA::ArgumentReg0 + i] = val;
+ this->cpuXC->setIntReg(AlphaISA::ArgumentReg0 + i, val);
}
void setSyscallReturn(int64_t return_value)
@@ -169,12 +171,12 @@ class AlphaFullCPU : public FullO3CPU<Impl>
const int RegA3 = 19; // only place this is used
if (return_value >= 0) {
// no error
- this->xc->regs.intRegFile[RegA3] = 0;
- this->xc->regs.intRegFile[AlphaISA::ReturnValueReg] = return_value;
+ this->cpuXC->setIntReg(RegA3, 0);
+ this->cpuXC->setIntReg(AlphaISA::ReturnValueReg, return_value);
} else {
// got an error, return details
- this->xc->regs.intRegFile[RegA3] = (IntReg) -1;
- this->xc->regs.intRegFile[AlphaISA::ReturnValueReg] = -return_value;
+ this->cpuXC->setIntReg(RegA3, (IntReg) -1);
+ this->cpuXC->setIntReg(AlphaISA::ReturnValueReg, -return_value);
}
}
@@ -208,9 +210,8 @@ class AlphaFullCPU : public FullO3CPU<Impl>
{
#if FULL_SYSTEM && defined(TARGET_ALPHA)
if (req->flags & LOCKED) {
- MiscRegFile *cregs = &req->xc->regs.miscRegs;
- cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr);
- cregs->setReg(TheISA::Lock_Flag_DepTag, true);
+ req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
+ req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
}
#endif
@@ -230,34 +231,34 @@ class AlphaFullCPU : public FullO3CPU<Impl>
Fault write(MemReqPtr &req, T &data)
{
#if FULL_SYSTEM && defined(TARGET_ALPHA)
-
- MiscRegFile *cregs;
+ ExecContext *xc;
// If this is a store conditional, act appropriately
if (req->flags & LOCKED) {
- cregs = &req->xc->regs.miscRegs;
+ xc = req->xc;
if (req->flags & UNCACHEABLE) {
// Don't update result register (see stq_c in isa_desc)
req->result = 2;
- req->xc->storeCondFailures = 0;//Needed? [RGD]
+ xc->setStCondFailures(0);//Needed? [RGD]
} else {
- bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag);
- Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag);
+ bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag);
+ Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag);
req->result = lock_flag;
if (!lock_flag ||
((lock_addr & ~0xf) != (req->paddr & ~0xf))) {
- cregs->setReg(TheISA::Lock_Flag_DepTag, false);
- if (((++req->xc->storeCondFailures) % 100000) == 0) {
+ xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
+ xc->setStCondFailures(xc->readStCondFailures() + 1);
+ if (((xc->readStCondFailures()) % 100000) == 0) {
std::cerr << "Warning: "
- << req->xc->storeCondFailures
+ << xc->readStCondFailures()
<< " consecutive store conditional failures "
- << "on cpu " << req->xc->cpu_id
+ << "on cpu " << req->xc->readCpuId()
<< std::endl;
}
return NoFault;
}
- else req->xc->storeCondFailures = 0;
+ else xc->setStCondFailures(0);
}
}
@@ -267,10 +268,10 @@ class AlphaFullCPU : public FullO3CPU<Impl>
// Conditionals would have returned above, and wouldn't fall
// through.
for (int i = 0; i < this->system->execContexts.size(); i++){
- cregs = &this->system->execContexts[i]->regs.miscRegs;
- if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
+ xc = this->system->execContexts[i];
+ if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
(req->paddr & ~0xf)) {
- cregs->setReg(TheISA::Lock_Flag_DepTag, false);
+ xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
}
}
diff --git a/cpu/o3/alpha_cpu_builder.cc b/cpu/o3/alpha_cpu_builder.cc
index 95d2f8f37..6025b8ef2 100644
--- a/cpu/o3/alpha_cpu_builder.cc
+++ b/cpu/o3/alpha_cpu_builder.cc
@@ -30,7 +30,6 @@
#include "base/loader/symtab.hh"
#include "base/misc.hh"
#include "cpu/base.hh"
-#include "cpu/exec_context.hh"
#include "cpu/exetrace.hh"
#include "cpu/o3/alpha_cpu.hh"
#include "cpu/o3/alpha_impl.hh"
diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh
index a1c659b51..9f1fa24f6 100644
--- a/cpu/o3/alpha_cpu_impl.hh
+++ b/cpu/o3/alpha_cpu_impl.hh
@@ -26,6 +26,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "arch/alpha/faults.hh"
#include "base/cprintf.hh"
#include "base/statistics.hh"
#include "base/timebuf.hh"
@@ -165,7 +166,7 @@ AlphaFullCPU<Impl>::copyToXC()
for (int i = 0; i < AlphaISA::NumIntRegs; ++i)
{
renamed_reg = this->renameMap.lookup(i);
- this->xc->regs.intRegFile[i] = this->regFile.readIntReg(renamed_reg);
+ this->cpuXC->setIntReg(i, this->regFile.readIntReg(renamed_reg));
DPRINTF(FullCPU, "FullCPU: Copying register %i, has data %lli.\n",
renamed_reg, this->regFile.intRegFile[renamed_reg]);
}
@@ -174,21 +175,27 @@ AlphaFullCPU<Impl>::copyToXC()
for (int i = 0; i < AlphaISA::NumFloatRegs; ++i)
{
renamed_reg = this->renameMap.lookup(i + AlphaISA::FP_Base_DepTag);
- this->xc->regs.floatRegFile.d[i] =
- this->regFile.readFloatRegDouble(renamed_reg);
- this->xc->regs.floatRegFile.q[i] =
- this->regFile.readFloatRegInt(renamed_reg);
+ this->cpuXC->setFloatRegDouble(i,
+ this->regFile.readFloatRegDouble(renamed_reg));
+ this->cpuXC->setFloatRegInt(i,
+ this->regFile.readFloatRegInt(renamed_reg));
}
-/*
- this->xc->regs.miscRegs.fpcr = this->regFile.miscRegs.fpcr;
- this->xc->regs.miscRegs.uniq = this->regFile.miscRegs.uniq;
- this->xc->regs.miscRegs.lock_flag = this->regFile.miscRegs.lock_flag;
- this->xc->regs.miscRegs.lock_addr = this->regFile.miscRegs.lock_addr;
-*/
- this->xc->regs.pc = this->rob.readHeadPC();
- this->xc->regs.npc = this->xc->regs.pc+4;
-
- this->xc->func_exe_inst = this->funcExeInst;
+
+ this->cpuXC->setMiscReg(AlphaISA::Fpcr_DepTag,
+ this->regFile.readMiscReg(AlphaISA::Fpcr_DepTag));
+ this->cpuXC->setMiscReg(AlphaISA::Uniq_DepTag,
+ this->regFile.readMiscReg(AlphaISA::Uniq_DepTag));
+ this->cpuXC->setMiscReg(AlphaISA::Lock_Flag_DepTag,
+ this->regFile.readMiscReg(AlphaISA::Lock_Flag_DepTag));
+ this->cpuXC->setMiscReg(AlphaISA::Lock_Addr_DepTag,
+ this->regFile.readMiscReg(AlphaISA::Lock_Addr_DepTag));
+
+ this->cpuXC->setPC(this->rob.readHeadPC());
+ this->cpuXC->setNextPC(this->cpuXC->readPC()+4);
+
+#if !FULL_SYSTEM
+ this->cpuXC->setFuncExeInst(this->funcExeInst);
+#endif
}
// This function will probably mess things up unless the ROB is empty and
@@ -207,9 +214,9 @@ AlphaFullCPU<Impl>::copyFromXC()
DPRINTF(FullCPU, "FullCPU: Copying over register %i, had data %lli, "
"now has data %lli.\n",
renamed_reg, this->regFile.intRegFile[renamed_reg],
- this->xc->regs.intRegFile[i]);
+ this->cpuXC->readIntReg(i));
- this->regFile.setIntReg(renamed_reg, this->xc->regs.intRegFile[i]);
+ this->regFile.setIntReg(renamed_reg, this->cpuXC->readIntReg(i));
}
// Then loop through the floating point registers.
@@ -217,22 +224,27 @@ AlphaFullCPU<Impl>::copyFromXC()
{
renamed_reg = this->renameMap.lookup(i + AlphaISA::FP_Base_DepTag);
this->regFile.setFloatRegDouble(renamed_reg,
- this->xc->regs.floatRegFile.d[i]);
+ this->cpuXC->readFloatRegDouble(i));
this->regFile.setFloatRegInt(renamed_reg,
- this->xc->regs.floatRegFile.q[i]);
+ this->cpuXC->readFloatRegInt(i));
}
- /*
+
// Then loop through the misc registers.
- this->regFile.miscRegs.fpcr = this->xc->regs.miscRegs.fpcr;
- this->regFile.miscRegs.uniq = this->xc->regs.miscRegs.uniq;
- this->regFile.miscRegs.lock_flag = this->xc->regs.miscRegs.lock_flag;
- this->regFile.miscRegs.lock_addr = this->xc->regs.miscRegs.lock_addr;
- */
- // Then finally set the PC and the next PC.
-// regFile.pc = xc->regs.pc;
-// regFile.npc = xc->regs.npc;
+ this->regFile.setMiscReg(AlphaISA::Fpcr_DepTag,
+ this->cpuXC->readMiscReg(AlphaISA::Fpcr_DepTag));
+ this->regFile.setMiscReg(AlphaISA::Uniq_DepTag,
+ this->cpuXC->readMiscReg(AlphaISA::Uniq_DepTag));
+ this->regFile.setMiscReg(AlphaISA::Lock_Flag_DepTag,
+ this->cpuXC->readMiscReg(AlphaISA::Lock_Flag_DepTag));
+ this->regFile.setMiscReg(AlphaISA::Lock_Addr_DepTag,
+ this->cpuXC->readMiscReg(AlphaISA::Lock_Addr_DepTag));
- this->funcExeInst = this->xc->func_exe_inst;
+ // Then finally set the PC and the next PC.
+// regFile.pc = cpuXC->regs.pc;
+// regFile.npc = cpuXC->regs.npc;
+#if !FULL_SYSTEM
+ this->funcExeInst = this->cpuXC->readFuncExeInst();
+#endif
}
#if FULL_SYSTEM
@@ -257,7 +269,7 @@ Fault
AlphaFullCPU<Impl>::hwrei()
{
if (!inPalMode())
- return new UnimplementedOpcodeFault;
+ return new AlphaISA::UnimplementedOpcodeFault;
this->setNextPC(this->regFile.miscRegs.readReg(AlphaISA::IPR_EXC_ADDR));
diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc
index a8c620028..62d68bb33 100644
--- a/cpu/o3/cpu.cc
+++ b/cpu/o3/cpu.cc
@@ -35,10 +35,11 @@
#endif
#include "sim/root.hh"
+#include "cpu/cpu_exec_context.hh"
+#include "cpu/exec_context.hh"
#include "cpu/o3/alpha_dyn_inst.hh"
#include "cpu/o3/alpha_impl.hh"
#include "cpu/o3/cpu.hh"
-#include "cpu/exec_context.hh"
using namespace std;
@@ -103,7 +104,7 @@ FullO3CPU<Impl>::FullO3CPU(Params &params)
renameQueue(5, 5),
iewQueue(5, 5),
- xc(NULL),
+ cpuXC(NULL),
globalSeqNum(1),
@@ -134,8 +135,8 @@ FullO3CPU<Impl>::FullO3CPU(Params &params)
for (int i = 0; i < this->number_of_threads; ++i) {
#if FULL_SYSTEM
assert(i == 0);
- system->execContexts[i] =
- new ExecContext(this, i, system, itb, dtb, mem);
+ thread[i] = new CPUExecContext(this, 0, system, itb, dtb, mem);
+ system->execContexts[i] = thread[i]->getProxy();
execContexts.push_back(system->execContexts[i]);
#else
@@ -143,21 +144,17 @@ FullO3CPU<Impl>::FullO3CPU(Params &params)
DPRINTF(FullCPU, "FullCPU: Workload[%i]'s starting PC is %#x, "
"process is %#x",
i, params.workload[i]->prog_entry, thread[i]);
- thread[i] = new ExecContext(this, i, params.workload[i], i);
+ thread[i] = new CPUExecContext(this, i, params.workload[i], i);
}
assert(params.workload[i]->getMemory() != NULL);
assert(mem != NULL);
- execContexts.push_back(thread[i]);
+ execContexts.push_back(thread[i]->getProxy());
#endif // !FULL_SYSTEM
}
// Note that this is a hack so that my code which still uses xc-> will
// still work. I should remove this eventually
-#if FULL_SYSTEM
- xc = system->execContexts[0];
-#else
- xc = thread[0];
-#endif
+ cpuXC = thread[0];
// The stages also need their CPU pointer setup. However this must be
// done at the upper level CPU because they have pointers to the upper
@@ -248,21 +245,21 @@ FullO3CPU<Impl>::init()
// that it can start properly.
#if FULL_SYSTEM
ExecContext *src_xc = system->execContexts[0];
- TheISA::initCPU(&src_xc->regs, src_xc->cpu_id);
+ TheISA::initCPU(src_xc, src_xc->readCpuId());
#else
- ExecContext *src_xc = thread[0];
+ ExecContext *src_xc = thread[0]->getProxy();
#endif
// First loop through the integer registers.
for (int i = 0; i < TheISA::NumIntRegs; ++i)
{
- regFile.intRegFile[i] = src_xc->regs.intRegFile[i];
+ regFile.intRegFile[i] = src_xc->readIntReg(i);
}
// Then loop through the floating point registers.
for (int i = 0; i < TheISA::NumFloatRegs; ++i)
{
- regFile.floatRegFile[i].d = src_xc->regs.floatRegFile.d[i];
- regFile.floatRegFile[i].q = src_xc->regs.floatRegFile.q[i];
+ regFile.floatRegFile[i].d = src_xc->readFloatRegDouble(i);
+ regFile.floatRegFile[i].q = src_xc->readFloatRegInt(i);
}
/*
// Then loop through the misc registers.
@@ -272,8 +269,8 @@ FullO3CPU<Impl>::init()
regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr;
*/
// Then finally set the PC and the next PC.
- regFile.pc = src_xc->regs.pc;
- regFile.npc = src_xc->regs.npc;
+ regFile.pc = src_xc->readPC();
+ regFile.npc = src_xc->readNextPC();
}
}
diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh
index 02908887e..6577e46e4 100644
--- a/cpu/o3/cpu.hh
+++ b/cpu/o3/cpu.hh
@@ -44,16 +44,12 @@
#include "base/timebuf.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
+#include "cpu/cpu_exec_context.hh"
#include "cpu/o3/comm.hh"
#include "cpu/o3/cpu_policy.hh"
-#include "cpu/exec_context.hh"
#include "sim/process.hh"
-#if FULL_SYSTEM
-#include "arch/ev5.hh"
-using namespace EV5;
-#endif
-
+class ExecContext;
class FunctionalMemory;
class Process;
@@ -152,11 +148,11 @@ class FullO3CPU : public BaseFullCPU
/** Get instruction asid. */
int getInstAsid()
- { return ITB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_ITB_ASN)); }
+ { return regFile.miscRegs.getInstAsid(); }
/** Get data asid. */
int getDataAsid()
- { return DTB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_DTB_ASN)); }
+ { return regFile.miscRegs.getDataAsid(); }
#else
bool validInstAddr(Addr addr)
{ return thread[0]->validInstAddr(addr); }
@@ -164,8 +160,8 @@ class FullO3CPU : public BaseFullCPU
bool validDataAddr(Addr addr)
{ return thread[0]->validDataAddr(addr); }
- int getInstAsid() { return thread[0]->asid; }
- int getDataAsid() { return thread[0]->asid; }
+ int getInstAsid() { return thread[0]->getInstAsid(); }
+ int getDataAsid() { return thread[0]->getDataAsid(); }
#endif
@@ -320,16 +316,17 @@ class FullO3CPU : public BaseFullCPU
public:
/** The temporary exec context to support older accessors. */
- ExecContext *xc;
+ CPUExecContext *cpuXC;
/** Temporary function to get pointer to exec context. */
ExecContext *xcBase()
{
-#if FULL_SYSTEM
- return system->execContexts[0];
-#else
+ return thread[0]->getProxy();
+ }
+
+ CPUExecContext *cpuXCBase()
+ {
return thread[0];
-#endif
}
InstSeqNum globalSeqNum;
@@ -344,9 +341,8 @@ class FullO3CPU : public BaseFullCPU
AlphaDTB *dtb;
// SWContext *swCtx;
-#else
- std::vector<ExecContext *> thread;
#endif
+ std::vector<CPUExecContext *> thread;
FunctionalMemory *mem;
diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh
index 03ad2da46..1e6e10f29 100644
--- a/cpu/o3/regfile.hh
+++ b/cpu/o3/regfile.hh
@@ -38,10 +38,8 @@
#include "cpu/o3/comm.hh"
#if FULL_SYSTEM
-#include "arch/ev5.hh"
#include "kern/kernel_stats.hh"
-using namespace EV5;
#endif
// This really only depends on the ISA, and not the Impl. It might be nicer
@@ -237,7 +235,6 @@ class PhysRegFile
private:
// This is ISA specifc stuff; remove it eventually once ISAImpl is used
// IntReg palregs[NumIntRegs]; // PAL shadow registers
- InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs
int intrflag; // interrupt flag
bool pal_shadow; // using pal_shadow registers
#endif
diff --git a/cpu/pc_event.cc b/cpu/pc_event.cc
index 83fbc3e2d..050bf1a88 100644
--- a/cpu/pc_event.cc
+++ b/cpu/pc_event.cc
@@ -38,6 +38,7 @@
#include "cpu/pc_event.hh"
#include "sim/debug.hh"
#include "sim/root.hh"
+#include "sim/system.hh"
using namespace std;
@@ -79,7 +80,7 @@ PCEventQueue::schedule(PCEvent *event)
bool
PCEventQueue::doService(ExecContext *xc)
{
- Addr pc = xc->regs.pc & ~0x3;
+ Addr pc = xc->readPC() & ~0x3;
int serviced = 0;
range_t range = equal_range(pc);
for (iterator i = range.first; i != range.second; ++i) {
@@ -87,7 +88,7 @@ PCEventQueue::doService(ExecContext *xc)
// another event. This for example, prevents two invocations
// of the SkipFuncEvent. Maybe we should have separate PC
// event queues for each processor?
- if (pc != (xc->regs.pc & ~0x3))
+ if (pc != (xc->readPC() & ~0x3))
continue;
DPRINTF(PCEvent, "PC based event serviced at %#x: %s\n",
@@ -126,7 +127,7 @@ BreakPCEvent::BreakPCEvent(PCEventQueue *q, const std::string &desc, Addr addr,
void
BreakPCEvent::process(ExecContext *xc)
{
- StringWrap name(xc->cpu->name() + ".break_event");
+ StringWrap name(xc->getCpuPtr()->name() + ".break_event");
DPRINTFN("break event %s triggered\n", descr());
debug_break();
if (remove)
diff --git a/cpu/profile.cc b/cpu/profile.cc
index 1a38792a0..fe3458b61 100644
--- a/cpu/profile.cc
+++ b/cpu/profile.cc
@@ -32,6 +32,7 @@
#include "base/callback.hh"
#include "base/statistics.hh"
#include "base/trace.hh"
+#include "base/loader/symtab.hh"
#include "cpu/base.hh"
#include "cpu/exec_context.hh"
#include "cpu/profile.hh"
diff --git a/cpu/profile.hh b/cpu/profile.hh
index 1eb012a27..d55c9eec9 100644
--- a/cpu/profile.hh
+++ b/cpu/profile.hh
@@ -35,6 +35,8 @@
#include "sim/host.hh"
#include "arch/stacktrace.hh"
+class ExecContext;
+
class ProfileNode
{
private:
diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc
index 51d679a63..8db72b77e 100644
--- a/cpu/simple/cpu.cc
+++ b/cpu/simple/cpu.cc
@@ -44,6 +44,7 @@
#include "base/stats/events.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
+#include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh"
#include "cpu/exetrace.hh"
#include "cpu/profile.hh"
@@ -94,7 +95,7 @@ SimpleCPU::init()
ExecContext *xc = execContexts[i];
// initialize CPU, including PC
- TheISA::initCPU(&xc->regs, xc->cpu_id);
+ TheISA::initCPU(xc, xc->readCpuId());
}
#endif
}
@@ -132,22 +133,24 @@ SimpleCPU::CacheCompletionEvent::description()
}
SimpleCPU::SimpleCPU(Params *p)
- : BaseCPU(p), tickEvent(this, p->width), xc(NULL),
+ : BaseCPU(p), tickEvent(this, p->width), cpuXC(NULL),
cacheCompletionEvent(this)
{
_status = Idle;
#if FULL_SYSTEM
- xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
+ cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
#else
- xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0);
+ cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process,
+ /* asid */ 0);
#endif // !FULL_SYSTEM
+ xcProxy = cpuXC->getProxy();
icacheInterface = p->icache_interface;
dcacheInterface = p->dcache_interface;
memReq = new MemReq();
- memReq->xc = xc;
+ memReq->xc = xcProxy;
memReq->asid = 0;
memReq->data = new uint8_t[64];
@@ -158,7 +161,7 @@ SimpleCPU::SimpleCPU(Params *p)
lastIcacheStall = 0;
lastDcacheStall = 0;
- execContexts.push_back(xc);
+ execContexts.push_back(xcProxy);
}
SimpleCPU::~SimpleCPU()
@@ -207,7 +210,7 @@ void
SimpleCPU::activateContext(int thread_num, int delay)
{
assert(thread_num == 0);
- assert(xc);
+ assert(cpuXC);
assert(_status == Idle);
notIdleFraction++;
@@ -220,7 +223,7 @@ void
SimpleCPU::suspendContext(int thread_num)
{
assert(thread_num == 0);
- assert(xc);
+ assert(cpuXC);
assert(_status == Running);
notIdleFraction--;
@@ -301,7 +304,7 @@ SimpleCPU::serialize(ostream &os)
SERIALIZE_ENUM(_status);
SERIALIZE_SCALAR(inst);
nameOut(os, csprintf("%s.xc", name()));
- xc->serialize(os);
+ cpuXC->serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os);
nameOut(os, csprintf("%s.cacheCompletionEvent", name()));
@@ -314,7 +317,7 @@ SimpleCPU::unserialize(Checkpoint *cp, const string &section)
BaseCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status);
UNSERIALIZE_SCALAR(inst);
- xc->unserialize(cp, csprintf("%s.xc", section));
+ cpuXC->unserialize(cp, csprintf("%s.xc", section));
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
cacheCompletionEvent
.unserialize(cp, csprintf("%s.cacheCompletionEvent", section));
@@ -345,16 +348,16 @@ SimpleCPU::copySrcTranslate(Addr src)
memReq->reset(src & ~(blk_size - 1), blk_size);
// translate to physical address
- Fault fault = xc->translateDataReadReq(memReq);
+ Fault fault = cpuXC->translateDataReadReq(memReq);
if (fault == NoFault) {
- xc->copySrcAddr = src;
- xc->copySrcPhysAddr = memReq->paddr + offset;
+ cpuXC->copySrcAddr = src;
+ cpuXC->copySrcPhysAddr = memReq->paddr + offset;
} else {
assert(!fault->isAlignmentFault());
- xc->copySrcAddr = 0;
- xc->copySrcPhysAddr = 0;
+ cpuXC->copySrcAddr = 0;
+ cpuXC->copySrcPhysAddr = 0;
}
return fault;
}
@@ -367,7 +370,7 @@ SimpleCPU::copy(Addr dest)
// Only support block sizes of 64 atm.
assert(blk_size == 64);
uint8_t data[blk_size];
- //assert(xc->copySrcAddr);
+ //assert(cpuXC->copySrcAddr);
int offset = dest & (blk_size - 1);
// Make sure block doesn't span page
@@ -380,19 +383,19 @@ SimpleCPU::copy(Addr dest)
memReq->reset(dest & ~(blk_size -1), blk_size);
// translate to physical address
- Fault fault = xc->translateDataWriteReq(memReq);
+ Fault fault = cpuXC->translateDataWriteReq(memReq);
if (fault == NoFault) {
Addr dest_addr = memReq->paddr + offset;
// Need to read straight from memory since we have more than 8 bytes.
- memReq->paddr = xc->copySrcPhysAddr;
- xc->mem->read(memReq, data);
+ memReq->paddr = cpuXC->copySrcPhysAddr;
+ cpuXC->mem->read(memReq, data);
memReq->paddr = dest_addr;
- xc->mem->write(memReq, data);
+ cpuXC->mem->write(memReq, data);
if (dcacheInterface) {
memReq->cmd = Copy;
memReq->completionEvent = NULL;
- memReq->paddr = xc->copySrcPhysAddr;
+ memReq->paddr = cpuXC->copySrcPhysAddr;
memReq->dest = dest_addr;
memReq->size = 64;
memReq->time = curTick;
@@ -412,7 +415,7 @@ Fault
SimpleCPU::read(Addr addr, T &data, unsigned flags)
{
if (status() == DcacheMissStall || status() == DcacheMissSwitch) {
- Fault fault = xc->read(memReq,data);
+ Fault fault = cpuXC->read(memReq,data);
if (traceData) {
traceData->setAddr(addr);
@@ -423,7 +426,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
- Fault fault = xc->translateDataReadReq(memReq);
+ Fault fault = cpuXC->translateDataReadReq(memReq);
// if we have a cache, do cache access too
if (fault == NoFault && dcacheInterface) {
@@ -443,12 +446,12 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
_status = DcacheMissStall;
} else {
// do functional access
- fault = xc->read(memReq, data);
+ fault = cpuXC->read(memReq, data);
}
} else if(fault == NoFault) {
// do functional access
- fault = xc->read(memReq, data);
+ fault = cpuXC->read(memReq, data);
}
@@ -508,11 +511,11 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
- Fault fault = xc->translateDataWriteReq(memReq);
+ Fault fault = cpuXC->translateDataWriteReq(memReq);
// do functional access
if (fault == NoFault)
- fault = xc->write(memReq, data);
+ fault = cpuXC->write(memReq, data);
if (fault == NoFault && dcacheInterface) {
memReq->cmd = Write;
@@ -589,7 +592,7 @@ SimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
Addr
SimpleCPU::dbg_vtophys(Addr addr)
{
- return vtophys(xc, addr);
+ return vtophys(xcProxy, addr);
}
#endif // FULL_SYSTEM
@@ -637,9 +640,9 @@ SimpleCPU::post_interrupt(int int_num, int index)
{
BaseCPU::post_interrupt(int_num, index);
- if (xc->status() == ExecContext::Suspended) {
+ if (cpuXC->status() == ExecContext::Suspended) {
DPRINTF(IPI,"Suspended Processor awoke\n");
- xc->activate();
+ cpuXC->activate();
}
}
#endif // FULL_SYSTEM
@@ -655,16 +658,16 @@ SimpleCPU::tick()
Fault fault = NoFault;
#if FULL_SYSTEM
- if (checkInterrupts && check_interrupts() && !xc->inPalMode() &&
+ if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode() &&
status() != IcacheMissComplete) {
int ipl = 0;
int summary = 0;
checkInterrupts = false;
- if (xc->readMiscReg(IPR_SIRR)) {
+ if (cpuXC->readMiscReg(IPR_SIRR)) {
for (int i = INTLEVEL_SOFTWARE_MIN;
i < INTLEVEL_SOFTWARE_MAX; i++) {
- if (xc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
+ if (cpuXC->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
summary |= (ULL(1) << i);
@@ -672,7 +675,7 @@ SimpleCPU::tick()
}
}
- uint64_t interrupts = xc->cpu->intr_status();
+ uint64_t interrupts = cpuXC->cpu->intr_status();
for (int i = INTLEVEL_EXTERNAL_MIN;
i < INTLEVEL_EXTERNAL_MAX; i++) {
if (interrupts & (ULL(1) << i)) {
@@ -682,24 +685,25 @@ SimpleCPU::tick()
}
}
- if (xc->readMiscReg(IPR_ASTRR))
+ if (cpuXC->readMiscReg(IPR_ASTRR))
panic("asynchronous traps not implemented\n");
- if (ipl && ipl > xc->readMiscReg(IPR_IPLR)) {
- xc->setMiscReg(IPR_ISR, summary);
- xc->setMiscReg(IPR_INTID, ipl);
- Fault(new InterruptFault)->invoke(xc);
+ if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) {
+ cpuXC->setMiscReg(IPR_ISR, summary);
+ cpuXC->setMiscReg(IPR_INTID, ipl);
+
+ Fault(new InterruptFault)->invoke(xcProxy);
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
- xc->readMiscReg(IPR_IPLR), ipl, summary);
+ cpuXC->readMiscReg(IPR_IPLR), ipl, summary);
}
}
#endif
// maintain $r0 semantics
- xc->regs.intRegFile[ZeroReg] = 0;
+ cpuXC->setIntReg(ZeroReg, 0);
#ifdef TARGET_ALPHA
- xc->regs.floatRegFile.d[ZeroReg] = 0.0;
+ cpuXC->setFloatRegDouble(ZeroReg, 0.0);
#endif // TARGET_ALPHA
if (status() == IcacheMissComplete) {
@@ -721,13 +725,13 @@ SimpleCPU::tick()
#endif
memReq->cmd = Read;
- memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t),
- IFETCH_FLAGS(xc->regs.pc));
+ memReq->reset(cpuXC->readPC() & ~3, sizeof(uint32_t),
+ IFETCH_FLAGS(cpuXC->readPC()));
- fault = xc->translateInstReq(memReq);
+ fault = cpuXC->translateInstReq(memReq);
if (fault == NoFault)
- fault = xc->mem->read(memReq, inst);
+ fault = cpuXC->mem->read(memReq, inst);
if (icacheInterface && fault == NoFault) {
memReq->completionEvent = NULL;
@@ -762,31 +766,32 @@ SimpleCPU::tick()
// decode the instruction
inst = gtoh(inst);
- curStaticInst = StaticInst::decode(makeExtMI(inst, xc->readPC()));
+ curStaticInst = StaticInst::decode(makeExtMI(inst, cpuXC->readPC()));
- traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst,
- xc->regs.pc);
+ traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst,
+ cpuXC->readPC());
#if FULL_SYSTEM
- xc->setInst(inst);
+ cpuXC->setInst(inst);
#endif // FULL_SYSTEM
- xc->func_exe_inst++;
+ cpuXC->func_exe_inst++;
fault = curStaticInst->execute(this, traceData);
#if FULL_SYSTEM
- if (xc->fnbin) {
- assert(xc->kernelStats);
- system->kernelBinning->execute(xc, inst);
+ if (system->kernelBinning->fnbin) {
+ assert(kernelStats);
+ system->kernelBinning->execute(xcProxy, inst);
}
- if (xc->profile) {
- bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
- xc->profilePC = usermode ? 1 : xc->regs.pc;
- ProfileNode *node = xc->profile->consume(xc, inst);
+ if (cpuXC->profile) {
+ bool usermode =
+ (cpuXC->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
+ cpuXC->profilePC = usermode ? 1 : cpuXC->readPC();
+ ProfileNode *node = cpuXC->profile->consume(xcProxy, inst);
if (node)
- xc->profileNode = node;
+ cpuXC->profileNode = node;
}
#endif
@@ -806,29 +811,37 @@ SimpleCPU::tick()
traceData->finalize();
}
- traceFunctions(xc->regs.pc);
+ traceFunctions(cpuXC->readPC());
} // if (fault == NoFault)
if (fault != NoFault) {
#if FULL_SYSTEM
- fault->invoke(xc);
+ fault->invoke(xcProxy);
#else // !FULL_SYSTEM
- fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc);
+ fatal("fault (%d) detected @ PC 0x%08p", fault, cpuXC->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));
+#else
// go to the next instruction
- xc->regs.pc = xc->regs.npc;
- xc->regs.npc += sizeof(MachInst);
+ cpuXC->setPC(cpuXC->readNextPC());
+ cpuXC->setNextPC(cpuXC->readNextNPC());
+ cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst));
+#endif
+
}
#if FULL_SYSTEM
Addr oldpc;
do {
- oldpc = xc->regs.pc;
- system->pcEventQueue.service(xc);
- } while (oldpc != xc->regs.pc);
+ oldpc = cpuXC->readPC();
+ system->pcEventQueue.service(xcProxy);
+ } while (oldpc != cpuXC->readPC());
#endif
assert(status() == Running ||
diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh
index 0b8d84e53..4ab9a1c3e 100644
--- a/cpu/simple/cpu.hh
+++ b/cpu/simple/cpu.hh
@@ -32,7 +32,7 @@
#include "base/statistics.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
-#include "cpu/exec_context.hh"
+#include "cpu/cpu_exec_context.hh"
#include "cpu/pc_event.hh"
#include "cpu/sampler/sampler.hh"
#include "cpu/static_inst.hh"
@@ -54,6 +54,7 @@ class Process;
#endif // FULL_SYSTEM
+class ExecContext;
class MemInterface;
class Checkpoint;
@@ -148,7 +149,9 @@ class SimpleCPU : public BaseCPU
public:
// execution context
- ExecContext *xc;
+ CPUExecContext *cpuXC;
+
+ ExecContext *xcProxy;
void switchOut(Sampler *s);
void takeOverFrom(BaseCPU *oldCPU);
@@ -275,86 +278,86 @@ class SimpleCPU : public BaseCPU
uint64_t readIntReg(const StaticInst *si, int idx)
{
- return xc->readIntReg(si->srcRegIdx(idx));
+ return cpuXC->readIntReg(si->srcRegIdx(idx));
}
float readFloatRegSingle(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return xc->readFloatRegSingle(reg_idx);
+ return cpuXC->readFloatRegSingle(reg_idx);
}
double readFloatRegDouble(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return xc->readFloatRegDouble(reg_idx);
+ return cpuXC->readFloatRegDouble(reg_idx);
}
uint64_t readFloatRegInt(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
- return xc->readFloatRegInt(reg_idx);
+ return cpuXC->readFloatRegInt(reg_idx);
}
void setIntReg(const StaticInst *si, int idx, uint64_t val)
{
- xc->setIntReg(si->destRegIdx(idx), val);
+ cpuXC->setIntReg(si->destRegIdx(idx), val);
}
void setFloatRegSingle(const StaticInst *si, int idx, float val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- xc->setFloatRegSingle(reg_idx, val);
+ cpuXC->setFloatRegSingle(reg_idx, val);
}
void setFloatRegDouble(const StaticInst *si, int idx, double val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- xc->setFloatRegDouble(reg_idx, val);
+ cpuXC->setFloatRegDouble(reg_idx, val);
}
void setFloatRegInt(const StaticInst *si, int idx, uint64_t val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
- xc->setFloatRegInt(reg_idx, val);
+ cpuXC->setFloatRegInt(reg_idx, val);
}
- uint64_t readPC() { return xc->readPC(); }
- void setNextPC(uint64_t val) { xc->setNextPC(val); }
+ uint64_t readPC() { return cpuXC->readPC(); }
+ void setNextPC(uint64_t val) { cpuXC->setNextPC(val); }
MiscReg readMiscReg(int misc_reg)
{
- return xc->readMiscReg(misc_reg);
+ return cpuXC->readMiscReg(misc_reg);
}
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
{
- return xc->readMiscRegWithEffect(misc_reg, fault);
+ return cpuXC->readMiscRegWithEffect(misc_reg, fault);
}
Fault setMiscReg(int misc_reg, const MiscReg &val)
{
- return xc->setMiscReg(misc_reg, val);
+ return cpuXC->setMiscReg(misc_reg, val);
}
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
- return xc->setMiscRegWithEffect(misc_reg, val);
+ return cpuXC->setMiscRegWithEffect(misc_reg, val);
}
#if FULL_SYSTEM
- Fault hwrei() { return xc->hwrei(); }
- int readIntrFlag() { return xc->readIntrFlag(); }
- void setIntrFlag(int val) { xc->setIntrFlag(val); }
- bool inPalMode() { return xc->inPalMode(); }
- void trap(Fault fault) { fault->invoke(xc); }
- bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); }
+ Fault hwrei() { return cpuXC->hwrei(); }
+ int readIntrFlag() { return cpuXC->readIntrFlag(); }
+ void setIntrFlag(int val) { cpuXC->setIntrFlag(val); }
+ bool inPalMode() { return cpuXC->inPalMode(); }
+ void ev5_trap(Fault fault) { fault->invoke(xcProxy); }
+ bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); }
#else
- void syscall() { xc->syscall(); }
+ void syscall() { cpuXC->syscall(); }
#endif
- bool misspeculating() { return xc->misspeculating(); }
- ExecContext *xcBase() { return xc; }
+ bool misspeculating() { return cpuXC->misspeculating(); }
+ ExecContext *xcBase() { return xcProxy; }
};
#endif // __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__
diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh
index 86ef021e9..f63c6ad7e 100644
--- a/dev/alpha_console.hh
+++ b/dev/alpha_console.hh
@@ -43,6 +43,7 @@ class BaseCPU;
class SimConsole;
class AlphaSystem;
class SimpleDisk;
+class MemoryController;
/**
* Memory mapped interface to the system console. This device
diff --git a/dev/baddev.hh b/dev/baddev.hh
index c2a204c05..189f28331 100644
--- a/dev/baddev.hh
+++ b/dev/baddev.hh
@@ -37,6 +37,8 @@
#include "base/range.hh"
#include "dev/io_device.hh"
+class MemoryController;
+
/**
* BadDevice
* This device just panics when accessed. It is supposed to warn
diff --git a/dev/isa_fake.hh b/dev/isa_fake.hh
index 290b24b54..73e40c681 100644
--- a/dev/isa_fake.hh
+++ b/dev/isa_fake.hh
@@ -37,6 +37,8 @@
#include "base/range.hh"
#include "dev/io_device.hh"
+class MemoryController;
+
/**
* IsaFake is a device that returns -1 on all reads and
* accepts all writes. It is meant to be placed at an address range
diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc
index 4dc4413a1..2649fe27a 100644
--- a/dev/tsunami_cchip.cc
+++ b/dev/tsunami_cchip.cc
@@ -42,6 +42,7 @@
#include "mem/bus/pio_interface.hh"
#include "mem/bus/pio_interface_impl.hh"
#include "mem/functional/memory_control.hh"
+#include "cpu/exec_context.hh"
#include "cpu/intr_control.hh"
#include "sim/builder.hh"
#include "sim/system.hh"
@@ -113,7 +114,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
case TSDEV_CC_MISC:
*(uint64_t*)data = (ipint << 8) & 0xF |
(itint << 4) & 0xF |
- (xc->cpu_id & 0x3);
+ (xc->readCpuId() & 0x3);
return NoFault;
case TSDEV_CC_AAR0:
case TSDEV_CC_AAR1:
diff --git a/dev/uart.hh b/dev/uart.hh
index 145b9ca9e..78b1dc68e 100644
--- a/dev/uart.hh
+++ b/dev/uart.hh
@@ -37,6 +37,7 @@
#include "dev/io_device.hh"
class SimConsole;
+class MemoryController;
class Platform;
const int RX_INT = 0x1;
diff --git a/dev/uart8250.hh b/dev/uart8250.hh
index 88abf8e24..63d1da3cf 100644
--- a/dev/uart8250.hh
+++ b/dev/uart8250.hh
@@ -53,6 +53,7 @@
#define IIR_LINE 0x06 /* Rx Line Status (highest priority)*/
class SimConsole;
+class MemoryController;
class Platform;
class Uart8250 : public Uart
diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc
index f898dad94..b85d88145 100644
--- a/kern/kernel_stats.cc
+++ b/kern/kernel_stats.cc
@@ -35,6 +35,7 @@
#include "cpu/exec_context.hh"
#include "kern/kernel_stats.hh"
#include "kern/tru64/tru64_syscalls.hh"
+#include "sim/system.hh"
using namespace std;
using namespace Stats;
@@ -43,11 +44,11 @@ namespace Kernel {
const char *modestr[] = { "kernel", "user", "idle", "interrupt" };
-Statistics::Statistics(ExecContext *context)
- : xc(context), idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
+Statistics::Statistics(System *system)
+ : idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
iplLast(0), iplLastTick(0)
{
- bin_int = xc->system->params()->bin_int;
+ bin_int = system->params()->bin_int;
}
void
@@ -180,16 +181,16 @@ Statistics::regStats(const string &_name)
}
void
-Statistics::setIdleProcess(Addr idlepcbb)
+Statistics::setIdleProcess(Addr idlepcbb, ExecContext *xc)
{
assert(themode == kernel || themode == interrupt);
idleProcess = idlepcbb;
themode = idle;
- changeMode(themode);
+ changeMode(themode, xc);
}
void
-Statistics::changeMode(cpu_mode newmode)
+Statistics::changeMode(cpu_mode newmode, ExecContext *xc)
{
_mode[newmode]++;
@@ -202,7 +203,7 @@ Statistics::changeMode(cpu_mode newmode)
_modeGood[newmode]++;
_modeTicks[themode] += curTick - lastModeTick;
- xc->system->kernelBinning->changeMode(newmode);
+ xc->getSystemPtr()->kernelBinning->changeMode(newmode);
lastModeTick = curTick;
themode = newmode;
@@ -225,7 +226,7 @@ Statistics::swpipl(int ipl)
}
void
-Statistics::mode(cpu_mode newmode)
+Statistics::mode(cpu_mode newmode, ExecContext *xc)
{
Addr pcbb = xc->readMiscReg(AlphaISA::IPR_PALtemp23);
@@ -236,20 +237,20 @@ Statistics::mode(cpu_mode newmode)
if (bin_int == false && newmode == interrupt)
newmode = kernel;
- changeMode(newmode);
+ changeMode(newmode, xc);
}
void
-Statistics::context(Addr oldpcbb, Addr newpcbb)
+Statistics::context(Addr oldpcbb, Addr newpcbb, ExecContext *xc)
{
assert(themode != user);
_swap_context++;
- changeMode(newpcbb == idleProcess ? idle : kernel);
+ changeMode(newpcbb == idleProcess ? idle : kernel, xc);
}
void
-Statistics::callpal(int code)
+Statistics::callpal(int code, ExecContext *xc)
{
if (!PAL::name(code))
return;
@@ -258,7 +259,7 @@ Statistics::callpal(int code)
switch (code) {
case PAL::callsys: {
- int number = xc->regs.intRegFile[0];
+ int number = xc->readIntReg(0);
if (SystemCalls<Tru64>::validSyscallNumber(number)) {
int cvtnum = SystemCalls<Tru64>::convert(number);
_syscall[cvtnum]++;
@@ -266,8 +267,8 @@ Statistics::callpal(int code)
} break;
case PAL::swpctx:
- if (xc->system->kernelBinning)
- xc->system->kernelBinning->palSwapContext(xc);
+ if (xc->getSystemPtr()->kernelBinning)
+ xc->getSystemPtr()->kernelBinning->palSwapContext(xc);
break;
}
}
diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh
index 830bfe09d..16ec721d0 100644
--- a/kern/kernel_stats.hh
+++ b/kern/kernel_stats.hh
@@ -128,14 +128,13 @@ class Statistics : public Serializable
private:
std::string myname;
- ExecContext *xc;
Addr idleProcess;
cpu_mode themode;
Tick lastModeTick;
bool bin_int;
- void changeMode(cpu_mode newmode);
+ void changeMode(cpu_mode newmode, ExecContext *xc);
private:
Stats::Scalar<> _arm;
@@ -165,7 +164,7 @@ class Statistics : public Serializable
Tick iplLastTick;
public:
- Statistics(ExecContext *context);
+ Statistics(System *system);
const std::string name() const { return myname; }
void regStats(const std::string &name);
@@ -177,11 +176,11 @@ class Statistics : public Serializable
void ivle() { _ivle++; }
void hwrei() { _hwrei++; }
void swpipl(int ipl);
- void mode(cpu_mode newmode);
- void context(Addr oldpcbb, Addr newpcbb);
- void callpal(int code);
+ void mode(cpu_mode newmode, ExecContext *xc);
+ void context(Addr oldpcbb, Addr newpcbb, ExecContext *xc);
+ void callpal(int code, ExecContext *xc);
- void setIdleProcess(Addr idle);
+ void setIdleProcess(Addr idle, ExecContext *xc);
public:
virtual void serialize(std::ostream &os);
diff --git a/kern/linux/events.cc b/kern/linux/events.cc
index a781165ac..9f50eef04 100644
--- a/kern/linux/events.cc
+++ b/kern/linux/events.cc
@@ -32,6 +32,7 @@
#include "kern/linux/events.hh"
#include "kern/linux/printk.hh"
#include "kern/system_events.hh"
+#include "sim/system.hh"
namespace Linux {
@@ -41,7 +42,7 @@ DebugPrintkEvent::process(ExecContext *xc)
{
if (DTRACE(DebugPrintf)) {
if (!raw) {
- StringWrap name(xc->system->name() + ".dprintk");
+ StringWrap name(xc->getSystemPtr()->name() + ".dprintk");
DPRINTFN("");
}
diff --git a/kern/system_events.cc b/kern/system_events.cc
index 91625e60a..9b9861497 100644
--- a/kern/system_events.cc
+++ b/kern/system_events.cc
@@ -34,17 +34,17 @@ using namespace TheISA;
void
SkipFuncEvent::process(ExecContext *xc)
{
- Addr newpc = xc->regs.intRegFile[ReturnAddressReg];
+ Addr newpc = xc->readIntReg(ReturnAddressReg);
DPRINTF(PCEvent, "skipping %s: pc=%x, newpc=%x\n", description,
- xc->regs.pc, newpc);
+ xc->readPC(), newpc);
- xc->regs.pc = newpc;
- xc->regs.npc = xc->regs.pc + sizeof(MachInst);
+ xc->setPC(newpc);
+ xc->setNextPC(xc->readPC() + sizeof(TheISA::MachInst));
- BranchPred *bp = xc->cpu->getBranchPred();
+ BranchPred *bp = xc->getCpuPtr()->getBranchPred();
if (bp != NULL) {
- bp->popRAS(xc->thread_num);
+ bp->popRAS(xc->getThreadNum());
}
}
@@ -61,20 +61,21 @@ FnEvent::process(ExecContext *xc)
if (xc->misspeculating())
return;
- xc->system->kernelBinning->call(xc, mybin);
+ xc->getSystemPtr()->kernelBinning->call(xc, mybin);
}
void
IdleStartEvent::process(ExecContext *xc)
{
- xc->kernelStats->setIdleProcess(xc->readMiscReg(AlphaISA::IPR_PALtemp23));
+ xc->getCpuPtr()->kernelStats->setIdleProcess(
+ xc->readMiscReg(AlphaISA::IPR_PALtemp23), xc);
remove();
}
void
InterruptStartEvent::process(ExecContext *xc)
{
- xc->kernelStats->mode(Kernel::interrupt);
+ xc->getCpuPtr()->kernelStats->mode(Kernel::interrupt, xc);
}
void
@@ -82,5 +83,5 @@ InterruptEndEvent::process(ExecContext *xc)
{
// We go back to kernel, if we are user, inside the rti
// pal code we will get switched to user because of the ICM write
- xc->kernelStats->mode(Kernel::kernel);
+ xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc);
}
diff --git a/kern/tru64/dump_mbuf.cc b/kern/tru64/dump_mbuf.cc
index 10137ceb0..c3c37531a 100644
--- a/kern/tru64/dump_mbuf.cc
+++ b/kern/tru64/dump_mbuf.cc
@@ -31,9 +31,11 @@
#include "base/cprintf.hh"
#include "base/trace.hh"
+#include "base/loader/symtab.hh"
#include "cpu/exec_context.hh"
#include "kern/tru64/mbuf.hh"
#include "sim/host.hh"
+#include "sim/system.hh"
#include "arch/arguments.hh"
#include "arch/isa_traits.hh"
#include "arch/vtophys.hh"
@@ -61,7 +63,7 @@ DumpMbuf(AlphaArguments args)
addr, m.m_data, m.m_len);
char *buffer = new char[m.m_len];
CopyOut(xc, buffer, m.m_data, m.m_len);
- Trace::dataDump(curTick, xc->system->name(), (uint8_t *)buffer,
+ Trace::dataDump(curTick, xc->getSystemPtr()->name(), (uint8_t *)buffer,
m.m_len);
delete [] buffer;
diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh
index 9c541ae1a..112f00f31 100644
--- a/kern/tru64/tru64.hh
+++ b/kern/tru64/tru64.hh
@@ -666,7 +666,7 @@ class Tru64 {
// just pass basep through uninterpreted.
TypedBufferArg<int64_t> basep(tgt_basep);
- basep.copyIn(xc->mem);
+ basep.copyIn(xc->getMemPtr());
long host_basep = (off_t)htog((int64_t)*basep);
int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep);
@@ -693,7 +693,7 @@ class Tru64 {
tgt_dp->d_reclen = tgt_bufsize;
tgt_dp->d_namlen = namelen;
strcpy(tgt_dp->d_name, host_dp->d_name);
- tgt_dp.copyOut(xc->mem);
+ tgt_dp.copyOut(xc->getMemPtr());
tgt_buf_ptr += tgt_bufsize;
host_buf_ptr += host_dp->d_reclen;
@@ -702,7 +702,7 @@ class Tru64 {
delete [] host_buf;
*basep = htog((int64_t)host_basep);
- basep.copyOut(xc->mem);
+ basep.copyOut(xc->getMemPtr());
return tgt_buf_ptr - tgt_buf;
#endif
@@ -714,20 +714,19 @@ class Tru64 {
ExecContext *xc)
{
using TheISA::RegFile;
- RegFile *regs = &xc->regs;
TypedBufferArg<Tru64::sigcontext> sc(xc->getSyscallArg(0));
- sc.copyIn(xc->mem);
+ sc.copyIn(xc->getMemPtr());
// Restore state from sigcontext structure.
// Note that we'll advance PC <- NPC before the end of the cycle,
// so we need to restore the desired PC into NPC.
// The current regs->pc will get clobbered.
- regs->npc = htog(sc->sc_pc);
+ xc->setNextPC(htog(sc->sc_pc));
for (int i = 0; i < 31; ++i) {
- regs->intRegFile[i] = htog(sc->sc_regs[i]);
- regs->floatRegFile.q[i] = htog(sc->sc_fpregs[i]);
+ xc->setIntReg(i, htog(sc->sc_regs[i]));
+ xc->setFloatRegInt(i, htog(sc->sc_fpregs[i]));
}
xc->setMiscReg(TheISA::Fpcr_DepTag, htog(sc->sc_fpcr));
@@ -762,7 +761,7 @@ class Tru64 {
elp->si_phz = htog(clk_hz);
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
elp->si_max_procs = htog(process->numCpus());
- elp.copyOut(xc->mem);
+ elp.copyOut(xc->getMemPtr());
return 0;
}
@@ -783,7 +782,7 @@ class Tru64 {
{
TypedBufferArg<Tru64::vm_stack> argp(xc->getSyscallArg(0));
- argp.copyIn(xc->mem);
+ argp.copyIn(xc->getMemPtr());
// if the user chose an address, just let them have it. Otherwise
// pick one for them.
@@ -792,7 +791,7 @@ class Tru64 {
int stack_size = (htog(argp->rsize) + htog(argp->ysize) +
htog(argp->gsize));
process->next_thread_stack_base -= stack_size;
- argp.copyOut(xc->mem);
+ argp.copyOut(xc->getMemPtr());
}
return 0;
@@ -812,7 +811,7 @@ class Tru64 {
TypedBufferArg<Tru64::nxm_task_attr> attrp(xc->getSyscallArg(0));
TypedBufferArg<Addr> configptr_ptr(xc->getSyscallArg(1));
- attrp.copyIn(xc->mem);
+ attrp.copyIn(xc->getMemPtr());
if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) {
cerr << "nxm_task_init: thread library version mismatch! "
@@ -853,7 +852,7 @@ class Tru64 {
config->nxm_slot_state = htog(slot_state_addr);
config->nxm_rad[0] = htog(rad_state_addr);
- config.copyOut(xc->mem);
+ config.copyOut(xc->getMemPtr());
// initialize the slot_state array and copy it out
TypedBufferArg<Tru64::nxm_slot_state_t> slot_state(slot_state_addr,
@@ -866,7 +865,7 @@ class Tru64 {
(i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL;
}
- slot_state.copyOut(xc->mem);
+ slot_state.copyOut(xc->getMemPtr());
// same for the per-RAD "shared" struct. Note that we need to
// allocate extra bytes for the per-VP array which is embedded at
@@ -900,13 +899,13 @@ class Tru64 {
}
}
- rad_state.copyOut(xc->mem);
+ rad_state.copyOut(xc->getMemPtr());
//
// copy pointer to shared config area out to user
//
*configptr_ptr = htog(config_addr);
- configptr_ptr.copyOut(xc->mem);
+ configptr_ptr.copyOut(xc->getMemPtr());
// Register this as a valid address range with the process
process->nxm_start = base_addr;
@@ -920,15 +919,15 @@ class Tru64 {
init_exec_context(ExecContext *ec,
Tru64::nxm_thread_attr *attrp, uint64_t uniq_val)
{
- memset(&ec->regs, 0, sizeof(ec->regs));
+ ec->clearArchRegs();
- ec->regs.intRegFile[TheISA::ArgumentReg0] = gtoh(attrp->registers.a0);
- ec->regs.intRegFile[27/*t12*/] = gtoh(attrp->registers.pc);
- ec->regs.intRegFile[TheISA::StackPointerReg] = gtoh(attrp->registers.sp);
+ ec->setIntReg(TheISA::ArgumentReg0, gtoh(attrp->registers.a0));
+ ec->setIntReg(27/*t12*/, gtoh(attrp->registers.pc));
+ ec->setIntReg(TheISA::StackPointerReg, gtoh(attrp->registers.sp));
ec->setMiscReg(TheISA::Uniq_DepTag, uniq_val);
- ec->regs.pc = gtoh(attrp->registers.pc);
- ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst);
+ ec->setPC(gtoh(attrp->registers.pc));
+ ec->setNextPC(gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst));
ec->activate();
}
@@ -943,7 +942,7 @@ class Tru64 {
int thread_index = xc->getSyscallArg(2);
// get attribute args
- attrp.copyIn(xc->mem);
+ attrp.copyIn(xc->getMemPtr());
if (gtoh(attrp->version) != NXM_LIB_VERSION) {
cerr << "nxm_thread_create: thread library version mismatch! "
@@ -968,7 +967,7 @@ class Tru64 {
TypedBufferArg<Tru64::nxm_shared> rad_state(0x14000,
rad_state_size);
- rad_state.copyIn(xc->mem);
+ rad_state.copyIn(xc->getMemPtr());
uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset);
@@ -979,7 +978,7 @@ class Tru64 {
// This is supposed to be a port number. Make something up.
*kidp = htog(99);
- kidp.copyOut(xc->mem);
+ kidp.copyOut(xc->getMemPtr());
return 0;
} else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) {
@@ -993,7 +992,7 @@ class Tru64 {
ssp->nxm_u.pth_id = attrp->pthid;
ssp->nxm_u.nxm_active = htog(uniq_val | 1);
- rad_state.copyOut(xc->mem);
+ rad_state.copyOut(xc->getMemPtr());
Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info);
int slot_state_size =
@@ -1003,7 +1002,7 @@ class Tru64 {
slot_state(slot_state_addr,
slot_state_size);
- slot_state.copyIn(xc->mem);
+ slot_state.copyIn(xc->getMemPtr());
if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) {
cerr << "nxm_thread_createFunc: requested VP slot "
@@ -1015,7 +1014,7 @@ class Tru64 {
// doesn't work anyway
slot_state[thread_index] = Tru64::NXM_SLOT_BOUND;
- slot_state.copyOut(xc->mem);
+ slot_state.copyOut(xc->getMemPtr());
// Find a free simulator execution context.
for (int i = 0; i < process->numCpus(); ++i) {
@@ -1029,7 +1028,7 @@ class Tru64 {
// and get away with just sticking the thread index
// here.
*kidp = htog(thread_index);
- kidp.copyOut(xc->mem);
+ kidp.copyOut(xc->getMemPtr());
return 0;
}
@@ -1066,8 +1065,8 @@ class Tru64 {
uint64_t action = xc->getSyscallArg(3);
uint64_t usecs = xc->getSyscallArg(4);
- cout << xc->cpu->name() << ": nxm_thread_block " << tid << " " << secs
- << " " << flags << " " << action << " " << usecs << endl;
+ cout << xc->getCpuPtr()->name() << ": nxm_thread_block " << tid << " "
+ << secs << " " << flags << " " << action << " " << usecs << endl;
return 0;
}
@@ -1083,7 +1082,7 @@ class Tru64 {
uint64_t usecs = xc->getSyscallArg(3);
uint64_t flags = xc->getSyscallArg(4);
- BaseCPU *cpu = xc->cpu;
+ BaseCPU *cpu = xc->getCpuPtr();
cout << cpu->name() << ": nxm_block "
<< hex << uaddr << dec << " " << val
@@ -1100,7 +1099,7 @@ class Tru64 {
{
Addr uaddr = xc->getSyscallArg(0);
- cout << xc->cpu->name() << ": nxm_unblock "
+ cout << xc->getCpuPtr()->name() << ": nxm_unblock "
<< hex << uaddr << dec << endl;
return 0;
@@ -1158,12 +1157,12 @@ class Tru64 {
{
TypedBufferArg<uint64_t> lockp(uaddr);
- lockp.copyIn(xc->mem);
+ lockp.copyIn(xc->getMemPtr());
if (gtoh(*lockp) == 0) {
// lock is free: grab it
*lockp = htog(1);
- lockp.copyOut(xc->mem);
+ lockp.copyOut(xc->getMemPtr());
} else {
// lock is busy: disable until free
process->waitList.push_back(Process::WaitRec(uaddr, xc));
@@ -1177,7 +1176,7 @@ class Tru64 {
{
TypedBufferArg<uint64_t> lockp(uaddr);
- lockp.copyIn(xc->mem);
+ lockp.copyIn(xc->getMemPtr());
assert(*lockp != 0);
// Check for a process waiting on the lock.
@@ -1186,7 +1185,7 @@ class Tru64 {
// clear lock field if no waiting context is taking over the lock
if (num_waiting == 0) {
*lockp = 0;
- lockp.copyOut(xc->mem);
+ lockp.copyOut(xc->getMemPtr());
}
}
@@ -1213,12 +1212,12 @@ class Tru64 {
Addr uaddr = xc->getSyscallArg(0);
TypedBufferArg<uint64_t> lockp(uaddr);
- lockp.copyIn(xc->mem);
+ lockp.copyIn(xc->getMemPtr());
if (gtoh(*lockp) == 0) {
// lock is free: grab it
*lockp = htog(1);
- lockp.copyOut(xc->mem);
+ lockp.copyOut(xc->getMemPtr());
return 0;
} else {
return 1;
@@ -1273,7 +1272,7 @@ class Tru64 {
TypedBufferArg<uint64_t> lockp(lock_addr);
// user is supposed to acquire lock before entering
- lockp.copyIn(xc->mem);
+ lockp.copyIn(xc->getMemPtr());
assert(gtoh(*lockp) != 0);
m5_unlock_mutex(lock_addr, process, xc);
diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc
index 1fd26b87b..8f2be6d9b 100644
--- a/kern/tru64/tru64_events.cc
+++ b/kern/tru64/tru64_events.cc
@@ -35,6 +35,7 @@
#include "mem/functional/memory_control.hh"
#include "arch/arguments.hh"
#include "arch/isa_traits.hh"
+#include "sim/system.hh"
using namespace TheISA;
@@ -47,13 +48,14 @@ BadAddrEvent::process(ExecContext *xc)
// annotation for vmunix::badaddr in:
// simos/simulation/apps/tcl/osf/tlaser.tcl
- uint64_t a0 = xc->regs.intRegFile[ArgumentReg0];
+ uint64_t a0 = xc->readIntReg(ArgumentReg0);
if (!TheISA::IsK0Seg(a0) ||
- xc->memctrl->badaddr(TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) {
+ xc->getSystemPtr()->memctrl->badaddr(
+ TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) {
DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0);
- xc->regs.intRegFile[ReturnValueReg] = 0x1;
+ xc->setIntReg(ReturnValueReg, 0x1);
SkipFuncEvent::process(xc);
}
else
@@ -64,7 +66,7 @@ void
PrintfEvent::process(ExecContext *xc)
{
if (DTRACE(Printf)) {
- DebugOut() << curTick << ": " << xc->cpu->name() << ": ";
+ DebugOut() << curTick << ": " << xc->getCpuPtr()->name() << ": ";
AlphaArguments args(xc);
tru64::Printf(args);
@@ -76,7 +78,7 @@ DebugPrintfEvent::process(ExecContext *xc)
{
if (DTRACE(DebugPrintf)) {
if (!raw)
- DebugOut() << curTick << ": " << xc->cpu->name() << ": ";
+ DebugOut() << curTick << ": " << xc->getCpuPtr()->name() << ": ";
AlphaArguments args(xc);
tru64::Printf(args);
diff --git a/sim/faults.cc b/sim/faults.cc
index 2b93353ce..701384989 100644
--- a/sim/faults.cc
+++ b/sim/faults.cc
@@ -38,8 +38,8 @@ void FaultBase::invoke(ExecContext * xc)
#else
void FaultBase::invoke(ExecContext * xc)
{
- DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc);
- xc->cpu->recordEvent(csprintf("Fault %s", name()));
+ DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->readPC());
+ xc->getCpuPtr()->recordEvent(csprintf("Fault %s", name()));
assert(!xc->misspeculating());
}
diff --git a/sim/process.cc b/sim/process.cc
index 894beeb05..f02ca8bfd 100644
--- a/sim/process.cc
+++ b/sim/process.cc
@@ -37,6 +37,7 @@
#include "base/loader/symtab.hh"
#include "base/statistics.hh"
#include "config/full_system.hh"
+#include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh"
#include "cpu/smt.hh"
#include "encumbered/cpu/full/thread.hh"
@@ -78,6 +79,8 @@ Process::Process(const string &nm,
init_regs = new RegFile;
memset(init_regs, 0, sizeof(RegFile));
+ cpuXC = new CPUExecContext(init_regs);
+
// initialize first 3 fds (stdin, stdout, stderr)
fd_map[STDIN_FILENO] = stdin_fd;
fd_map[STDOUT_FILENO] = stdout_fd;
@@ -146,7 +149,7 @@ Process::registerExecContext(ExecContext *xc)
if (myIndex == 0) {
// copy process's initial regs struct
- xc->regs = *init_regs;
+ xc->copyArchRegs(cpuXC->getProxy());
}
// return CPU number to caller and increment available CPU count
@@ -354,7 +357,7 @@ LiveProcess::syscall(ExecContext *xc)
{
num_syscalls++;
- int64_t callnum = xc->regs.intRegFile[SyscallNumReg];
+ int64_t callnum = xc->readIntReg(SyscallNumReg);
SyscallDesc *desc = getDesc(callnum);
if (desc == NULL)
diff --git a/sim/process.hh b/sim/process.hh
index 71b7d02b3..3a48f128c 100644
--- a/sim/process.hh
+++ b/sim/process.hh
@@ -46,6 +46,7 @@
#include "base/statistics.hh"
#include "base/trace.hh"
+class CPUExecContext;
class ExecContext;
class FunctionalMemory;
class SyscallDesc;
@@ -83,6 +84,7 @@ class Process : public SimObject
std::list<WaitRec> waitList;
RegFile *init_regs; // initial register contents
+ CPUExecContext *cpuXC; // XC to hold the init_regs
Addr text_base; // text (code) segment base
unsigned text_size; // text (code) size in bytes
diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc
index f4285be8a..e475006e7 100644
--- a/sim/pseudo_inst.cc
+++ b/sim/pseudo_inst.cc
@@ -64,7 +64,7 @@ namespace AlphaPseudo
void
arm(ExecContext *xc)
{
- xc->kernelStats->arm();
+ xc->getCpuPtr()->kernelStats->arm();
}
void
@@ -74,7 +74,7 @@ namespace AlphaPseudo
return;
xc->suspend();
- xc->kernelStats->quiesce();
+ xc->getCpuPtr()->kernelStats->quiesce();
}
void
@@ -83,13 +83,15 @@ namespace AlphaPseudo
if (!doQuiesce || ns == 0)
return;
- if (xc->quiesceEvent.scheduled())
- xc->quiesceEvent.reschedule(curTick + Clock::Int::ns * ns);
+ Event *quiesceEvent = xc->getQuiesceEvent();
+
+ if (quiesceEvent->scheduled())
+ quiesceEvent->reschedule(curTick + Clock::Int::ns * ns);
else
- xc->quiesceEvent.schedule(curTick + Clock::Int::ns * ns);
+ quiesceEvent->schedule(curTick + Clock::Int::ns * ns);
xc->suspend();
- xc->kernelStats->quiesce();
+ xc->getCpuPtr()->kernelStats->quiesce();
}
void
@@ -98,25 +100,29 @@ namespace AlphaPseudo
if (!doQuiesce || cycles == 0)
return;
- if (xc->quiesceEvent.scheduled())
- xc->quiesceEvent.reschedule(curTick + xc->cpu->cycles(cycles));
+ Event *quiesceEvent = xc->getQuiesceEvent();
+
+ if (quiesceEvent->scheduled())
+ quiesceEvent->reschedule(curTick +
+ xc->getCpuPtr()->cycles(cycles));
else
- xc->quiesceEvent.schedule(curTick + xc->cpu->cycles(cycles));
+ quiesceEvent->schedule(curTick +
+ xc->getCpuPtr()->cycles(cycles));
xc->suspend();
- xc->kernelStats->quiesce();
+ xc->getCpuPtr()->kernelStats->quiesce();
}
uint64_t
quiesceTime(ExecContext *xc)
{
- return (xc->lastActivate - xc->lastSuspend) / Clock::Int::ns ;
+ return (xc->readLastActivate() - xc->readLastSuspend()) / Clock::Int::ns;
}
void
ivlb(ExecContext *xc)
{
- xc->kernelStats->ivlb();
+ xc->getCpuPtr()->kernelStats->ivlb();
}
void
@@ -174,7 +180,7 @@ namespace AlphaPseudo
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
- xc->system->kernelSymtab->insert(addr,symbol);
+ xc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
}
void
@@ -207,7 +213,7 @@ namespace AlphaPseudo
uint64_t
readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset)
{
- const string &file = xc->cpu->system->params()->readfile;
+ const string &file = xc->getCpuPtr()->system->params()->readfile;
if (file.empty()) {
return ULL(0);
}
diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc
index 682d11267..793c0c6cb 100644
--- a/sim/syscall_emul.cc
+++ b/sim/syscall_emul.cc
@@ -47,12 +47,12 @@ void
SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc)
{
DPRINTFR(SyscallVerbose, "%s: syscall %s called\n",
- xc->cpu->name(), name);
+ xc->getCpuPtr()->name(), name);
SyscallReturn retval = (*funcPtr)(this, callnum, process, xc);
DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n",
- xc->cpu->name(), name, retval.value());
+ xc->getCpuPtr()->name(), name, retval.value());
if (!(flags & SyscallDesc::SuppressReturnValue))
xc->setSyscallReturn(retval);
@@ -130,7 +130,7 @@ readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
int bytes_read = read(fd, bufArg.bufferPtr(), nbytes);
if (bytes_read != -1)
- bufArg.copyOut(xc->mem);
+ bufArg.copyOut(xc->getMemPtr());
return bytes_read;
}
@@ -142,7 +142,7 @@ writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
int nbytes = xc->getSyscallArg(2);
BufferArg bufArg(xc->getSyscallArg(1), nbytes);
- bufArg.copyIn(xc->mem);
+ bufArg.copyIn(xc->getMemPtr());
int bytes_written = write(fd, bufArg.bufferPtr(), nbytes);
@@ -183,7 +183,7 @@ gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
strncpy((char *)name.bufferPtr(), hostname, name_len);
- name.copyOut(xc->mem);
+ name.copyOut(xc->getMemPtr());
return 0;
}
@@ -193,7 +193,7 @@ unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
string path;
- if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
return (TheISA::IntReg)-EFAULT;
int result = unlink(path.c_str());
@@ -205,12 +205,12 @@ renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
string old_name;
- if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != NoFault)
+ if (xc->getMemPtr()->readString(old_name, xc->getSyscallArg(0)) != NoFault)
return -EFAULT;
string new_name;
- if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != NoFault)
+ if (xc->getMemPtr()->readString(new_name, xc->getSyscallArg(1)) != NoFault)
return -EFAULT;
int64_t result = rename(old_name.c_str(), new_name.c_str());
@@ -222,7 +222,7 @@ truncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
string path;
- if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
return -EFAULT;
off_t length = xc->getSyscallArg(1);
@@ -250,7 +250,7 @@ chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
string path;
- if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
return -EFAULT;
/* XXX endianess */
diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh
index 539358b8f..35129bcb4 100644
--- a/sim/syscall_emul.hh
+++ b/sim/syscall_emul.hh
@@ -369,7 +369,7 @@ openFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
return -EFAULT;
if (path == "/dev/sysdev0") {
@@ -416,7 +416,7 @@ chmodFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
return -EFAULT;
uint32_t mode = xc->getSyscallArg(1);
@@ -469,7 +469,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
return -EFAULT;
struct stat hostBuf;
@@ -478,7 +478,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -507,7 +507,7 @@ fstat64Func(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStat64Buf(xc->mem, fd, xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStat64Buf(xc->getMemPtr(), fd, xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -521,7 +521,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
return -EFAULT;
struct stat hostBuf;
@@ -530,7 +530,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -543,7 +543,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
return -EFAULT;
#if BSD_HOST
@@ -557,7 +557,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStat64Buf(xc->mem, -1, xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStat64Buf(xc->getMemPtr(), -1, xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -581,7 +581,7 @@ fstatFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -594,7 +594,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
return -EFAULT;
struct statfs hostBuf;
@@ -603,7 +603,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -626,7 +626,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, Process *process,
if (result < 0)
return -errno;
- OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf);
+ OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf);
return 0;
}
@@ -650,11 +650,11 @@ writevFunc(SyscallDesc *desc, int callnum, Process *process,
for (int i = 0; i < count; ++i)
{
typename OS::tgt_iovec tiov;
- xc->mem->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec),
+ xc->getMemPtr()->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec),
&tiov, sizeof(typename OS::tgt_iovec));
hiov[i].iov_len = gtoh(tiov.iov_len);
hiov[i].iov_base = new char [hiov[i].iov_len];
- xc->mem->access(Read, gtoh(tiov.iov_base),
+ xc->getMemPtr()->access(Read, gtoh(tiov.iov_base),
hiov[i].iov_base, hiov[i].iov_len);
}
@@ -737,7 +737,7 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process,
break;
}
- rlp.copyOut(xc->mem);
+ rlp.copyOut(xc->getMemPtr());
return 0;
}
@@ -754,7 +754,7 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process,
tp->tv_sec = htog(tp->tv_sec);
tp->tv_usec = htog(tp->tv_usec);
- tp.copyOut(xc->mem);
+ tp.copyOut(xc->getMemPtr());
return 0;
}
@@ -768,11 +768,11 @@ utimesFunc(SyscallDesc *desc, int callnum, Process *process,
{
std::string path;
- if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault)
+ if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault)
return -EFAULT;
TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1));
- tp.copyIn(xc->mem);
+ tp.copyIn(xc->getMemPtr());
struct timeval hostTimeval[2];
for (int i = 0; i < 2; ++i)
@@ -824,7 +824,7 @@ getrusageFunc(SyscallDesc *desc, int callnum, Process *process,
rup->ru_nvcsw = 0;
rup->ru_nivcsw = 0;
- rup.copyOut(xc->mem);
+ rup.copyOut(xc->getMemPtr());
return 0;
}