Merge ktlim@zizzer:/bk/m5
into zamp.eecs.umich.edu:/z/ktlim2/m5-proxyxc
Further changes still need to be made to the XC code.
arch/alpha/ev5.cc:
arch/alpha/freebsd/system.cc:
arch/alpha/linux/system.cc:
base/remote_gdb.cc:
cpu/cpu_exec_context.cc:
cpu/cpu_exec_context.hh:
cpu/simple/cpu.cc:
cpu/simple/cpu.hh:
kern/kernel_stats.cc:
sim/pseudo_inst.cc:
Hand merge.
--HG--
rename : kern/freebsd/freebsd_system.cc => arch/alpha/freebsd/system.cc
rename : kern/linux/linux_system.cc => arch/alpha/linux/system.cc
rename : kern/linux/linux_threadinfo.hh => arch/alpha/linux/threadinfo.hh
rename : arch/alpha/alpha_linux_process.cc => arch/alpha/linux_process.cc
rename : arch/alpha/alpha_memory.cc => arch/alpha/tlb.cc
rename : arch/alpha/alpha_tru64_process.cc => arch/alpha/tru64_process.cc
rename : cpu/exec_context.cc => cpu/cpu_exec_context.cc
rename : cpu/exec_context.hh => cpu/cpu_exec_context.hh
extra : convert_revision : c1fe71fdd87d1fcd376f4feec69fc3fa29152e3e
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(®s->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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -174,8 +174,6 @@ extern const int reg_redir[NumIntRegs];
|
||||
ExecContext *xc);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
void clearIprs();
|
||||
|
||||
protected:
|
||||
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
49
cpu/base.cc
49
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 §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
|
||||
UNSERIALIZE_SCALAR(intstatus);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
if (kernelStats)
|
||||
kernelStats->unserialize(cp, section);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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(®s, 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(®s, 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(®s, 0, sizeof(RegFile));
|
||||
proxy = new ProxyExecContext<CPUExecContext>(this);
|
||||
}
|
||||
|
||||
CPUExecContext::CPUExecContext(RegFile *regFile)
|
||||
: cpu(NULL), thread_num(-1), process(NULL), mem(NULL), asid(-1),
|
||||
func_exe_inst(0), storeCondFailures(0)
|
||||
{
|
||||
regs = *regFile;
|
||||
proxy = new ProxyExecContext<CPUExecContext>(this);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ExecContext::~ExecContext()
|
||||
CPUExecContext::~CPUExecContext()
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
delete kernelStats;
|
||||
#endif
|
||||
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 §ion)
|
||||
CPUExecContext::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ENUM(_status);
|
||||
regs.unserialize(cp, section);
|
||||
@@ -185,28 +196,26 @@ ExecContext::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
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());
|
||||
}
|
||||
|
||||
521
cpu/cpu_exec_context.hh
Normal file
521
cpu/cpu_exec_context.hh
Normal file
@@ -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 §ion);
|
||||
|
||||
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(®s, 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__
|
||||
@@ -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;
|
||||
|
||||
void setStatus(Status newStatus) { _status = newStatus; }
|
||||
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;
|
||||
|
||||
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();
|
||||
|
||||
public:
|
||||
RegFile regs; // correct-path register context
|
||||
|
||||
// pointer to CPU associated with this context
|
||||
BaseCPU *cpu;
|
||||
|
||||
// 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;
|
||||
virtual void halt() = 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;
|
||||
|
||||
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;
|
||||
|
||||
virtual void dumpFuncProfile() = 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.
|
||||
*/
|
||||
Addr copySrcPhysAddr;
|
||||
virtual void takeOverFrom(ExecContext *oldContext) = 0;
|
||||
|
||||
virtual void regStats(const std::string &name) = 0;
|
||||
|
||||
/*
|
||||
* number of executed instructions, for matching with syscall trace
|
||||
* points in EIO files.
|
||||
*/
|
||||
Counter func_exe_inst;
|
||||
virtual void serialize(std::ostream &os) = 0;
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion) = 0;
|
||||
|
||||
virtual int getThreadNum() = 0;
|
||||
|
||||
virtual bool validInstAddr(Addr addr) = 0;
|
||||
virtual bool validDataAddr(Addr addr) = 0;
|
||||
virtual int getInstAsid() = 0;
|
||||
virtual int getDataAsid() = 0;
|
||||
|
||||
virtual Fault translateInstReq(MemReqPtr &req) = 0;
|
||||
|
||||
virtual Fault translateDataReadReq(MemReqPtr &req) = 0;
|
||||
|
||||
virtual Fault translateDataWriteReq(MemReqPtr &req) = 0;
|
||||
|
||||
virtual TheISA::MachInst getInst() = 0;
|
||||
|
||||
virtual void copyArchRegs(ExecContext *xc) = 0;
|
||||
|
||||
virtual void clearArchRegs() = 0;
|
||||
|
||||
//
|
||||
// Count failed store conditionals so we can warn of apparent
|
||||
// application deadlock situations.
|
||||
unsigned storeCondFailures;
|
||||
// New accessors for new decoder.
|
||||
//
|
||||
virtual uint64_t readIntReg(int reg_idx) = 0;
|
||||
|
||||
// constructor: initialize context from given process structure
|
||||
#if FULL_SYSTEM
|
||||
ExecContext(BaseCPU *_cpu, int _thread_num, System *_system,
|
||||
AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem);
|
||||
#else
|
||||
ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid);
|
||||
ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
|
||||
int _asid);
|
||||
#endif
|
||||
virtual ~ExecContext();
|
||||
virtual float readFloatRegSingle(int reg_idx) = 0;
|
||||
|
||||
virtual void takeOverFrom(ExecContext *oldContext);
|
||||
virtual double readFloatRegDouble(int reg_idx) = 0;
|
||||
|
||||
void regStats(const std::string &name);
|
||||
virtual uint64_t readFloatRegInt(int reg_idx) = 0;
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
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
|
||||
bool validInstAddr(Addr addr) { return true; }
|
||||
bool validDataAddr(Addr addr) { return true; }
|
||||
int getInstAsid() { return regs.instAsid(); }
|
||||
int getDataAsid() { return regs.dataAsid(); }
|
||||
virtual int readIntrFlag() = 0;
|
||||
virtual void setIntrFlag(int val) = 0;
|
||||
virtual Fault hwrei() = 0;
|
||||
virtual bool inPalMode() = 0;
|
||||
virtual void ev5_trap(Fault fault) = 0;
|
||||
virtual bool simPalCheck(int palFunc) = 0;
|
||||
#endif
|
||||
|
||||
Fault translateInstReq(MemReqPtr &req)
|
||||
{
|
||||
return itb->translate(req);
|
||||
}
|
||||
virtual bool misspeculating() = 0;
|
||||
|
||||
Fault translateDataReadReq(MemReqPtr &req)
|
||||
{
|
||||
return dtb->translate(req, 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?
|
||||
*/
|
||||
|
||||
Fault translateDataWriteReq(MemReqPtr &req)
|
||||
{
|
||||
return dtb->translate(req, true);
|
||||
}
|
||||
virtual void trap(Fault fault) = 0;
|
||||
|
||||
#if !FULL_SYSTEM
|
||||
virtual IntReg getSyscallArg(int i) = 0;
|
||||
|
||||
// used to shift args for indirect syscall
|
||||
virtual void setSyscallArg(int i, IntReg val) = 0;
|
||||
|
||||
virtual void setSyscallReturn(SyscallReturn return_value) = 0;
|
||||
|
||||
virtual void syscall() = 0;
|
||||
|
||||
virtual Counter readFuncExeInst() = 0;
|
||||
|
||||
virtual void setFuncExeInst(Counter new_val) = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class XC>
|
||||
class ProxyExecContext : public ExecContext
|
||||
{
|
||||
public:
|
||||
ProxyExecContext(XC *actual_xc)
|
||||
{ actualXC = actual_xc; }
|
||||
|
||||
private:
|
||||
XC *actualXC;
|
||||
|
||||
public:
|
||||
|
||||
BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); }
|
||||
|
||||
void setCpuId(int id) { actualXC->setCpuId(id); }
|
||||
|
||||
int readCpuId() { return actualXC->readCpuId(); }
|
||||
|
||||
FunctionalMemory *getMemPtr() { return actualXC->getMemPtr(); }
|
||||
|
||||
#if FULL_SYSTEM
|
||||
System *getSystemPtr() { return actualXC->getSystemPtr(); }
|
||||
|
||||
PhysicalMemory *getPhysMemPtr() { return actualXC->getPhysMemPtr(); }
|
||||
|
||||
AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
|
||||
|
||||
AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
|
||||
#else
|
||||
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);
|
||||
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;
|
||||
}
|
||||
Status status() const { return actualXC->status(); }
|
||||
|
||||
/// Set the status to Active. Optional delay indicates number of
|
||||
/// cycles to wait before beginning execution.
|
||||
void activate(int delay = 1) { actualXC->activate(delay); }
|
||||
|
||||
/// Set the status to Suspended.
|
||||
void suspend() { actualXC->suspend(); }
|
||||
|
||||
/// Set the status to Unallocated.
|
||||
void deallocate() { actualXC->deallocate(); }
|
||||
|
||||
/// Set the status to Halted.
|
||||
void halt() { actualXC->halt(); }
|
||||
|
||||
#if FULL_SYSTEM
|
||||
void dumpFuncProfile() { actualXC->dumpFuncProfile(); }
|
||||
#endif
|
||||
|
||||
void takeOverFrom(ExecContext *oldContext)
|
||||
{ actualXC->takeOverFrom(oldContext); }
|
||||
|
||||
void regStats(const std::string &name) { actualXC->regStats(name); }
|
||||
|
||||
void serialize(std::ostream &os) { actualXC->serialize(os); }
|
||||
void unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{ actualXC->unserialize(cp, section); }
|
||||
|
||||
int getThreadNum() { return actualXC->getThreadNum(); }
|
||||
|
||||
bool validInstAddr(Addr addr) { return actualXC->validInstAddr(addr); }
|
||||
bool validDataAddr(Addr addr) { return actualXC->validDataAddr(addr); }
|
||||
int getInstAsid() { return actualXC->getInstAsid(); }
|
||||
int getDataAsid() { return actualXC->getDataAsid(); }
|
||||
|
||||
Fault translateInstReq(MemReqPtr &req)
|
||||
{
|
||||
return dummyTranslation(req);
|
||||
}
|
||||
{ return actualXC->translateInstReq(req); }
|
||||
|
||||
Fault translateDataReadReq(MemReqPtr &req)
|
||||
{
|
||||
return dummyTranslation(req);
|
||||
}
|
||||
{ return actualXC->translateDataReadReq(req); }
|
||||
|
||||
Fault translateDataWriteReq(MemReqPtr &req)
|
||||
{
|
||||
return dummyTranslation(req);
|
||||
}
|
||||
{ return actualXC->translateDataWriteReq(req); }
|
||||
|
||||
#endif
|
||||
// @todo: Do I need this?
|
||||
MachInst getInst() { return actualXC->getInst(); }
|
||||
|
||||
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
|
||||
// @todo: Do I need this?
|
||||
void copyArchRegs(ExecContext *xc) { actualXC->copyArchRegs(xc); }
|
||||
|
||||
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)
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#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 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();
|
||||
}
|
||||
}
|
||||
{ actualXC->setSyscallReturn(return_value); }
|
||||
|
||||
void syscall()
|
||||
{
|
||||
process->syscall(this);
|
||||
}
|
||||
void syscall() { actualXC->syscall(); }
|
||||
|
||||
Counter readFuncExeInst() { return actualXC->readFuncExeInst(); }
|
||||
|
||||
void setFuncExeInst(Counter new_val)
|
||||
{ return actualXC->setFuncExeInst(new_val); }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// for non-speculative execution context, spec_mode is always false
|
||||
inline bool
|
||||
ExecContext::misspeculating()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // __CPU_EXEC_CONTEXT_HH__
|
||||
#endif
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ¶ms)
|
||||
renameQueue(5, 5),
|
||||
iewQueue(5, 5),
|
||||
|
||||
xc(NULL),
|
||||
cpuXC(NULL),
|
||||
|
||||
globalSeqNum(1),
|
||||
|
||||
@@ -134,8 +135,8 @@ FullO3CPU<Impl>::FullO3CPU(Params ¶ms)
|
||||
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 ¶ms)
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 §ion)
|
||||
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 ||
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user