summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConscript2
-rw-r--r--arch/alpha/arguments.cc8
-rw-r--r--arch/alpha/ev5.cc73
-rw-r--r--arch/alpha/freebsd/system.cc8
-rw-r--r--arch/alpha/isa/decoder.isa2
-rw-r--r--arch/alpha/isa_traits.hh2
-rw-r--r--arch/alpha/linux/system.cc4
-rw-r--r--arch/alpha/linux/threadinfo.hh2
-rw-r--r--arch/alpha/linux_process.cc8
-rw-r--r--arch/alpha/stacktrace.cc29
-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--base/remote_gdb.cc22
-rw-r--r--cpu/base.cc49
-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)105
-rw-r--r--cpu/cpu_exec_context.hh521
-rw-r--r--cpu/exec_context.hh566
-rw-r--r--cpu/exetrace.cc1
-rw-r--r--cpu/intr_control.cc8
-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.hh45
-rw-r--r--cpu/o3/alpha_cpu_builder.cc1
-rw-r--r--cpu/o3/alpha_cpu_impl.hh51
-rw-r--r--cpu/o3/cpu.cc33
-rw-r--r--cpu/o3/cpu.hh21
-rw-r--r--cpu/pc_event.cc7
-rw-r--r--cpu/simple/cpu.cc137
-rw-r--r--cpu/simple/cpu.hh53
-rw-r--r--dev/tsunami_cchip.cc2
-rw-r--r--kern/kernel_stats.cc30
-rw-r--r--kern/kernel_stats.hh13
-rw-r--r--kern/system_events.cc21
-rw-r--r--kern/tru64/dump_mbuf.cc2
-rw-r--r--kern/tru64/tru64.hh79
-rw-r--r--kern/tru64/tru64_events.cc11
-rw-r--r--sim/process.cc7
-rw-r--r--sim/process.hh2
-rw-r--r--sim/pseudo_inst.cc10
-rw-r--r--sim/syscall_emul.cc20
-rw-r--r--sim/syscall_emul.hh40
46 files changed, 1300 insertions, 795 deletions
diff --git a/SConscript b/SConscript
index efcb2baf6..a405d252f 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/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..11faf1850 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,12 +155,6 @@ ExecContext::hwrei()
return NoFault;
}
-void
-AlphaISA::MiscRegFile::clearIprs()
-{
- bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg));
-}
-
AlphaISA::MiscReg
AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc)
{
@@ -213,7 +210,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 +227,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 +324,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 +351,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 +432,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 +470,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 +494,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 +502,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:
@@ -535,9 +534,9 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
* 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/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 a551db485..b4084723f 100644
--- a/arch/alpha/isa_traits.hh
+++ b/arch/alpha/isa_traits.hh
@@ -174,8 +174,6 @@ extern const int reg_redir[NumIntRegs];
ExecContext *xc);
#if FULL_SYSTEM
- void clearIprs();
-
protected:
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
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/linux_process.cc b/arch/alpha/linux_process.cc
index 0b193fb55..b80966133 100644
--- a/arch/alpha/linux_process.cc
+++ b/arch/alpha/linux_process.cc
@@ -61,7 +61,7 @@ pipeFunc(SyscallDesc *desc, int callnum, Process *process,
// Alpha Linux convention for pipe() is that fd[0] is returned as
// the return value of the function, and fd[1] is returned in r20.
- xc->regs.intRegFile[20] = sim_fds[1];
+ xc->setIntReg(20, sim_fds[1]);
return sim_fds[0];
}
@@ -79,7 +79,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;
}
@@ -99,7 +99,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;
}
@@ -125,7 +125,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/stacktrace.cc b/arch/alpha/stacktrace.cc
index 89b6b73a9..50f2e4d21 100644
--- a/arch/alpha/stacktrace.cc
+++ b/arch/alpha/stacktrace.cc
@@ -44,23 +44,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 +126,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 +140,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 +150,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 +182,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 +324,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 90e8b1139..5f6b802e9 100644
--- a/arch/alpha/tru64_process.cc
+++ b/arch/alpha/tru64_process.cc
@@ -52,7 +52,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;
}
@@ -69,21 +69,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;
}
@@ -100,14 +100,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;
}
@@ -116,14 +116,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/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..e2a4c214a 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
}
@@ -253,11 +271,11 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
for (int i = 0; i < TheISA::NumInterruptLevels; ++i)
interrupts[i] = oldCPU->interrupts[i];
intstatus = oldCPU->intstatus;
-
+/*
for (int i = 0; i < execContexts.size(); ++i)
if (execContexts[i]->profile)
execContexts[i]->profile->clear();
-
+*/
if (profileEvent)
profileEvent->schedule(curTick);
#endif
@@ -272,11 +290,11 @@ BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval)
void
BaseCPU::ProfileEvent::process()
{
- for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) {
+/* for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) {
ExecContext *xc = cpu->execContexts[i];
xc->profile->sample(xc->profileNode, xc->profilePC);
}
-
+*/
schedule(curTick + interval);
}
@@ -327,6 +345,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 +358,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..ae428646d 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,24 @@ 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)
{
- 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 +79,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,30 +87,38 @@ 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);
}
ExecContext::EndQuiesceEvent::EndQuiesceEvent(ExecContext *_xc)
@@ -130,8 +140,9 @@ ExecContext::EndQuiesceEvent::description()
#endif
void
-ExecContext::takeOverFrom(ExecContext *oldContext)
+CPUExecContext::takeOverFrom(ExecContext *oldContext)
{
+/*
// some things should already be set up
assert(mem == oldContext->mem);
#if FULL_SYSTEM
@@ -148,11 +159,12 @@ ExecContext::takeOverFrom(ExecContext *oldContext)
storeCondFailures = 0;
- oldContext->_status = ExecContext::Unallocated;
+ oldContext->_status = CPUExecContext::Unallocated;
+*/
}
void
-ExecContext::serialize(ostream &os)
+CPUExecContext::serialize(ostream &os)
{
SERIALIZE_ENUM(_status);
regs.serialize(os);
@@ -165,14 +177,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 +196,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 +224,65 @@ 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
+ setMiscReg(AlphaISA::Fpcr_DepTag, xc->readMiscReg(AlphaISA::Fpcr_DepTag));
+ setMiscReg(AlphaISA::Uniq_DepTag, xc->readMiscReg(AlphaISA::Uniq_DepTag));
+ setMiscReg(AlphaISA::Lock_Flag_DepTag,
+ xc->readMiscReg(AlphaISA::Lock_Flag_DepTag));
+ setMiscReg(AlphaISA::Lock_Addr_DepTag,
+ xc->readMiscReg(AlphaISA::Lock_Addr_DepTag));
+
+ // 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..a40253d4b
--- /dev/null
+++ b/cpu/cpu_exec_context.hh
@@ -0,0 +1,521 @@
+/*
+ * 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 */
+ ExecContext *xc;
+
+ EndQuiesceEvent(ExecContext *_xc);
+
+ /** Event process to occur at interrupt*/
+ virtual void process();
+
+ /** Event description */
+ virtual const char *description();
+ };
+ EndQuiesceEvent quiesceEvent;
+
+#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;
+ }
+
+ 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)
+ {
+ // check for error condition. Alpha syscall convention is to
+ // indicate success/failure in reg a3 (r19) and put the
+ // return value itself in the standard return value reg (v0).
+ const int RegA3 = 19; // only place this is used
+ if (return_value.successful()) {
+ // no error
+ regs.intRegFile[RegA3] = 0;
+ regs.intRegFile[TheISA::ReturnValueReg] = return_value.value();
+ } else {
+ // got an error, return details
+ regs.intRegFile[RegA3] = (TheISA::IntReg) -1;
+ regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value();
+ }
+ }
+
+ 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 bc3551b4f..9c96b5c42 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,29 @@
#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 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 +69,7 @@ class ExecContext
Active,
/// Temporarily inactive. Entered while waiting for
- /// initialization,synchronization, etc.
+ /// synchronization, etc.
Suspended,
/// Permanently shut down. Entered when target executes
@@ -96,402 +78,326 @@ 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;
/// 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 *oldContext) = 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;
+ virtual int getThreadNum() = 0;
- Tick lastActivate;
- Tick lastSuspend;
+ virtual bool validInstAddr(Addr addr) = 0;
+ virtual bool validDataAddr(Addr addr) = 0;
+ virtual int getInstAsid() = 0;
+ virtual int getDataAsid() = 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 Fault translateInstReq(MemReqPtr &req) = 0;
- EndQuiesceEvent(ExecContext *_xc);
+ virtual Fault translateDataReadReq(MemReqPtr &req) = 0;
- /** Event process to occur at interrupt*/
- virtual void process();
+ virtual Fault translateDataWriteReq(MemReqPtr &req) = 0;
- /** Event description */
- virtual const char *description();
- };
- EndQuiesceEvent quiesceEvent;
+ virtual TheISA::MachInst getInst() = 0;
-#else
- Process *process;
+ virtual void copyArchRegs(ExecContext *xc) = 0;
+
+ virtual void clearArchRegs() = 0;
+
+ //
+ // New accessors for new decoder.
+ //
+ virtual uint64_t readIntReg(int reg_idx) = 0;
+
+ virtual float readFloatRegSingle(int reg_idx) = 0;
+
+ virtual double readFloatRegDouble(int reg_idx) = 0;
- FunctionalMemory *mem; // functional storage for process address space
+ virtual uint64_t readFloatRegInt(int reg_idx) = 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;
+ 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 setPC(uint64_t val) = 0;
+
+ virtual uint64_t readNextPC() = 0;
+
+ 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;
+
+ virtual unsigned readStCondFailures() = 0;
+
+ virtual void setStCondFailures(unsigned sc_failures) = 0;
+
+#if FULL_SYSTEM
+ virtual int readIntrFlag() = 0;
+ virtual void setIntrFlag(int val) = 0;
+ virtual Fault hwrei() = 0;
+ virtual bool inPalMode() = 0;
+ virtual void ev5_trap(Fault fault) = 0;
+ virtual bool simPalCheck(int palFunc) = 0;
#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.
+ virtual bool misspeculating() = 0;
+
+ /** Meant to be more generic trap function to be
+ * called when an instruction faults.
+ * @param fault The fault generated by executing the instruction.
+ * @todo How to do this properly so it's dependent upon ISA only?
*/
- Addr copySrcPhysAddr;
+ virtual void trap(Fault fault) = 0;
- /*
- * number of executed instructions, for matching with syscall trace
- * points in EIO files.
- */
- Counter func_exe_inst;
+#if !FULL_SYSTEM
+ virtual IntReg getSyscallArg(int i) = 0;
- //
- // Count failed store conditionals so we can warn of apparent
- // application deadlock situations.
- unsigned storeCondFailures;
+ // used to shift args for indirect syscall
+ virtual void setSyscallArg(int i, IntReg val) = 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);
+ virtual void setSyscallReturn(SyscallReturn return_value) = 0;
+
+ virtual void syscall() = 0;
+
+ virtual Counter readFuncExeInst() = 0;
+
+ virtual void setFuncExeInst(Counter new_val) = 0;
#endif
- virtual ~ExecContext();
+};
- virtual void takeOverFrom(ExecContext *oldContext);
+template <class XC>
+class ProxyExecContext : public ExecContext
+{
+ public:
+ ProxyExecContext(XC *actual_xc)
+ { actualXC = actual_xc; }
- void regStats(const std::string &name);
+ private:
+ XC *actualXC;
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
+ public:
-#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(); }
+ BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); }
- Fault translateInstReq(MemReqPtr &req)
- {
- return itb->translate(req);
- }
+ void setCpuId(int id) { actualXC->setCpuId(id); }
- Fault translateDataReadReq(MemReqPtr &req)
- {
- return dtb->translate(req, false);
- }
+ int readCpuId() { return actualXC->readCpuId(); }
- Fault translateDataWriteReq(MemReqPtr &req)
- {
- return dtb->translate(req, true);
- }
+ FunctionalMemory *getMemPtr() { return actualXC->getMemPtr(); }
-#else
- bool validInstAddr(Addr addr)
- { return process->validInstAddr(addr); }
+#if FULL_SYSTEM
+ System *getSystemPtr() { return actualXC->getSystemPtr(); }
- bool validDataAddr(Addr addr)
- { return process->validDataAddr(addr); }
+ PhysicalMemory *getPhysMemPtr() { return actualXC->getPhysMemPtr(); }
- int getInstAsid() { return asid; }
- int getDataAsid() { return asid; }
+ AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
- Fault dummyTranslation(MemReqPtr &req)
- {
-#if 0
- assert((req->vaddr >> 48 & 0xffff) == 0);
+ AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
+#else
+ Process *getProcessPtr() { return actualXC->getProcessPtr(); }
#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);
- }
+ Status status() const { return actualXC->status(); }
-#endif
+ /// Set the status to Active. Optional delay indicates number of
+ /// cycles to wait before beginning execution.
+ void activate(int delay = 1) { actualXC->activate(delay); }
- 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);
- }
-#endif
+ /// Set the status to Suspended.
+ void suspend() { actualXC->suspend(); }
- Fault error;
- error = mem->read(req, data);
- data = LittleEndianGuest::gtoh(data);
- return error;
- }
+ /// Set the status to Unallocated.
+ void deallocate() { actualXC->deallocate(); }
- 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);
- }
- }
+ /// Set the status to Halted.
+ void halt() { actualXC->halt(); }
+#if FULL_SYSTEM
+ void dumpFuncProfile() { actualXC->dumpFuncProfile(); }
#endif
- return mem->write(req, (T)LittleEndianGuest::htog(data));
- }
- virtual bool misspeculating();
+ void takeOverFrom(ExecContext *oldContext)
+ { actualXC->takeOverFrom(oldContext); }
+ void regStats(const std::string &name) { actualXC->regStats(name); }
- MachInst getInst() { return inst; }
+ void serialize(std::ostream &os) { actualXC->serialize(os); }
+ void unserialize(Checkpoint *cp, const std::string &section)
+ { actualXC->unserialize(cp, section); }
- void setInst(MachInst new_inst)
- {
- inst = new_inst;
- }
+ int getThreadNum() { return actualXC->getThreadNum(); }
- Fault instRead(MemReqPtr &req)
- {
- return mem->read(req, inst);
- }
+ 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(); }
+
+ Fault translateInstReq(MemReqPtr &req)
+ { return actualXC->translateInstReq(req); }
+
+ Fault translateDataReadReq(MemReqPtr &req)
+ { return actualXC->translateDataReadReq(req); }
+
+ 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(); }
+
+ void ev5_trap(Fault fault) { actualXC->ev5_trap(fault); }
+
+ bool simPalCheck(int palFunc) { return actualXC->simPalCheck(palFunc); }
#endif
+ // @todo: Fix this!
+ bool misspeculating() { return false; }
+
+ /** Meant to be more generic trap function to be
+ * called when an instruction faults.
+ * @param fault The fault generated by executing the instruction.
+ * @todo How to do this properly so it's dependent upon ISA only?
+ */
+
+ void trap(Fault fault) { actualXC->trap(fault); }
+
#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)
- {
- // check for error condition. Alpha syscall convention is to
- // indicate success/failure in reg a3 (r19) and put the
- // return value itself in the standard return value reg (v0).
- const int RegA3 = 19; // only place this is used
- if (return_value.successful()) {
- // no error
- regs.intRegFile[RegA3] = 0;
- regs.intRegFile[TheISA::ReturnValueReg] = return_value.value();
- } else {
- // got an error, return details
- regs.intRegFile[RegA3] = (TheISA::IntReg) -1;
- regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value();
- }
- }
-
- void syscall()
- {
- process->syscall(this);
- }
-#endif
-};
+ { actualXC->setSyscallReturn(return_value); }
+ void syscall() { actualXC->syscall(); }
-// for non-speculative execution context, spec_mode is always false
-inline bool
-ExecContext::misspeculating()
-{
- return false;
-}
+ Counter readFuncExeInst() { return actualXC->readFuncExeInst(); }
-#endif // __CPU_EXEC_CONTEXT_HH__
+ void setFuncExeInst(Counter new_val)
+ { return actualXC->setFuncExeInst(new_val); }
+#endif
+};
+
+#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..d1866a0c4 100644
--- a/cpu/intr_control.cc
+++ b/cpu/intr_control.cc
@@ -48,7 +48,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 +56,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 +64,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 +72,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..531f6aa45 100644
--- a/cpu/o3/alpha_cpu.hh
+++ b/cpu/o3/alpha_cpu.hh
@@ -152,13 +152,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 +169,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 +208,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 +229,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 +266,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..33e363d4f 100644
--- a/cpu/o3/alpha_cpu_impl.hh
+++ b/cpu/o3/alpha_cpu_impl.hh
@@ -165,7 +165,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 +174,23 @@ 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->cpuXC->regs.miscRegs.fpcr = this->regFile.miscRegs.fpcr;
+ this->cpuXC->regs.miscRegs.uniq = this->regFile.miscRegs.uniq;
+ this->cpuXC->regs.miscRegs.lock_flag = this->regFile.miscRegs.lock_flag;
+ this->cpuXC->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->cpuXC->setPC(this->rob.readHeadPC());
+ this->cpuXC->setNextPC(this->cpuXC->readPC()+4);
- this->xc->func_exe_inst = this->funcExeInst;
+#if !FULL_SYSTEM
+ this->cpuXC->setFuncExeInst(this->funcExeInst);
+#endif
}
// This function will probably mess things up unless the ROB is empty and
@@ -207,9 +209,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 +219,23 @@ 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;
+ this->regFile.miscRegs.fpcr = this->cpuXC->regs.miscRegs.fpcr;
+ this->regFile.miscRegs.uniq = this->cpuXC->regs.miscRegs.uniq;
+ this->regFile.miscRegs.lock_flag = this->cpuXC->regs.miscRegs.lock_flag;
+ this->regFile.miscRegs.lock_addr = this->cpuXC->regs.miscRegs.lock_addr;
*/
// Then finally set the PC and the next PC.
-// regFile.pc = xc->regs.pc;
-// regFile.npc = xc->regs.npc;
-
- this->funcExeInst = this->xc->func_exe_inst;
+// regFile.pc = cpuXC->regs.pc;
+// regFile.npc = cpuXC->regs.npc;
+#if !FULL_SYSTEM
+ this->funcExeInst = this->cpuXC->readFuncExeInst();
+#endif
}
#if FULL_SYSTEM
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..8f29a25fb 100644
--- a/cpu/o3/cpu.hh
+++ b/cpu/o3/cpu.hh
@@ -44,9 +44,9 @@
#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
@@ -54,6 +54,7 @@
using namespace EV5;
#endif
+class ExecContext;
class FunctionalMemory;
class Process;
@@ -164,8 +165,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 +321,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 +346,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/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/simple/cpu.cc b/cpu/simple/cpu.cc
index 51d679a63..38b43fef5 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;
@@ -764,29 +768,30 @@ SimpleCPU::tick()
inst = gtoh(inst);
curStaticInst = StaticInst::decode(makeExtMI(inst, xc->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,29 @@ 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 {
// go to the next instruction
- xc->regs.pc = xc->regs.npc;
- xc->regs.npc += sizeof(MachInst);
+ cpuXC->setPC(cpuXC->readNextPC());
+ cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst));
}
#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/tsunami_cchip.cc b/dev/tsunami_cchip.cc
index 4dc4413a1..d311df4f5 100644
--- a/dev/tsunami_cchip.cc
+++ b/dev/tsunami_cchip.cc
@@ -113,7 +113,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/kern/kernel_stats.cc b/kern/kernel_stats.cc
index 33485ca15..988b0f639 100644
--- a/kern/kernel_stats.cc
+++ b/kern/kernel_stats.cc
@@ -43,11 +43,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
@@ -193,16 +193,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]++;
@@ -215,7 +215,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;
@@ -238,7 +238,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);
@@ -249,20 +249,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;
@@ -271,7 +271,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]++;
@@ -279,8 +279,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 4896a0705..c0a7fb858 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);
@@ -182,11 +181,11 @@ class Statistics : public Serializable
fault->stat()++;
}// FIXME: When there are no generic system fault objects, this will go back to _faults[fault]++; }
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/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..25ed82ef3 100644
--- a/kern/tru64/dump_mbuf.cc
+++ b/kern/tru64/dump_mbuf.cc
@@ -61,7 +61,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..12aae6950 100644
--- a/kern/tru64/tru64_events.cc
+++ b/kern/tru64/tru64_events.cc
@@ -47,13 +47,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 +65,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 +77,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/process.cc b/sim/process.cc
index fddd9a0b9..851192dcd 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[ReturnValueReg];
+ int64_t callnum = xc->readIntReg(ReturnValueReg);
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..85b26ef23 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
@@ -116,7 +116,7 @@ namespace AlphaPseudo
void
ivlb(ExecContext *xc)
{
- xc->kernelStats->ivlb();
+ xc->getCpuPtr()->kernelStats->ivlb();
}
void
@@ -174,7 +174,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 +207,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 d22dde3b8..2f6ed128d 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 eca9f79e0..cadaa1cd3 100644
--- a/sim/syscall_emul.hh
+++ b/sim/syscall_emul.hh
@@ -321,7 +321,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") {
@@ -368,7 +368,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);
@@ -421,7 +421,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;
@@ -430,7 +430,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;
}
@@ -459,7 +459,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;
}
@@ -473,7 +473,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;
@@ -482,7 +482,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;
}
@@ -495,7 +495,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
@@ -509,7 +509,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;
}
@@ -533,7 +533,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;
}
@@ -546,7 +546,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;
@@ -555,7 +555,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;
}
@@ -578,7 +578,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;
}
@@ -602,11 +602,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);
}
@@ -689,7 +689,7 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process,
break;
}
- rlp.copyOut(xc->mem);
+ rlp.copyOut(xc->getMemPtr());
return 0;
}
@@ -706,7 +706,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;
}
@@ -720,11 +720,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)
@@ -776,7 +776,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;
}