summaryrefslogtreecommitdiff
path: root/src/cpu/o3
diff options
context:
space:
mode:
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