diff options
46 files changed, 1300 insertions, 795 deletions
diff --git a/SConscript b/SConscript index efcb2baf6..a405d252f 100644 --- a/SConscript +++ b/SConscript @@ -82,7 +82,7 @@ base_sources = Split(''' cpu/base.cc cpu/base_dyn_inst.cc - cpu/exec_context.cc + cpu/cpu_exec_context.cc cpu/exetrace.cc cpu/pc_event.cc cpu/static_inst.cc diff --git a/arch/alpha/arguments.cc b/arch/alpha/arguments.cc index 4e8190cbc..019390aeb 100644 --- a/arch/alpha/arguments.cc +++ b/arch/alpha/arguments.cc @@ -54,13 +54,13 @@ AlphaArguments::getArg(bool fp) { if (number < 6) { if (fp) - return xc->regs.floatRegFile.q[16 + number]; + return xc->readFloatRegInt(16 + number); else - return xc->regs.intRegFile[16 + number]; + return xc->readIntReg(16 + number); } else { - Addr sp = xc->regs.intRegFile[30]; + Addr sp = xc->readIntReg(30); Addr paddr = vtophys(xc, sp + (number-6) * sizeof(uint64_t)); - return xc->physmem->phys_read_qword(paddr); + return xc->getPhysMemPtr()->phys_read_qword(paddr); } } diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index e313c1a1c..11faf1850 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -34,6 +34,7 @@ #include "base/stats/events.hh" #include "config/full_system.hh" #include "cpu/base.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/exec_context.hh" #include "cpu/fast/cpu.hh" #include "kern/kernel_stats.hh" @@ -49,15 +50,15 @@ using namespace EV5; // Machine dependent functions // void -AlphaISA::initCPU(RegFile *regs, int cpuId) +AlphaISA::initCPU(ExecContext *xc, int cpuId) { - initIPRs(®s->miscRegs, cpuId); + initIPRs(xc, cpuId); - regs->intRegFile[16] = cpuId; - regs->intRegFile[0] = cpuId; + xc->setIntReg(16, cpuId); + xc->setIntReg(0, cpuId); - regs->pc = regs->miscRegs.readReg(IPR_PAL_BASE) + (new ResetFault)->vect(); - regs->npc = regs->pc + sizeof(MachInst); + xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + (new ResetFault)->vect()); + xc->setNextPC(xc->readPC() + sizeof(MachInst)); } //////////////////////////////////////////////////////////////////////// @@ -65,13 +66,15 @@ AlphaISA::initCPU(RegFile *regs, int cpuId) // // void -AlphaISA::initIPRs(MiscRegFile *miscRegs, int cpuId) +AlphaISA::initIPRs(ExecContext *xc, int cpuId) { - miscRegs->clearIprs(); + for (int i = 0; i < NumInternalProcRegs; ++i) { + xc->setMiscReg(i, 0); + } - miscRegs->setReg(IPR_PAL_BASE, PalBase); - miscRegs->setReg(IPR_MCSR, 0x6); - miscRegs->setReg(IPR_PALtemp16, cpuId); + xc->setMiscReg(IPR_PAL_BASE, PalBase); + xc->setMiscReg(IPR_MCSR, 0x6); + xc->setMiscReg(IPR_PALtemp16, cpuId); } @@ -130,12 +133,12 @@ AlphaISA::zeroRegisters(CPU *cpu) // Insure ISA semantics // (no longer very clean due to the change in setIntReg() in the // cpu model. Consider changing later.) - cpu->xc->setIntReg(ZeroReg, 0); - cpu->xc->setFloatRegDouble(ZeroReg, 0.0); + cpu->cpuXC->setIntReg(ZeroReg, 0); + cpu->cpuXC->setFloatRegDouble(ZeroReg, 0.0); } Fault -ExecContext::hwrei() +CPUExecContext::hwrei() { if (!inPalMode()) return new UnimplementedOpcodeFault; @@ -143,7 +146,7 @@ ExecContext::hwrei() setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR)); if (!misspeculating()) { - kernelStats->hwrei(); + cpu->kernelStats->hwrei(); cpu->checkInterrupts = true; } @@ -152,12 +155,6 @@ ExecContext::hwrei() return NoFault; } -void -AlphaISA::MiscRegFile::clearIprs() -{ - bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg)); -} - AlphaISA::MiscReg AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) { @@ -213,7 +210,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) case AlphaISA::IPR_CC: retval |= ipr[idx] & ULL(0xffffffff00000000); - retval |= xc->cpu->curCycle() & ULL(0x00000000ffffffff); + retval |= xc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff); break; case AlphaISA::IPR_VA: @@ -230,7 +227,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) case AlphaISA::IPR_DTB_PTE: { - AlphaISA::PTE &pte = xc->dtb->index(!xc->misspeculating()); + AlphaISA::PTE &pte = xc->getDTBPtr()->index(!xc->misspeculating()); retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32; retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8; @@ -327,7 +324,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // write entire quad w/ no side-effect old = ipr[idx]; ipr[idx] = val; - xc->kernelStats->context(old, val); + xc->getCpuPtr()->kernelStats->context(old, val, xc); break; case AlphaISA::IPR_DTB_PTE: @@ -354,14 +351,14 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // only write least significant five bits - interrupt level ipr[idx] = val & 0x1f; - xc->kernelStats->swpipl(ipr[idx]); + xc->getCpuPtr()->kernelStats->swpipl(ipr[idx]); break; case AlphaISA::IPR_DTB_CM: if (val & 0x18) - xc->kernelStats->mode(Kernel::user); + xc->getCpuPtr()->kernelStats->mode(Kernel::user, xc); else - xc->kernelStats->mode(Kernel::kernel); + xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc); case AlphaISA::IPR_ICM: // only write two mode bits - processor mode @@ -435,21 +432,22 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // really a control write ipr[idx] = 0; - xc->dtb->flushAll(); + xc->getDTBPtr()->flushAll(); break; case AlphaISA::IPR_DTB_IAP: // really a control write ipr[idx] = 0; - xc->dtb->flushProcesses(); + xc->getDTBPtr()->flushProcesses(); break; case AlphaISA::IPR_DTB_IS: // really a control write ipr[idx] = val; - xc->dtb->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + xc->getDTBPtr()->flushAddr(val, + DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); break; case AlphaISA::IPR_DTB_TAG: { @@ -472,7 +470,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB - xc->dtb->insert(val, pte); + xc->getDTBPtr()->insert(val, pte); } break; @@ -496,7 +494,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB - xc->itb->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); + xc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); } break; @@ -504,21 +502,22 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // really a control write ipr[idx] = 0; - xc->itb->flushAll(); + xc->getITBPtr()->flushAll(); break; case AlphaISA::IPR_ITB_IAP: // really a control write ipr[idx] = 0; - xc->itb->flushProcesses(); + xc->getITBPtr()->flushProcesses(); break; case AlphaISA::IPR_ITB_IS: // really a control write ipr[idx] = val; - xc->itb->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); + xc->getITBPtr()->flushAddr(val, + ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); break; default: @@ -535,9 +534,9 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) * If return value is false, actual PAL call will be suppressed. */ bool -ExecContext::simPalCheck(int palFunc) +CPUExecContext::simPalCheck(int palFunc) { - kernelStats->callpal(palFunc); + cpu->kernelStats->callpal(palFunc, proxy); switch (palFunc) { case PAL::halt: diff --git a/arch/alpha/freebsd/system.cc b/arch/alpha/freebsd/system.cc index 681d4ad46..e32053afd 100644 --- a/arch/alpha/freebsd/system.cc +++ b/arch/alpha/freebsd/system.cc @@ -39,8 +39,8 @@ #include "cpu/exec_context.hh" #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" -#include "sim/builder.hh" #include "arch/isa_traits.hh" +#include "sim/builder.hh" #include "sim/byteswap.hh" #include "arch/vtophys.hh" @@ -77,8 +77,8 @@ FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc) Addr ppc_paddr = 0; Addr timer_paddr = 0; - ppc_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg1]; - timer_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg2]; + ppc_vaddr = (Addr)xc->readIntReg(ArgumentReg1); + timer_vaddr = (Addr)xc->readIntReg(ArgumentReg2); ppc_paddr = vtophys(physmem, ppc_vaddr); timer_paddr = vtophys(physmem, timer_vaddr); @@ -95,7 +95,7 @@ void FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ExecContext *xc) { SkipFuncEvent::process(xc); - ((FreebsdAlphaSystem *)xc->system)->doCalibrateClocks(xc); + ((FreebsdAlphaSystem *)xc->getSystemPtr())->doCalibrateClocks(xc); } diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index 54bc97920..e09673269 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -784,7 +784,7 @@ decode OPCODE default Unknown::unknown() { 0x21: m5exit({{ AlphaPseudo::m5exit(xc->xcBase(), R16); }}, No_OpClass, IsNonSpeculative); - 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); + 0x30: initparam({{ Ra = xc->xcBase()->getCpuPtr()->system->init_param; }}); 0x40: resetstats({{ AlphaPseudo::resetstats(xc->xcBase(), R16, R17); }}, IsNonSpeculative); diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index a551db485..b4084723f 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -174,8 +174,6 @@ extern const int reg_redir[NumIntRegs]; ExecContext *xc); #if FULL_SYSTEM - void clearIprs(); - protected: InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs diff --git a/arch/alpha/linux/system.cc b/arch/alpha/linux/system.cc index 6a820d14f..f9275d15e 100644 --- a/arch/alpha/linux/system.cc +++ b/arch/alpha/linux/system.cc @@ -195,7 +195,7 @@ LinuxAlphaSystem::setDelayLoop(ExecContext *xc) uint8_t *loops_per_jiffy = physmem->dma_addr(paddr, sizeof(uint32_t)); - Tick cpuFreq = xc->cpu->frequency(); + Tick cpuFreq = xc->getCpuPtr()->frequency(); Tick intrFreq = platform->intrFrequency(); *(uint32_t *)loops_per_jiffy = (uint32_t)((cpuFreq / intrFreq) * 0.9988); @@ -208,7 +208,7 @@ LinuxAlphaSystem::SkipDelayLoopEvent::process(ExecContext *xc) { SkipFuncEvent::process(xc); // calculate and set loops_per_jiffy - ((LinuxAlphaSystem *)xc->system)->setDelayLoop(xc); + ((LinuxAlphaSystem *)xc->getSystemPtr())->setDelayLoop(xc); } void diff --git a/arch/alpha/linux/threadinfo.hh b/arch/alpha/linux/threadinfo.hh index bdb8e1e4c..8f03c9314 100644 --- a/arch/alpha/linux/threadinfo.hh +++ b/arch/alpha/linux/threadinfo.hh @@ -54,7 +54,7 @@ class ThreadInfo * thread_info struct. So we can get the address by masking off * the lower 14 bits. */ - current = xc->regs.intRegFile[TheISA::StackPointerReg] & ~0x3fff; + current = xc->readIntReg(TheISA::StackPointerReg) & ~0x3fff; return VPtr<thread_info>(xc, current); } diff --git a/arch/alpha/linux_process.cc b/arch/alpha/linux_process.cc index 0b193fb55..b80966133 100644 --- a/arch/alpha/linux_process.cc +++ b/arch/alpha/linux_process.cc @@ -61,7 +61,7 @@ pipeFunc(SyscallDesc *desc, int callnum, Process *process, // Alpha Linux convention for pipe() is that fd[0] is returned as // the return value of the function, and fd[1] is returned in r20. - xc->regs.intRegFile[20] = sim_fds[1]; + xc->setIntReg(20, sim_fds[1]); return sim_fds[0]; } @@ -79,7 +79,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); strcpy(name->machine, "alpha"); - name.copyOut(xc->mem); + name.copyOut(xc->getMemPtr()); return 0; } @@ -99,7 +99,7 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1)); // I don't think this exactly matches the HW FPCR *fpcr = 0; - fpcr.copyOut(xc->mem); + fpcr.copyOut(xc->getMemPtr()); return 0; } @@ -125,7 +125,7 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, case 14: { // SSI_IEEE_FP_CONTROL TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1)); // I don't think this exactly matches the HW FPCR - fpcr.copyIn(xc->mem); + fpcr.copyIn(xc->getMemPtr()); DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); return 0; diff --git a/arch/alpha/stacktrace.cc b/arch/alpha/stacktrace.cc index 89b6b73a9..50f2e4d21 100644 --- a/arch/alpha/stacktrace.cc +++ b/arch/alpha/stacktrace.cc @@ -44,23 +44,23 @@ ProcessInfo::ProcessInfo(ExecContext *_xc) { Addr addr = 0; - if (!xc->system->kernelSymtab->findAddress("thread_info_size", addr)) + if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) panic("thread info not compiled into kernel\n"); thread_info_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); - if (!xc->system->kernelSymtab->findAddress("task_struct_size", addr)) + if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) panic("thread info not compiled into kernel\n"); task_struct_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); - if (!xc->system->kernelSymtab->findAddress("thread_info_task", addr)) + if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) panic("thread info not compiled into kernel\n"); task_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); - if (!xc->system->kernelSymtab->findAddress("task_struct_pid", addr)) + if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) panic("thread info not compiled into kernel\n"); pid_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); - if (!xc->system->kernelSymtab->findAddress("task_struct_comm", addr)) + if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) panic("thread info not compiled into kernel\n"); name_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); } @@ -126,8 +126,9 @@ StackTrace::trace(ExecContext *_xc, bool is_call) bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; - Addr pc = xc->regs.npc; - bool kernel = xc->system->kernelStart <= pc && pc <= xc->system->kernelEnd; + Addr pc = xc->readNextPC(); + bool kernel = xc->getSystemPtr()->kernelStart <= pc && + pc <= xc->getSystemPtr()->kernelEnd; if (usermode) { stack.push_back(user); @@ -139,8 +140,8 @@ StackTrace::trace(ExecContext *_xc, bool is_call) return; } - SymbolTable *symtab = xc->system->kernelSymtab; - Addr ksp = xc->regs.intRegFile[TheISA::StackPointerReg]; + SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab; + Addr ksp = xc->readIntReg(TheISA::StackPointerReg); Addr bottom = ksp & ~0x3fff; Addr addr; @@ -149,7 +150,7 @@ StackTrace::trace(ExecContext *_xc, bool is_call) panic("could not find address %#x", pc); stack.push_back(addr); - pc = xc->regs.pc; + pc = xc->readPC(); } Addr ra; @@ -181,8 +182,8 @@ StackTrace::trace(ExecContext *_xc, bool is_call) return; } - bool kernel = xc->system->kernelStart <= pc && - pc <= xc->system->kernelEnd; + bool kernel = xc->getSystemPtr()->kernelStart <= pc && + pc <= xc->getSystemPtr()->kernelEnd; if (!kernel) return; @@ -323,8 +324,8 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, void StackTrace::dump() { - StringWrap name(xc->cpu->name()); - SymbolTable *symtab = xc->system->kernelSymtab; + StringWrap name(xc->getCpuPtr()->name()); + SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab; DPRINTFN("------ Stack ------\n"); diff --git a/arch/alpha/tlb.cc b/arch/alpha/tlb.cc index 0f2cedc83..e30a8e595 100644 --- a/arch/alpha/tlb.cc +++ b/arch/alpha/tlb.cc @@ -496,9 +496,8 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const Fault AlphaDTB::translate(MemReqPtr &req, bool write) const { - RegFile *regs = &req->xc->regs; ExecContext *xc = req->xc; - Addr pc = regs->pc; + Addr pc = xc->readPC(); AlphaISA::mode_type mode = (AlphaISA::mode_type)DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)); diff --git a/arch/alpha/tru64_process.cc b/arch/alpha/tru64_process.cc index 90e8b1139..5f6b802e9 100644 --- a/arch/alpha/tru64_process.cc +++ b/arch/alpha/tru64_process.cc @@ -52,7 +52,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, strcpy(name->version, "732"); strcpy(name->machine, "alpha"); - name.copyOut(xc->mem); + name.copyOut(xc->getMemPtr()); return 0; } @@ -69,21 +69,21 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, case Tru64::GSI_MAX_CPU: { TypedBufferArg<uint32_t> max_cpu(xc->getSyscallArg(1)); *max_cpu = htog((uint32_t)process->numCpus()); - max_cpu.copyOut(xc->mem); + max_cpu.copyOut(xc->getMemPtr()); return 1; } case Tru64::GSI_CPUS_IN_BOX: { TypedBufferArg<uint32_t> cpus_in_box(xc->getSyscallArg(1)); *cpus_in_box = htog((uint32_t)process->numCpus()); - cpus_in_box.copyOut(xc->mem); + cpus_in_box.copyOut(xc->getMemPtr()); return 1; } case Tru64::GSI_PHYSMEM: { TypedBufferArg<uint64_t> physmem(xc->getSyscallArg(1)); *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB - physmem.copyOut(xc->mem); + physmem.copyOut(xc->getMemPtr()); return 1; } @@ -100,14 +100,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, infop->cpu_ex_binding = htog(0); infop->mhz = htog(667); - infop.copyOut(xc->mem); + infop.copyOut(xc->getMemPtr()); return 1; } case Tru64::GSI_PROC_TYPE: { TypedBufferArg<uint64_t> proc_type(xc->getSyscallArg(1)); *proc_type = htog((uint64_t)11); - proc_type.copyOut(xc->mem); + proc_type.copyOut(xc->getMemPtr()); return 1; } @@ -116,14 +116,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, strncpy((char *)bufArg.bufferPtr(), "COMPAQ Professional Workstation XP1000", nbytes); - bufArg.copyOut(xc->mem); + bufArg.copyOut(xc->getMemPtr()); return 1; } case Tru64::GSI_CLK_TCK: { TypedBufferArg<uint64_t> clk_hz(xc->getSyscallArg(1)); *clk_hz = htog((uint64_t)1024); - clk_hz.copyOut(xc->mem); + clk_hz.copyOut(xc->getMemPtr()); return 1; } diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc index 1d70196c5..40261426d 100644 --- a/arch/alpha/vtophys.cc +++ b/arch/alpha/vtophys.cc @@ -95,7 +95,7 @@ vtophys(ExecContext *xc, Addr addr) paddr = vaddr; } else { AlphaISA::PageTableEntry pte = - kernel_pte_lookup(xc->physmem, ptbr, vaddr); + kernel_pte_lookup(xc->getPhysMemPtr(), ptbr, vaddr); if (pte.valid()) paddr = pte.paddr() | vaddr.offset(); } @@ -110,14 +110,14 @@ vtophys(ExecContext *xc, Addr addr) uint8_t * ptomem(ExecContext *xc, Addr paddr, size_t len) { - return xc->physmem->dma_addr(paddr, len); + return xc->getPhysMemPtr()->dma_addr(paddr, len); } uint8_t * vtomem(ExecContext *xc, Addr vaddr, size_t len) { Addr paddr = vtophys(xc, vaddr); - return xc->physmem->dma_addr(paddr, len); + return xc->getPhysMemPtr()->dma_addr(paddr, len); } void @@ -131,7 +131,7 @@ CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) paddr = vtophys(xc, src); len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), (int)cplen); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len); assert(dmaaddr); memcpy(dst, dmaaddr, len); @@ -144,7 +144,8 @@ CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) while (cplen > AlphaISA::PageBytes) { paddr = vtophys(xc, src); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, + AlphaISA::PageBytes); assert(dmaaddr); memcpy(dst, dmaaddr, AlphaISA::PageBytes); @@ -155,7 +156,7 @@ CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) if (cplen > 0) { paddr = vtophys(xc, src); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, cplen); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen); assert(dmaaddr); memcpy(dst, dmaaddr, cplen); @@ -173,7 +174,7 @@ CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) paddr = vtophys(xc, dest); len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), (int)cplen); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len); assert(dmaaddr); memcpy(dmaaddr, src, len); @@ -186,7 +187,8 @@ CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) while (cplen > AlphaISA::PageBytes) { paddr = vtophys(xc, dest); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, + AlphaISA::PageBytes); assert(dmaaddr); memcpy(dmaaddr, src, AlphaISA::PageBytes); @@ -197,7 +199,7 @@ CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) if (cplen > 0) { paddr = vtophys(xc, dest); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, cplen); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen); assert(dmaaddr); memcpy(dmaaddr, src, cplen); @@ -214,7 +216,7 @@ CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) paddr = vtophys(xc, vaddr); len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), (int)maxlen); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len); assert(dmaaddr); char *term = (char *)memchr(dmaaddr, 0, len); @@ -232,7 +234,8 @@ CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) while (maxlen > AlphaISA::PageBytes) { paddr = vtophys(xc, vaddr); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, + AlphaISA::PageBytes); assert(dmaaddr); char *term = (char *)memchr(dmaaddr, 0, AlphaISA::PageBytes); @@ -249,7 +252,7 @@ CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) if (maxlen > 0) { paddr = vtophys(xc, vaddr); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, maxlen); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, maxlen); assert(dmaaddr); char *term = (char *)memchr(dmaaddr, 0, maxlen); diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 57a179719..84093459c 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -470,7 +470,7 @@ RemoteGDB::setregs() context->setFloatRegInt(i, gdbregs[i + KGDB_REG_F0]); } #endif - context->regs.pc = gdbregs[KGDB_REG_PC]; + context->setPC(gdbregs[KGDB_REG_PC]); } void @@ -509,7 +509,7 @@ RemoteGDB::clearSingleStep() void RemoteGDB::setSingleStep() { - Addr pc = context->regs.pc; + Addr pc = context->readPC(); Addr npc, bpc; bool set_bt = false; @@ -858,7 +858,7 @@ RemoteGDB::trap(int type) return false; DPRINTF(GDBMisc, "trap: PC=%#x NPC=%#x\n", - context->regs.pc, context->regs.npc); + context->readPC(), context->readNextPC()); clearSingleStep(); @@ -1013,8 +1013,8 @@ RemoteGDB::trap(int type) subcmd = hex2i(&p); if (*p++ == ';') { val = hex2i(&p); - context->regs.pc = val; - context->regs.npc = val + sizeof(MachInst); + context->setPC(val); + context->setNextPC(val + sizeof(MachInst)); } clearSingleStep(); goto out; @@ -1022,8 +1022,8 @@ RemoteGDB::trap(int type) case KGDB_CONT: if (p - data < datalen) { val = hex2i(&p); - context->regs.pc = val; - context->regs.npc = val + sizeof(MachInst); + context->setPC(val); + context->setNextPC(val + sizeof(MachInst)); } clearSingleStep(); goto out; @@ -1032,8 +1032,8 @@ RemoteGDB::trap(int type) subcmd = hex2i(&p); if (*p++ == ';') { val = hex2i(&p); - context->regs.pc = val; - context->regs.npc = val + sizeof(MachInst); + context->setPC(val); + context->setNextPC(val + sizeof(MachInst)); } setSingleStep(); goto out; @@ -1041,8 +1041,8 @@ RemoteGDB::trap(int type) case KGDB_STEP: if (p - data < datalen) { val = hex2i(&p); - context->regs.pc = val; - context->regs.npc = val + sizeof(MachInst); + context->setPC(val); + context->setNextPC(val + sizeof(MachInst)); } setSingleStep(); goto out; diff --git a/cpu/base.cc b/cpu/base.cc index 5a7ecf152..e2a4c214a 100644 --- a/cpu/base.cc +++ b/cpu/base.cc @@ -39,10 +39,16 @@ #include "cpu/profile.hh" #include "cpu/sampler/sampler.hh" #include "sim/param.hh" +#include "sim/process.hh" #include "sim/sim_events.hh" +#include "sim/system.hh" #include "base/trace.hh" +#if FULL_SYSTEM +#include "kern/kernel_stats.hh" +#endif + using namespace std; vector<BaseCPU *> BaseCPU::cpuList; @@ -147,7 +153,10 @@ BaseCPU::BaseCPU(Params *p) profileEvent = NULL; if (params->profile) profileEvent = new ProfileEvent(this, params->profile); + + kernelStats = new Kernel::Statistics(system); #endif + } BaseCPU::Params::Params() @@ -165,6 +174,10 @@ BaseCPU::enableFunctionTrace() BaseCPU::~BaseCPU() { +#if FULL_SYSTEM + if (kernelStats) + delete kernelStats; +#endif } void @@ -203,6 +216,11 @@ BaseCPU::regStats() } } else if (size == 1) execContexts[0]->regStats(name()); + +#if FULL_SYSTEM + if (kernelStats) + kernelStats->regStats(name() + ".kern"); +#endif } @@ -216,9 +234,9 @@ BaseCPU::registerExecContexts() if (id != -1) id += i; - xc->cpu_id = system->registerExecContext(xc, id); + xc->setCpuId(system->registerExecContext(xc, id)); #else - xc->cpu_id = xc->process->registerExecContext(xc); + xc->setCpuId(xc->getProcessPtr()->registerExecContext(xc)); #endif } } @@ -240,12 +258,12 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) ExecContext *oldXC = oldCPU->execContexts[i]; newXC->takeOverFrom(oldXC); - assert(newXC->cpu_id == oldXC->cpu_id); + assert(newXC->readCpuId() == oldXC->readCpuId()); #if FULL_SYSTEM - system->replaceExecContext(newXC, newXC->cpu_id); + system->replaceExecContext(newXC, newXC->readCpuId()); #else - assert(newXC->process == oldXC->process); - newXC->process->replaceExecContext(newXC, newXC->cpu_id); + assert(newXC->getProcessPtr() == oldXC->getProcessPtr()); + newXC->getProcessPtr()->replaceExecContext(newXC, newXC->readCpuId()); #endif } @@ -253,11 +271,11 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) for (int i = 0; i < TheISA::NumInterruptLevels; ++i) interrupts[i] = oldCPU->interrupts[i]; intstatus = oldCPU->intstatus; - +/* for (int i = 0; i < execContexts.size(); ++i) if (execContexts[i]->profile) execContexts[i]->profile->clear(); - +*/ if (profileEvent) profileEvent->schedule(curTick); #endif @@ -272,11 +290,11 @@ BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval) void BaseCPU::ProfileEvent::process() { - for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) { +/* for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) { ExecContext *xc = cpu->execContexts[i]; xc->profile->sample(xc->profileNode, xc->profilePC); } - +*/ schedule(curTick + interval); } @@ -327,6 +345,12 @@ BaseCPU::serialize(std::ostream &os) { SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); SERIALIZE_SCALAR(intstatus); + +#if FULL_SYSTEM + if (kernelStats) + kernelStats->serialize(os); +#endif + } void @@ -334,6 +358,11 @@ BaseCPU::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); UNSERIALIZE_SCALAR(intstatus); + +#if FULL_SYSTEM + if (kernelStats) + kernelStats->unserialize(cp, section); +#endif } #endif // FULL_SYSTEM diff --git a/cpu/base.hh b/cpu/base.hh index d5764d495..d9d5d2b88 100644 --- a/cpu/base.hh +++ b/cpu/base.hh @@ -40,6 +40,7 @@ #if FULL_SYSTEM class System; +namespace Kernel { class Statistics; } #endif class BranchPred; @@ -234,6 +235,10 @@ class BaseCPU : public SimObject public: // Number of CPU cycles simulated Stats::Scalar<> numCycles; + +#if FULL_SYSTEM + Kernel::Statistics *kernelStats; +#endif }; #endif // __CPU_BASE_HH__ diff --git a/cpu/base_dyn_inst.cc b/cpu/base_dyn_inst.cc index 5905cdad2..bf7c35cad 100644 --- a/cpu/base_dyn_inst.cc +++ b/cpu/base_dyn_inst.cc @@ -68,7 +68,7 @@ template <class Impl> BaseDynInst<Impl>::BaseDynInst(MachInst machInst, Addr inst_PC, Addr pred_PC, InstSeqNum seq_num, FullCPU *cpu) - : staticInst(machInst), traceData(NULL), cpu(cpu), xc(cpu->xcBase()) + : staticInst(machInst), traceData(NULL), cpu(cpu), cpuXC(cpu->cpuXCBase()) { seqNum = seq_num; @@ -139,14 +139,14 @@ BaseDynInst<Impl>::prefetch(Addr addr, unsigned flags) // state. // Generate a MemReq so we can translate the effective address. - MemReqPtr req = new MemReq(addr, xc, 1, flags); + MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), 1, flags); req->asid = asid; // Prefetches never cause faults. fault = NoFault; // note this is a local, not BaseDynInst::fault - Fault trans_fault = xc->translateDataReadReq(req); + Fault trans_fault = cpuXC->translateDataReadReq(req); if (trans_fault == NoFault && !(req->flags & UNCACHEABLE)) { // It's a valid address to cacheable space. Record key MemReq @@ -184,10 +184,10 @@ BaseDynInst<Impl>::writeHint(Addr addr, int size, unsigned flags) // will casue a TLB miss trap if necessary... not sure whether // that's the best thing to do or not. We don't really need the // MemReq otherwise, since wh64 has no functional effect. - MemReqPtr req = new MemReq(addr, xc, size, flags); + MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), size, flags); req->asid = asid; - fault = xc->translateDataWriteReq(req); + fault = cpuXC->translateDataWriteReq(req); if (fault == NoFault && !(req->flags & UNCACHEABLE)) { // Record key MemReq parameters so we can generate another one @@ -212,18 +212,18 @@ template <class Impl> Fault BaseDynInst<Impl>::copySrcTranslate(Addr src) { - MemReqPtr req = new MemReq(src, xc, 64); + MemReqPtr req = new MemReq(src, cpuXC->getProxy(), 64); req->asid = asid; // translate to physical address - Fault fault = xc->translateDataReadReq(req); + Fault fault = cpuXC->translateDataReadReq(req); if (fault == NoFault) { - xc->copySrcAddr = src; - xc->copySrcPhysAddr = req->paddr; + cpuXC->copySrcAddr = src; + cpuXC->copySrcPhysAddr = req->paddr; } else { - xc->copySrcAddr = 0; - xc->copySrcPhysAddr = 0; + cpuXC->copySrcAddr = 0; + cpuXC->copySrcPhysAddr = 0; } return fault; } @@ -236,18 +236,18 @@ Fault BaseDynInst<Impl>::copy(Addr dest) { uint8_t data[64]; - FunctionalMemory *mem = xc->mem; - assert(xc->copySrcPhysAddr || xc->misspeculating()); - MemReqPtr req = new MemReq(dest, xc, 64); + FunctionalMemory *mem = cpuXC->mem; + assert(cpuXC->copySrcPhysAddr || cpuXC->misspeculating()); + MemReqPtr req = new MemReq(dest, cpuXC->getProxy(), 64); req->asid = asid; // translate to physical address - Fault fault = xc->translateDataWriteReq(req); + Fault fault = cpuXC->translateDataWriteReq(req); if (fault == NoFault) { Addr dest_addr = req->paddr; // Need to read straight from memory since we have more than 8 bytes. - req->paddr = xc->copySrcPhysAddr; + req->paddr = cpuXC->copySrcPhysAddr; mem->read(req, data); req->paddr = dest_addr; mem->write(req, data); diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh index e94c44151..3a7852f79 100644 --- a/cpu/base_dyn_inst.hh +++ b/cpu/base_dyn_inst.hh @@ -145,7 +145,7 @@ class BaseDynInst : public FastAlloc, public RefCounted FullCPU *cpu; /** Pointer to the exec context. Will not exist in the final version. */ - ExecContext *xc; + CPUExecContext *cpuXC; /** The kind of fault this instruction has generated. */ Fault fault; @@ -406,7 +406,7 @@ class BaseDynInst : public FastAlloc, public RefCounted /** Returns the exec context. * @todo: Remove this once the ExecContext is no longer used. */ - ExecContext *xcBase() { return xc; } + ExecContext *xcBase() { return cpuXC->getProxy(); } private: /** Instruction effective address. @@ -444,7 +444,7 @@ template<class T> inline Fault BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags) { - MemReqPtr req = new MemReq(addr, xc, sizeof(T), flags); + MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), sizeof(T), flags); req->asid = asid; fault = cpu->translateDataReadReq(req); @@ -492,7 +492,7 @@ BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res) traceData->setData(data); } - MemReqPtr req = new MemReq(addr, xc, sizeof(T), flags); + MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), sizeof(T), flags); req->asid = asid; diff --git a/cpu/exec_context.cc b/cpu/cpu_exec_context.cc index e0ab1007f..ae428646d 100644 --- a/cpu/exec_context.cc +++ b/cpu/cpu_exec_context.cc @@ -29,6 +29,7 @@ #include <string> #include "cpu/base.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/exec_context.hh" #if FULL_SYSTEM @@ -50,23 +51,24 @@ using namespace std; // constructor #if FULL_SYSTEM -ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, +CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_mem) : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0), lastSuspend(0), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), memctrl(_sys->memctrl), physmem(_sys->physmem), - kernelBinning(system->kernelBinning), bin(kernelBinning->bin), fnbin(kernelBinning->fnbin), profile(NULL), quiesceEvent(this), func_exe_inst(0), storeCondFailures(0) { - kernelStats = new Kernel::Statistics(this); + proxy = new ProxyExecContext<CPUExecContext>(this); + memset(®s, 0, sizeof(RegFile)); if (cpu->params->profile) { profile = new FunctionProfile(system->kernelSymtab); Callback *cb = - new MakeCallback<ExecContext, &ExecContext::dumpFuncProfile>(this); + new MakeCallback<CPUExecContext, + &CPUExecContext::dumpFuncProfile>(this); registerExitCallback(cb); } @@ -77,7 +79,7 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, profilePC = 3; } #else -ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, +CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid) : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0), @@ -85,30 +87,38 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, func_exe_inst(0), storeCondFailures(0) { memset(®s, 0, sizeof(RegFile)); + proxy = new ProxyExecContext<CPUExecContext>(this); } -ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, +CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, int _asid) : cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid), func_exe_inst(0), storeCondFailures(0) { memset(®s, 0, sizeof(RegFile)); + proxy = new ProxyExecContext<CPUExecContext>(this); } -#endif -ExecContext::~ExecContext() +CPUExecContext::CPUExecContext(RegFile *regFile) + : cpu(NULL), thread_num(-1), process(NULL), mem(NULL), asid(-1), + func_exe_inst(0), storeCondFailures(0) { -#if FULL_SYSTEM - delete kernelStats; + regs = *regFile; + proxy = new ProxyExecContext<CPUExecContext>(this); +} + #endif + +CPUExecContext::~CPUExecContext() +{ + delete proxy; } #if FULL_SYSTEM void -ExecContext::dumpFuncProfile() +CPUExecContext::dumpFuncProfile() { std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); - profile->dump(this, *os); } ExecContext::EndQuiesceEvent::EndQuiesceEvent(ExecContext *_xc) @@ -130,8 +140,9 @@ ExecContext::EndQuiesceEvent::description() #endif void -ExecContext::takeOverFrom(ExecContext *oldContext) +CPUExecContext::takeOverFrom(ExecContext *oldContext) { +/* // some things should already be set up assert(mem == oldContext->mem); #if FULL_SYSTEM @@ -148,11 +159,12 @@ ExecContext::takeOverFrom(ExecContext *oldContext) storeCondFailures = 0; - oldContext->_status = ExecContext::Unallocated; + oldContext->_status = CPUExecContext::Unallocated; +*/ } void -ExecContext::serialize(ostream &os) +CPUExecContext::serialize(ostream &os) { SERIALIZE_ENUM(_status); regs.serialize(os); @@ -165,14 +177,13 @@ ExecContext::serialize(ostream &os) if (quiesceEvent.scheduled()) quiesceEndTick = quiesceEvent.when(); SERIALIZE_SCALAR(quiesceEndTick); - kernelStats->serialize(os); #endif } void -ExecContext::unserialize(Checkpoint *cp, const std::string §ion) +CPUExecContext::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ENUM(_status); regs.unserialize(cp, section); @@ -185,28 +196,26 @@ ExecContext::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(quiesceEndTick); if (quiesceEndTick) quiesceEvent.schedule(quiesceEndTick); - - kernelStats->unserialize(cp, section); #endif } void -ExecContext::activate(int delay) +CPUExecContext::activate(int delay) { - if (status() == Active) + if (status() == ExecContext::Active) return; lastActivate = curTick; - _status = Active; + _status = ExecContext::Active; cpu->activateContext(thread_num, delay); } void -ExecContext::suspend() +CPUExecContext::suspend() { - if (status() == Suspended) + if (status() == ExecContext::Suspended) return; lastActivate = curTick; @@ -215,41 +224,65 @@ ExecContext::suspend() #if FULL_SYSTEM // Don't change the status from active if there are pending interrupts if (cpu->check_interrupts()) { - assert(status() == Active); + assert(status() == ExecContext::Active); return; } #endif */ - _status = Suspended; + _status = ExecContext::Suspended; cpu->suspendContext(thread_num); } void -ExecContext::deallocate() +CPUExecContext::deallocate() { - if (status() == Unallocated) + if (status() == ExecContext::Unallocated) return; - _status = Unallocated; + _status = ExecContext::Unallocated; cpu->deallocateContext(thread_num); } void -ExecContext::halt() +CPUExecContext::halt() { - if (status() == Halted) + if (status() == ExecContext::Halted) return; - _status = Halted; + _status = ExecContext::Halted; cpu->haltContext(thread_num); } void -ExecContext::regStats(const string &name) +CPUExecContext::regStats(const string &name) { -#if FULL_SYSTEM - kernelStats->regStats(name + ".kern"); -#endif +} + +void +CPUExecContext::copyArchRegs(ExecContext *xc) +{ + // First loop through the integer registers. + for (int i = 0; i < AlphaISA::NumIntRegs; ++i) { + setIntReg(i, xc->readIntReg(i)); + } + + // Then loop through the floating point registers. + for (int i = 0; i < AlphaISA::NumFloatRegs; ++i) { + setFloatRegDouble(i, xc->readFloatRegDouble(i)); + setFloatRegInt(i, xc->readFloatRegInt(i)); + } + + // Copy misc. registers + setMiscReg(AlphaISA::Fpcr_DepTag, xc->readMiscReg(AlphaISA::Fpcr_DepTag)); + setMiscReg(AlphaISA::Uniq_DepTag, xc->readMiscReg(AlphaISA::Uniq_DepTag)); + setMiscReg(AlphaISA::Lock_Flag_DepTag, + xc->readMiscReg(AlphaISA::Lock_Flag_DepTag)); + setMiscReg(AlphaISA::Lock_Addr_DepTag, + xc->readMiscReg(AlphaISA::Lock_Addr_DepTag)); + + // Lastly copy PC/NPC + setPC(xc->readPC()); + setNextPC(xc->readNextPC()); } diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh new file mode 100644 index 000000000..a40253d4b --- /dev/null +++ b/cpu/cpu_exec_context.hh @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2001-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __CPU_CPU_EXEC_CONTEXT_HH__ +#define __CPU_CPU_EXEC_CONTEXT_HH__ + +#include "arch/isa_traits.hh" +#include "config/full_system.hh" +#include "cpu/exec_context.hh" +#include "mem/functional/functional.hh" +#include "mem/mem_req.hh" +#include "sim/byteswap.hh" +#include "sim/eventq.hh" +#include "sim/host.hh" +#include "sim/serialize.hh" + +// forward declaration: see functional_memory.hh +class FunctionalMemory; +class PhysicalMemory; +class BaseCPU; + +#if FULL_SYSTEM + +#include "sim/system.hh" +#include "arch/tlb.hh" + +class FunctionProfile; +class ProfileNode; +class MemoryController; + +#else // !FULL_SYSTEM + +#include "sim/process.hh" + +#endif // FULL_SYSTEM + +// +// The CPUExecContext object represents a functional context for +// instruction execution. It incorporates everything required for +// architecture-level functional simulation of a single thread. +// + +class CPUExecContext +{ + protected: + typedef TheISA::RegFile RegFile; + typedef TheISA::MachInst MachInst; + typedef TheISA::MiscRegFile MiscRegFile; + typedef TheISA::MiscReg MiscReg; + public: + typedef ExecContext::Status Status; + + private: + Status _status; + + public: + Status status() const { return _status; } + + void setStatus(Status newStatus) { _status = newStatus; } + + /// Set the status to Active. Optional delay indicates number of + /// cycles to wait before beginning execution. + void activate(int delay = 1); + + /// Set the status to Suspended. + void suspend(); + + /// Set the status to Unallocated. + void deallocate(); + + /// Set the status to Halted. + void halt(); + + protected: + RegFile regs; // correct-path register context + + public: + // pointer to CPU associated with this context + BaseCPU *cpu; + + ProxyExecContext<CPUExecContext> *proxy; + + // Current instruction + MachInst inst; + + // Index of hardware thread context on the CPU that this represents. + int thread_num; + + // ID of this context w.r.t. the System or Process object to which + // it belongs. For full-system mode, this is the system CPU ID. + int cpu_id; + + Tick lastActivate; + Tick lastSuspend; + +#if FULL_SYSTEM + FunctionalMemory *mem; + AlphaITB *itb; + AlphaDTB *dtb; + System *system; + + // the following two fields are redundant, since we can always + // look them up through the system pointer, but we'll leave them + // here for now for convenience + MemoryController *memctrl; + PhysicalMemory *physmem; + + FunctionProfile *profile; + ProfileNode *profileNode; + Addr profilePC; + void dumpFuncProfile(); + + /** Event for timing out quiesce instruction */ + struct EndQuiesceEvent : public Event + { + /** A pointer to the execution context that is quiesced */ + ExecContext *xc; + + EndQuiesceEvent(ExecContext *_xc); + + /** Event process to occur at interrupt*/ + virtual void process(); + + /** Event description */ + virtual const char *description(); + }; + EndQuiesceEvent quiesceEvent; + +#else + Process *process; + + FunctionalMemory *mem; // functional storage for process address space + + // Address space ID. Note that this is used for TIMING cache + // simulation only; all functional memory accesses should use + // one of the FunctionalMemory pointers above. + short asid; + +#endif + + /** + * Temporary storage to pass the source address from copy_load to + * copy_store. + * @todo Remove this temporary when we have a better way to do it. + */ + Addr copySrcAddr; + /** + * Temp storage for the physical source address of a copy. + * @todo Remove this temporary when we have a better way to do it. + */ + Addr copySrcPhysAddr; + + + /* + * number of executed instructions, for matching with syscall trace + * points in EIO files. + */ + Counter func_exe_inst; + + // + // Count failed store conditionals so we can warn of apparent + // application deadlock situations. + unsigned storeCondFailures; + + // constructor: initialize context from given process structure +#if FULL_SYSTEM + CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system, + AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem); +#else + CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid); + CPUExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, + int _asid); + // Constructor to use XC to pass reg file around. Not used for anything + // else. + CPUExecContext(RegFile *regFile); +#endif + virtual ~CPUExecContext(); + + virtual void takeOverFrom(ExecContext *oldContext); + + void regStats(const std::string &name); + + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + + BaseCPU *getCpuPtr() { return cpu; } + + ExecContext *getProxy() { return proxy; } + + int getThreadNum() { return thread_num; } + +#if FULL_SYSTEM + System *getSystemPtr() { return system; } + + PhysicalMemory *getPhysMemPtr() { return physmem; } + + AlphaITB *getITBPtr() { return itb; } + + AlphaDTB *getDTBPtr() { return dtb; } + + bool validInstAddr(Addr addr) { return true; } + bool validDataAddr(Addr addr) { return true; } + int getInstAsid() { return regs.instAsid(); } + int getDataAsid() { return regs.dataAsid(); } + + Fault translateInstReq(MemReqPtr &req) + { + return itb->translate(req); + } + + Fault translateDataReadReq(MemReqPtr &req) + { + return dtb->translate(req, false); + } + + Fault translateDataWriteReq(MemReqPtr &req) + { + return dtb->translate(req, true); + } + +#else + Process *getProcessPtr() { return process; } + + bool validInstAddr(Addr addr) + { return process->validInstAddr(addr); } + + bool validDataAddr(Addr addr) + { return process->validDataAddr(addr); } + + int getInstAsid() { return asid; } + int getDataAsid() { return asid; } + + Fault dummyTranslation(MemReqPtr &req) + { +#if 0 + assert((req->vaddr >> 48 & 0xffff) == 0); +#endif + + // put the asid in the upper 16 bits of the paddr + req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); + req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; + return NoFault; + } + Fault translateInstReq(MemReqPtr &req) + { + return dummyTranslation(req); + } + Fault translateDataReadReq(MemReqPtr &req) + { + return dummyTranslation(req); + } + Fault translateDataWriteReq(MemReqPtr &req) + { + return dummyTranslation(req); + } + +#endif + + template <class T> + Fault read(MemReqPtr &req, T &data) + { +#if FULL_SYSTEM && defined(TARGET_ALPHA) + if (req->flags & LOCKED) { + req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr); + req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true); + } +#endif + + Fault error; + error = mem->read(req, data); + data = LittleEndianGuest::gtoh(data); + return error; + } + + template <class T> + Fault write(MemReqPtr &req, T &data) + { +#if FULL_SYSTEM && defined(TARGET_ALPHA) + ExecContext *xc; + + // If this is a store conditional, act appropriately + if (req->flags & LOCKED) { + xc = req->xc; + + if (req->flags & UNCACHEABLE) { + // Don't update result register (see stq_c in isa_desc) + req->result = 2; + xc->setStCondFailures(0);//Needed? [RGD] + } else { + bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag); + Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag); + req->result = lock_flag; + if (!lock_flag || + ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { + xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); + xc->setStCondFailures(xc->readStCondFailures() + 1); + if (((xc->readStCondFailures()) % 100000) == 0) { + std::cerr << "Warning: " + << xc->readStCondFailures() + << " consecutive store conditional failures " + << "on cpu " << req->xc->readCpuId() + << std::endl; + } + return NoFault; + } + else xc->setStCondFailures(0); + } + } + + // Need to clear any locked flags on other proccessors for + // this address. Only do this for succsful Store Conditionals + // and all other stores (WH64?). Unsuccessful Store + // Conditionals would have returned above, and wouldn't fall + // through. + for (int i = 0; i < system->execContexts.size(); i++){ + xc = system->execContexts[i]; + if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) == + (req->paddr & ~0xf)) { + xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); + } + } + +#endif + return mem->write(req, (T)LittleEndianGuest::htog(data)); + } + + virtual bool misspeculating(); + + + MachInst getInst() { return inst; } + + void setInst(MachInst new_inst) + { + inst = new_inst; + } + + Fault instRead(MemReqPtr &req) + { + return mem->read(req, inst); + } + + void setCpuId(int id) { cpu_id = id; } + + int readCpuId() { return cpu_id; } + + FunctionalMemory *getMemPtr() { return mem; } + + void copyArchRegs(ExecContext *xc); + + // + // New accessors for new decoder. + // + uint64_t readIntReg(int reg_idx) + { + return regs.intRegFile[reg_idx]; + } + + float readFloatRegSingle(int reg_idx) + { + return (float)regs.floatRegFile.d[reg_idx]; + } + + double readFloatRegDouble(int reg_idx) + { + return regs.floatRegFile.d[reg_idx]; + } + + uint64_t readFloatRegInt(int reg_idx) + { + return regs.floatRegFile.q[reg_idx]; + } + + void setIntReg(int reg_idx, uint64_t val) + { + regs.intRegFile[reg_idx] = val; + } + + void setFloatRegSingle(int reg_idx, float val) + { + regs.floatRegFile.d[reg_idx] = (double)val; + } + + void setFloatRegDouble(int reg_idx, double val) + { + regs.floatRegFile.d[reg_idx] = val; + } + + void setFloatRegInt(int reg_idx, uint64_t val) + { + regs.floatRegFile.q[reg_idx] = val; + } + + uint64_t readPC() + { + return regs.pc; + } + + void setPC(uint64_t val) + { + regs.pc = val; + } + + uint64_t readNextPC() + { + return regs.npc; + } + + void setNextPC(uint64_t val) + { + regs.npc = val; + } + + MiscReg readMiscReg(int misc_reg) + { + return regs.miscRegs.readReg(misc_reg); + } + + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + { + return regs.miscRegs.readRegWithEffect(misc_reg, fault, proxy); + } + + Fault setMiscReg(int misc_reg, const MiscReg &val) + { + return regs.miscRegs.setReg(misc_reg, val); + } + + Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + { + return regs.miscRegs.setRegWithEffect(misc_reg, val, proxy); + } + + unsigned readStCondFailures() { return storeCondFailures; } + + void setStCondFailures(unsigned sc_failures) + { storeCondFailures = sc_failures; } + + void clearArchRegs() { memset(®s, 0, sizeof(regs)); } + +#if FULL_SYSTEM + int readIntrFlag() { return regs.intrflag; } + void setIntrFlag(int val) { regs.intrflag = val; } + Fault hwrei(); + bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } + bool simPalCheck(int palFunc); +#endif + +#if !FULL_SYSTEM + TheISA::IntReg getSyscallArg(int i) + { + return regs.intRegFile[TheISA::ArgumentReg0 + i]; + } + + // used to shift args for indirect syscall + void setSyscallArg(int i, TheISA::IntReg val) + { + regs.intRegFile[TheISA::ArgumentReg0 + i] = val; + } + + void setSyscallReturn(SyscallReturn return_value) + { + // check for error condition. Alpha syscall convention is to + // indicate success/failure in reg a3 (r19) and put the + // return value itself in the standard return value reg (v0). + const int RegA3 = 19; // only place this is used + if (return_value.successful()) { + // no error + regs.intRegFile[RegA3] = 0; + regs.intRegFile[TheISA::ReturnValueReg] = return_value.value(); + } else { + // got an error, return details + regs.intRegFile[RegA3] = (TheISA::IntReg) -1; + regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value(); + } + } + + void syscall() + { + process->syscall(proxy); + } + + Counter readFuncExeInst() { return func_exe_inst; } + + void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; } +#endif +}; + + +// for non-speculative execution context, spec_mode is always false +inline bool +CPUExecContext::misspeculating() +{ + return false; +} + +#endif // __CPU_CPU_EXEC_CONTEXT_HH__ diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index bc3551b4f..9c96b5c42 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2006 The Regents of The University of Michigan + * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,47 +30,29 @@ #define __CPU_EXEC_CONTEXT_HH__ #include "config/full_system.hh" -#include "mem/functional/functional.hh" #include "mem/mem_req.hh" -#include "sim/eventq.hh" +#include "sim/faults.hh" #include "sim/host.hh" #include "sim/serialize.hh" -#include "arch/isa_traits.hh" -//#include "arch/isa_registers.hh" #include "sim/byteswap.hh" // forward declaration: see functional_memory.hh +// @todo: Figure out a more architecture independent way to obtain the ITB and +// DTB pointers. +class AlphaDTB; +class AlphaITB; +class BaseCPU; class FunctionalMemory; class PhysicalMemory; -class BaseCPU; - -#if FULL_SYSTEM - -#include "sim/system.hh" -#include "arch/tlb.hh" - -class FunctionProfile; -class ProfileNode; -class MemoryController; -namespace Kernel { class Binning; class Statistics; } - -#else // !FULL_SYSTEM - -#include "sim/process.hh" - -#endif // FULL_SYSTEM - -// -// The ExecContext object represents a functional context for -// instruction execution. It incorporates everything required for -// architecture-level functional simulation of a single thread. -// +class Process; +class System; class ExecContext { protected: typedef TheISA::RegFile RegFile; typedef TheISA::MachInst MachInst; + typedef TheISA::IntReg IntReg; typedef TheISA::MiscRegFile MiscRegFile; typedef TheISA::MiscReg MiscReg; public: @@ -87,7 +69,7 @@ class ExecContext Active, /// Temporarily inactive. Entered while waiting for - /// initialization,synchronization, etc. + /// synchronization, etc. Suspended, /// Permanently shut down. Entered when target executes @@ -96,402 +78,326 @@ class ExecContext Halted }; - private: - Status _status; + virtual ~ExecContext() { }; - public: - Status status() const { return _status; } + virtual BaseCPU *getCpuPtr() = 0; + + virtual void setCpuId(int id) = 0; + + virtual int readCpuId() = 0; + + virtual FunctionalMemory *getMemPtr() = 0; + +#if FULL_SYSTEM + virtual System *getSystemPtr() = 0; + + virtual PhysicalMemory *getPhysMemPtr() = 0; - void setStatus(Status newStatus) { _status = newStatus; } + virtual AlphaITB *getITBPtr() = 0; + + virtual AlphaDTB * getDTBPtr() = 0; +#else + virtual Process *getProcessPtr() = 0; +#endif + + virtual Status status() const = 0; /// Set the status to Active. Optional delay indicates number of /// cycles to wait before beginning execution. - void activate(int delay = 1); + virtual void activate(int delay = 1) = 0; /// Set the status to Suspended. - void suspend(); + virtual void suspend() = 0; /// Set the status to Unallocated. - void deallocate(); + virtual void deallocate() = 0; /// Set the status to Halted. - void halt(); + virtual void halt() = 0; - public: - RegFile regs; // correct-path register context +#if FULL_SYSTEM + virtual void dumpFuncProfile() = 0; +#endif - // pointer to CPU associated with this context - BaseCPU *cpu; + virtual void takeOverFrom(ExecContext *oldContext) = 0; - // Current instruction - MachInst inst; + virtual void regStats(const std::string &name) = 0; - // Index of hardware thread context on the CPU that this represents. - int thread_num; + virtual void serialize(std::ostream &os) = 0; + virtual void unserialize(Checkpoint *cp, const std::string §ion) = 0; - // ID of this context w.r.t. the System or Process object to which - // it belongs. For full-system mode, this is the system CPU ID. - int cpu_id; + virtual int getThreadNum() = 0; - Tick lastActivate; - Tick lastSuspend; + virtual bool validInstAddr(Addr addr) = 0; + virtual bool validDataAddr(Addr addr) = 0; + virtual int getInstAsid() = 0; + virtual int getDataAsid() = 0; -#if FULL_SYSTEM - FunctionalMemory *mem; - AlphaITB *itb; - AlphaDTB *dtb; - System *system; - - // the following two fields are redundant, since we can always - // look them up through the system pointer, but we'll leave them - // here for now for convenience - MemoryController *memctrl; - PhysicalMemory *physmem; - - Kernel::Binning *kernelBinning; - Kernel::Statistics *kernelStats; - bool bin; - bool fnbin; - - FunctionProfile *profile; - ProfileNode *profileNode; - Addr profilePC; - void dumpFuncProfile(); - - /** Event for timing out quiesce instruction */ - struct EndQuiesceEvent : public Event - { - /** A pointer to the execution context that is quiesced */ - ExecContext *xc; + virtual Fault translateInstReq(MemReqPtr &req) = 0; - EndQuiesceEvent(ExecContext *_xc); + virtual Fault translateDataReadReq(MemReqPtr &req) = 0; - /** Event process to occur at interrupt*/ - virtual void process(); + virtual Fault translateDataWriteReq(MemReqPtr &req) = 0; - /** Event description */ - virtual const char *description(); - }; - EndQuiesceEvent quiesceEvent; + virtual TheISA::MachInst getInst() = 0; -#else - Process *process; + virtual void copyArchRegs(ExecContext *xc) = 0; + + virtual void clearArchRegs() = 0; + + // + // New accessors for new decoder. + // + virtual uint64_t readIntReg(int reg_idx) = 0; + + virtual float readFloatRegSingle(int reg_idx) = 0; + + virtual double readFloatRegDouble(int reg_idx) = 0; - FunctionalMemory *mem; // functional storage for process address space + virtual uint64_t readFloatRegInt(int reg_idx) = 0; - // Address space ID. Note that this is used for TIMING cache - // simulation only; all functional memory accesses should use - // one of the FunctionalMemory pointers above. - short asid; + virtual void setIntReg(int reg_idx, uint64_t val) = 0; + virtual void setFloatRegSingle(int reg_idx, float val) = 0; + + virtual void setFloatRegDouble(int reg_idx, double val) = 0; + + virtual void setFloatRegInt(int reg_idx, uint64_t val) = 0; + + virtual uint64_t readPC() = 0; + + virtual void setPC(uint64_t val) = 0; + + virtual uint64_t readNextPC() = 0; + + virtual void setNextPC(uint64_t val) = 0; + + virtual MiscReg readMiscReg(int misc_reg) = 0; + + virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) = 0; + + virtual Fault setMiscReg(int misc_reg, const MiscReg &val) = 0; + + virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0; + + virtual unsigned readStCondFailures() = 0; + + virtual void setStCondFailures(unsigned sc_failures) = 0; + +#if FULL_SYSTEM + virtual int readIntrFlag() = 0; + virtual void setIntrFlag(int val) = 0; + virtual Fault hwrei() = 0; + virtual bool inPalMode() = 0; + virtual void ev5_trap(Fault fault) = 0; + virtual bool simPalCheck(int palFunc) = 0; #endif - /** - * Temporary storage to pass the source address from copy_load to - * copy_store. - * @todo Remove this temporary when we have a better way to do it. - */ - Addr copySrcAddr; - /** - * Temp storage for the physical source address of a copy. - * @todo Remove this temporary when we have a better way to do it. + virtual bool misspeculating() = 0; + + /** Meant to be more generic trap function to be + * called when an instruction faults. + * @param fault The fault generated by executing the instruction. + * @todo How to do this properly so it's dependent upon ISA only? */ - Addr copySrcPhysAddr; + virtual void trap(Fault fault) = 0; - /* - * number of executed instructions, for matching with syscall trace - * points in EIO files. - */ - Counter func_exe_inst; +#if !FULL_SYSTEM + virtual IntReg getSyscallArg(int i) = 0; - // - // Count failed store conditionals so we can warn of apparent - // application deadlock situations. - unsigned storeCondFailures; + // used to shift args for indirect syscall + virtual void setSyscallArg(int i, IntReg val) = 0; - // constructor: initialize context from given process structure -#if FULL_SYSTEM - ExecContext(BaseCPU *_cpu, int _thread_num, System *_system, - AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem); -#else - ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid); - ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, - int _asid); + virtual void setSyscallReturn(SyscallReturn return_value) = 0; + + virtual void syscall() = 0; + + virtual Counter readFuncExeInst() = 0; + + virtual void setFuncExeInst(Counter new_val) = 0; #endif - virtual ~ExecContext(); +}; - virtual void takeOverFrom(ExecContext *oldContext); +template <class XC> +class ProxyExecContext : public ExecContext +{ + public: + ProxyExecContext(XC *actual_xc) + { actualXC = actual_xc; } - void regStats(const std::string &name); + private: + XC *actualXC; - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + public: -#if FULL_SYSTEM - bool validInstAddr(Addr addr) { return true; } - bool validDataAddr(Addr addr) { return true; } - int getInstAsid() { return regs.instAsid(); } - int getDataAsid() { return regs.dataAsid(); } + BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); } - Fault translateInstReq(MemReqPtr &req) - { - return itb->translate(req); - } + void setCpuId(int id) { actualXC->setCpuId(id); } - Fault translateDataReadReq(MemReqPtr &req) - { - return dtb->translate(req, false); - } + int readCpuId() { return actualXC->readCpuId(); } - Fault translateDataWriteReq(MemReqPtr &req) - { - return dtb->translate(req, true); - } + FunctionalMemory *getMemPtr() { return actualXC->getMemPtr(); } -#else - bool validInstAddr(Addr addr) - { return process->validInstAddr(addr); } +#if FULL_SYSTEM + System *getSystemPtr() { return actualXC->getSystemPtr(); } - bool validDataAddr(Addr addr) - { return process->validDataAddr(addr); } + PhysicalMemory *getPhysMemPtr() { return actualXC->getPhysMemPtr(); } - int getInstAsid() { return asid; } - int getDataAsid() { return asid; } + AlphaITB *getITBPtr() { return actualXC->getITBPtr(); } - Fault dummyTranslation(MemReqPtr &req) - { -#if 0 - assert((req->vaddr >> 48 & 0xffff) == 0); + AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); } +#else + Process *getProcessPtr() { return actualXC->getProcessPtr(); } #endif - // put the asid in the upper 16 bits of the paddr - req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); - req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; - return NoFault; - } - Fault translateInstReq(MemReqPtr &req) - { - return dummyTranslation(req); - } - Fault translateDataReadReq(MemReqPtr &req) - { - return dummyTranslation(req); - } - Fault translateDataWriteReq(MemReqPtr &req) - { - return dummyTranslation(req); - } + Status status() const { return actualXC->status(); } -#endif + /// Set the status to Active. Optional delay indicates number of + /// cycles to wait before beginning execution. + void activate(int delay = 1) { actualXC->activate(delay); } - template <class T> - Fault read(MemReqPtr &req, T &data) - { -#if FULL_SYSTEM && defined(TARGET_ALPHA) - if (req->flags & LOCKED) { - MiscRegFile *cregs = &req->xc->regs.miscRegs; - cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr); - cregs->setReg(TheISA::Lock_Flag_DepTag, true); - } -#endif + /// Set the status to Suspended. + void suspend() { actualXC->suspend(); } - Fault error; - error = mem->read(req, data); - data = LittleEndianGuest::gtoh(data); - return error; - } + /// Set the status to Unallocated. + void deallocate() { actualXC->deallocate(); } - template <class T> - Fault write(MemReqPtr &req, T &data) - { -#if FULL_SYSTEM && defined(TARGET_ALPHA) - - MiscRegFile *cregs; - - // If this is a store conditional, act appropriately - if (req->flags & LOCKED) { - cregs = &req->xc->regs.miscRegs; - - if (req->flags & UNCACHEABLE) { - // Don't update result register (see stq_c in isa_desc) - req->result = 2; - req->xc->storeCondFailures = 0;//Needed? [RGD] - } else { - bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag); - Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag); - req->result = lock_flag; - if (!lock_flag || - ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { - cregs->setReg(TheISA::Lock_Flag_DepTag, false); - if (((++req->xc->storeCondFailures) % 100000) == 0) { - std::cerr << "Warning: " - << req->xc->storeCondFailures - << " consecutive store conditional failures " - << "on cpu " << req->xc->cpu_id - << std::endl; - } - return NoFault; - } - else req->xc->storeCondFailures = 0; - } - } - - // Need to clear any locked flags on other proccessors for - // this address. Only do this for succsful Store Conditionals - // and all other stores (WH64?). Unsuccessful Store - // Conditionals would have returned above, and wouldn't fall - // through. - for (int i = 0; i < system->execContexts.size(); i++){ - cregs = &system->execContexts[i]->regs.miscRegs; - if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) == - (req->paddr & ~0xf)) { - cregs->setReg(TheISA::Lock_Flag_DepTag, false); - } - } + /// Set the status to Halted. + void halt() { actualXC->halt(); } +#if FULL_SYSTEM + void dumpFuncProfile() { actualXC->dumpFuncProfile(); } #endif - return mem->write(req, (T)LittleEndianGuest::htog(data)); - } - virtual bool misspeculating(); + void takeOverFrom(ExecContext *oldContext) + { actualXC->takeOverFrom(oldContext); } + void regStats(const std::string &name) { actualXC->regStats(name); } - MachInst getInst() { return inst; } + void serialize(std::ostream &os) { actualXC->serialize(os); } + void unserialize(Checkpoint *cp, const std::string §ion) + { actualXC->unserialize(cp, section); } - void setInst(MachInst new_inst) - { - inst = new_inst; - } + int getThreadNum() { return actualXC->getThreadNum(); } - Fault instRead(MemReqPtr &req) - { - return mem->read(req, inst); - } + bool validInstAddr(Addr addr) { return actualXC->validInstAddr(addr); } + bool validDataAddr(Addr addr) { return actualXC->validDataAddr(addr); } + int getInstAsid() { return actualXC->getInstAsid(); } + int getDataAsid() { return actualXC->getDataAsid(); } + + Fault translateInstReq(MemReqPtr &req) + { return actualXC->translateInstReq(req); } + + Fault translateDataReadReq(MemReqPtr &req) + { return actualXC->translateDataReadReq(req); } + + Fault translateDataWriteReq(MemReqPtr &req) + { return actualXC->translateDataWriteReq(req); } + + // @todo: Do I need this? + MachInst getInst() { return actualXC->getInst(); } + + // @todo: Do I need this? + void copyArchRegs(ExecContext *xc) { actualXC->copyArchRegs(xc); } + + void clearArchRegs() { actualXC->clearArchRegs(); } // // New accessors for new decoder. // uint64_t readIntReg(int reg_idx) - { - return regs.intRegFile[reg_idx]; - } + { return actualXC->readIntReg(reg_idx); } float readFloatRegSingle(int reg_idx) - { - return (float)regs.floatRegFile.d[reg_idx]; - } + { return actualXC->readFloatRegSingle(reg_idx); } double readFloatRegDouble(int reg_idx) - { - return regs.floatRegFile.d[reg_idx]; - } + { return actualXC->readFloatRegDouble(reg_idx); } uint64_t readFloatRegInt(int reg_idx) - { - return regs.floatRegFile.q[reg_idx]; - } + { return actualXC->readFloatRegInt(reg_idx); } void setIntReg(int reg_idx, uint64_t val) - { - regs.intRegFile[reg_idx] = val; - } + { actualXC->setIntReg(reg_idx, val); } void setFloatRegSingle(int reg_idx, float val) - { - regs.floatRegFile.d[reg_idx] = (double)val; - } + { actualXC->setFloatRegSingle(reg_idx, val); } void setFloatRegDouble(int reg_idx, double val) - { - regs.floatRegFile.d[reg_idx] = val; - } + { actualXC->setFloatRegDouble(reg_idx, val); } void setFloatRegInt(int reg_idx, uint64_t val) - { - regs.floatRegFile.q[reg_idx] = val; - } + { actualXC->setFloatRegInt(reg_idx, val); } - uint64_t readPC() - { - return regs.pc; - } + uint64_t readPC() { return actualXC->readPC(); } - void setNextPC(uint64_t val) - { - regs.npc = val; - } + void setPC(uint64_t val) { actualXC->setPC(val); } + + uint64_t readNextPC() { return actualXC->readNextPC(); } + + void setNextPC(uint64_t val) { actualXC->setNextPC(val); } MiscReg readMiscReg(int misc_reg) - { - return regs.miscRegs.readReg(misc_reg); - } + { return actualXC->readMiscReg(misc_reg); } MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) - { - return regs.miscRegs.readRegWithEffect(misc_reg, fault, this); - } + { return actualXC->readMiscRegWithEffect(misc_reg, fault); } Fault setMiscReg(int misc_reg, const MiscReg &val) - { - return regs.miscRegs.setReg(misc_reg, val); - } + { return actualXC->setMiscReg(misc_reg, val); } Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) - { - return regs.miscRegs.setRegWithEffect(misc_reg, val, this); - } + { return actualXC->setMiscRegWithEffect(misc_reg, val); } + + unsigned readStCondFailures() + { return actualXC->readStCondFailures(); } + + void setStCondFailures(unsigned sc_failures) + { actualXC->setStCondFailures(sc_failures); } #if FULL_SYSTEM - int readIntrFlag() { return regs.intrflag; } - void setIntrFlag(int val) { regs.intrflag = val; } - Fault hwrei(); - bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } - bool simPalCheck(int palFunc); + int readIntrFlag() { return actualXC->readIntrFlag(); } + + void setIntrFlag(int val) { actualXC->setIntrFlag(val); } + + Fault hwrei() { return actualXC->hwrei(); } + + bool inPalMode() { return actualXC->inPalMode(); } + + void ev5_trap(Fault fault) { actualXC->ev5_trap(fault); } + + bool simPalCheck(int palFunc) { return actualXC->simPalCheck(palFunc); } #endif + // @todo: Fix this! + bool misspeculating() { return false; } + + /** Meant to be more generic trap function to be + * called when an instruction faults. + * @param fault The fault generated by executing the instruction. + * @todo How to do this properly so it's dependent upon ISA only? + */ + + void trap(Fault fault) { actualXC->trap(fault); } + #if !FULL_SYSTEM - TheISA::IntReg getSyscallArg(int i) - { - return regs.intRegFile[TheISA::ArgumentReg0 + i]; - } + IntReg getSyscallArg(int i) { return actualXC->getSyscallArg(i); } // used to shift args for indirect syscall - void setSyscallArg(int i, TheISA::IntReg val) - { - regs.intRegFile[TheISA::ArgumentReg0 + i] = val; - } + void setSyscallArg(int i, IntReg val) + { actualXC->setSyscallArg(i, val); } void setSyscallReturn(SyscallReturn return_value) - { - // check for error condition. Alpha syscall convention is to - // indicate success/failure in reg a3 (r19) and put the - // return value itself in the standard return value reg (v0). - const int RegA3 = 19; // only place this is used - if (return_value.successful()) { - // no error - regs.intRegFile[RegA3] = 0; - regs.intRegFile[TheISA::ReturnValueReg] = return_value.value(); - } else { - // got an error, return details - regs.intRegFile[RegA3] = (TheISA::IntReg) -1; - regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value(); - } - } - - void syscall() - { - process->syscall(this); - } -#endif -}; + { actualXC->setSyscallReturn(return_value); } + void syscall() { actualXC->syscall(); } -// for non-speculative execution context, spec_mode is always false -inline bool -ExecContext::misspeculating() -{ - return false; -} + Counter readFuncExeInst() { return actualXC->readFuncExeInst(); } -#endif // __CPU_EXEC_CONTEXT_HH__ + void setFuncExeInst(Counter new_val) + { return actualXC->setFuncExeInst(new_val); } +#endif +}; + +#endif diff --git a/cpu/exetrace.cc b/cpu/exetrace.cc index 8393a1b85..84b5eacf7 100644 --- a/cpu/exetrace.cc +++ b/cpu/exetrace.cc @@ -34,7 +34,6 @@ #include "encumbered/cpu/full/spec_state.hh" #include "encumbered/cpu/full/issue.hh" #include "cpu/exetrace.hh" -#include "cpu/exec_context.hh" #include "base/loader/symtab.hh" #include "cpu/base.hh" #include "cpu/static_inst.hh" diff --git a/cpu/intr_control.cc b/cpu/intr_control.cc index 5f17c7212..d1866a0c4 100644 --- a/cpu/intr_control.cc +++ b/cpu/intr_control.cc @@ -48,7 +48,7 @@ void IntrControl::post(int int_num, int index) { std::vector<ExecContext *> &xcvec = cpu->system->execContexts; - BaseCPU *temp = xcvec[0]->cpu; + BaseCPU *temp = xcvec[0]->getCpuPtr(); temp->post_interrupt(int_num, index); } @@ -56,7 +56,7 @@ void IntrControl::post(int cpu_id, int int_num, int index) { std::vector<ExecContext *> &xcvec = cpu->system->execContexts; - BaseCPU *temp = xcvec[cpu_id]->cpu; + BaseCPU *temp = xcvec[cpu_id]->getCpuPtr(); temp->post_interrupt(int_num, index); } @@ -64,7 +64,7 @@ void IntrControl::clear(int int_num, int index) { std::vector<ExecContext *> &xcvec = cpu->system->execContexts; - BaseCPU *temp = xcvec[0]->cpu; + BaseCPU *temp = xcvec[0]->getCpuPtr(); temp->clear_interrupt(int_num, index); } @@ -72,7 +72,7 @@ void IntrControl::clear(int cpu_id, int int_num, int index) { std::vector<ExecContext *> &xcvec = cpu->system->execContexts; - BaseCPU *temp = xcvec[cpu_id]->cpu; + BaseCPU *temp = xcvec[cpu_id]->getCpuPtr(); temp->clear_interrupt(int_num, index); } diff --git a/cpu/intr_control.hh b/cpu/intr_control.hh index 2a57a8dfc..5ec4e14cb 100644 --- a/cpu/intr_control.hh +++ b/cpu/intr_control.hh @@ -34,7 +34,6 @@ #include "cpu/base.hh" #include "sim/sim_object.hh" #include "sim/system.hh" -#include "cpu/exec_context.hh" class IntrControl : public SimObject diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc index 5a4024587..94b66b70b 100644 --- a/cpu/memtest/memtest.cc +++ b/cpu/memtest/memtest.cc @@ -36,7 +36,7 @@ #include "base/misc.hh" #include "base/statistics.hh" -#include "cpu/exec_context.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/memtest/memtest.hh" #include "mem/cache/base_cache.hh" #include "sim/builder.hh" @@ -79,7 +79,7 @@ MemTest::MemTest(const string &name, vector<string> cmd; cmd.push_back("/bin/ls"); vector<string> null_vec; - xc = new ExecContext(NULL, 0, mainMem, 0); + cpuXC = new CPUExecContext(NULL, 0, mainMem, 0); blockSize = cacheInterface->getBlockSize(); blockAddrMask = blockSize - 1; @@ -269,7 +269,7 @@ MemTest::tick() req->data = new uint8_t[req->size]; req->paddr &= ~(req->size - 1); req->time = curTick; - req->xc = xc; + req->xc = cpuXC->getProxy(); if (cmd < percentReads) { // read diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh index 7abcf017a..cdb40a26a 100644 --- a/cpu/memtest/memtest.hh +++ b/cpu/memtest/memtest.hh @@ -83,7 +83,7 @@ class MemTest : public SimObject MemInterface *cacheInterface; FunctionalMemory *mainMem; FunctionalMemory *checkMem; - ExecContext *xc; + CPUExecContext *cpuXC; unsigned size; // size of testing memory region diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index 38c00a3a9..531f6aa45 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -152,13 +152,13 @@ class AlphaFullCPU : public FullO3CPU<Impl> // set the register. IntReg getSyscallArg(int i) { - return this->xc->regs.intRegFile[AlphaISA::ArgumentReg0 + i]; + return this->cpuXC->readIntReg(AlphaISA::ArgumentReg0 + i); } // used to shift args for indirect syscall void setSyscallArg(int i, IntReg val) { - this->xc->regs.intRegFile[AlphaISA::ArgumentReg0 + i] = val; + this->cpuXC->setIntReg(AlphaISA::ArgumentReg0 + i, val); } void setSyscallReturn(int64_t return_value) @@ -169,12 +169,12 @@ class AlphaFullCPU : public FullO3CPU<Impl> const int RegA3 = 19; // only place this is used if (return_value >= 0) { // no error - this->xc->regs.intRegFile[RegA3] = 0; - this->xc->regs.intRegFile[AlphaISA::ReturnValueReg] = return_value; + this->cpuXC->setIntReg(RegA3, 0); + this->cpuXC->setIntReg(AlphaISA::ReturnValueReg, return_value); } else { // got an error, return details - this->xc->regs.intRegFile[RegA3] = (IntReg) -1; - this->xc->regs.intRegFile[AlphaISA::ReturnValueReg] = -return_value; + this->cpuXC->setIntReg(RegA3, (IntReg) -1); + this->cpuXC->setIntReg(AlphaISA::ReturnValueReg, -return_value); } } @@ -208,9 +208,8 @@ class AlphaFullCPU : public FullO3CPU<Impl> { #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { - MiscRegFile *cregs = &req->xc->regs.miscRegs; - cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr); - cregs->setReg(TheISA::Lock_Flag_DepTag, true); + req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr); + req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true); } #endif @@ -230,34 +229,34 @@ class AlphaFullCPU : public FullO3CPU<Impl> Fault write(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) - - MiscRegFile *cregs; + ExecContext *xc; // If this is a store conditional, act appropriately if (req->flags & LOCKED) { - cregs = &req->xc->regs.miscRegs; + xc = req->xc; if (req->flags & UNCACHEABLE) { // Don't update result register (see stq_c in isa_desc) req->result = 2; - req->xc->storeCondFailures = 0;//Needed? [RGD] + xc->setStCondFailures(0);//Needed? [RGD] } else { - bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag); - Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag); + bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag); + Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag); req->result = lock_flag; if (!lock_flag || ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { - cregs->setReg(TheISA::Lock_Flag_DepTag, false); - if (((++req->xc->storeCondFailures) % 100000) == 0) { + xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); + xc->setStCondFailures(xc->readStCondFailures() + 1); + if (((xc->readStCondFailures()) % 100000) == 0) { std::cerr << "Warning: " - << req->xc->storeCondFailures + << xc->readStCondFailures() << " consecutive store conditional failures " - << "on cpu " << req->xc->cpu_id + << "on cpu " << req->xc->readCpuId() << std::endl; } return NoFault; } - else req->xc->storeCondFailures = 0; + else xc->setStCondFailures(0); } } @@ -267,10 +266,10 @@ class AlphaFullCPU : public FullO3CPU<Impl> // Conditionals would have returned above, and wouldn't fall // through. for (int i = 0; i < this->system->execContexts.size(); i++){ - cregs = &this->system->execContexts[i]->regs.miscRegs; - if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) == + xc = this->system->execContexts[i]; + if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) == (req->paddr & ~0xf)) { - cregs->setReg(TheISA::Lock_Flag_DepTag, false); + xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); } } diff --git a/cpu/o3/alpha_cpu_builder.cc b/cpu/o3/alpha_cpu_builder.cc index 95d2f8f37..6025b8ef2 100644 --- a/cpu/o3/alpha_cpu_builder.cc +++ b/cpu/o3/alpha_cpu_builder.cc @@ -30,7 +30,6 @@ #include "base/loader/symtab.hh" #include "base/misc.hh" #include "cpu/base.hh" -#include "cpu/exec_context.hh" #include "cpu/exetrace.hh" #include "cpu/o3/alpha_cpu.hh" #include "cpu/o3/alpha_impl.hh" diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index a1c659b51..33e363d4f 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -165,7 +165,7 @@ AlphaFullCPU<Impl>::copyToXC() for (int i = 0; i < AlphaISA::NumIntRegs; ++i) { renamed_reg = this->renameMap.lookup(i); - this->xc->regs.intRegFile[i] = this->regFile.readIntReg(renamed_reg); + this->cpuXC->setIntReg(i, this->regFile.readIntReg(renamed_reg)); DPRINTF(FullCPU, "FullCPU: Copying register %i, has data %lli.\n", renamed_reg, this->regFile.intRegFile[renamed_reg]); } @@ -174,21 +174,23 @@ AlphaFullCPU<Impl>::copyToXC() for (int i = 0; i < AlphaISA::NumFloatRegs; ++i) { renamed_reg = this->renameMap.lookup(i + AlphaISA::FP_Base_DepTag); - this->xc->regs.floatRegFile.d[i] = - this->regFile.readFloatRegDouble(renamed_reg); - this->xc->regs.floatRegFile.q[i] = - this->regFile.readFloatRegInt(renamed_reg); + this->cpuXC->setFloatRegDouble(i, + this->regFile.readFloatRegDouble(renamed_reg)); + this->cpuXC->setFloatRegInt(i, + this->regFile.readFloatRegInt(renamed_reg)); } /* - this->xc->regs.miscRegs.fpcr = this->regFile.miscRegs.fpcr; - this->xc->regs.miscRegs.uniq = this->regFile.miscRegs.uniq; - this->xc->regs.miscRegs.lock_flag = this->regFile.miscRegs.lock_flag; - this->xc->regs.miscRegs.lock_addr = this->regFile.miscRegs.lock_addr; + this->cpuXC->regs.miscRegs.fpcr = this->regFile.miscRegs.fpcr; + this->cpuXC->regs.miscRegs.uniq = this->regFile.miscRegs.uniq; + this->cpuXC->regs.miscRegs.lock_flag = this->regFile.miscRegs.lock_flag; + this->cpuXC->regs.miscRegs.lock_addr = this->regFile.miscRegs.lock_addr; */ - this->xc->regs.pc = this->rob.readHeadPC(); - this->xc->regs.npc = this->xc->regs.pc+4; + this->cpuXC->setPC(this->rob.readHeadPC()); + this->cpuXC->setNextPC(this->cpuXC->readPC()+4); - this->xc->func_exe_inst = this->funcExeInst; +#if !FULL_SYSTEM + this->cpuXC->setFuncExeInst(this->funcExeInst); +#endif } // This function will probably mess things up unless the ROB is empty and @@ -207,9 +209,9 @@ AlphaFullCPU<Impl>::copyFromXC() DPRINTF(FullCPU, "FullCPU: Copying over register %i, had data %lli, " "now has data %lli.\n", renamed_reg, this->regFile.intRegFile[renamed_reg], - this->xc->regs.intRegFile[i]); + this->cpuXC->readIntReg(i)); - this->regFile.setIntReg(renamed_reg, this->xc->regs.intRegFile[i]); + this->regFile.setIntReg(renamed_reg, this->cpuXC->readIntReg(i)); } // Then loop through the floating point registers. @@ -217,22 +219,23 @@ AlphaFullCPU<Impl>::copyFromXC() { renamed_reg = this->renameMap.lookup(i + AlphaISA::FP_Base_DepTag); this->regFile.setFloatRegDouble(renamed_reg, - this->xc->regs.floatRegFile.d[i]); + this->cpuXC->readFloatRegDouble(i)); this->regFile.setFloatRegInt(renamed_reg, - this->xc->regs.floatRegFile.q[i]); + this->cpuXC->readFloatRegInt(i)); } /* // Then loop through the misc registers. - this->regFile.miscRegs.fpcr = this->xc->regs.miscRegs.fpcr; - this->regFile.miscRegs.uniq = this->xc->regs.miscRegs.uniq; - this->regFile.miscRegs.lock_flag = this->xc->regs.miscRegs.lock_flag; - this->regFile.miscRegs.lock_addr = this->xc->regs.miscRegs.lock_addr; + this->regFile.miscRegs.fpcr = this->cpuXC->regs.miscRegs.fpcr; + this->regFile.miscRegs.uniq = this->cpuXC->regs.miscRegs.uniq; + this->regFile.miscRegs.lock_flag = this->cpuXC->regs.miscRegs.lock_flag; + this->regFile.miscRegs.lock_addr = this->cpuXC->regs.miscRegs.lock_addr; */ // Then finally set the PC and the next PC. -// regFile.pc = xc->regs.pc; -// regFile.npc = xc->regs.npc; - - this->funcExeInst = this->xc->func_exe_inst; +// regFile.pc = cpuXC->regs.pc; +// regFile.npc = cpuXC->regs.npc; +#if !FULL_SYSTEM + this->funcExeInst = this->cpuXC->readFuncExeInst(); +#endif } #if FULL_SYSTEM diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc index a8c620028..62d68bb33 100644 --- a/cpu/o3/cpu.cc +++ b/cpu/o3/cpu.cc @@ -35,10 +35,11 @@ #endif #include "sim/root.hh" +#include "cpu/cpu_exec_context.hh" +#include "cpu/exec_context.hh" #include "cpu/o3/alpha_dyn_inst.hh" #include "cpu/o3/alpha_impl.hh" #include "cpu/o3/cpu.hh" -#include "cpu/exec_context.hh" using namespace std; @@ -103,7 +104,7 @@ FullO3CPU<Impl>::FullO3CPU(Params ¶ms) renameQueue(5, 5), iewQueue(5, 5), - xc(NULL), + cpuXC(NULL), globalSeqNum(1), @@ -134,8 +135,8 @@ FullO3CPU<Impl>::FullO3CPU(Params ¶ms) for (int i = 0; i < this->number_of_threads; ++i) { #if FULL_SYSTEM assert(i == 0); - system->execContexts[i] = - new ExecContext(this, i, system, itb, dtb, mem); + thread[i] = new CPUExecContext(this, 0, system, itb, dtb, mem); + system->execContexts[i] = thread[i]->getProxy(); execContexts.push_back(system->execContexts[i]); #else @@ -143,21 +144,17 @@ FullO3CPU<Impl>::FullO3CPU(Params ¶ms) DPRINTF(FullCPU, "FullCPU: Workload[%i]'s starting PC is %#x, " "process is %#x", i, params.workload[i]->prog_entry, thread[i]); - thread[i] = new ExecContext(this, i, params.workload[i], i); + thread[i] = new CPUExecContext(this, i, params.workload[i], i); } assert(params.workload[i]->getMemory() != NULL); assert(mem != NULL); - execContexts.push_back(thread[i]); + execContexts.push_back(thread[i]->getProxy()); #endif // !FULL_SYSTEM } // Note that this is a hack so that my code which still uses xc-> will // still work. I should remove this eventually -#if FULL_SYSTEM - xc = system->execContexts[0]; -#else - xc = thread[0]; -#endif + cpuXC = thread[0]; // The stages also need their CPU pointer setup. However this must be // done at the upper level CPU because they have pointers to the upper @@ -248,21 +245,21 @@ FullO3CPU<Impl>::init() // that it can start properly. #if FULL_SYSTEM ExecContext *src_xc = system->execContexts[0]; - TheISA::initCPU(&src_xc->regs, src_xc->cpu_id); + TheISA::initCPU(src_xc, src_xc->readCpuId()); #else - ExecContext *src_xc = thread[0]; + ExecContext *src_xc = thread[0]->getProxy(); #endif // First loop through the integer registers. for (int i = 0; i < TheISA::NumIntRegs; ++i) { - regFile.intRegFile[i] = src_xc->regs.intRegFile[i]; + regFile.intRegFile[i] = src_xc->readIntReg(i); } // Then loop through the floating point registers. for (int i = 0; i < TheISA::NumFloatRegs; ++i) { - regFile.floatRegFile[i].d = src_xc->regs.floatRegFile.d[i]; - regFile.floatRegFile[i].q = src_xc->regs.floatRegFile.q[i]; + regFile.floatRegFile[i].d = src_xc->readFloatRegDouble(i); + regFile.floatRegFile[i].q = src_xc->readFloatRegInt(i); } /* // Then loop through the misc registers. @@ -272,8 +269,8 @@ FullO3CPU<Impl>::init() regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr; */ // Then finally set the PC and the next PC. - regFile.pc = src_xc->regs.pc; - regFile.npc = src_xc->regs.npc; + regFile.pc = src_xc->readPC(); + regFile.npc = src_xc->readNextPC(); } } diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh index 02908887e..8f29a25fb 100644 --- a/cpu/o3/cpu.hh +++ b/cpu/o3/cpu.hh @@ -44,9 +44,9 @@ #include "base/timebuf.hh" #include "config/full_system.hh" #include "cpu/base.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/o3/comm.hh" #include "cpu/o3/cpu_policy.hh" -#include "cpu/exec_context.hh" #include "sim/process.hh" #if FULL_SYSTEM @@ -54,6 +54,7 @@ using namespace EV5; #endif +class ExecContext; class FunctionalMemory; class Process; @@ -164,8 +165,8 @@ class FullO3CPU : public BaseFullCPU bool validDataAddr(Addr addr) { return thread[0]->validDataAddr(addr); } - int getInstAsid() { return thread[0]->asid; } - int getDataAsid() { return thread[0]->asid; } + int getInstAsid() { return thread[0]->getInstAsid(); } + int getDataAsid() { return thread[0]->getDataAsid(); } #endif @@ -320,16 +321,17 @@ class FullO3CPU : public BaseFullCPU public: /** The temporary exec context to support older accessors. */ - ExecContext *xc; + CPUExecContext *cpuXC; /** Temporary function to get pointer to exec context. */ ExecContext *xcBase() { -#if FULL_SYSTEM - return system->execContexts[0]; -#else + return thread[0]->getProxy(); + } + + CPUExecContext *cpuXCBase() + { return thread[0]; -#endif } InstSeqNum globalSeqNum; @@ -344,9 +346,8 @@ class FullO3CPU : public BaseFullCPU AlphaDTB *dtb; // SWContext *swCtx; -#else - std::vector<ExecContext *> thread; #endif + std::vector<CPUExecContext *> thread; FunctionalMemory *mem; diff --git a/cpu/pc_event.cc b/cpu/pc_event.cc index 83fbc3e2d..050bf1a88 100644 --- a/cpu/pc_event.cc +++ b/cpu/pc_event.cc @@ -38,6 +38,7 @@ #include "cpu/pc_event.hh" #include "sim/debug.hh" #include "sim/root.hh" +#include "sim/system.hh" using namespace std; @@ -79,7 +80,7 @@ PCEventQueue::schedule(PCEvent *event) bool PCEventQueue::doService(ExecContext *xc) { - Addr pc = xc->regs.pc & ~0x3; + Addr pc = xc->readPC() & ~0x3; int serviced = 0; range_t range = equal_range(pc); for (iterator i = range.first; i != range.second; ++i) { @@ -87,7 +88,7 @@ PCEventQueue::doService(ExecContext *xc) // another event. This for example, prevents two invocations // of the SkipFuncEvent. Maybe we should have separate PC // event queues for each processor? - if (pc != (xc->regs.pc & ~0x3)) + if (pc != (xc->readPC() & ~0x3)) continue; DPRINTF(PCEvent, "PC based event serviced at %#x: %s\n", @@ -126,7 +127,7 @@ BreakPCEvent::BreakPCEvent(PCEventQueue *q, const std::string &desc, Addr addr, void BreakPCEvent::process(ExecContext *xc) { - StringWrap name(xc->cpu->name() + ".break_event"); + StringWrap name(xc->getCpuPtr()->name() + ".break_event"); DPRINTFN("break event %s triggered\n", descr()); debug_break(); if (remove) diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 51d679a63..38b43fef5 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -44,6 +44,7 @@ #include "base/stats/events.hh" #include "base/trace.hh" #include "cpu/base.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/exec_context.hh" #include "cpu/exetrace.hh" #include "cpu/profile.hh" @@ -94,7 +95,7 @@ SimpleCPU::init() ExecContext *xc = execContexts[i]; // initialize CPU, including PC - TheISA::initCPU(&xc->regs, xc->cpu_id); + TheISA::initCPU(xc, xc->readCpuId()); } #endif } @@ -132,22 +133,24 @@ SimpleCPU::CacheCompletionEvent::description() } SimpleCPU::SimpleCPU(Params *p) - : BaseCPU(p), tickEvent(this, p->width), xc(NULL), + : BaseCPU(p), tickEvent(this, p->width), cpuXC(NULL), cacheCompletionEvent(this) { _status = Idle; #if FULL_SYSTEM - xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem); + cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb, p->mem); #else - xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0); + cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process, + /* asid */ 0); #endif // !FULL_SYSTEM + xcProxy = cpuXC->getProxy(); icacheInterface = p->icache_interface; dcacheInterface = p->dcache_interface; memReq = new MemReq(); - memReq->xc = xc; + memReq->xc = xcProxy; memReq->asid = 0; memReq->data = new uint8_t[64]; @@ -158,7 +161,7 @@ SimpleCPU::SimpleCPU(Params *p) lastIcacheStall = 0; lastDcacheStall = 0; - execContexts.push_back(xc); + execContexts.push_back(xcProxy); } SimpleCPU::~SimpleCPU() @@ -207,7 +210,7 @@ void SimpleCPU::activateContext(int thread_num, int delay) { assert(thread_num == 0); - assert(xc); + assert(cpuXC); assert(_status == Idle); notIdleFraction++; @@ -220,7 +223,7 @@ void SimpleCPU::suspendContext(int thread_num) { assert(thread_num == 0); - assert(xc); + assert(cpuXC); assert(_status == Running); notIdleFraction--; @@ -301,7 +304,7 @@ SimpleCPU::serialize(ostream &os) SERIALIZE_ENUM(_status); SERIALIZE_SCALAR(inst); nameOut(os, csprintf("%s.xc", name())); - xc->serialize(os); + cpuXC->serialize(os); nameOut(os, csprintf("%s.tickEvent", name())); tickEvent.serialize(os); nameOut(os, csprintf("%s.cacheCompletionEvent", name())); @@ -314,7 +317,7 @@ SimpleCPU::unserialize(Checkpoint *cp, const string §ion) BaseCPU::unserialize(cp, section); UNSERIALIZE_ENUM(_status); UNSERIALIZE_SCALAR(inst); - xc->unserialize(cp, csprintf("%s.xc", section)); + cpuXC->unserialize(cp, csprintf("%s.xc", section)); tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); cacheCompletionEvent .unserialize(cp, csprintf("%s.cacheCompletionEvent", section)); @@ -345,16 +348,16 @@ SimpleCPU::copySrcTranslate(Addr src) memReq->reset(src & ~(blk_size - 1), blk_size); // translate to physical address - Fault fault = xc->translateDataReadReq(memReq); + Fault fault = cpuXC->translateDataReadReq(memReq); if (fault == NoFault) { - xc->copySrcAddr = src; - xc->copySrcPhysAddr = memReq->paddr + offset; + cpuXC->copySrcAddr = src; + cpuXC->copySrcPhysAddr = memReq->paddr + offset; } else { assert(!fault->isAlignmentFault()); - xc->copySrcAddr = 0; - xc->copySrcPhysAddr = 0; + cpuXC->copySrcAddr = 0; + cpuXC->copySrcPhysAddr = 0; } return fault; } @@ -367,7 +370,7 @@ SimpleCPU::copy(Addr dest) // Only support block sizes of 64 atm. assert(blk_size == 64); uint8_t data[blk_size]; - //assert(xc->copySrcAddr); + //assert(cpuXC->copySrcAddr); int offset = dest & (blk_size - 1); // Make sure block doesn't span page @@ -380,19 +383,19 @@ SimpleCPU::copy(Addr dest) memReq->reset(dest & ~(blk_size -1), blk_size); // translate to physical address - Fault fault = xc->translateDataWriteReq(memReq); + Fault fault = cpuXC->translateDataWriteReq(memReq); if (fault == NoFault) { Addr dest_addr = memReq->paddr + offset; // Need to read straight from memory since we have more than 8 bytes. - memReq->paddr = xc->copySrcPhysAddr; - xc->mem->read(memReq, data); + memReq->paddr = cpuXC->copySrcPhysAddr; + cpuXC->mem->read(memReq, data); memReq->paddr = dest_addr; - xc->mem->write(memReq, data); + cpuXC->mem->write(memReq, data); if (dcacheInterface) { memReq->cmd = Copy; memReq->completionEvent = NULL; - memReq->paddr = xc->copySrcPhysAddr; + memReq->paddr = cpuXC->copySrcPhysAddr; memReq->dest = dest_addr; memReq->size = 64; memReq->time = curTick; @@ -412,7 +415,7 @@ Fault SimpleCPU::read(Addr addr, T &data, unsigned flags) { if (status() == DcacheMissStall || status() == DcacheMissSwitch) { - Fault fault = xc->read(memReq,data); + Fault fault = cpuXC->read(memReq,data); if (traceData) { traceData->setAddr(addr); @@ -423,7 +426,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) memReq->reset(addr, sizeof(T), flags); // translate to physical address - Fault fault = xc->translateDataReadReq(memReq); + Fault fault = cpuXC->translateDataReadReq(memReq); // if we have a cache, do cache access too if (fault == NoFault && dcacheInterface) { @@ -443,12 +446,12 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) _status = DcacheMissStall; } else { // do functional access - fault = xc->read(memReq, data); + fault = cpuXC->read(memReq, data); } } else if(fault == NoFault) { // do functional access - fault = xc->read(memReq, data); + fault = cpuXC->read(memReq, data); } @@ -508,11 +511,11 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) memReq->reset(addr, sizeof(T), flags); // translate to physical address - Fault fault = xc->translateDataWriteReq(memReq); + Fault fault = cpuXC->translateDataWriteReq(memReq); // do functional access if (fault == NoFault) - fault = xc->write(memReq, data); + fault = cpuXC->write(memReq, data); if (fault == NoFault && dcacheInterface) { memReq->cmd = Write; @@ -589,7 +592,7 @@ SimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) Addr SimpleCPU::dbg_vtophys(Addr addr) { - return vtophys(xc, addr); + return vtophys(xcProxy, addr); } #endif // FULL_SYSTEM @@ -637,9 +640,9 @@ SimpleCPU::post_interrupt(int int_num, int index) { BaseCPU::post_interrupt(int_num, index); - if (xc->status() == ExecContext::Suspended) { + if (cpuXC->status() == ExecContext::Suspended) { DPRINTF(IPI,"Suspended Processor awoke\n"); - xc->activate(); + cpuXC->activate(); } } #endif // FULL_SYSTEM @@ -655,16 +658,16 @@ SimpleCPU::tick() Fault fault = NoFault; #if FULL_SYSTEM - if (checkInterrupts && check_interrupts() && !xc->inPalMode() && + if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode() && status() != IcacheMissComplete) { int ipl = 0; int summary = 0; checkInterrupts = false; - if (xc->readMiscReg(IPR_SIRR)) { + if (cpuXC->readMiscReg(IPR_SIRR)) { for (int i = INTLEVEL_SOFTWARE_MIN; i < INTLEVEL_SOFTWARE_MAX; i++) { - if (xc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { + if (cpuXC->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { // See table 4-19 of 21164 hardware reference ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); @@ -672,7 +675,7 @@ SimpleCPU::tick() } } - uint64_t interrupts = xc->cpu->intr_status(); + uint64_t interrupts = cpuXC->cpu->intr_status(); for (int i = INTLEVEL_EXTERNAL_MIN; i < INTLEVEL_EXTERNAL_MAX; i++) { if (interrupts & (ULL(1) << i)) { @@ -682,24 +685,25 @@ SimpleCPU::tick() } } - if (xc->readMiscReg(IPR_ASTRR)) + if (cpuXC->readMiscReg(IPR_ASTRR)) panic("asynchronous traps not implemented\n"); - if (ipl && ipl > xc->readMiscReg(IPR_IPLR)) { - xc->setMiscReg(IPR_ISR, summary); - xc->setMiscReg(IPR_INTID, ipl); - Fault(new InterruptFault)->invoke(xc); + if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) { + cpuXC->setMiscReg(IPR_ISR, summary); + cpuXC->setMiscReg(IPR_INTID, ipl); + + Fault(new InterruptFault)->invoke(xcProxy); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - xc->readMiscReg(IPR_IPLR), ipl, summary); + cpuXC->readMiscReg(IPR_IPLR), ipl, summary); } } #endif // maintain $r0 semantics - xc->regs.intRegFile[ZeroReg] = 0; + cpuXC->setIntReg(ZeroReg, 0); #ifdef TARGET_ALPHA - xc->regs.floatRegFile.d[ZeroReg] = 0.0; + cpuXC->setFloatRegDouble(ZeroReg, 0.0); #endif // TARGET_ALPHA if (status() == IcacheMissComplete) { @@ -721,13 +725,13 @@ SimpleCPU::tick() #endif memReq->cmd = Read; - memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t), - IFETCH_FLAGS(xc->regs.pc)); + memReq->reset(cpuXC->readPC() & ~3, sizeof(uint32_t), + IFETCH_FLAGS(cpuXC->readPC())); - fault = xc->translateInstReq(memReq); + fault = cpuXC->translateInstReq(memReq); if (fault == NoFault) - fault = xc->mem->read(memReq, inst); + fault = cpuXC->mem->read(memReq, inst); if (icacheInterface && fault == NoFault) { memReq->completionEvent = NULL; @@ -764,29 +768,30 @@ SimpleCPU::tick() inst = gtoh(inst); curStaticInst = StaticInst::decode(makeExtMI(inst, xc->readPC())); - traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst, - xc->regs.pc); + traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst, + cpuXC->readPC()); #if FULL_SYSTEM - xc->setInst(inst); + cpuXC->setInst(inst); #endif // FULL_SYSTEM - xc->func_exe_inst++; + cpuXC->func_exe_inst++; fault = curStaticInst->execute(this, traceData); #if FULL_SYSTEM - if (xc->fnbin) { - assert(xc->kernelStats); - system->kernelBinning->execute(xc, inst); + if (system->kernelBinning->fnbin) { + assert(kernelStats); + system->kernelBinning->execute(xcProxy, inst); } - if (xc->profile) { - bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; - xc->profilePC = usermode ? 1 : xc->regs.pc; - ProfileNode *node = xc->profile->consume(xc, inst); + if (cpuXC->profile) { + bool usermode = + (cpuXC->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + cpuXC->profilePC = usermode ? 1 : cpuXC->readPC(); + ProfileNode *node = cpuXC->profile->consume(xcProxy, inst); if (node) - xc->profileNode = node; + cpuXC->profileNode = node; } #endif @@ -806,29 +811,29 @@ SimpleCPU::tick() traceData->finalize(); } - traceFunctions(xc->regs.pc); + traceFunctions(cpuXC->readPC()); } // if (fault == NoFault) if (fault != NoFault) { #if FULL_SYSTEM - fault->invoke(xc); + fault->invoke(xcProxy); #else // !FULL_SYSTEM - fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc); + fatal("fault (%d) detected @ PC 0x%08p", fault, cpuXC->readPC()); #endif // FULL_SYSTEM } else { // go to the next instruction - xc->regs.pc = xc->regs.npc; - xc->regs.npc += sizeof(MachInst); + cpuXC->setPC(cpuXC->readNextPC()); + cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); } #if FULL_SYSTEM Addr oldpc; do { - oldpc = xc->regs.pc; - system->pcEventQueue.service(xc); - } while (oldpc != xc->regs.pc); + oldpc = cpuXC->readPC(); + system->pcEventQueue.service(xcProxy); + } while (oldpc != cpuXC->readPC()); #endif assert(status() == Running || diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index 0b8d84e53..4ab9a1c3e 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -32,7 +32,7 @@ #include "base/statistics.hh" #include "config/full_system.hh" #include "cpu/base.hh" -#include "cpu/exec_context.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/pc_event.hh" #include "cpu/sampler/sampler.hh" #include "cpu/static_inst.hh" @@ -54,6 +54,7 @@ class Process; #endif // FULL_SYSTEM +class ExecContext; class MemInterface; class Checkpoint; @@ -148,7 +149,9 @@ class SimpleCPU : public BaseCPU public: // execution context - ExecContext *xc; + CPUExecContext *cpuXC; + + ExecContext *xcProxy; void switchOut(Sampler *s); void takeOverFrom(BaseCPU *oldCPU); @@ -275,86 +278,86 @@ class SimpleCPU : public BaseCPU uint64_t readIntReg(const StaticInst *si, int idx) { - return xc->readIntReg(si->srcRegIdx(idx)); + return cpuXC->readIntReg(si->srcRegIdx(idx)); } float readFloatRegSingle(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return xc->readFloatRegSingle(reg_idx); + return cpuXC->readFloatRegSingle(reg_idx); } double readFloatRegDouble(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return xc->readFloatRegDouble(reg_idx); + return cpuXC->readFloatRegDouble(reg_idx); } uint64_t readFloatRegInt(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return xc->readFloatRegInt(reg_idx); + return cpuXC->readFloatRegInt(reg_idx); } void setIntReg(const StaticInst *si, int idx, uint64_t val) { - xc->setIntReg(si->destRegIdx(idx), val); + cpuXC->setIntReg(si->destRegIdx(idx), val); } void setFloatRegSingle(const StaticInst *si, int idx, float val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - xc->setFloatRegSingle(reg_idx, val); + cpuXC->setFloatRegSingle(reg_idx, val); } void setFloatRegDouble(const StaticInst *si, int idx, double val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - xc->setFloatRegDouble(reg_idx, val); + cpuXC->setFloatRegDouble(reg_idx, val); } void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - xc->setFloatRegInt(reg_idx, val); + cpuXC->setFloatRegInt(reg_idx, val); } - uint64_t readPC() { return xc->readPC(); } - void setNextPC(uint64_t val) { xc->setNextPC(val); } + uint64_t readPC() { return cpuXC->readPC(); } + void setNextPC(uint64_t val) { cpuXC->setNextPC(val); } MiscReg readMiscReg(int misc_reg) { - return xc->readMiscReg(misc_reg); + return cpuXC->readMiscReg(misc_reg); } MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) { - return xc->readMiscRegWithEffect(misc_reg, fault); + return cpuXC->readMiscRegWithEffect(misc_reg, fault); } Fault setMiscReg(int misc_reg, const MiscReg &val) { - return xc->setMiscReg(misc_reg, val); + return cpuXC->setMiscReg(misc_reg, val); } Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) { - return xc->setMiscRegWithEffect(misc_reg, val); + return cpuXC->setMiscRegWithEffect(misc_reg, val); } #if FULL_SYSTEM - Fault hwrei() { return xc->hwrei(); } - int readIntrFlag() { return xc->readIntrFlag(); } - void setIntrFlag(int val) { xc->setIntrFlag(val); } - bool inPalMode() { return xc->inPalMode(); } - void trap(Fault fault) { fault->invoke(xc); } - bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } + Fault hwrei() { return cpuXC->hwrei(); } + int readIntrFlag() { return cpuXC->readIntrFlag(); } + void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } + bool inPalMode() { return cpuXC->inPalMode(); } + void ev5_trap(Fault fault) { fault->invoke(xcProxy); } + bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } #else - void syscall() { xc->syscall(); } + void syscall() { cpuXC->syscall(); } #endif - bool misspeculating() { return xc->misspeculating(); } - ExecContext *xcBase() { return xc; } + bool misspeculating() { return cpuXC->misspeculating(); } + ExecContext *xcBase() { return xcProxy; } }; #endif // __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index 4dc4413a1..d311df4f5 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -113,7 +113,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data) case TSDEV_CC_MISC: *(uint64_t*)data = (ipint << 8) & 0xF | (itint << 4) & 0xF | - (xc->cpu_id & 0x3); + (xc->readCpuId() & 0x3); return NoFault; case TSDEV_CC_AAR0: case TSDEV_CC_AAR1: diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index 33485ca15..988b0f639 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -43,11 +43,11 @@ namespace Kernel { const char *modestr[] = { "kernel", "user", "idle", "interrupt" }; -Statistics::Statistics(ExecContext *context) - : xc(context), idleProcess((Addr)-1), themode(kernel), lastModeTick(0), +Statistics::Statistics(System *system) + : idleProcess((Addr)-1), themode(kernel), lastModeTick(0), iplLast(0), iplLastTick(0) { - bin_int = xc->system->params()->bin_int; + bin_int = system->params()->bin_int; } void @@ -193,16 +193,16 @@ Statistics::regStats(const string &_name) } void -Statistics::setIdleProcess(Addr idlepcbb) +Statistics::setIdleProcess(Addr idlepcbb, ExecContext *xc) { assert(themode == kernel || themode == interrupt); idleProcess = idlepcbb; themode = idle; - changeMode(themode); + changeMode(themode, xc); } void -Statistics::changeMode(cpu_mode newmode) +Statistics::changeMode(cpu_mode newmode, ExecContext *xc) { _mode[newmode]++; @@ -215,7 +215,7 @@ Statistics::changeMode(cpu_mode newmode) _modeGood[newmode]++; _modeTicks[themode] += curTick - lastModeTick; - xc->system->kernelBinning->changeMode(newmode); + xc->getSystemPtr()->kernelBinning->changeMode(newmode); lastModeTick = curTick; themode = newmode; @@ -238,7 +238,7 @@ Statistics::swpipl(int ipl) } void -Statistics::mode(cpu_mode newmode) +Statistics::mode(cpu_mode newmode, ExecContext *xc) { Addr pcbb = xc->readMiscReg(AlphaISA::IPR_PALtemp23); @@ -249,20 +249,20 @@ Statistics::mode(cpu_mode newmode) if (bin_int == false && newmode == interrupt) newmode = kernel; - changeMode(newmode); + changeMode(newmode, xc); } void -Statistics::context(Addr oldpcbb, Addr newpcbb) +Statistics::context(Addr oldpcbb, Addr newpcbb, ExecContext *xc) { assert(themode != user); _swap_context++; - changeMode(newpcbb == idleProcess ? idle : kernel); + changeMode(newpcbb == idleProcess ? idle : kernel, xc); } void -Statistics::callpal(int code) +Statistics::callpal(int code, ExecContext *xc) { if (!PAL::name(code)) return; @@ -271,7 +271,7 @@ Statistics::callpal(int code) switch (code) { case PAL::callsys: { - int number = xc->regs.intRegFile[0]; + int number = xc->readIntReg(0); if (SystemCalls<Tru64>::validSyscallNumber(number)) { int cvtnum = SystemCalls<Tru64>::convert(number); _syscall[cvtnum]++; @@ -279,8 +279,8 @@ Statistics::callpal(int code) } break; case PAL::swpctx: - if (xc->system->kernelBinning) - xc->system->kernelBinning->palSwapContext(xc); + if (xc->getSystemPtr()->kernelBinning) + xc->getSystemPtr()->kernelBinning->palSwapContext(xc); break; } } diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh index 4896a0705..c0a7fb858 100644 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@ -128,14 +128,13 @@ class Statistics : public Serializable private: std::string myname; - ExecContext *xc; Addr idleProcess; cpu_mode themode; Tick lastModeTick; bool bin_int; - void changeMode(cpu_mode newmode); + void changeMode(cpu_mode newmode, ExecContext *xc); private: Stats::Scalar<> _arm; @@ -165,7 +164,7 @@ class Statistics : public Serializable Tick iplLastTick; public: - Statistics(ExecContext *context); + Statistics(System *system); const std::string name() const { return myname; } void regStats(const std::string &name); @@ -182,11 +181,11 @@ class Statistics : public Serializable fault->stat()++; }// FIXME: When there are no generic system fault objects, this will go back to _faults[fault]++; } void swpipl(int ipl); - void mode(cpu_mode newmode); - void context(Addr oldpcbb, Addr newpcbb); - void callpal(int code); + void mode(cpu_mode newmode, ExecContext *xc); + void context(Addr oldpcbb, Addr newpcbb, ExecContext *xc); + void callpal(int code, ExecContext *xc); - void setIdleProcess(Addr idle); + void setIdleProcess(Addr idle, ExecContext *xc); public: virtual void serialize(std::ostream &os); diff --git a/kern/system_events.cc b/kern/system_events.cc index 91625e60a..9b9861497 100644 --- a/kern/system_events.cc +++ b/kern/system_events.cc @@ -34,17 +34,17 @@ using namespace TheISA; void SkipFuncEvent::process(ExecContext *xc) { - Addr newpc = xc->regs.intRegFile[ReturnAddressReg]; + Addr newpc = xc->readIntReg(ReturnAddressReg); DPRINTF(PCEvent, "skipping %s: pc=%x, newpc=%x\n", description, - xc->regs.pc, newpc); + xc->readPC(), newpc); - xc->regs.pc = newpc; - xc->regs.npc = xc->regs.pc + sizeof(MachInst); + xc->setPC(newpc); + xc->setNextPC(xc->readPC() + sizeof(TheISA::MachInst)); - BranchPred *bp = xc->cpu->getBranchPred(); + BranchPred *bp = xc->getCpuPtr()->getBranchPred(); if (bp != NULL) { - bp->popRAS(xc->thread_num); + bp->popRAS(xc->getThreadNum()); } } @@ -61,20 +61,21 @@ FnEvent::process(ExecContext *xc) if (xc->misspeculating()) return; - xc->system->kernelBinning->call(xc, mybin); + xc->getSystemPtr()->kernelBinning->call(xc, mybin); } void IdleStartEvent::process(ExecContext *xc) { - xc->kernelStats->setIdleProcess(xc->readMiscReg(AlphaISA::IPR_PALtemp23)); + xc->getCpuPtr()->kernelStats->setIdleProcess( + xc->readMiscReg(AlphaISA::IPR_PALtemp23), xc); remove(); } void InterruptStartEvent::process(ExecContext *xc) { - xc->kernelStats->mode(Kernel::interrupt); + xc->getCpuPtr()->kernelStats->mode(Kernel::interrupt, xc); } void @@ -82,5 +83,5 @@ InterruptEndEvent::process(ExecContext *xc) { // We go back to kernel, if we are user, inside the rti // pal code we will get switched to user because of the ICM write - xc->kernelStats->mode(Kernel::kernel); + xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc); } diff --git a/kern/tru64/dump_mbuf.cc b/kern/tru64/dump_mbuf.cc index 10137ceb0..25ed82ef3 100644 --- a/kern/tru64/dump_mbuf.cc +++ b/kern/tru64/dump_mbuf.cc @@ -61,7 +61,7 @@ DumpMbuf(AlphaArguments args) addr, m.m_data, m.m_len); char *buffer = new char[m.m_len]; CopyOut(xc, buffer, m.m_data, m.m_len); - Trace::dataDump(curTick, xc->system->name(), (uint8_t *)buffer, + Trace::dataDump(curTick, xc->getSystemPtr()->name(), (uint8_t *)buffer, m.m_len); delete [] buffer; diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh index 9c541ae1a..112f00f31 100644 --- a/kern/tru64/tru64.hh +++ b/kern/tru64/tru64.hh @@ -666,7 +666,7 @@ class Tru64 { // just pass basep through uninterpreted. TypedBufferArg<int64_t> basep(tgt_basep); - basep.copyIn(xc->mem); + basep.copyIn(xc->getMemPtr()); long host_basep = (off_t)htog((int64_t)*basep); int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep); @@ -693,7 +693,7 @@ class Tru64 { tgt_dp->d_reclen = tgt_bufsize; tgt_dp->d_namlen = namelen; strcpy(tgt_dp->d_name, host_dp->d_name); - tgt_dp.copyOut(xc->mem); + tgt_dp.copyOut(xc->getMemPtr()); tgt_buf_ptr += tgt_bufsize; host_buf_ptr += host_dp->d_reclen; @@ -702,7 +702,7 @@ class Tru64 { delete [] host_buf; *basep = htog((int64_t)host_basep); - basep.copyOut(xc->mem); + basep.copyOut(xc->getMemPtr()); return tgt_buf_ptr - tgt_buf; #endif @@ -714,20 +714,19 @@ class Tru64 { ExecContext *xc) { using TheISA::RegFile; - RegFile *regs = &xc->regs; TypedBufferArg<Tru64::sigcontext> sc(xc->getSyscallArg(0)); - sc.copyIn(xc->mem); + sc.copyIn(xc->getMemPtr()); // Restore state from sigcontext structure. // Note that we'll advance PC <- NPC before the end of the cycle, // so we need to restore the desired PC into NPC. // The current regs->pc will get clobbered. - regs->npc = htog(sc->sc_pc); + xc->setNextPC(htog(sc->sc_pc)); for (int i = 0; i < 31; ++i) { - regs->intRegFile[i] = htog(sc->sc_regs[i]); - regs->floatRegFile.q[i] = htog(sc->sc_fpregs[i]); + xc->setIntReg(i, htog(sc->sc_regs[i])); + xc->setFloatRegInt(i, htog(sc->sc_fpregs[i])); } xc->setMiscReg(TheISA::Fpcr_DepTag, htog(sc->sc_fpcr)); @@ -762,7 +761,7 @@ class Tru64 { elp->si_phz = htog(clk_hz); elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch? elp->si_max_procs = htog(process->numCpus()); - elp.copyOut(xc->mem); + elp.copyOut(xc->getMemPtr()); return 0; } @@ -783,7 +782,7 @@ class Tru64 { { TypedBufferArg<Tru64::vm_stack> argp(xc->getSyscallArg(0)); - argp.copyIn(xc->mem); + argp.copyIn(xc->getMemPtr()); // if the user chose an address, just let them have it. Otherwise // pick one for them. @@ -792,7 +791,7 @@ class Tru64 { int stack_size = (htog(argp->rsize) + htog(argp->ysize) + htog(argp->gsize)); process->next_thread_stack_base -= stack_size; - argp.copyOut(xc->mem); + argp.copyOut(xc->getMemPtr()); } return 0; @@ -812,7 +811,7 @@ class Tru64 { TypedBufferArg<Tru64::nxm_task_attr> attrp(xc->getSyscallArg(0)); TypedBufferArg<Addr> configptr_ptr(xc->getSyscallArg(1)); - attrp.copyIn(xc->mem); + attrp.copyIn(xc->getMemPtr()); if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) { cerr << "nxm_task_init: thread library version mismatch! " @@ -853,7 +852,7 @@ class Tru64 { config->nxm_slot_state = htog(slot_state_addr); config->nxm_rad[0] = htog(rad_state_addr); - config.copyOut(xc->mem); + config.copyOut(xc->getMemPtr()); // initialize the slot_state array and copy it out TypedBufferArg<Tru64::nxm_slot_state_t> slot_state(slot_state_addr, @@ -866,7 +865,7 @@ class Tru64 { (i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL; } - slot_state.copyOut(xc->mem); + slot_state.copyOut(xc->getMemPtr()); // same for the per-RAD "shared" struct. Note that we need to // allocate extra bytes for the per-VP array which is embedded at @@ -900,13 +899,13 @@ class Tru64 { } } - rad_state.copyOut(xc->mem); + rad_state.copyOut(xc->getMemPtr()); // // copy pointer to shared config area out to user // *configptr_ptr = htog(config_addr); - configptr_ptr.copyOut(xc->mem); + configptr_ptr.copyOut(xc->getMemPtr()); // Register this as a valid address range with the process process->nxm_start = base_addr; @@ -920,15 +919,15 @@ class Tru64 { init_exec_context(ExecContext *ec, Tru64::nxm_thread_attr *attrp, uint64_t uniq_val) { - memset(&ec->regs, 0, sizeof(ec->regs)); + ec->clearArchRegs(); - ec->regs.intRegFile[TheISA::ArgumentReg0] = gtoh(attrp->registers.a0); - ec->regs.intRegFile[27/*t12*/] = gtoh(attrp->registers.pc); - ec->regs.intRegFile[TheISA::StackPointerReg] = gtoh(attrp->registers.sp); + ec->setIntReg(TheISA::ArgumentReg0, gtoh(attrp->registers.a0)); + ec->setIntReg(27/*t12*/, gtoh(attrp->registers.pc)); + ec->setIntReg(TheISA::StackPointerReg, gtoh(attrp->registers.sp)); ec->setMiscReg(TheISA::Uniq_DepTag, uniq_val); - ec->regs.pc = gtoh(attrp->registers.pc); - ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst); + ec->setPC(gtoh(attrp->registers.pc)); + ec->setNextPC(gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst)); ec->activate(); } @@ -943,7 +942,7 @@ class Tru64 { int thread_index = xc->getSyscallArg(2); // get attribute args - attrp.copyIn(xc->mem); + attrp.copyIn(xc->getMemPtr()); if (gtoh(attrp->version) != NXM_LIB_VERSION) { cerr << "nxm_thread_create: thread library version mismatch! " @@ -968,7 +967,7 @@ class Tru64 { TypedBufferArg<Tru64::nxm_shared> rad_state(0x14000, rad_state_size); - rad_state.copyIn(xc->mem); + rad_state.copyIn(xc->getMemPtr()); uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset); @@ -979,7 +978,7 @@ class Tru64 { // This is supposed to be a port number. Make something up. *kidp = htog(99); - kidp.copyOut(xc->mem); + kidp.copyOut(xc->getMemPtr()); return 0; } else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) { @@ -993,7 +992,7 @@ class Tru64 { ssp->nxm_u.pth_id = attrp->pthid; ssp->nxm_u.nxm_active = htog(uniq_val | 1); - rad_state.copyOut(xc->mem); + rad_state.copyOut(xc->getMemPtr()); Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info); int slot_state_size = @@ -1003,7 +1002,7 @@ class Tru64 { slot_state(slot_state_addr, slot_state_size); - slot_state.copyIn(xc->mem); + slot_state.copyIn(xc->getMemPtr()); if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) { cerr << "nxm_thread_createFunc: requested VP slot " @@ -1015,7 +1014,7 @@ class Tru64 { // doesn't work anyway slot_state[thread_index] = Tru64::NXM_SLOT_BOUND; - slot_state.copyOut(xc->mem); + slot_state.copyOut(xc->getMemPtr()); // Find a free simulator execution context. for (int i = 0; i < process->numCpus(); ++i) { @@ -1029,7 +1028,7 @@ class Tru64 { // and get away with just sticking the thread index // here. *kidp = htog(thread_index); - kidp.copyOut(xc->mem); + kidp.copyOut(xc->getMemPtr()); return 0; } @@ -1066,8 +1065,8 @@ class Tru64 { uint64_t action = xc->getSyscallArg(3); uint64_t usecs = xc->getSyscallArg(4); - cout << xc->cpu->name() << ": nxm_thread_block " << tid << " " << secs - << " " << flags << " " << action << " " << usecs << endl; + cout << xc->getCpuPtr()->name() << ": nxm_thread_block " << tid << " " + << secs << " " << flags << " " << action << " " << usecs << endl; return 0; } @@ -1083,7 +1082,7 @@ class Tru64 { uint64_t usecs = xc->getSyscallArg(3); uint64_t flags = xc->getSyscallArg(4); - BaseCPU *cpu = xc->cpu; + BaseCPU *cpu = xc->getCpuPtr(); cout << cpu->name() << ": nxm_block " << hex << uaddr << dec << " " << val @@ -1100,7 +1099,7 @@ class Tru64 { { Addr uaddr = xc->getSyscallArg(0); - cout << xc->cpu->name() << ": nxm_unblock " + cout << xc->getCpuPtr()->name() << ": nxm_unblock " << hex << uaddr << dec << endl; return 0; @@ -1158,12 +1157,12 @@ class Tru64 { { TypedBufferArg<uint64_t> lockp(uaddr); - lockp.copyIn(xc->mem); + lockp.copyIn(xc->getMemPtr()); if (gtoh(*lockp) == 0) { // lock is free: grab it *lockp = htog(1); - lockp.copyOut(xc->mem); + lockp.copyOut(xc->getMemPtr()); } else { // lock is busy: disable until free process->waitList.push_back(Process::WaitRec(uaddr, xc)); @@ -1177,7 +1176,7 @@ class Tru64 { { TypedBufferArg<uint64_t> lockp(uaddr); - lockp.copyIn(xc->mem); + lockp.copyIn(xc->getMemPtr()); assert(*lockp != 0); // Check for a process waiting on the lock. @@ -1186,7 +1185,7 @@ class Tru64 { // clear lock field if no waiting context is taking over the lock if (num_waiting == 0) { *lockp = 0; - lockp.copyOut(xc->mem); + lockp.copyOut(xc->getMemPtr()); } } @@ -1213,12 +1212,12 @@ class Tru64 { Addr uaddr = xc->getSyscallArg(0); TypedBufferArg<uint64_t> lockp(uaddr); - lockp.copyIn(xc->mem); + lockp.copyIn(xc->getMemPtr()); if (gtoh(*lockp) == 0) { // lock is free: grab it *lockp = htog(1); - lockp.copyOut(xc->mem); + lockp.copyOut(xc->getMemPtr()); return 0; } else { return 1; @@ -1273,7 +1272,7 @@ class Tru64 { TypedBufferArg<uint64_t> lockp(lock_addr); // user is supposed to acquire lock before entering - lockp.copyIn(xc->mem); + lockp.copyIn(xc->getMemPtr()); assert(gtoh(*lockp) != 0); m5_unlock_mutex(lock_addr, process, xc); diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc index 1fd26b87b..12aae6950 100644 --- a/kern/tru64/tru64_events.cc +++ b/kern/tru64/tru64_events.cc @@ -47,13 +47,14 @@ BadAddrEvent::process(ExecContext *xc) // annotation for vmunix::badaddr in: // simos/simulation/apps/tcl/osf/tlaser.tcl - uint64_t a0 = xc->regs.intRegFile[ArgumentReg0]; + uint64_t a0 = xc->readIntReg(ArgumentReg0); if (!TheISA::IsK0Seg(a0) || - xc->memctrl->badaddr(TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) { + xc->getSystemPtr()->memctrl->badaddr( + TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) { DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0); - xc->regs.intRegFile[ReturnValueReg] = 0x1; + xc->setIntReg(ReturnValueReg, 0x1); SkipFuncEvent::process(xc); } else @@ -64,7 +65,7 @@ void PrintfEvent::process(ExecContext *xc) { if (DTRACE(Printf)) { - DebugOut() << curTick << ": " << xc->cpu->name() << ": "; + DebugOut() << curTick << ": " << xc->getCpuPtr()->name() << ": "; AlphaArguments args(xc); tru64::Printf(args); @@ -76,7 +77,7 @@ DebugPrintfEvent::process(ExecContext *xc) { if (DTRACE(DebugPrintf)) { if (!raw) - DebugOut() << curTick << ": " << xc->cpu->name() << ": "; + DebugOut() << curTick << ": " << xc->getCpuPtr()->name() << ": "; AlphaArguments args(xc); tru64::Printf(args); diff --git a/sim/process.cc b/sim/process.cc index fddd9a0b9..851192dcd 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -37,6 +37,7 @@ #include "base/loader/symtab.hh" #include "base/statistics.hh" #include "config/full_system.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/exec_context.hh" #include "cpu/smt.hh" #include "encumbered/cpu/full/thread.hh" @@ -78,6 +79,8 @@ Process::Process(const string &nm, init_regs = new RegFile; memset(init_regs, 0, sizeof(RegFile)); + cpuXC = new CPUExecContext(init_regs); + // initialize first 3 fds (stdin, stdout, stderr) fd_map[STDIN_FILENO] = stdin_fd; fd_map[STDOUT_FILENO] = stdout_fd; @@ -146,7 +149,7 @@ Process::registerExecContext(ExecContext *xc) if (myIndex == 0) { // copy process's initial regs struct - xc->regs = *init_regs; + xc->copyArchRegs(cpuXC->getProxy()); } // return CPU number to caller and increment available CPU count @@ -354,7 +357,7 @@ LiveProcess::syscall(ExecContext *xc) { num_syscalls++; - int64_t callnum = xc->regs.intRegFile[ReturnValueReg]; + int64_t callnum = xc->readIntReg(ReturnValueReg); SyscallDesc *desc = getDesc(callnum); if (desc == NULL) diff --git a/sim/process.hh b/sim/process.hh index 71b7d02b3..3a48f128c 100644 --- a/sim/process.hh +++ b/sim/process.hh @@ -46,6 +46,7 @@ #include "base/statistics.hh" #include "base/trace.hh" +class CPUExecContext; class ExecContext; class FunctionalMemory; class SyscallDesc; @@ -83,6 +84,7 @@ class Process : public SimObject std::list<WaitRec> waitList; RegFile *init_regs; // initial register contents + CPUExecContext *cpuXC; // XC to hold the init_regs Addr text_base; // text (code) segment base unsigned text_size; // text (code) size in bytes diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc index f4285be8a..85b26ef23 100644 --- a/sim/pseudo_inst.cc +++ b/sim/pseudo_inst.cc @@ -64,7 +64,7 @@ namespace AlphaPseudo void arm(ExecContext *xc) { - xc->kernelStats->arm(); + xc->getCpuPtr()->kernelStats->arm(); } void @@ -74,7 +74,7 @@ namespace AlphaPseudo return; xc->suspend(); - xc->kernelStats->quiesce(); + xc->getCpuPtr()->kernelStats->quiesce(); } void @@ -116,7 +116,7 @@ namespace AlphaPseudo void ivlb(ExecContext *xc) { - xc->kernelStats->ivlb(); + xc->getCpuPtr()->kernelStats->ivlb(); } void @@ -174,7 +174,7 @@ namespace AlphaPseudo DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); - xc->system->kernelSymtab->insert(addr,symbol); + xc->getSystemPtr()->kernelSymtab->insert(addr,symbol); } void @@ -207,7 +207,7 @@ namespace AlphaPseudo uint64_t readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset) { - const string &file = xc->cpu->system->params()->readfile; + const string &file = xc->getCpuPtr()->system->params()->readfile; if (file.empty()) { return ULL(0); } diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index d22dde3b8..2f6ed128d 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -47,12 +47,12 @@ void SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc) { DPRINTFR(SyscallVerbose, "%s: syscall %s called\n", - xc->cpu->name(), name); + xc->getCpuPtr()->name(), name); SyscallReturn retval = (*funcPtr)(this, callnum, process, xc); DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n", - xc->cpu->name(), name, retval.value()); + xc->getCpuPtr()->name(), name, retval.value()); if (!(flags & SyscallDesc::SuppressReturnValue)) xc->setSyscallReturn(retval); @@ -130,7 +130,7 @@ readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); if (bytes_read != -1) - bufArg.copyOut(xc->mem); + bufArg.copyOut(xc->getMemPtr()); return bytes_read; } @@ -142,7 +142,7 @@ writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) int nbytes = xc->getSyscallArg(2); BufferArg bufArg(xc->getSyscallArg(1), nbytes); - bufArg.copyIn(xc->mem); + bufArg.copyIn(xc->getMemPtr()); int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); @@ -183,7 +183,7 @@ gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) strncpy((char *)name.bufferPtr(), hostname, name_len); - name.copyOut(xc->mem); + name.copyOut(xc->getMemPtr()); return 0; } @@ -193,7 +193,7 @@ unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return (TheISA::IntReg)-EFAULT; int result = unlink(path.c_str()); @@ -205,12 +205,12 @@ renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string old_name; - if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(old_name, xc->getSyscallArg(0)) != NoFault) return -EFAULT; string new_name; - if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != NoFault) + if (xc->getMemPtr()->readString(new_name, xc->getSyscallArg(1)) != NoFault) return -EFAULT; int64_t result = rename(old_name.c_str(), new_name.c_str()); @@ -222,7 +222,7 @@ truncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; off_t length = xc->getSyscallArg(1); @@ -250,7 +250,7 @@ chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; /* XXX endianess */ diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index eca9f79e0..cadaa1cd3 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -321,7 +321,7 @@ openFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; if (path == "/dev/sysdev0") { @@ -368,7 +368,7 @@ chmodFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; uint32_t mode = xc->getSyscallArg(1); @@ -421,7 +421,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; struct stat hostBuf; @@ -430,7 +430,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -459,7 +459,7 @@ fstat64Func(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStat64Buf(xc->mem, fd, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStat64Buf(xc->getMemPtr(), fd, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -473,7 +473,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; struct stat hostBuf; @@ -482,7 +482,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -495,7 +495,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; #if BSD_HOST @@ -509,7 +509,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStat64Buf(xc->mem, -1, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStat64Buf(xc->getMemPtr(), -1, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -533,7 +533,7 @@ fstatFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -546,7 +546,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; struct statfs hostBuf; @@ -555,7 +555,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -578,7 +578,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -602,11 +602,11 @@ writevFunc(SyscallDesc *desc, int callnum, Process *process, for (int i = 0; i < count; ++i) { typename OS::tgt_iovec tiov; - xc->mem->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec), + xc->getMemPtr()->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec), &tiov, sizeof(typename OS::tgt_iovec)); hiov[i].iov_len = gtoh(tiov.iov_len); hiov[i].iov_base = new char [hiov[i].iov_len]; - xc->mem->access(Read, gtoh(tiov.iov_base), + xc->getMemPtr()->access(Read, gtoh(tiov.iov_base), hiov[i].iov_base, hiov[i].iov_len); } @@ -689,7 +689,7 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process, break; } - rlp.copyOut(xc->mem); + rlp.copyOut(xc->getMemPtr()); return 0; } @@ -706,7 +706,7 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, tp->tv_sec = htog(tp->tv_sec); tp->tv_usec = htog(tp->tv_usec); - tp.copyOut(xc->mem); + tp.copyOut(xc->getMemPtr()); return 0; } @@ -720,11 +720,11 @@ utimesFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; TypedBufferArg<typename OS::timeval [2]> tp(xc->getSyscallArg(1)); - tp.copyIn(xc->mem); + tp.copyIn(xc->getMemPtr()); struct timeval hostTimeval[2]; for (int i = 0; i < 2; ++i) @@ -776,7 +776,7 @@ getrusageFunc(SyscallDesc *desc, int callnum, Process *process, rup->ru_nvcsw = 0; rup->ru_nivcsw = 0; - rup.copyOut(xc->mem); + rup.copyOut(xc->getMemPtr()); return 0; } |