summaryrefslogtreecommitdiff
path: root/src/cpu/o3
diff options
context:
space:
mode:
authorAli Saidi <saidi@eecs.umich.edu>2008-10-20 16:22:59 -0400
committerAli Saidi <saidi@eecs.umich.edu>2008-10-20 16:22:59 -0400
commitb760b99f4d9f5469d88c67ae8a06e5f9543a43e7 (patch)
tree39cb41ec58be172c0f4b65162ae637be42bbabb0 /src/cpu/o3
parent4fac54f227f0ee0ee169955cb2510609434f7d85 (diff)
downloadgem5-b760b99f4d9f5469d88c67ae8a06e5f9543a43e7.tar.xz
O3CPU: Undo Gabe's changes to remove hwrei and simpalcheck from O3 CPU. Removing hwrei causes
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.
Diffstat (limited to 'src/cpu/o3')
-rw-r--r--src/cpu/o3/cpu.cc45
-rw-r--r--src/cpu/o3/cpu.hh5
-rw-r--r--src/cpu/o3/dyn_inst.hh3
-rw-r--r--src/cpu/o3/dyn_inst_impl.hh32
4 files changed, 85 insertions, 0 deletions
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index c110bbd50..41b7e8b14 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -53,6 +53,10 @@
#include "cpu/checker/cpu.hh"
#endif
+#if THE_ISA == ALPHA_ISA
+#include "arch/alpha/osfpal.hh"
+#endif
+
class BaseCPUParams;
using namespace TheISA;
@@ -903,6 +907,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()
{
// Check if there are any outstanding interrupts
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 07ba8d701..406d965be 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -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();
diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh
index 28dd60f5f..292547b6b 100644
--- a/src/cpu/o3/dyn_inst.hh
+++ b/src/cpu/o3/dyn_inst.hh
@@ -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);
diff --git a/src/cpu/o3/dyn_inst_impl.hh b/src/cpu/o3/dyn_inst_impl.hh
index 3b713ea8f..6398a3afe 100644
--- a/src/cpu/o3/dyn_inst_impl.hh
+++ b/src/cpu/o3/dyn_inst_impl.hh
@@ -125,11 +125,43 @@ 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