summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/mips/faults.cc219
-rw-r--r--src/arch/mips/faults.hh282
2 files changed, 207 insertions, 294 deletions
diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc
index 509e03036..9ec93f3fe 100644
--- a/src/arch/mips/faults.cc
+++ b/src/arch/mips/faults.cc
@@ -48,54 +48,56 @@ namespace MipsISA
typedef MipsFaultBase::FaultVals FaultVals;
-template <> FaultVals MipsFault<MachineCheckFault>::vals =
- { "Machine Check", 0x0401 };
-
-template <> FaultVals MipsFault<ResetFault>::vals =
-#if FULL_SYSTEM
- { "Reset Fault", 0xBFC00000};
-#else
- { "Reset Fault", 0x001};
-#endif
-
-template <> FaultVals MipsFault<AddressErrorFault>::vals =
- { "Address Error", 0x0180 };
-
template <> FaultVals MipsFault<SystemCallFault>::vals =
- { "Syscall", 0x0180 };
-
-template <> FaultVals MipsFault<CoprocessorUnusableFault>::vals =
- { "Coprocessor Unusable Fault", 0x180 };
+ { "Syscall", 0x180, ExcCodeSys };
template <> FaultVals MipsFault<ReservedInstructionFault>::vals =
- { "Reserved Instruction Fault", 0x0180 };
+ { "Reserved Instruction Fault", 0x180, ExcCodeRI };
template <> FaultVals MipsFault<ThreadFault>::vals =
- { "Thread Fault", 0x00F1 };
+ { "Thread Fault", 0x180, ExcCodeDummy };
template <> FaultVals MipsFault<IntegerOverflowFault>::vals =
- { "Integer Overflow Exception", 0x180 };
-
-template <> FaultVals MipsFault<InterruptFault>::vals =
- { "interrupt", 0x0180 };
+ { "Integer Overflow Exception", 0x180, ExcCodeOv };
template <> FaultVals MipsFault<TrapFault>::vals =
- { "Trap", 0x0180 };
+ { "Trap", 0x180, ExcCodeTr };
template <> FaultVals MipsFault<BreakpointFault>::vals =
- { "Breakpoint", 0x0180 };
+ { "Breakpoint", 0x180, ExcCodeBp };
+
+template <> FaultVals MipsFault<DspStateDisabledFault>::vals =
+ { "DSP Disabled Fault", 0x180, ExcCodeDummy };
+
+template <> FaultVals MipsFault<MachineCheckFault>::vals =
+ { "Machine Check", 0x180, ExcCodeMCheck };
+
+template <> FaultVals MipsFault<ResetFault>::vals =
+ { "Reset Fault", 0x000, ExcCodeDummy };
+
+template <> FaultVals MipsFault<SoftResetFault>::vals =
+ { "Soft Reset Fault", 0x000, ExcCodeDummy };
+
+template <> FaultVals MipsFault<NonMaskableInterrupt>::vals =
+ { "Non Maskable Interrupt", 0x000, ExcCodeDummy };
+
+template <> FaultVals MipsFault<CoprocessorUnusableFault>::vals =
+ { "Coprocessor Unusable Fault", 0x180, ExcCodeCpU };
+
+template <> FaultVals MipsFault<InterruptFault>::vals =
+ { "Interrupt", 0x000, ExcCodeInt };
+
+template <> FaultVals MipsFault<AddressErrorFault>::vals =
+ { "Address Error", 0x180, ExcCodeDummy };
template <> FaultVals MipsFault<TlbInvalidFault>::vals =
- { "Invalid TLB Entry Exception", 0x0180 };
+ { "Invalid TLB Entry Exception", 0x180, ExcCodeDummy };
template <> FaultVals MipsFault<TlbRefillFault>::vals =
- { "TLB Refill Exception", 0x0180 };
+ { "TLB Refill Exception", 0x180, ExcCodeDummy };
template <> FaultVals MipsFault<TlbModifiedFault>::vals =
- { "TLB Modified Exception", 0x0180 };
-
-template <> FaultVals MipsFault<DspStateDisabledFault>::vals =
- { "DSP Disabled Fault", 0x001a };
+ { "TLB Modified Exception", 0x180, ExcCodeMod };
void
MipsFaultBase::setExceptionState(ThreadContext *tc, uint8_t excCode)
@@ -129,118 +131,28 @@ MipsFaultBase::setExceptionState(ThreadContext *tc, uint8_t excCode)
tc->setMiscRegNoEffect(MISCREG_CAUSE, cause);
}
-#if FULL_SYSTEM
-
-void
-IntegerOverflowFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- setExceptionState(tc, 0xC);
-
- // Set new PC
- StatusReg status = tc->readMiscReg(MISCREG_STATUS);
- if (!status.bev) {
- // See MIPS ARM Vol 3, Revision 2, Page 38
- tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE));
- } else {
- tc->pcState(0xBFC00200);
- }
-}
-
-void
-TrapFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- setExceptionState(tc, 0xD);
-
- tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE));
-}
-
-void
-BreakpointFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
- setExceptionState(tc, 0x9);
-
- tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE));
-}
-
-void
-AddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- setExceptionState(tc, store ? 0x5 : 0x4);
- tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr);
-
- tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE));
-}
-
void
-TlbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst)
+MipsFaultBase::invoke(ThreadContext *tc, StaticInstPtr inst)
{
- setTlbExceptionState(tc, store ? 0x3 : 0x2);
- tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE));
-}
-
-void
-TlbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
- // Since handler depends on EXL bit, must check EXL bit before setting it!!
- StatusReg status = tc->readMiscReg(MISCREG_STATUS);
-
- setTlbExceptionState(tc, store ? 0x3 : 0x2);
-
- // See MIPS ARM Vol 3, Revision 2, Page 38
- if (status.exl == 1) {
- tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE));
+ if (FULL_SYSTEM) {
+ DPRINTF(MipsPRA, "Fault %s encountered.\n", name());
+ setExceptionState(tc, code());
+ tc->pcState(vect(tc));
} else {
- tc->pcState(tc->readMiscReg(MISCREG_EBASE));
+ panic("Fault %s encountered.\n", name());
}
}
void
-TlbModifiedFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
- setTlbExceptionState(tc, 0x1);
-
- tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE));
-}
-
-void
-SystemCallFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- setExceptionState(tc, 0x8);
-
- tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE));
-}
-
-void
-InterruptFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- setExceptionState(tc, 0x0A);
-
- CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
- if (cause.iv) {
- // Offset 200 for release 2
- tc->pcState(0x20 + vect() + tc->readMiscRegNoEffect(MISCREG_EBASE));
- } else {
- //Ofset at 180 for release 1
- tc->pcState(vect() + tc->readMiscRegNoEffect(MISCREG_EBASE));
- }
-}
-
-#endif // FULL_SYSTEM
-
-void
ResetFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
-#if FULL_SYSTEM
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- /* All reset activity must be invoked from here */
- tc->pcState(vect());
- DPRINTF(MipsPRA, "ResetFault::invoke : PC set to %x", tc->readPC());
-#endif
+ if (FULL_SYSTEM) {
+ DPRINTF(MipsPRA, "%s encountered.\n", name());
+ /* All reset activity must be invoked from here */
+ Addr handler = vect(tc);
+ tc->pcState(handler);
+ DPRINTF(MipsPRA, "ResetFault::invoke : PC set to %x", handler);
+ }
// Set Coprocessor 1 (Floating Point) To Usable
StatusReg status = tc->readMiscRegNoEffect(MISCREG_STATUS);
@@ -249,46 +161,15 @@ ResetFault::invoke(ThreadContext *tc, StaticInstPtr inst)
}
void
-ReservedInstructionFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
-#if FULL_SYSTEM
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- setExceptionState(tc, 0x0A);
- tc->pcState(vect() + tc->readMiscRegNoEffect(MISCREG_EBASE));
-#else
- panic("%s encountered.\n", name());
-#endif
-}
-
-void
-ThreadFault::invoke(ThreadContext *tc, StaticInstPtr inst)
+SoftResetFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- panic("%s encountered.\n", name());
+ panic("Soft reset not implemented.\n");
}
void
-DspStateDisabledFault::invoke(ThreadContext *tc, StaticInstPtr inst)
+NonMaskableInterrupt::invoke(ThreadContext *tc, StaticInstPtr inst)
{
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- panic("%s encountered.\n", name());
-}
-
-void
-CoprocessorUnusableFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
-#if FULL_SYSTEM
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- setExceptionState(tc, 0xb);
- // The ID of the coprocessor causing the exception is stored in
- // CoprocessorUnusableFault::coProcID
- CauseReg cause = tc->readMiscReg(MISCREG_CAUSE);
- cause.ce = coProcID;
- tc->setMiscRegNoEffect(MISCREG_CAUSE, cause);
- tc->pcState(vect() + tc->readMiscReg(MISCREG_EBASE));
-#else
- warn("%s (CP%d) encountered.\n", name(), coProcID);
-#endif
+ panic("Non maskable interrupt not implemented.\n");
}
} // namespace MipsISA
diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh
index afc9b400a..e78abbb43 100644
--- a/src/arch/mips/faults.hh
+++ b/src/arch/mips/faults.hh
@@ -44,21 +44,63 @@ namespace MipsISA
typedef const Addr FaultVect;
+enum ExcCode {
+ // A dummy value to use when the code isn't defined or doesn't matter.
+ ExcCodeDummy = 0,
+
+ ExcCodeInt = 0,
+ ExcCodeMod = 1,
+ ExcCodeTlbL = 2,
+ ExcCodeTlbS = 3,
+ ExcCodeAdEL = 4,
+ ExcCodeAdES = 5,
+ ExcCodeIBE = 6,
+ ExcCodeDBE = 7,
+ ExcCodeSys = 8,
+ ExcCodeBp = 9,
+ ExcCodeRI = 10,
+ ExcCodeCpU = 11,
+ ExcCodeOv = 12,
+ ExcCodeTr = 13,
+ ExcCodeC2E = 18,
+ ExcCodeMDMX = 22,
+ ExcCodeWatch = 23,
+ ExcCodeMCheck = 24,
+ ExcCodeThread = 25,
+ ExcCodeCacheErr = 30
+};
+
class MipsFaultBase : public FaultBase
{
public:
struct FaultVals
{
const FaultName name;
- const FaultVect vect;
+ const FaultVect offset;
+ const ExcCode code;
};
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc,
- StaticInst::StaticInstPtr inst = StaticInst::nullStaticInstPtr)
- {}
-#endif
void setExceptionState(ThreadContext *, uint8_t);
+
+ virtual FaultVect offset(ThreadContext *tc) const = 0;
+ virtual ExcCode code() const = 0;
+ virtual FaultVect base(ThreadContext *tc) const
+ {
+ StatusReg status = tc->readMiscReg(MISCREG_STATUS);
+ if (status.bev)
+ return tc->readMiscReg(MISCREG_EBASE);
+ else
+ return 0xbfc00200;
+ }
+
+ FaultVect
+ vect(ThreadContext *tc) const
+ {
+ return base(tc) + offset(tc);
+ }
+
+ void invoke(ThreadContext * tc,
+ StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
template <typename T>
@@ -68,54 +110,22 @@ class MipsFault : public MipsFaultBase
static FaultVals vals;
public:
FaultName name() const { return vals.name; }
- FaultVect vect() const { return vals.vect; }
-};
-
-template <typename T>
-class AddressFault : public MipsFault<T>
-{
- protected:
- Addr vaddr;
- bool store;
-
- AddressFault(Addr _vaddr, bool _store) : vaddr(_vaddr), store(_store)
- {}
+ FaultVect offset(ThreadContext *tc) const { return vals.offset; }
+ ExcCode code() const { return vals.code; }
};
-template <typename T>
-class TlbFault : public AddressFault<T>
-{
- protected:
- Addr asid;
- Addr vpn;
-
- TlbFault(Addr _asid, Addr _vaddr, Addr _vpn, bool _store) :
- AddressFault<T>(_vaddr, _store), asid(_asid), vpn(_vpn)
- {}
-
- void
- setTlbExceptionState(ThreadContext *tc, uint8_t excCode)
- {
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- this->setExceptionState(tc, excCode);
-
- tc->setMiscRegNoEffect(MISCREG_BADVADDR, this->vaddr);
- EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
- entryHi.asid = this->asid;
- entryHi.vpn2 = this->vpn >> 2;
- entryHi.vpn2x = this->vpn & 0x3;
- tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
-
- ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
- context.badVPN2 = this->vpn >> 2;
- tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
- }
-};
+class SystemCallFault : public MipsFault<SystemCallFault> {};
+class ReservedInstructionFault : public MipsFault<ReservedInstructionFault> {};
+class ThreadFault : public MipsFault<ThreadFault> {};
+class IntegerOverflowFault : public MipsFault<IntegerOverflowFault> {};
+class TrapFault : public MipsFault<TrapFault> {};
+class BreakpointFault : public MipsFault<BreakpointFault> {};
+class DspStateDisabledFault : public MipsFault<DspStateDisabledFault> {};
class MachineCheckFault : public MipsFault<MachineCheckFault>
{
public:
- bool isMachineCheckFault() {return true;}
+ bool isMachineCheckFault() { return true; }
};
static inline Fault genMachineCheckFault()
@@ -123,25 +133,6 @@ static inline Fault genMachineCheckFault()
return new MachineCheckFault;
}
-class NonMaskableInterrupt : public MipsFault<NonMaskableInterrupt>
-{
- public:
- bool isNonMaskableInterrupt() {return true;}
-};
-
-class AddressErrorFault : public AddressFault<AddressErrorFault>
-{
- public:
- AddressErrorFault(Addr _vaddr, bool _store) :
- AddressFault<AddressErrorFault>(_vaddr, _store)
- {}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-#endif
-
-};
-
class ResetFault : public MipsFault<ResetFault>
{
public:
@@ -150,16 +141,14 @@ class ResetFault : public MipsFault<ResetFault>
};
-class SystemCallFault : public MipsFault<SystemCallFault>
+class SoftResetFault : public MipsFault<SoftResetFault>
{
public:
-#if FULL_SYSTEM
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-#endif
};
-class SoftResetFault : public MipsFault<SoftResetFault>
+class NonMaskableInterrupt : public MipsFault<NonMaskableInterrupt>
{
public:
void invoke(ThreadContext * tc,
@@ -174,58 +163,111 @@ class CoprocessorUnusableFault : public MipsFault<CoprocessorUnusableFault>
CoprocessorUnusableFault(int _procid) : coProcID(_procid)
{}
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
+ void
+ invoke(ThreadContext * tc,
+ StaticInstPtr inst = StaticInst::nullStaticInstPtr)
+ {
+ MipsFault<CoprocessorUnusableFault>::invoke(tc, inst);
+ if (FULL_SYSTEM) {
+ CauseReg cause = tc->readMiscReg(MISCREG_CAUSE);
+ cause.ce = coProcID;
+ tc->setMiscReg(MISCREG_CAUSE, cause);
+ }
+ }
};
-class ReservedInstructionFault : public MipsFault<ReservedInstructionFault>
+class InterruptFault : public MipsFault<InterruptFault>
{
public:
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
+ FaultVect
+ offset(ThreadContext *tc) const
+ {
+ CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
+ return cause.iv ? 0x200 : 0x000;
+ }
};
-class ThreadFault : public MipsFault<ThreadFault>
+template <typename T>
+class AddressFault : public MipsFault<T>
{
- public:
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-};
+ protected:
+ Addr vaddr;
+ bool store;
-class IntegerOverflowFault : public MipsFault<IntegerOverflowFault>
-{
- public:
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-#endif
-};
+ AddressFault(Addr _vaddr, bool _store) : vaddr(_vaddr), store(_store)
+ {}
-class InterruptFault : public MipsFault<InterruptFault>
-{
- public:
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-#endif
+ void
+ invoke(ThreadContext * tc,
+ StaticInstPtr inst = StaticInst::nullStaticInstPtr)
+ {
+ MipsFault<T>::invoke(tc, inst);
+ if (FULL_SYSTEM)
+ tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr);
+ }
};
-class TrapFault : public MipsFault<TrapFault>
+class AddressErrorFault : public AddressFault<AddressErrorFault>
{
public:
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-#endif
+ AddressErrorFault(Addr _vaddr, bool _store) :
+ AddressFault<AddressErrorFault>(_vaddr, _store)
+ {}
+
+ ExcCode
+ code() const
+ {
+ return store ? ExcCodeAdES : ExcCodeAdEL;
+ }
+
};
-class BreakpointFault : public MipsFault<BreakpointFault>
+template <typename T>
+class TlbFault : public AddressFault<T>
{
- public:
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-#endif
+ protected:
+ Addr asid;
+ Addr vpn;
+
+ TlbFault(Addr _asid, Addr _vaddr, Addr _vpn, bool _store) :
+ AddressFault<T>(_vaddr, _store), asid(_asid), vpn(_vpn)
+ {}
+
+ void
+ setTlbExceptionState(ThreadContext *tc, uint8_t excCode)
+ {
+ this->setExceptionState(tc, excCode);
+
+ tc->setMiscRegNoEffect(MISCREG_BADVADDR, this->vaddr);
+ EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
+ entryHi.asid = this->asid;
+ entryHi.vpn2 = this->vpn >> 2;
+ entryHi.vpn2x = this->vpn & 0x3;
+ tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
+
+ ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
+ context.badVPN2 = this->vpn >> 2;
+ tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
+ }
+
+ void
+ invoke(ThreadContext * tc,
+ StaticInstPtr inst = StaticInst::nullStaticInstPtr)
+ {
+ if (FULL_SYSTEM) {
+ DPRINTF(MipsPRA, "Fault %s encountered.\n", name());
+ tc->pcState(this->vect(tc));
+ setTlbExceptionState(tc, this->code());
+ } else {
+ AddressFault<T>::invoke(tc, inst);
+ }
+ }
+
+ ExcCode
+ code() const
+ {
+ return this->store ? ExcCodeTlbS : ExcCodeTlbL;
+ }
};
class TlbRefillFault : public TlbFault<TlbRefillFault>
@@ -234,10 +276,13 @@ class TlbRefillFault : public TlbFault<TlbRefillFault>
TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool store) :
TlbFault<TlbRefillFault>(asid, vaddr, vpn, store)
{}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-#endif
+
+ FaultVect
+ offset(ThreadContext *tc) const
+ {
+ StatusReg status = tc->readMiscReg(MISCREG_STATUS);
+ return status.exl ? 0x180 : 0x000;
+ }
};
class TlbInvalidFault : public TlbFault<TlbInvalidFault>
@@ -246,10 +291,6 @@ class TlbInvalidFault : public TlbFault<TlbInvalidFault>
TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool store) :
TlbFault<TlbInvalidFault>(asid, vaddr, vpn, store)
{}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-#endif
};
class TlbModifiedFault : public TlbFault<TlbModifiedFault>
@@ -258,17 +299,8 @@ class TlbModifiedFault : public TlbFault<TlbModifiedFault>
TlbModifiedFault(Addr asid, Addr vaddr, Addr vpn) :
TlbFault<TlbModifiedFault>(asid, vaddr, vpn, false)
{}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-#endif
-};
-class DspStateDisabledFault : public MipsFault<DspStateDisabledFault>
-{
- public:
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
+ ExcCode code() const { return vals.code; }
};
} // namespace MipsISA