O3CPU: Undo Gabe's changes to remove hwrei and simpalcheck from O3 CPU. Removing...
authorAli Saidi <saidi@eecs.umich.edu>
Mon, 20 Oct 2008 20:22:59 +0000 (16:22 -0400)
committerAli Saidi <saidi@eecs.umich.edu>
Mon, 20 Oct 2008 20:22:59 +0000 (16:22 -0400)
the instruction after the hwrei to be fetched before the ITB/DTB_CM register is updated in a call pal
call sys and thus the translation fails because the user is attempting to access a super page address.

Minimally, it seems as though some sort of fetch stall or refetch after a hwrei is required. I think
this works currently because the hwrei uses the exec context interface, and the o3 stalls when that occurs.

Additionally, these changes don't update the LOCK register and probably break ll/sc. Both o3 changes were
removed since a great deal of manual patching would be required to only remove the hwrei change.

16 files changed:
src/arch/alpha/ev5.cc
src/arch/alpha/isa/decoder.isa
src/arch/alpha/isa/main.isa
src/arch/x86/bios/IntelMP.py
src/cpu/checker/cpu.hh
src/cpu/exec_context.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/dyn_inst.hh
src/cpu/o3/dyn_inst_impl.hh
src/cpu/ozone/cpu.hh
src/cpu/ozone/cpu_impl.hh
src/cpu/ozone/dyn_inst.hh
src/cpu/ozone/dyn_inst_impl.hh
src/cpu/simple/base.hh
src/cpu/simple_thread.hh

index c11b3632ef972ccde751be13d1bd52ed4d6c3ba2..7dc02a611e06c6bf8e87ef4b1bd803ca85a99f0c 100644 (file)
@@ -547,3 +547,53 @@ copyIprs(ThreadContext *src, ThreadContext *dest)
 }
 
 } // namespace AlphaISA
+
+#if FULL_SYSTEM
+
+using namespace AlphaISA;
+
+Fault
+SimpleThread::hwrei()
+{
+    if (!(readPC() & 0x3))
+        return new UnimplementedOpcodeFault;
+
+    setNextPC(readMiscRegNoEffect(IPR_EXC_ADDR));
+
+    if (!misspeculating()) {
+        if (kernelStats)
+            kernelStats->hwrei();
+    }
+
+    // FIXME: XXX check for interrupts? XXX
+    return NoFault;
+}
+
+/**
+ * Check for special simulator handling of specific PAL calls.
+ * If return value is false, actual PAL call will be suppressed.
+ */
+bool
+SimpleThread::simPalCheck(int palFunc)
+{
+    if (kernelStats)
+        kernelStats->callpal(palFunc, tc);
+
+    switch (palFunc) {
+      case PAL::halt:
+        halt();
+        if (--System::numSystemsRunning == 0)
+            exitSimLoop("all cpus halted");
+        break;
+
+      case PAL::bpt:
+      case PAL::bugchk:
+        if (system->breakpoint())
+            return false;
+        break;
+    }
+
+    return true;
+}
+
+#endif // FULL_SYSTEM
index 06676ae87103b3bff222fc824dd13692619f6383..270940df2e1c806c38ed7071fe647417ac0969d5 100644 (file)
@@ -698,28 +698,7 @@ decode OPCODE default Unknown::unknown() {
         else {
             // check to see if simulator wants to do something special
             // on this PAL call (including maybe suppress it)
-            
-            bool dopal = true;
-
-            ThreadContext * tc = xc->tcBase();
-            AlphaISA::Kernel::Statistics * kernelStats = tc->getKernelStats();
-            System * system = tc->getSystemPtr();
-            if (kernelStats)
-                kernelStats->callpal(palFunc, tc);
-
-            switch (palFunc) {
-              case PAL::halt:
-                tc->halt();
-                if (--System::numSystemsRunning == 0)
-                    exitSimLoop("all cpus halted");
-                break;
-
-              case PAL::bpt:
-              case PAL::bugchk:
-                if (system->breakpoint())
-                    dopal = false;
-                break;
-            }
+            bool dopal = xc->simPalCheck(palFunc);
 
             if (dopal) {
                 xc->setMiscReg(IPR_EXC_ADDR, NPC);
@@ -807,16 +786,7 @@ decode OPCODE default Unknown::unknown() {
     format BasicOperate {
         0x1e: decode PALMODE {
             0: OpcdecFault::hw_rei();
-            1: hw_rei({{
-                NPC = ExcAddr;
-                ThreadContext * tc = xc->tcBase();
-                if (!tc->misspeculating()) {
-                    AlphaISA::Kernel::Statistics * kernelStats =
-                        tc->getKernelStats();
-                    if (kernelStats)
-                        kernelStats->hwrei();
-                }
-            }}, IsSerializing, IsSerializeBefore);
+            1:hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore);
         }
 
         // M5 special opcodes use the reserved 0x01 opcode space
index 0f7f74359a93eb938e793d2c84a5313c2e8adb97..5231712c8eccd6e98bfdc09a70be6fabb26d3019 100644 (file)
@@ -69,8 +69,6 @@ output exec {{
 #include <math.h>
 
 #if FULL_SYSTEM
-#include "arch/alpha/kernel_stats.hh"
-#include "arch/alpha/osfpal.hh"
 #include "sim/pseudo_inst.hh"
 #endif
 #include "arch/alpha/ipr.hh"
@@ -189,7 +187,6 @@ def operands {{
     'Runiq': ('ControlReg', 'uq', 'MISCREG_UNIQ', None, 1),
     'FPCR':  ('ControlReg', 'uq', 'MISCREG_FPCR', None, 1),
     'IntrFlag': ('ControlReg', 'uq', 'MISCREG_INTR', None, 1),
-    'ExcAddr': ('ControlReg', 'uq', 'IPR_EXC_ADDR', None, 1),
     # The next two are hacks for non-full-system call-pal emulation
     'R0':  ('IntReg', 'uq', '0', None, 1),
     'R16': ('IntReg', 'uq', '16', None, 1),
index 7589321809f1c848352653fbc5a8f39543d5674b..70e7963fa07eaf1bf284e9e45e725f7fc3e2621b 100644 (file)
@@ -86,15 +86,6 @@ class X86IntelMPConfigTable(SimObject):
     ext_entries = VectorParam.X86IntelMPExtConfigEntry([],
             'extended configuration table entries')
 
-    def add_entry(self, entry):
-        if isinstance(entry, X86IntelMPBaseConfigEntry):
-            self.base_entries.append(entry)
-        elif isinstance(entry, X86IntelMPExtConfigEntry):
-            self.base_entries.append(entry)
-        else:
-            panic("Don't know what type of Intel MP entry %s is." \
-                    % entry.__class__.__name__)
-
 class X86IntelMPBaseConfigEntry(SimObject):
     type = 'X86IntelMPBaseConfigEntry'
     cxx_class = 'X86ISA::IntelMP::BaseConfigEntry'
index 0f01f17c57a690446644d6dd370f4900943e07cb..5b3c4582c9b0e4622b74b8c1d3447879a69dcbc3 100644 (file)
@@ -336,7 +336,9 @@ class CheckerCPU : public BaseCPU
     void translateDataReadReq(Request *req);
 
 #if FULL_SYSTEM
+    Fault hwrei() { return thread->hwrei(); }
     void ev5_trap(Fault fault) { fault->invoke(tc); }
+    bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
 #else
     // Assume that the normal CPU's call to syscall was successful.
     // The checker's state would have already been updated by the syscall.
index 836cf43528a4ac1919467f0b95a55079c02ac1e9..2b9fe4bcf11dbda86990f85be8c7b604041a8d59 100644 (file)
@@ -143,7 +143,17 @@ class ExecContext {
      * given flags. */
     void writeHint(Addr addr, int size, unsigned flags);
 
-#if !FULL_SYSTEM
+#if FULL_SYSTEM
+    /** Somewhat Alpha-specific function that handles returning from
+     * an error or interrupt. */
+    Fault hwrei();
+
+    /**
+     * Check for special simulator handling of specific PAL calls.  If
+     * return value is false, actual PAL call will be suppressed.
+     */
+    bool simPalCheck(int palFunc);
+#else
     /** Executes a syscall specified by the callnum. */
     void syscall(int64_t callnum);
 #endif
index c110bbd50b09d1953c78a03aeca373e051aaa283..41b7e8b14ff5c413ce4e63ed67a0af620a2130fb 100644 (file)
 #include "cpu/checker/cpu.hh"
 #endif
 
+#if THE_ISA == ALPHA_ISA
+#include "arch/alpha/osfpal.hh"
+#endif
+
 class BaseCPUParams;
 
 using namespace TheISA;
@@ -901,6 +905,47 @@ FullO3CPU<Impl>::post_interrupt(int int_num, int index)
     }
 }
 
+template <class Impl>
+Fault
+FullO3CPU<Impl>::hwrei(unsigned tid)
+{
+#if THE_ISA == ALPHA_ISA
+    // Need to clear the lock flag upon returning from an interrupt.
+    this->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG, false, tid);
+
+    this->thread[tid]->kernelStats->hwrei();
+
+    // FIXME: XXX check for interrupts? XXX
+#endif
+    return NoFault;
+}
+
+template <class Impl>
+bool
+FullO3CPU<Impl>::simPalCheck(int palFunc, unsigned tid)
+{
+#if THE_ISA == ALPHA_ISA
+    if (this->thread[tid]->kernelStats)
+        this->thread[tid]->kernelStats->callpal(palFunc,
+                                                this->threadContexts[tid]);
+
+    switch (palFunc) {
+      case PAL::halt:
+        halt();
+        if (--System::numSystemsRunning == 0)
+            exitSimLoop("all cpus halted");
+        break;
+
+      case PAL::bpt:
+      case PAL::bugchk:
+        if (this->system->breakpoint())
+            return false;
+        break;
+    }
+#endif
+    return true;
+}
+
 template <class Impl>
 Fault
 FullO3CPU<Impl>::getInterrupts()
index 07ba8d7018470308cddebb48f3100885ec4367da..406d965bec6d5d1f21bcaaa95a09eced2bd19783 100644 (file)
@@ -414,6 +414,11 @@ class FullO3CPU : public BaseO3CPU
     /** Posts an interrupt. */
     void post_interrupt(int int_num, int index);
 
+    /** HW return from error interrupt. */
+    Fault hwrei(unsigned tid);
+
+    bool simPalCheck(int palFunc, unsigned tid);
+
     /** Returns the Fault for any valid interrupt. */
     Fault getInterrupts();
 
index 28dd60f5faf5d35cfd6715e787fcca1055828bfb..292547b6b87690ec7f4eda572e6fcde980efbfa0 100644 (file)
@@ -168,8 +168,11 @@ class BaseO3DynInst : public BaseDynInst<Impl>
     }
 
 #if FULL_SYSTEM
+    /** Calls hardware return from error interrupt. */
+    Fault hwrei();
     /** Traps to handle specified fault. */
     void trap(Fault fault);
+    bool simPalCheck(int palFunc);
 #else
     /** Calls a syscall. */
     void syscall(int64_t callnum);
index 3b713ea8f51a76dbd8c41539eee1d1b1b8cc126b..6398a3afee8c9d9892c3bb860697b8a624ca6ab3 100644 (file)
@@ -124,12 +124,44 @@ BaseO3DynInst<Impl>::completeAcc(PacketPtr pkt)
 }
 
 #if FULL_SYSTEM
+template <class Impl>
+Fault
+BaseO3DynInst<Impl>::hwrei()
+{
+#if THE_ISA == ALPHA_ISA
+    // Can only do a hwrei when in pal mode.
+    if (!(this->readPC() & 0x3))
+        return new AlphaISA::UnimplementedOpcodeFault;
+
+    // Set the next PC based on the value of the EXC_ADDR IPR.
+    this->setNextPC(this->cpu->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
+                                           this->threadNumber));
+
+    // Tell CPU to clear any state it needs to if a hwrei is taken.
+    this->cpu->hwrei(this->threadNumber);
+#else
+
+#endif
+    // FIXME: XXX check for interrupts? XXX
+    return NoFault;
+}
+
 template <class Impl>
 void
 BaseO3DynInst<Impl>::trap(Fault fault)
 {
     this->cpu->trap(fault, this->threadNumber);
 }
+
+template <class Impl>
+bool
+BaseO3DynInst<Impl>::simPalCheck(int palFunc)
+{
+#if THE_ISA != ALPHA_ISA
+    panic("simPalCheck called, but PAL only exists in Alpha!\n");
+#endif
+    return this->cpu->simPalCheck(palFunc, this->threadNumber);
+}
 #else
 template <class Impl>
 void
index ee5e9e6683078092c0d0490554939ef9fc56dc7e..845cbbd95f8ef71659cabeac4be0ecdd05e69f01 100644 (file)
@@ -507,6 +507,8 @@ class OzoneCPU : public BaseCPU
     void dumpInsts() { frontEnd->dumpInsts(); }
 
 #if FULL_SYSTEM
+    Fault hwrei();
+    bool simPalCheck(int palFunc);
     void processInterrupts();
 #else
     void syscall(uint64_t &callnum);
index 94af07525eedc8b6b04e11f1f720038a0ab30229..c8e0dfe3d7bb54ba0a0030efa598fa153959eaab 100644 (file)
@@ -668,6 +668,21 @@ OzoneCPU<Impl>::setSyscallReturn(SyscallReturn return_value, int tid)
     }
 }
 #else
+template <class Impl>
+Fault
+OzoneCPU<Impl>::hwrei()
+{
+    // Need to move this to ISA code
+    // May also need to make this per thread
+
+    lockFlag = false;
+    lockAddrList.clear();
+    thread.kernelStats->hwrei();
+
+    // FIXME: XXX check for interrupts? XXX
+    return NoFault;
+}
+
 template <class Impl>
 void
 OzoneCPU<Impl>::processInterrupts()
@@ -685,6 +700,31 @@ OzoneCPU<Impl>::processInterrupts()
         interrupt->invoke(thread.getTC());
     }
 }
+
+template <class Impl>
+bool
+OzoneCPU<Impl>::simPalCheck(int palFunc)
+{
+    // Need to move this to ISA code
+    // May also need to make this per thread
+    thread.kernelStats->callpal(palFunc, tc);
+
+    switch (palFunc) {
+      case PAL::halt:
+        haltContext(thread.readTid());
+        if (--System::numSystemsRunning == 0)
+            exitSimLoop("all cpus halted");
+        break;
+
+      case PAL::bpt:
+      case PAL::bugchk:
+        if (system->breakpoint())
+            return false;
+        break;
+    }
+
+    return true;
+}
 #endif
 
 template <class Impl>
index 12a19e70df31f88a0ea3c5f111c5093f93ae5305..e138cbe13a5da5c2f838673a3a0fbd014531765b 100644 (file)
@@ -240,7 +240,9 @@ class OzoneDynInst : public BaseDynInst<Impl>
     void setMiscReg(int misc_reg, const MiscReg &val);
 
 #if FULL_SYSTEM
+    Fault hwrei();
     void trap(Fault fault);
+    bool simPalCheck(int palFunc);
 #else
     void syscall(uint64_t &callnum);
 #endif
index 39600768763bf53760f0f6c286f513a85ab845e0..8519917f5accb0a00a390f56ad628583ff4ead92 100644 (file)
@@ -248,12 +248,34 @@ OzoneDynInst<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
 
 #if FULL_SYSTEM
 
+template <class Impl>
+Fault
+OzoneDynInst<Impl>::hwrei()
+{
+    if (!(this->readPC() & 0x3))
+        return new AlphaISA::UnimplementedOpcodeFault;
+
+    this->setNextPC(this->thread->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR));
+
+    this->cpu->hwrei();
+
+    // FIXME: XXX check for interrupts? XXX
+    return NoFault;
+}
+
 template <class Impl>
 void
 OzoneDynInst<Impl>::trap(Fault fault)
 {
     fault->invoke(this->thread->getTC());
 }
+
+template <class Impl>
+bool
+OzoneDynInst<Impl>::simPalCheck(int palFunc)
+{
+    return this->cpu->simPalCheck(palFunc);
+}
 #else
 template <class Impl>
 void
index 03c20a6f27ecb438c4e5e9e4a2bf99bdd7ae846a..b7fcf1708df123c1ffbf1d6bb24581de6039f352 100644 (file)
@@ -413,7 +413,9 @@ class BaseSimpleCPU : public BaseCPU
     //Fault CacheOp(uint8_t Op, Addr EA);
 
 #if FULL_SYSTEM
+    Fault hwrei() { return thread->hwrei(); }
     void ev5_trap(Fault fault) { fault->invoke(tc); }
+    bool simPalCheck(int palFunc) { return thread->simPalCheck(palFunc); }
 #else
     void syscall(int64_t callnum) { thread->syscall(callnum); }
 #endif
index d26e984a3e4419edae840b1fcab5ead919688f0d..189cbeec5ea3f5be18280b9672cb087fe18cdebd 100644 (file)
@@ -185,6 +185,10 @@ class SimpleThread : public ThreadState
 
     void dumpFuncProfile();
 
+    Fault hwrei();
+
+    bool simPalCheck(int palFunc);
+
 #endif
 
     /*******************************************