Steps towards setting up the infrastructure to allow the new CPU model to work in...
authorKevin Lim <ktlim@umich.edu>
Sat, 4 Mar 2006 20:18:40 +0000 (15:18 -0500)
committerKevin Lim <ktlim@umich.edu>
Sat, 4 Mar 2006 20:18:40 +0000 (15:18 -0500)
The major change is renaming the old ExecContext to CPUExecContext, and creating two new classes, ExecContext (an abstract class), and ProxyExecContext (a templated class that derives from ExecContext).

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

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

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

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

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

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

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

    Avoid accessing objects directly within the XC.

--HG--
rename : cpu/exec_context.cc => cpu/cpu_exec_context.cc
rename : cpu/exec_context.hh => cpu/cpu_exec_context.hh
extra : convert_revision : a75393a8945c80cca225b5e9d9c22a16609efb85

47 files changed:
SConscript
arch/alpha/alpha_linux_process.cc
arch/alpha/alpha_memory.cc
arch/alpha/alpha_tru64_process.cc
arch/alpha/arguments.cc
arch/alpha/ev5.cc
arch/alpha/isa/decoder.isa
arch/alpha/isa_traits.hh
arch/alpha/stacktrace.cc
arch/alpha/vtophys.cc
base/remote_gdb.cc
cpu/base.cc
cpu/base.hh
cpu/base_dyn_inst.cc
cpu/base_dyn_inst.hh
cpu/cpu_exec_context.cc [new file with mode: 0644]
cpu/cpu_exec_context.hh [new file with mode: 0644]
cpu/exec_context.cc [deleted file]
cpu/exec_context.hh
cpu/exetrace.cc
cpu/intr_control.cc
cpu/intr_control.hh
cpu/memtest/memtest.cc
cpu/memtest/memtest.hh
cpu/o3/alpha_cpu.hh
cpu/o3/alpha_cpu_builder.cc
cpu/o3/alpha_cpu_impl.hh
cpu/o3/cpu.cc
cpu/o3/cpu.hh
cpu/pc_event.cc
cpu/simple/cpu.cc
cpu/simple/cpu.hh
dev/tsunami_cchip.cc
kern/freebsd/freebsd_system.cc
kern/kernel_stats.cc
kern/kernel_stats.hh
kern/linux/linux_system.cc
kern/linux/linux_threadinfo.hh
kern/system_events.cc
kern/tru64/dump_mbuf.cc
kern/tru64/tru64.hh
kern/tru64/tru64_events.cc
sim/process.cc
sim/process.hh
sim/pseudo_inst.cc
sim/syscall_emul.cc
sim/syscall_emul.hh

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