Steps towards setting up the infrastructure to allow the new CPU model to work in full system mode.

The major change is renaming the old ExecContext to CPUExecContext, and creating two new classes, ExecContext (an abstract class), and ProxyExecContext (a templated class that derives from ExecContext).

Code outside of the CPU continues to use ExecContext as normal (other than not being able to access variables within the XC).  The CPU uses the CPUExecContext, or however else it stores its own state.  It then creates a ProxyExecContext, templated on the class used to hold its state.  This proxy is passed to any code outside of the CPU that needs to access the XC.  This allows code outside of the CPU to use the ExecContext interface to access any state needed, without knowledge of how that state is laid out.

Note that these changes will not compile without the accompanying revision to automatically rename the shadow registers.

SConscript:
    Include new file, cpu_exec_context.cc.
arch/alpha/alpha_linux_process.cc:
arch/alpha/alpha_memory.cc:
arch/alpha/alpha_tru64_process.cc:
arch/alpha/arguments.cc:
arch/alpha/isa/decoder.isa:
arch/alpha/stacktrace.cc:
arch/alpha/vtophys.cc:
base/remote_gdb.cc:
cpu/intr_control.cc:
    Avoid directly accessing objects within the XC.
arch/alpha/ev5.cc:
    Avoid directly accessing objects within the XC.

    KernelStats have been moved to the BaseCPU instead of the XC.
arch/alpha/isa_traits.hh:
    Remove clearIprs().  It wasn't used very often and it did not work well with the proxy ExecContext.
cpu/base.cc:
    Place kernel stats within the BaseCPU instead of the ExecContext.

    For now comment out the profiling code sampling until its exact location is decided upon.
cpu/base.hh:
    Kernel stats are now in the BaseCPU instead of the ExecContext.
cpu/base_dyn_inst.cc:
cpu/base_dyn_inst.hh:
cpu/memtest/memtest.cc:
cpu/memtest/memtest.hh:
    Changes to support rename of old ExecContext to CPUExecContext.  See changeset for more details.
cpu/exetrace.cc:
    Remove unneeded include of exec_context.hh.
cpu/intr_control.hh:
cpu/o3/alpha_cpu_builder.cc:
    Remove unneeded include of exec_context.hh
cpu/o3/alpha_cpu.hh:
cpu/o3/alpha_cpu_impl.hh:
cpu/o3/cpu.cc:
cpu/o3/cpu.hh:
cpu/simple/cpu.cc:
cpu/simple/cpu.hh:
    Changes to support rename of old ExecContext to CPUExecContext.  See changeset for more details.

    Also avoid accessing anything directly from the XC.
cpu/pc_event.cc:
    Avoid accessing objects directly from the XC.
dev/tsunami_cchip.cc:
    Avoid accessing objects directly within the XC>
kern/freebsd/freebsd_system.cc:
kern/linux/linux_system.cc:
kern/linux/linux_threadinfo.hh:
kern/tru64/dump_mbuf.cc:
kern/tru64/tru64.hh:
kern/tru64/tru64_events.cc:
sim/syscall_emul.cc:
sim/syscall_emul.hh:
    Avoid accessing objects directly within the XC.
kern/kernel_stats.cc:
kern/kernel_stats.hh:
    Kernel stats no longer exist within the XC.
kern/system_events.cc:
    Avoid accessing objects directly within the XC.  Also kernel stats are now in the BaseCPU.
sim/process.cc:
sim/process.hh:
    Avoid accessing regs directly within an ExecContext.  Instead use a CPUExecContext to initialize the registers and copy them over.
cpu/cpu_exec_context.cc:
    Rename old ExecContext to CPUExecContext.  This is used by the old CPU models to store any necessary architectural state.  Also include the ProxyExecContext, which is used to access the CPUExecContext's state in code outside of the CPU.
cpu/cpu_exec_context.hh:
    Rename old ExecContext to CPUExecContext.  This is used by the old CPU models to store any necessary architectural state.  Also include the ProxyExecContext, which is used to access the CPUExecContext's state in code outside of the CPU.

    Remove kernel stats from the ExecContext.
sim/pseudo_inst.cc:
    Kernel stats now live within the CPU.

    Avoid accessing objects directly within the XC.

--HG--
rename : cpu/exec_context.cc => cpu/cpu_exec_context.cc
rename : cpu/exec_context.hh => cpu/cpu_exec_context.hh
extra : convert_revision : a75393a8945c80cca225b5e9d9c22a16609efb85
This commit is contained in:
Kevin Lim
2006-03-04 15:18:40 -05:00
parent 96fd6b5c40
commit f15e492375
46 changed files with 1330 additions and 831 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

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

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

@@ -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"
@@ -70,17 +71,17 @@ AlphaISA::swap_palshadow(RegFile *regs, bool use_shadow)
// Machine dependent functions
//
void
AlphaISA::initCPU(RegFile *regs, int cpuId)
AlphaISA::initCPU(ExecContext *xc, int cpuId)
{
initIPRs(&regs->miscRegs, cpuId);
initIPRs(xc, cpuId);
// CPU comes up with PAL regs enabled
swap_palshadow(regs, true);
regs->intRegFile[16] = cpuId;
regs->intRegFile[0] = cpuId;
xc->setIntReg(16, cpuId);
xc->setIntReg(0, cpuId);
regs->pc = regs->miscRegs.readReg(IPR_PAL_BASE) + fault_addr(ResetFault);
regs->npc = regs->pc + sizeof(MachInst);
xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + fault_addr(ResetFault));
xc->setNextPC(xc->readPC() + sizeof(MachInst));
}
////////////////////////////////////////////////////////////////////////
@@ -109,13 +110,15 @@ const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = {
//
//
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);
}
@@ -174,18 +177,18 @@ 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);
}
void
ExecContext::ev5_trap(Fault fault)
CPUExecContext::ev5_trap(Fault fault)
{
DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name, regs.pc);
cpu->recordEvent(csprintf("Fault %s", fault->name));
assert(!misspeculating());
kernelStats->fault(fault);
cpu->kernelStats->fault(fault);
if (fault == ArithmeticFault)
panic("Arithmetic traps are unimplemented!");
@@ -237,7 +240,7 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc)
}
Fault
ExecContext::hwrei()
CPUExecContext::hwrei()
{
if (!inPalMode())
return UnimplementedOpcodeFault;
@@ -245,7 +248,7 @@ ExecContext::hwrei()
setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR));
if (!misspeculating()) {
kernelStats->hwrei();
cpu->kernelStats->hwrei();
if ((readMiscReg(AlphaISA::IPR_EXC_ADDR) & 1) == 0)
AlphaISA::swap_palshadow(&regs, false);
@@ -257,12 +260,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)
{
@@ -318,7 +315,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:
@@ -335,7 +332,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;
@@ -432,7 +429,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:
@@ -459,14 +456,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
@@ -540,21 +537,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: {
@@ -577,7 +575,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;
@@ -601,7 +599,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;
@@ -609,21 +607,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:
@@ -640,9 +639,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

@@ -770,7 +770,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

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

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

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

@@ -429,7 +429,7 @@ RemoteGDB::getregs()
memcpy(&gdbregs[KGDB_REG_F0], context->regs.floatRegFile.q,
32 * sizeof(uint64_t));
#endif
gdbregs[KGDB_REG_PC] = context->regs.pc;
gdbregs[KGDB_REG_PC] = context->readPC();
}
///////////////////////////////////////////////////////////
@@ -447,7 +447,7 @@ RemoteGDB::setregs()
memcpy(context->regs.floatRegFile.q, &gdbregs[KGDB_REG_F0],
32 * sizeof(uint64_t));
#endif
context->regs.pc = gdbregs[KGDB_REG_PC];
context->setPC(gdbregs[KGDB_REG_PC]);
}
void
@@ -486,7 +486,7 @@ RemoteGDB::clearSingleStep()
void
RemoteGDB::setSingleStep()
{
Addr pc = context->regs.pc;
Addr pc = context->readPC();
Addr npc, bpc;
bool set_bt = false;
@@ -835,7 +835,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();
@@ -990,8 +990,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;
@@ -999,8 +999,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;
@@ -1009,8 +1009,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;
@@ -1018,8 +1018,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

@@ -67,7 +67,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;
@@ -138,14 +138,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
@@ -183,10 +183,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
@@ -211,18 +211,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;
}
@@ -235,18 +235,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
@@ -49,23 +50,23 @@ using namespace std;
// constructor
#if FULL_SYSTEM
ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
AlphaITB *_itb, AlphaDTB *_dtb,
FunctionalMemory *_mem)
: _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
cpu_id(-1), 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),
memctrl(_sys->memctrl), physmem(_sys->physmem), profile(NULL),
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);
}
@@ -76,7 +77,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),
@@ -84,36 +85,46 @@ 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);
profile->dump(proxy, *os);
}
#endif
void
ExecContext::takeOverFrom(ExecContext *oldContext)
CPUExecContext::takeOverFrom(ExecContext *oldContext)
{
/*
// some things should already be set up
assert(mem == oldContext->mem);
#if FULL_SYSTEM
@@ -130,98 +141,115 @@ 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);
// thread_num and cpu_id are deterministic from the config
SERIALIZE_SCALAR(func_exe_inst);
SERIALIZE_SCALAR(inst);
#if FULL_SYSTEM
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);
// thread_num and cpu_id are deterministic from the config
UNSERIALIZE_SCALAR(func_exe_inst);
UNSERIALIZE_SCALAR(inst);
#if FULL_SYSTEM
kernelStats->unserialize(cp, section);
#endif
}
void
ExecContext::activate(int delay)
CPUExecContext::activate(int delay)
{
if (status() == Active)
if (status() == ExecContext::Active)
return;
_status = Active;
_status = ExecContext::Active;
cpu->activateContext(thread_num, delay);
}
void
ExecContext::suspend()
CPUExecContext::suspend()
{
if (status() == Suspended)
if (status() == ExecContext::Suspended)
return;
#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
ExecContext::trap(Fault fault)
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());
}
void
CPUExecContext::trap(Fault fault)
{
//TheISA::trap(fault); //One possible way to do it...

510
cpu/cpu_exec_context.hh Normal file
View File

@@ -0,0 +1,510 @@
/*
* Copyright (c) 2001-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __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/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 "targetarch/alpha_memory.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;
#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();
#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); }
void ev5_trap(Fault fault);
bool simPalCheck(int palFunc);
#endif
/** 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);
#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-2005 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,46 +30,29 @@
#define __CPU_EXEC_CONTEXT_HH__
#include "config/full_system.hh"
#include "mem/functional/functional.hh"
#include "mem/mem_req.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 "targetarch/alpha_memory.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:
@@ -86,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
@@ -95,392 +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;
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();
#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;
//
// Count failed store conditionals so we can warn of apparent
// application deadlock situations.
unsigned storeCondFailures;
virtual int getThreadNum() = 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 bool validInstAddr(Addr addr) = 0;
virtual bool validDataAddr(Addr addr) = 0;
virtual int getInstAsid() = 0;
virtual int getDataAsid() = 0;
virtual void takeOverFrom(ExecContext *oldContext);
virtual Fault translateInstReq(MemReqPtr &req) = 0;
void regStats(const std::string &name);
virtual Fault translateDataReadReq(MemReqPtr &req) = 0;
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
virtual Fault translateDataWriteReq(MemReqPtr &req) = 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 TheISA::MachInst getInst() = 0;
Fault translateInstReq(MemReqPtr &req)
{
return itb->translate(req);
}
virtual void copyArchRegs(ExecContext *xc) = 0;
Fault translateDataReadReq(MemReqPtr &req)
{
return dtb->translate(req, false);
}
Fault translateDataWriteReq(MemReqPtr &req)
{
return dtb->translate(req, true);
}
#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);
#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) {
MiscRegFile *cregs = &req->xc->regs.miscRegs;
cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr);
cregs->setReg(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)
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);
}
virtual void clearArchRegs() = 0;
//
// New accessors for new decoder.
//
uint64_t readIntReg(int reg_idx)
{
return regs.intRegFile[reg_idx];
}
virtual uint64_t readIntReg(int reg_idx) = 0;
float readFloatRegSingle(int reg_idx)
{
return (float)regs.floatRegFile.d[reg_idx];
}
virtual float readFloatRegSingle(int reg_idx) = 0;
double readFloatRegDouble(int reg_idx)
{
return regs.floatRegFile.d[reg_idx];
}
virtual double readFloatRegDouble(int reg_idx) = 0;
uint64_t readFloatRegInt(int reg_idx)
{
return regs.floatRegFile.q[reg_idx];
}
virtual uint64_t readFloatRegInt(int reg_idx) = 0;
void setIntReg(int reg_idx, uint64_t val)
{
regs.intRegFile[reg_idx] = val;
}
virtual void setIntReg(int reg_idx, uint64_t val) = 0;
void setFloatRegSingle(int reg_idx, float val)
{
regs.floatRegFile.d[reg_idx] = (double)val;
}
virtual void setFloatRegSingle(int reg_idx, float val) = 0;
void setFloatRegDouble(int reg_idx, double val)
{
regs.floatRegFile.d[reg_idx] = val;
}
virtual void setFloatRegDouble(int reg_idx, double val) = 0;
void setFloatRegInt(int reg_idx, uint64_t val)
{
regs.floatRegFile.q[reg_idx] = val;
}
virtual void setFloatRegInt(int reg_idx, uint64_t val) = 0;
uint64_t readPC()
{
return regs.pc;
}
virtual uint64_t readPC() = 0;
void setNextPC(uint64_t val)
{
regs.npc = val;
}
virtual void setPC(uint64_t val) = 0;
MiscReg readMiscReg(int misc_reg)
{
return regs.miscRegs.readReg(misc_reg);
}
virtual uint64_t readNextPC() = 0;
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
{
return regs.miscRegs.readRegWithEffect(misc_reg, fault, this);
}
virtual void setNextPC(uint64_t val) = 0;
Fault setMiscReg(int misc_reg, const MiscReg &val)
{
return regs.miscRegs.setReg(misc_reg, val);
}
virtual MiscReg readMiscReg(int misc_reg) = 0;
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{
return regs.miscRegs.setRegWithEffect(misc_reg, val, this);
}
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
int readIntrFlag() { return regs.intrflag; }
void setIntrFlag(int val) { regs.intrflag = val; }
Fault hwrei();
bool inPalMode() { return AlphaISA::PcPAL(regs.pc); }
void ev5_trap(Fault fault);
bool simPalCheck(int palFunc);
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
virtual bool misspeculating() = 0;
/** Meant to be more generic trap function to be
* called when an instruction faults.
* @param fault The fault generated by executing the instruction.
* @todo How to do this properly so it's dependent upon ISA only?
*/
void trap(Fault fault);
virtual void trap(Fault fault) = 0;
#if !FULL_SYSTEM
TheISA::IntReg getSyscallArg(int i)
{
return regs.intRegFile[TheISA::ArgumentReg0 + i];
}
virtual IntReg getSyscallArg(int i) = 0;
// used to shift args for indirect syscall
void setSyscallArg(int i, TheISA::IntReg val)
{
regs.intRegFile[TheISA::ArgumentReg0 + i] = val;
}
virtual void setSyscallArg(int i, IntReg val) = 0;
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();
}
}
virtual void setSyscallReturn(SyscallReturn return_value) = 0;
void syscall()
{
process->syscall(this);
}
virtual void syscall() = 0;
virtual Counter readFuncExeInst() = 0;
virtual void setFuncExeInst(Counter new_val) = 0;
#endif
};
// for non-speculative execution context, spec_mode is always false
inline bool
ExecContext::misspeculating()
template <class XC>
class ProxyExecContext : public ExecContext
{
return false;
}
public:
ProxyExecContext(XC *actual_xc)
{ actualXC = actual_xc; }
#endif // __CPU_EXEC_CONTEXT_HH__
private:
XC *actualXC;
public:
BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); }
void setCpuId(int id) { actualXC->setCpuId(id); }
int readCpuId() { return actualXC->readCpuId(); }
FunctionalMemory *getMemPtr() { return actualXC->getMemPtr(); }
#if FULL_SYSTEM
System *getSystemPtr() { return actualXC->getSystemPtr(); }
PhysicalMemory *getPhysMemPtr() { return actualXC->getPhysMemPtr(); }
AlphaITB *getITBPtr() { return actualXC->getITBPtr(); }
AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); }
#else
Process *getProcessPtr() { return actualXC->getProcessPtr(); }
#endif
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 actualXC->translateInstReq(req); }
Fault translateDataReadReq(MemReqPtr &req)
{ return actualXC->translateDataReadReq(req); }
Fault translateDataWriteReq(MemReqPtr &req)
{ return actualXC->translateDataWriteReq(req); }
// @todo: Do I need this?
MachInst getInst() { return actualXC->getInst(); }
// @todo: Do I need this?
void copyArchRegs(ExecContext *xc) { actualXC->copyArchRegs(xc); }
void clearArchRegs() { actualXC->clearArchRegs(); }
//
// New accessors for new decoder.
//
uint64_t readIntReg(int reg_idx)
{ return actualXC->readIntReg(reg_idx); }
float readFloatRegSingle(int reg_idx)
{ return actualXC->readFloatRegSingle(reg_idx); }
double readFloatRegDouble(int reg_idx)
{ return actualXC->readFloatRegDouble(reg_idx); }
uint64_t readFloatRegInt(int reg_idx)
{ return actualXC->readFloatRegInt(reg_idx); }
void setIntReg(int reg_idx, uint64_t val)
{ actualXC->setIntReg(reg_idx, val); }
void setFloatRegSingle(int reg_idx, float val)
{ actualXC->setFloatRegSingle(reg_idx, val); }
void setFloatRegDouble(int reg_idx, double val)
{ actualXC->setFloatRegDouble(reg_idx, val); }
void setFloatRegInt(int reg_idx, uint64_t val)
{ actualXC->setFloatRegInt(reg_idx, val); }
uint64_t readPC() { return actualXC->readPC(); }
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 actualXC->readMiscReg(misc_reg); }
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
{ return actualXC->readMiscRegWithEffect(misc_reg, fault); }
Fault setMiscReg(int misc_reg, const MiscReg &val)
{ return actualXC->setMiscReg(misc_reg, val); }
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
{ 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 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
IntReg getSyscallArg(int i) { return actualXC->getSyscallArg(i); }
// used to shift args for indirect syscall
void setSyscallArg(int i, IntReg val)
{ actualXC->setSyscallArg(i, val); }
void setSyscallReturn(SyscallReturn return_value)
{ actualXC->setSyscallReturn(return_value); }
void syscall() { actualXC->syscall(); }
Counter readFuncExeInst() { return actualXC->readFuncExeInst(); }
void setFuncExeInst(Counter new_val)
{ return actualXC->setFuncExeInst(new_val); }
#endif
};
#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);
assert(fault != AlignmentFault);
if (fault == NoFault) {
xc->copySrcAddr = src;
xc->copySrcPhysAddr = memReq->paddr + offset;
cpuXC->copySrcAddr = src;
cpuXC->copySrcPhysAddr = memReq->paddr + offset;
} else {
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,21 +383,21 @@ 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);
assert(fault != AlignmentFault);
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;
@@ -411,7 +414,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);
@@ -422,7 +425,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) {
@@ -442,12 +445,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);
}
@@ -507,11 +510,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;
@@ -588,7 +591,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
@@ -636,9 +639,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
@@ -654,16 +657,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);
@@ -671,7 +674,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)) {
@@ -681,24 +684,24 @@ 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);
xc->ev5_trap(InterruptFault);
if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) {
cpuXC->setMiscReg(IPR_ISR, summary);
cpuXC->setMiscReg(IPR_INTID, ipl);
cpuXC->ev5_trap(InterruptFault);
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) {
@@ -720,13 +723,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;
@@ -763,29 +766,30 @@ SimpleCPU::tick()
inst = gtoh(inst);
curStaticInst = StaticInst::decode(inst);
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
@@ -805,29 +809,29 @@ SimpleCPU::tick()
traceData->finalize();
}
traceFunctions(xc->regs.pc);
traceFunctions(cpuXC->readPC());
} // if (fault == NoFault)
if (fault != NoFault) {
#if FULL_SYSTEM
xc->ev5_trap(fault);
cpuXC->ev5_trap(fault);
#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 ev5_trap(Fault fault) { xc->ev5_trap(fault); }
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) { cpuXC->ev5_trap(fault); }
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

@@ -33,13 +33,13 @@
*
*/
#include "arch/isa_traits.hh"
#include "base/loader/symtab.hh"
#include "cpu/exec_context.hh"
#include "kern/freebsd/freebsd_system.hh"
#include "mem/functional/memory_control.hh"
#include "mem/functional/physical.hh"
#include "sim/builder.hh"
#include "arch/isa_traits.hh"
#include "sim/byteswap.hh"
#include "targetarch/vtophys.hh"
@@ -76,8 +76,8 @@ FreebsdSystem::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);
@@ -94,7 +94,7 @@ void
FreebsdSystem::SkipCalibrateClocksEvent::process(ExecContext *xc)
{
SkipFuncEvent::process(xc);
((FreebsdSystem *)xc->system)->doCalibrateClocks(xc);
((FreebsdSystem *)xc->getSystemPtr())->doCalibrateClocks(xc);
}

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);
@@ -184,11 +183,11 @@ class Statistics : public Serializable
else _faults[fault->id]++;
}// 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

@@ -192,7 +192,7 @@ LinuxSystem::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);
@@ -204,7 +204,7 @@ LinuxSystem::SkipDelayLoopEvent::process(ExecContext *xc)
{
SkipFuncEvent::process(xc);
// calculate and set loops_per_jiffy
((LinuxSystem *)xc->system)->setDelayLoop(xc);
((LinuxSystem *)xc->getSystemPtr())->setDelayLoop(xc);
}
void
@@ -212,7 +212,7 @@ LinuxSystem::DebugPrintkEvent::process(ExecContext *xc)
{
if (DTRACE(DebugPrintf)) {
if (!raw) {
StringWrap name(xc->system->name() + ".dprintk");
StringWrap name(xc->getSystemPtr()->name() + ".dprintk");
DPRINTFN("");
}

View File

@@ -53,7 +53,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

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

@@ -665,7 +665,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);
@@ -692,7 +692,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;
@@ -701,7 +701,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
@@ -713,20 +713,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));
@@ -761,7 +760,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;
}
@@ -782,7 +781,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.
@@ -791,7 +790,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;
@@ -811,7 +810,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! "
@@ -852,7 +851,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,
@@ -865,7 +864,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
@@ -899,13 +898,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;
@@ -919,15 +918,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();
}
@@ -942,7 +941,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! "
@@ -967,7 +966,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);
@@ -978,7 +977,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) {
@@ -992,7 +991,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 =
@@ -1002,7 +1001,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 "
@@ -1014,7 +1013,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) {
@@ -1028,7 +1027,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;
}
@@ -1065,8 +1064,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;
}
@@ -1082,7 +1081,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
@@ -1099,7 +1098,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;
@@ -1157,12 +1156,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));
@@ -1176,7 +1175,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.
@@ -1185,7 +1184,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());
}
}
@@ -1212,12 +1211,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;
@@ -1272,7 +1271,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"
@@ -81,6 +82,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;
@@ -149,7 +152,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
@@ -357,7 +360,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,13 +74,13 @@ namespace AlphaPseudo
return;
xc->suspend();
xc->kernelStats->quiesce();
xc->getCpuPtr()->kernelStats->quiesce();
}
void
ivlb(ExecContext *xc)
{
xc->kernelStats->ivlb();
xc->getCpuPtr()->kernelStats->ivlb();
}
void
@@ -138,7 +138,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
@@ -171,7 +171,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;
}