summaryrefslogtreecommitdiff
path: root/src/arch/arm/faults.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:14 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:14 -0500
commit527b735cfc1e9031dc0a63ab43b1eb2ecf1fa4ec (patch)
tree61134ba71b8da4a6f288abcda2eb8517a1648891 /src/arch/arm/faults.cc
parent4491170df6e7a130c43d38d4220e5dff3c1dd214 (diff)
downloadgem5-527b735cfc1e9031dc0a63ab43b1eb2ecf1fa4ec.tar.xz
ARM: Implement and update the DFSR and IFSR registers on faults.
Diffstat (limited to 'src/arch/arm/faults.cc')
-rw-r--r--src/arch/arm/faults.cc36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index 528fc32a5..f1ecd31b9 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -50,29 +50,29 @@
namespace ArmISA
{
-template<> ArmFaultBase::FaultVals ArmFault<Reset>::vals =
+template<> ArmFault::FaultVals ArmFaultVals<Reset>::vals =
{"reset", 0x00, MODE_SVC, 0, 0, true, true};
-template<> ArmFaultBase::FaultVals ArmFault<UndefinedInstruction>::vals =
+template<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals =
{"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ;
-template<> ArmFaultBase::FaultVals ArmFault<SupervisorCall>::vals =
+template<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals =
{"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false};
-template<> ArmFaultBase::FaultVals ArmFault<PrefetchAbort>::vals =
+template<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals =
{"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false};
-template<> ArmFaultBase::FaultVals ArmFault<DataAbort>::vals =
+template<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals =
{"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false};
-template<> ArmFaultBase::FaultVals ArmFault<Interrupt>::vals =
+template<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals =
{"IRQ", 0x18, MODE_IRQ, 4, 4, true, false};
-template<> ArmFaultBase::FaultVals ArmFault<FastInterrupt>::vals =
+template<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals =
{"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true};
Addr
-ArmFaultBase::getVector(ThreadContext *tc)
+ArmFault::getVector(ThreadContext *tc)
{
// ARM ARM B1-3
@@ -91,7 +91,7 @@ ArmFaultBase::getVector(ThreadContext *tc)
#if FULL_SYSTEM
void
-ArmFaultBase::invoke(ThreadContext *tc)
+ArmFault::invoke(ThreadContext *tc)
{
// ARM ARM B1.6.3
FaultBase::invoke(tc);
@@ -185,6 +185,24 @@ SupervisorCall::invoke(ThreadContext *tc)
#endif // FULL_SYSTEM
+template<class T>
+void
+AbortFault<T>::invoke(ThreadContext *tc)
+{
+ ArmFaultVals<T>::invoke(tc);
+ FSR fsr = 0;
+ fsr.fsLow = bits(status, 3, 0);
+ fsr.fsHigh = bits(status, 4);
+ fsr.domain = domain;
+ fsr.wnr = (write ? 1 : 0);
+ fsr.ext = 0;
+ tc->setMiscReg(T::FsrIndex, fsr);
+ tc->setMiscReg(T::FarIndex, faultAddr);
+}
+
+template void AbortFault<PrefetchAbort>::invoke(ThreadContext *tc);
+template void AbortFault<DataAbort>::invoke(ThreadContext *tc);
+
// return via SUBS pc, lr, xxx; rfe, movs, ldm