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:
Kevin Lim
2006-03-05 00:34:54 -05:00
46 changed files with 1318 additions and 813 deletions

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -34,6 +34,7 @@
#include "base/stats/events.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh"
#include "cpu/fast/cpu.hh"
#include "kern/kernel_stats.hh"
@@ -49,15 +50,15 @@ using namespace EV5;
// Machine dependent functions
//
void
AlphaISA::initCPU(RegFile *regs, int cpuId)
AlphaISA::initCPU(ExecContext *xc, int cpuId)
{
initIPRs(&regs->miscRegs, cpuId);
initIPRs(xc, cpuId);
regs->intRegFile[16] = cpuId;
regs->intRegFile[0] = cpuId;
xc->setIntReg(16, cpuId);
xc->setIntReg(0, cpuId);
regs->pc = regs->miscRegs.readReg(IPR_PAL_BASE) + (new ResetFault)->vect();
regs->npc = regs->pc + sizeof(MachInst);
xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + (new ResetFault)->vect());
xc->setNextPC(xc->readPC() + sizeof(MachInst));
}
////////////////////////////////////////////////////////////////////////
@@ -65,13 +66,15 @@ AlphaISA::initCPU(RegFile *regs, int cpuId)
//
//
void
AlphaISA::initIPRs(MiscRegFile *miscRegs, int cpuId)
AlphaISA::initIPRs(ExecContext *xc, int cpuId)
{
miscRegs->clearIprs();
for (int i = 0; i < NumInternalProcRegs; ++i) {
xc->setMiscReg(i, 0);
}
miscRegs->setReg(IPR_PAL_BASE, PalBase);
miscRegs->setReg(IPR_MCSR, 0x6);
miscRegs->setReg(IPR_PALtemp16, cpuId);
xc->setMiscReg(IPR_PAL_BASE, PalBase);
xc->setMiscReg(IPR_MCSR, 0x6);
xc->setMiscReg(IPR_PALtemp16, cpuId);
}
@@ -130,12 +133,12 @@ AlphaISA::zeroRegisters(CPU *cpu)
// Insure ISA semantics
// (no longer very clean due to the change in setIntReg() in the
// cpu model. Consider changing later.)
cpu->xc->setIntReg(ZeroReg, 0);
cpu->xc->setFloatRegDouble(ZeroReg, 0.0);
cpu->cpuXC->setIntReg(ZeroReg, 0);
cpu->cpuXC->setFloatRegDouble(ZeroReg, 0.0);
}
Fault
ExecContext::hwrei()
CPUExecContext::hwrei()
{
if (!inPalMode())
return new UnimplementedOpcodeFault;
@@ -143,7 +146,7 @@ ExecContext::hwrei()
setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR));
if (!misspeculating()) {
kernelStats->hwrei();
cpu->kernelStats->hwrei();
cpu->checkInterrupts = true;
}
@@ -152,12 +155,6 @@ ExecContext::hwrei()
return NoFault;
}
void
AlphaISA::MiscRegFile::clearIprs()
{
bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg));
}
AlphaISA::MiscReg
AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc)
{
@@ -213,7 +210,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc)
case AlphaISA::IPR_CC:
retval |= ipr[idx] & ULL(0xffffffff00000000);
retval |= xc->cpu->curCycle() & ULL(0x00000000ffffffff);
retval |= xc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff);
break;
case AlphaISA::IPR_VA:
@@ -230,7 +227,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc)
case AlphaISA::IPR_DTB_PTE:
{
AlphaISA::PTE &pte = xc->dtb->index(!xc->misspeculating());
AlphaISA::PTE &pte = xc->getDTBPtr()->index(!xc->misspeculating());
retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32;
retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8;
@@ -327,7 +324,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// write entire quad w/ no side-effect
old = ipr[idx];
ipr[idx] = val;
xc->kernelStats->context(old, val);
xc->getCpuPtr()->kernelStats->context(old, val, xc);
break;
case AlphaISA::IPR_DTB_PTE:
@@ -354,14 +351,14 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// only write least significant five bits - interrupt level
ipr[idx] = val & 0x1f;
xc->kernelStats->swpipl(ipr[idx]);
xc->getCpuPtr()->kernelStats->swpipl(ipr[idx]);
break;
case AlphaISA::IPR_DTB_CM:
if (val & 0x18)
xc->kernelStats->mode(Kernel::user);
xc->getCpuPtr()->kernelStats->mode(Kernel::user, xc);
else
xc->kernelStats->mode(Kernel::kernel);
xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc);
case AlphaISA::IPR_ICM:
// only write two mode bits - processor mode
@@ -435,21 +432,22 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// really a control write
ipr[idx] = 0;
xc->dtb->flushAll();
xc->getDTBPtr()->flushAll();
break;
case AlphaISA::IPR_DTB_IAP:
// really a control write
ipr[idx] = 0;
xc->dtb->flushProcesses();
xc->getDTBPtr()->flushProcesses();
break;
case AlphaISA::IPR_DTB_IS:
// really a control write
ipr[idx] = val;
xc->dtb->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
xc->getDTBPtr()->flushAddr(val,
DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
break;
case AlphaISA::IPR_DTB_TAG: {
@@ -472,7 +470,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]);
// insert new TAG/PTE value into data TLB
xc->dtb->insert(val, pte);
xc->getDTBPtr()->insert(val, pte);
}
break;
@@ -496,7 +494,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]);
// insert new TAG/PTE value into data TLB
xc->itb->insert(ipr[AlphaISA::IPR_ITB_TAG], pte);
xc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte);
}
break;
@@ -504,21 +502,22 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// really a control write
ipr[idx] = 0;
xc->itb->flushAll();
xc->getITBPtr()->flushAll();
break;
case AlphaISA::IPR_ITB_IAP:
// really a control write
ipr[idx] = 0;
xc->itb->flushProcesses();
xc->getITBPtr()->flushProcesses();
break;
case AlphaISA::IPR_ITB_IS:
// really a control write
ipr[idx] = val;
xc->itb->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]));
xc->getITBPtr()->flushAddr(val,
ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]));
break;
default:
@@ -535,9 +534,9 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
* If return value is false, actual PAL call will be suppressed.
*/
bool
ExecContext::simPalCheck(int palFunc)
CPUExecContext::simPalCheck(int palFunc)
{
kernelStats->callpal(palFunc);
cpu->kernelStats->callpal(palFunc, proxy);
switch (palFunc) {
case PAL::halt:

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -174,8 +174,6 @@ extern const int reg_redir[NumIntRegs];
ExecContext *xc);
#if FULL_SYSTEM
void clearIprs();
protected:
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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");

View File

@@ -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));

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -39,10 +39,16 @@
#include "cpu/profile.hh"
#include "cpu/sampler/sampler.hh"
#include "sim/param.hh"
#include "sim/process.hh"
#include "sim/sim_events.hh"
#include "sim/system.hh"
#include "base/trace.hh"
#if FULL_SYSTEM
#include "kern/kernel_stats.hh"
#endif
using namespace std;
vector<BaseCPU *> BaseCPU::cpuList;
@@ -147,7 +153,10 @@ BaseCPU::BaseCPU(Params *p)
profileEvent = NULL;
if (params->profile)
profileEvent = new ProfileEvent(this, params->profile);
kernelStats = new Kernel::Statistics(system);
#endif
}
BaseCPU::Params::Params()
@@ -165,6 +174,10 @@ BaseCPU::enableFunctionTrace()
BaseCPU::~BaseCPU()
{
#if FULL_SYSTEM
if (kernelStats)
delete kernelStats;
#endif
}
void
@@ -203,6 +216,11 @@ BaseCPU::regStats()
}
} else if (size == 1)
execContexts[0]->regStats(name());
#if FULL_SYSTEM
if (kernelStats)
kernelStats->regStats(name() + ".kern");
#endif
}
@@ -216,9 +234,9 @@ BaseCPU::registerExecContexts()
if (id != -1)
id += i;
xc->cpu_id = system->registerExecContext(xc, id);
xc->setCpuId(system->registerExecContext(xc, id));
#else
xc->cpu_id = xc->process->registerExecContext(xc);
xc->setCpuId(xc->getProcessPtr()->registerExecContext(xc));
#endif
}
}
@@ -240,12 +258,12 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
ExecContext *oldXC = oldCPU->execContexts[i];
newXC->takeOverFrom(oldXC);
assert(newXC->cpu_id == oldXC->cpu_id);
assert(newXC->readCpuId() == oldXC->readCpuId());
#if FULL_SYSTEM
system->replaceExecContext(newXC, newXC->cpu_id);
system->replaceExecContext(newXC, newXC->readCpuId());
#else
assert(newXC->process == oldXC->process);
newXC->process->replaceExecContext(newXC, newXC->cpu_id);
assert(newXC->getProcessPtr() == oldXC->getProcessPtr());
newXC->getProcessPtr()->replaceExecContext(newXC, newXC->readCpuId());
#endif
}
@@ -253,11 +271,11 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
for (int i = 0; i < TheISA::NumInterruptLevels; ++i)
interrupts[i] = oldCPU->interrupts[i];
intstatus = oldCPU->intstatus;
/*
for (int i = 0; i < execContexts.size(); ++i)
if (execContexts[i]->profile)
execContexts[i]->profile->clear();
*/
if (profileEvent)
profileEvent->schedule(curTick);
#endif
@@ -272,11 +290,11 @@ BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval)
void
BaseCPU::ProfileEvent::process()
{
for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) {
/* for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) {
ExecContext *xc = cpu->execContexts[i];
xc->profile->sample(xc->profileNode, xc->profilePC);
}
*/
schedule(curTick + interval);
}
@@ -327,6 +345,12 @@ BaseCPU::serialize(std::ostream &os)
{
SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
SERIALIZE_SCALAR(intstatus);
#if FULL_SYSTEM
if (kernelStats)
kernelStats->serialize(os);
#endif
}
void
@@ -334,6 +358,11 @@ BaseCPU::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
UNSERIALIZE_SCALAR(intstatus);
#if FULL_SYSTEM
if (kernelStats)
kernelStats->unserialize(cp, section);
#endif
}
#endif // FULL_SYSTEM

View File

@@ -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__

View File

@@ -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);

View File

@@ -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;

View File

@@ -29,6 +29,7 @@
#include <string>
#include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh"
#if FULL_SYSTEM
@@ -50,23 +51,24 @@ using namespace std;
// constructor
#if FULL_SYSTEM
ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
AlphaITB *_itb, AlphaDTB *_dtb,
FunctionalMemory *_mem)
: _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
cpu_id(-1), lastActivate(0), lastSuspend(0), mem(_mem), itb(_itb),
dtb(_dtb), system(_sys), memctrl(_sys->memctrl), physmem(_sys->physmem),
kernelBinning(system->kernelBinning), bin(kernelBinning->bin),
fnbin(kernelBinning->fnbin), profile(NULL), quiesceEvent(this),
func_exe_inst(0), storeCondFailures(0)
{
kernelStats = new Kernel::Statistics(this);
proxy = new ProxyExecContext<CPUExecContext>(this);
memset(&regs, 0, sizeof(RegFile));
if (cpu->params->profile) {
profile = new FunctionProfile(system->kernelSymtab);
Callback *cb =
new MakeCallback<ExecContext, &ExecContext::dumpFuncProfile>(this);
new MakeCallback<CPUExecContext,
&CPUExecContext::dumpFuncProfile>(this);
registerExitCallback(cb);
}
@@ -77,7 +79,7 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
profilePC = 3;
}
#else
ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
Process *_process, int _asid)
: _status(ExecContext::Unallocated),
cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0),
@@ -85,30 +87,38 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
func_exe_inst(0), storeCondFailures(0)
{
memset(&regs, 0, sizeof(RegFile));
proxy = new ProxyExecContext<CPUExecContext>(this);
}
ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num,
FunctionalMemory *_mem, int _asid)
: cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid),
func_exe_inst(0), storeCondFailures(0)
{
memset(&regs, 0, sizeof(RegFile));
proxy = new ProxyExecContext<CPUExecContext>(this);
}
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 &section)
CPUExecContext::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ENUM(_status);
regs.unserialize(cp, section);
@@ -185,28 +196,26 @@ ExecContext::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(quiesceEndTick);
if (quiesceEndTick)
quiesceEvent.schedule(quiesceEndTick);
kernelStats->unserialize(cp, section);
#endif
}
void
ExecContext::activate(int delay)
CPUExecContext::activate(int delay)
{
if (status() == Active)
if (status() == ExecContext::Active)
return;
lastActivate = curTick;
_status = Active;
_status = ExecContext::Active;
cpu->activateContext(thread_num, delay);
}
void
ExecContext::suspend()
CPUExecContext::suspend()
{
if (status() == Suspended)
if (status() == ExecContext::Suspended)
return;
lastActivate = curTick;
@@ -215,41 +224,65 @@ ExecContext::suspend()
#if FULL_SYSTEM
// Don't change the status from active if there are pending interrupts
if (cpu->check_interrupts()) {
assert(status() == Active);
assert(status() == ExecContext::Active);
return;
}
#endif
*/
_status = Suspended;
_status = ExecContext::Suspended;
cpu->suspendContext(thread_num);
}
void
ExecContext::deallocate()
CPUExecContext::deallocate()
{
if (status() == Unallocated)
if (status() == ExecContext::Unallocated)
return;
_status = Unallocated;
_status = ExecContext::Unallocated;
cpu->deallocateContext(thread_num);
}
void
ExecContext::halt()
CPUExecContext::halt()
{
if (status() == Halted)
if (status() == ExecContext::Halted)
return;
_status = Halted;
_status = ExecContext::Halted;
cpu->haltContext(thread_num);
}
void
ExecContext::regStats(const string &name)
CPUExecContext::regStats(const string &name)
{
#if FULL_SYSTEM
kernelStats->regStats(name + ".kern");
#endif
}
void
CPUExecContext::copyArchRegs(ExecContext *xc)
{
// First loop through the integer registers.
for (int i = 0; i < AlphaISA::NumIntRegs; ++i) {
setIntReg(i, xc->readIntReg(i));
}
// Then loop through the floating point registers.
for (int i = 0; i < AlphaISA::NumFloatRegs; ++i) {
setFloatRegDouble(i, xc->readFloatRegDouble(i));
setFloatRegInt(i, xc->readFloatRegInt(i));
}
// Copy misc. registers
setMiscReg(AlphaISA::Fpcr_DepTag, xc->readMiscReg(AlphaISA::Fpcr_DepTag));
setMiscReg(AlphaISA::Uniq_DepTag, xc->readMiscReg(AlphaISA::Uniq_DepTag));
setMiscReg(AlphaISA::Lock_Flag_DepTag,
xc->readMiscReg(AlphaISA::Lock_Flag_DepTag));
setMiscReg(AlphaISA::Lock_Addr_DepTag,
xc->readMiscReg(AlphaISA::Lock_Addr_DepTag));
// Lastly copy PC/NPC
setPC(xc->readPC());
setNextPC(xc->readNextPC());
}

521
cpu/cpu_exec_context.hh Normal file
View 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 &section);
BaseCPU *getCpuPtr() { return cpu; }
ExecContext *getProxy() { return proxy; }
int getThreadNum() { return thread_num; }
#if FULL_SYSTEM
System *getSystemPtr() { return system; }
PhysicalMemory *getPhysMemPtr() { return physmem; }
AlphaITB *getITBPtr() { return itb; }
AlphaDTB *getDTBPtr() { return dtb; }
bool validInstAddr(Addr addr) { return true; }
bool validDataAddr(Addr addr) { return true; }
int getInstAsid() { return regs.instAsid(); }
int getDataAsid() { return regs.dataAsid(); }
Fault translateInstReq(MemReqPtr &req)
{
return itb->translate(req);
}
Fault translateDataReadReq(MemReqPtr &req)
{
return dtb->translate(req, false);
}
Fault translateDataWriteReq(MemReqPtr &req)
{
return dtb->translate(req, true);
}
#else
Process *getProcessPtr() { return process; }
bool validInstAddr(Addr addr)
{ return process->validInstAddr(addr); }
bool validDataAddr(Addr addr)
{ return process->validDataAddr(addr); }
int getInstAsid() { return asid; }
int getDataAsid() { return asid; }
Fault dummyTranslation(MemReqPtr &req)
{
#if 0
assert((req->vaddr >> 48 & 0xffff) == 0);
#endif
// put the asid in the upper 16 bits of the paddr
req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16);
req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
return NoFault;
}
Fault translateInstReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
Fault translateDataReadReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
Fault translateDataWriteReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
#endif
template <class T>
Fault read(MemReqPtr &req, T &data)
{
#if FULL_SYSTEM && defined(TARGET_ALPHA)
if (req->flags & LOCKED) {
req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr);
req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true);
}
#endif
Fault error;
error = mem->read(req, data);
data = LittleEndianGuest::gtoh(data);
return error;
}
template <class T>
Fault write(MemReqPtr &req, T &data)
{
#if FULL_SYSTEM && defined(TARGET_ALPHA)
ExecContext *xc;
// If this is a store conditional, act appropriately
if (req->flags & LOCKED) {
xc = req->xc;
if (req->flags & UNCACHEABLE) {
// Don't update result register (see stq_c in isa_desc)
req->result = 2;
xc->setStCondFailures(0);//Needed? [RGD]
} else {
bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag);
Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag);
req->result = lock_flag;
if (!lock_flag ||
((lock_addr & ~0xf) != (req->paddr & ~0xf))) {
xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
xc->setStCondFailures(xc->readStCondFailures() + 1);
if (((xc->readStCondFailures()) % 100000) == 0) {
std::cerr << "Warning: "
<< xc->readStCondFailures()
<< " consecutive store conditional failures "
<< "on cpu " << req->xc->readCpuId()
<< std::endl;
}
return NoFault;
}
else xc->setStCondFailures(0);
}
}
// Need to clear any locked flags on other proccessors for
// this address. Only do this for succsful Store Conditionals
// and all other stores (WH64?). Unsuccessful Store
// Conditionals would have returned above, and wouldn't fall
// through.
for (int i = 0; i < system->execContexts.size(); i++){
xc = system->execContexts[i];
if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) ==
(req->paddr & ~0xf)) {
xc->setMiscReg(TheISA::Lock_Flag_DepTag, false);
}
}
#endif
return mem->write(req, (T)LittleEndianGuest::htog(data));
}
virtual bool misspeculating();
MachInst getInst() { return inst; }
void setInst(MachInst new_inst)
{
inst = new_inst;
}
Fault instRead(MemReqPtr &req)
{
return mem->read(req, inst);
}
void setCpuId(int id) { cpu_id = id; }
int readCpuId() { return cpu_id; }
FunctionalMemory *getMemPtr() { return mem; }
void copyArchRegs(ExecContext *xc);
//
// New accessors for new decoder.
//
uint64_t readIntReg(int reg_idx)
{
return regs.intRegFile[reg_idx];
}
float readFloatRegSingle(int reg_idx)
{
return (float)regs.floatRegFile.d[reg_idx];
}
double readFloatRegDouble(int reg_idx)
{
return regs.floatRegFile.d[reg_idx];
}
uint64_t readFloatRegInt(int reg_idx)
{
return regs.floatRegFile.q[reg_idx];
}
void setIntReg(int reg_idx, uint64_t val)
{
regs.intRegFile[reg_idx] = val;
}
void setFloatRegSingle(int reg_idx, float val)
{
regs.floatRegFile.d[reg_idx] = (double)val;
}
void setFloatRegDouble(int reg_idx, double val)
{
regs.floatRegFile.d[reg_idx] = val;
}
void setFloatRegInt(int reg_idx, uint64_t val)
{
regs.floatRegFile.q[reg_idx] = val;
}
uint64_t readPC()
{
return regs.pc;
}
void setPC(uint64_t val)
{
regs.pc = val;
}
uint64_t readNextPC()
{
return regs.npc;
}
void setNextPC(uint64_t val)
{
regs.npc = val;
}
MiscReg readMiscReg(int misc_reg)
{
return regs.miscRegs.readReg(misc_reg);
}
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
{
return regs.miscRegs.readRegWithEffect(misc_reg, fault, proxy);
}
Fault setMiscReg(int misc_reg, const MiscReg &val)
{
return regs.miscRegs.setReg(misc_reg, val);
}
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
return regs.miscRegs.setRegWithEffect(misc_reg, val, proxy);
}
unsigned readStCondFailures() { return storeCondFailures; }
void setStCondFailures(unsigned sc_failures)
{ storeCondFailures = sc_failures; }
void clearArchRegs() { memset(&regs, 0, sizeof(regs)); }
#if FULL_SYSTEM
int readIntrFlag() { return regs.intrflag; }
void setIntrFlag(int val) { regs.intrflag = val; }
Fault hwrei();
bool inPalMode() { return AlphaISA::PcPAL(regs.pc); }
bool simPalCheck(int palFunc);
#endif
#if !FULL_SYSTEM
TheISA::IntReg getSyscallArg(int i)
{
return regs.intRegFile[TheISA::ArgumentReg0 + i];
}
// used to shift args for indirect syscall
void setSyscallArg(int i, TheISA::IntReg val)
{
regs.intRegFile[TheISA::ArgumentReg0 + i] = val;
}
void setSyscallReturn(SyscallReturn return_value)
{
// check for error condition. Alpha syscall convention is to
// indicate success/failure in reg a3 (r19) and put the
// return value itself in the standard return value reg (v0).
const int RegA3 = 19; // only place this is used
if (return_value.successful()) {
// no error
regs.intRegFile[RegA3] = 0;
regs.intRegFile[TheISA::ReturnValueReg] = return_value.value();
} else {
// got an error, return details
regs.intRegFile[RegA3] = (TheISA::IntReg) -1;
regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value();
}
}
void syscall()
{
process->syscall(proxy);
}
Counter readFuncExeInst() { return func_exe_inst; }
void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; }
#endif
};
// for non-speculative execution context, spec_mode is always false
inline bool
CPUExecContext::misspeculating()
{
return false;
}
#endif // __CPU_CPU_EXEC_CONTEXT_HH__

View File

@@ -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 &section) = 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 &section);
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 &section)
{ 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

View File

@@ -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"

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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"

View File

@@ -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

View File

@@ -35,10 +35,11 @@
#endif
#include "sim/root.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh"
#include "cpu/o3/alpha_dyn_inst.hh"
#include "cpu/o3/alpha_impl.hh"
#include "cpu/o3/cpu.hh"
#include "cpu/exec_context.hh"
using namespace std;
@@ -103,7 +104,7 @@ FullO3CPU<Impl>::FullO3CPU(Params &params)
renameQueue(5, 5),
iewQueue(5, 5),
xc(NULL),
cpuXC(NULL),
globalSeqNum(1),
@@ -134,8 +135,8 @@ FullO3CPU<Impl>::FullO3CPU(Params &params)
for (int i = 0; i < this->number_of_threads; ++i) {
#if FULL_SYSTEM
assert(i == 0);
system->execContexts[i] =
new ExecContext(this, i, system, itb, dtb, mem);
thread[i] = new CPUExecContext(this, 0, system, itb, dtb, mem);
system->execContexts[i] = thread[i]->getProxy();
execContexts.push_back(system->execContexts[i]);
#else
@@ -143,21 +144,17 @@ FullO3CPU<Impl>::FullO3CPU(Params &params)
DPRINTF(FullCPU, "FullCPU: Workload[%i]'s starting PC is %#x, "
"process is %#x",
i, params.workload[i]->prog_entry, thread[i]);
thread[i] = new ExecContext(this, i, params.workload[i], i);
thread[i] = new CPUExecContext(this, i, params.workload[i], i);
}
assert(params.workload[i]->getMemory() != NULL);
assert(mem != NULL);
execContexts.push_back(thread[i]);
execContexts.push_back(thread[i]->getProxy());
#endif // !FULL_SYSTEM
}
// Note that this is a hack so that my code which still uses xc-> will
// still work. I should remove this eventually
#if FULL_SYSTEM
xc = system->execContexts[0];
#else
xc = thread[0];
#endif
cpuXC = thread[0];
// The stages also need their CPU pointer setup. However this must be
// done at the upper level CPU because they have pointers to the upper
@@ -248,21 +245,21 @@ FullO3CPU<Impl>::init()
// that it can start properly.
#if FULL_SYSTEM
ExecContext *src_xc = system->execContexts[0];
TheISA::initCPU(&src_xc->regs, src_xc->cpu_id);
TheISA::initCPU(src_xc, src_xc->readCpuId());
#else
ExecContext *src_xc = thread[0];
ExecContext *src_xc = thread[0]->getProxy();
#endif
// First loop through the integer registers.
for (int i = 0; i < TheISA::NumIntRegs; ++i)
{
regFile.intRegFile[i] = src_xc->regs.intRegFile[i];
regFile.intRegFile[i] = src_xc->readIntReg(i);
}
// Then loop through the floating point registers.
for (int i = 0; i < TheISA::NumFloatRegs; ++i)
{
regFile.floatRegFile[i].d = src_xc->regs.floatRegFile.d[i];
regFile.floatRegFile[i].q = src_xc->regs.floatRegFile.q[i];
regFile.floatRegFile[i].d = src_xc->readFloatRegDouble(i);
regFile.floatRegFile[i].q = src_xc->readFloatRegInt(i);
}
/*
// Then loop through the misc registers.
@@ -272,8 +269,8 @@ FullO3CPU<Impl>::init()
regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr;
*/
// Then finally set the PC and the next PC.
regFile.pc = src_xc->regs.pc;
regFile.npc = src_xc->regs.npc;
regFile.pc = src_xc->readPC();
regFile.npc = src_xc->readNextPC();
}
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -44,6 +44,7 @@
#include "base/stats/events.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh"
#include "cpu/exetrace.hh"
#include "cpu/profile.hh"
@@ -94,7 +95,7 @@ SimpleCPU::init()
ExecContext *xc = execContexts[i];
// initialize CPU, including PC
TheISA::initCPU(&xc->regs, xc->cpu_id);
TheISA::initCPU(xc, xc->readCpuId());
}
#endif
}
@@ -132,22 +133,24 @@ SimpleCPU::CacheCompletionEvent::description()
}
SimpleCPU::SimpleCPU(Params *p)
: BaseCPU(p), tickEvent(this, p->width), xc(NULL),
: BaseCPU(p), tickEvent(this, p->width), cpuXC(NULL),
cacheCompletionEvent(this)
{
_status = Idle;
#if FULL_SYSTEM
xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
#else
xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0);
cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process,
/* asid */ 0);
#endif // !FULL_SYSTEM
xcProxy = cpuXC->getProxy();
icacheInterface = p->icache_interface;
dcacheInterface = p->dcache_interface;
memReq = new MemReq();
memReq->xc = xc;
memReq->xc = xcProxy;
memReq->asid = 0;
memReq->data = new uint8_t[64];
@@ -158,7 +161,7 @@ SimpleCPU::SimpleCPU(Params *p)
lastIcacheStall = 0;
lastDcacheStall = 0;
execContexts.push_back(xc);
execContexts.push_back(xcProxy);
}
SimpleCPU::~SimpleCPU()
@@ -207,7 +210,7 @@ void
SimpleCPU::activateContext(int thread_num, int delay)
{
assert(thread_num == 0);
assert(xc);
assert(cpuXC);
assert(_status == Idle);
notIdleFraction++;
@@ -220,7 +223,7 @@ void
SimpleCPU::suspendContext(int thread_num)
{
assert(thread_num == 0);
assert(xc);
assert(cpuXC);
assert(_status == Running);
notIdleFraction--;
@@ -301,7 +304,7 @@ SimpleCPU::serialize(ostream &os)
SERIALIZE_ENUM(_status);
SERIALIZE_SCALAR(inst);
nameOut(os, csprintf("%s.xc", name()));
xc->serialize(os);
cpuXC->serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os);
nameOut(os, csprintf("%s.cacheCompletionEvent", name()));
@@ -314,7 +317,7 @@ SimpleCPU::unserialize(Checkpoint *cp, const string &section)
BaseCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status);
UNSERIALIZE_SCALAR(inst);
xc->unserialize(cp, csprintf("%s.xc", section));
cpuXC->unserialize(cp, csprintf("%s.xc", section));
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
cacheCompletionEvent
.unserialize(cp, csprintf("%s.cacheCompletionEvent", section));
@@ -345,16 +348,16 @@ SimpleCPU::copySrcTranslate(Addr src)
memReq->reset(src & ~(blk_size - 1), blk_size);
// translate to physical address
Fault fault = xc->translateDataReadReq(memReq);
Fault fault = cpuXC->translateDataReadReq(memReq);
if (fault == NoFault) {
xc->copySrcAddr = src;
xc->copySrcPhysAddr = memReq->paddr + offset;
cpuXC->copySrcAddr = src;
cpuXC->copySrcPhysAddr = memReq->paddr + offset;
} else {
assert(!fault->isAlignmentFault());
xc->copySrcAddr = 0;
xc->copySrcPhysAddr = 0;
cpuXC->copySrcAddr = 0;
cpuXC->copySrcPhysAddr = 0;
}
return fault;
}
@@ -367,7 +370,7 @@ SimpleCPU::copy(Addr dest)
// Only support block sizes of 64 atm.
assert(blk_size == 64);
uint8_t data[blk_size];
//assert(xc->copySrcAddr);
//assert(cpuXC->copySrcAddr);
int offset = dest & (blk_size - 1);
// Make sure block doesn't span page
@@ -380,19 +383,19 @@ SimpleCPU::copy(Addr dest)
memReq->reset(dest & ~(blk_size -1), blk_size);
// translate to physical address
Fault fault = xc->translateDataWriteReq(memReq);
Fault fault = cpuXC->translateDataWriteReq(memReq);
if (fault == NoFault) {
Addr dest_addr = memReq->paddr + offset;
// Need to read straight from memory since we have more than 8 bytes.
memReq->paddr = xc->copySrcPhysAddr;
xc->mem->read(memReq, data);
memReq->paddr = cpuXC->copySrcPhysAddr;
cpuXC->mem->read(memReq, data);
memReq->paddr = dest_addr;
xc->mem->write(memReq, data);
cpuXC->mem->write(memReq, data);
if (dcacheInterface) {
memReq->cmd = Copy;
memReq->completionEvent = NULL;
memReq->paddr = xc->copySrcPhysAddr;
memReq->paddr = cpuXC->copySrcPhysAddr;
memReq->dest = dest_addr;
memReq->size = 64;
memReq->time = curTick;
@@ -412,7 +415,7 @@ Fault
SimpleCPU::read(Addr addr, T &data, unsigned flags)
{
if (status() == DcacheMissStall || status() == DcacheMissSwitch) {
Fault fault = xc->read(memReq,data);
Fault fault = cpuXC->read(memReq,data);
if (traceData) {
traceData->setAddr(addr);
@@ -423,7 +426,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
Fault fault = xc->translateDataReadReq(memReq);
Fault fault = cpuXC->translateDataReadReq(memReq);
// if we have a cache, do cache access too
if (fault == NoFault && dcacheInterface) {
@@ -443,12 +446,12 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
_status = DcacheMissStall;
} else {
// do functional access
fault = xc->read(memReq, data);
fault = cpuXC->read(memReq, data);
}
} else if(fault == NoFault) {
// do functional access
fault = xc->read(memReq, data);
fault = cpuXC->read(memReq, data);
}
@@ -508,11 +511,11 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
Fault fault = xc->translateDataWriteReq(memReq);
Fault fault = cpuXC->translateDataWriteReq(memReq);
// do functional access
if (fault == NoFault)
fault = xc->write(memReq, data);
fault = cpuXC->write(memReq, data);
if (fault == NoFault && dcacheInterface) {
memReq->cmd = Write;
@@ -589,7 +592,7 @@ SimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
Addr
SimpleCPU::dbg_vtophys(Addr addr)
{
return vtophys(xc, addr);
return vtophys(xcProxy, addr);
}
#endif // FULL_SYSTEM
@@ -637,9 +640,9 @@ SimpleCPU::post_interrupt(int int_num, int index)
{
BaseCPU::post_interrupt(int_num, index);
if (xc->status() == ExecContext::Suspended) {
if (cpuXC->status() == ExecContext::Suspended) {
DPRINTF(IPI,"Suspended Processor awoke\n");
xc->activate();
cpuXC->activate();
}
}
#endif // FULL_SYSTEM
@@ -655,16 +658,16 @@ SimpleCPU::tick()
Fault fault = NoFault;
#if FULL_SYSTEM
if (checkInterrupts && check_interrupts() && !xc->inPalMode() &&
if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode() &&
status() != IcacheMissComplete) {
int ipl = 0;
int summary = 0;
checkInterrupts = false;
if (xc->readMiscReg(IPR_SIRR)) {
if (cpuXC->readMiscReg(IPR_SIRR)) {
for (int i = INTLEVEL_SOFTWARE_MIN;
i < INTLEVEL_SOFTWARE_MAX; i++) {
if (xc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
if (cpuXC->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
summary |= (ULL(1) << i);
@@ -672,7 +675,7 @@ SimpleCPU::tick()
}
}
uint64_t interrupts = xc->cpu->intr_status();
uint64_t interrupts = cpuXC->cpu->intr_status();
for (int i = INTLEVEL_EXTERNAL_MIN;
i < INTLEVEL_EXTERNAL_MAX; i++) {
if (interrupts & (ULL(1) << i)) {
@@ -682,24 +685,25 @@ SimpleCPU::tick()
}
}
if (xc->readMiscReg(IPR_ASTRR))
if (cpuXC->readMiscReg(IPR_ASTRR))
panic("asynchronous traps not implemented\n");
if (ipl && ipl > xc->readMiscReg(IPR_IPLR)) {
xc->setMiscReg(IPR_ISR, summary);
xc->setMiscReg(IPR_INTID, ipl);
Fault(new InterruptFault)->invoke(xc);
if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) {
cpuXC->setMiscReg(IPR_ISR, summary);
cpuXC->setMiscReg(IPR_INTID, ipl);
Fault(new InterruptFault)->invoke(xcProxy);
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
xc->readMiscReg(IPR_IPLR), ipl, summary);
cpuXC->readMiscReg(IPR_IPLR), ipl, summary);
}
}
#endif
// maintain $r0 semantics
xc->regs.intRegFile[ZeroReg] = 0;
cpuXC->setIntReg(ZeroReg, 0);
#ifdef TARGET_ALPHA
xc->regs.floatRegFile.d[ZeroReg] = 0.0;
cpuXC->setFloatRegDouble(ZeroReg, 0.0);
#endif // TARGET_ALPHA
if (status() == IcacheMissComplete) {
@@ -721,13 +725,13 @@ SimpleCPU::tick()
#endif
memReq->cmd = Read;
memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t),
IFETCH_FLAGS(xc->regs.pc));
memReq->reset(cpuXC->readPC() & ~3, sizeof(uint32_t),
IFETCH_FLAGS(cpuXC->readPC()));
fault = xc->translateInstReq(memReq);
fault = cpuXC->translateInstReq(memReq);
if (fault == NoFault)
fault = xc->mem->read(memReq, inst);
fault = cpuXC->mem->read(memReq, inst);
if (icacheInterface && fault == NoFault) {
memReq->completionEvent = NULL;
@@ -764,29 +768,30 @@ SimpleCPU::tick()
inst = gtoh(inst);
curStaticInst = StaticInst::decode(makeExtMI(inst, xc->readPC()));
traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst,
xc->regs.pc);
traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst,
cpuXC->readPC());
#if FULL_SYSTEM
xc->setInst(inst);
cpuXC->setInst(inst);
#endif // FULL_SYSTEM
xc->func_exe_inst++;
cpuXC->func_exe_inst++;
fault = curStaticInst->execute(this, traceData);
#if FULL_SYSTEM
if (xc->fnbin) {
assert(xc->kernelStats);
system->kernelBinning->execute(xc, inst);
if (system->kernelBinning->fnbin) {
assert(kernelStats);
system->kernelBinning->execute(xcProxy, inst);
}
if (xc->profile) {
bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
xc->profilePC = usermode ? 1 : xc->regs.pc;
ProfileNode *node = xc->profile->consume(xc, inst);
if (cpuXC->profile) {
bool usermode =
(cpuXC->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
cpuXC->profilePC = usermode ? 1 : cpuXC->readPC();
ProfileNode *node = cpuXC->profile->consume(xcProxy, inst);
if (node)
xc->profileNode = node;
cpuXC->profileNode = node;
}
#endif
@@ -806,29 +811,29 @@ SimpleCPU::tick()
traceData->finalize();
}
traceFunctions(xc->regs.pc);
traceFunctions(cpuXC->readPC());
} // if (fault == NoFault)
if (fault != NoFault) {
#if FULL_SYSTEM
fault->invoke(xc);
fault->invoke(xcProxy);
#else // !FULL_SYSTEM
fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc);
fatal("fault (%d) detected @ PC 0x%08p", fault, cpuXC->readPC());
#endif // FULL_SYSTEM
}
else {
// go to the next instruction
xc->regs.pc = xc->regs.npc;
xc->regs.npc += sizeof(MachInst);
cpuXC->setPC(cpuXC->readNextPC());
cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst));
}
#if FULL_SYSTEM
Addr oldpc;
do {
oldpc = xc->regs.pc;
system->pcEventQueue.service(xc);
} while (oldpc != xc->regs.pc);
oldpc = cpuXC->readPC();
system->pcEventQueue.service(xcProxy);
} while (oldpc != cpuXC->readPC());
#endif
assert(status() == Running ||

View File

@@ -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__

View File

@@ -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:

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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;
}