From 9a38dc6194b4c0ad85972b356a3d42e5ad1f55ee Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 19 Sep 2011 06:17:21 -0700 Subject: [PATCH] MIPS: Final overhaul of MIPS faults to kill #if FULL_SYSTEM This change is a significant reorganization of the MIPS fault code that gets rid of duplication, fixes some bugs, doubtlessly introduces others, and adds names for the exception code constants. --- src/arch/mips/faults.cc | 219 +++++++------------------------ src/arch/mips/faults.hh | 282 ++++++++++++++++++++++------------------ 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::vals = - { "Machine Check", 0x0401 }; - -template <> FaultVals MipsFault::vals = -#if FULL_SYSTEM - { "Reset Fault", 0xBFC00000}; -#else - { "Reset Fault", 0x001}; -#endif - -template <> FaultVals MipsFault::vals = - { "Address Error", 0x0180 }; - template <> FaultVals MipsFault::vals = - { "Syscall", 0x0180 }; - -template <> FaultVals MipsFault::vals = - { "Coprocessor Unusable Fault", 0x180 }; + { "Syscall", 0x180, ExcCodeSys }; template <> FaultVals MipsFault::vals = - { "Reserved Instruction Fault", 0x0180 }; + { "Reserved Instruction Fault", 0x180, ExcCodeRI }; template <> FaultVals MipsFault::vals = - { "Thread Fault", 0x00F1 }; + { "Thread Fault", 0x180, ExcCodeDummy }; template <> FaultVals MipsFault::vals = - { "Integer Overflow Exception", 0x180 }; - -template <> FaultVals MipsFault::vals = - { "interrupt", 0x0180 }; + { "Integer Overflow Exception", 0x180, ExcCodeOv }; template <> FaultVals MipsFault::vals = - { "Trap", 0x0180 }; + { "Trap", 0x180, ExcCodeTr }; template <> FaultVals MipsFault::vals = - { "Breakpoint", 0x0180 }; + { "Breakpoint", 0x180, ExcCodeBp }; + +template <> FaultVals MipsFault::vals = + { "DSP Disabled Fault", 0x180, ExcCodeDummy }; + +template <> FaultVals MipsFault::vals = + { "Machine Check", 0x180, ExcCodeMCheck }; + +template <> FaultVals MipsFault::vals = + { "Reset Fault", 0x000, ExcCodeDummy }; + +template <> FaultVals MipsFault::vals = + { "Soft Reset Fault", 0x000, ExcCodeDummy }; + +template <> FaultVals MipsFault::vals = + { "Non Maskable Interrupt", 0x000, ExcCodeDummy }; + +template <> FaultVals MipsFault::vals = + { "Coprocessor Unusable Fault", 0x180, ExcCodeCpU }; + +template <> FaultVals MipsFault::vals = + { "Interrupt", 0x000, ExcCodeInt }; + +template <> FaultVals MipsFault::vals = + { "Address Error", 0x180, ExcCodeDummy }; template <> FaultVals MipsFault::vals = - { "Invalid TLB Entry Exception", 0x0180 }; + { "Invalid TLB Entry Exception", 0x180, ExcCodeDummy }; template <> FaultVals MipsFault::vals = - { "TLB Refill Exception", 0x0180 }; + { "TLB Refill Exception", 0x180, ExcCodeDummy }; template <> FaultVals MipsFault::vals = - { "TLB Modified Exception", 0x0180 }; - -template <> FaultVals MipsFault::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 @@ -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 -class AddressFault : public MipsFault -{ - 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 -class TlbFault : public AddressFault -{ - protected: - Addr asid; - Addr vpn; - - TlbFault(Addr _asid, Addr _vaddr, Addr _vpn, bool _store) : - AddressFault(_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 {}; +class ReservedInstructionFault : public MipsFault {}; +class ThreadFault : public MipsFault {}; +class IntegerOverflowFault : public MipsFault {}; +class TrapFault : public MipsFault {}; +class BreakpointFault : public MipsFault {}; +class DspStateDisabledFault : public MipsFault {}; class MachineCheckFault : public MipsFault { 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 -{ - public: - bool isNonMaskableInterrupt() {return true;} -}; - -class AddressErrorFault : public AddressFault -{ - public: - AddressErrorFault(Addr _vaddr, bool _store) : - AddressFault(_vaddr, _store) - {} -#if FULL_SYSTEM - void invoke(ThreadContext * tc, - StaticInstPtr inst = StaticInst::nullStaticInstPtr); -#endif - -}; - class ResetFault : public MipsFault { public: @@ -150,16 +141,14 @@ class ResetFault : public MipsFault }; -class SystemCallFault : public MipsFault +class SoftResetFault : public MipsFault { public: -#if FULL_SYSTEM void invoke(ThreadContext * tc, StaticInstPtr inst = StaticInst::nullStaticInstPtr); -#endif }; -class SoftResetFault : public MipsFault +class NonMaskableInterrupt : public MipsFault { public: void invoke(ThreadContext * tc, @@ -174,58 +163,111 @@ class CoprocessorUnusableFault : public MipsFault CoprocessorUnusableFault(int _procid) : coProcID(_procid) {} - void invoke(ThreadContext * tc, - StaticInstPtr inst = StaticInst::nullStaticInstPtr); + void + invoke(ThreadContext * tc, + StaticInstPtr inst = StaticInst::nullStaticInstPtr) + { + MipsFault::invoke(tc, inst); + if (FULL_SYSTEM) { + CauseReg cause = tc->readMiscReg(MISCREG_CAUSE); + cause.ce = coProcID; + tc->setMiscReg(MISCREG_CAUSE, cause); + } + } }; -class ReservedInstructionFault : public MipsFault +class InterruptFault : public MipsFault { 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 +template +class AddressFault : public MipsFault { - public: - void invoke(ThreadContext * tc, - StaticInstPtr inst = StaticInst::nullStaticInstPtr); -}; + protected: + Addr vaddr; + bool store; -class IntegerOverflowFault : public MipsFault -{ - 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 -{ - public: -#if FULL_SYSTEM - void invoke(ThreadContext * tc, - StaticInstPtr inst = StaticInst::nullStaticInstPtr); -#endif + void + invoke(ThreadContext * tc, + StaticInstPtr inst = StaticInst::nullStaticInstPtr) + { + MipsFault::invoke(tc, inst); + if (FULL_SYSTEM) + tc->setMiscRegNoEffect(MISCREG_BADVADDR, vaddr); + } }; -class TrapFault : public MipsFault +class AddressErrorFault : public AddressFault { public: -#if FULL_SYSTEM - void invoke(ThreadContext * tc, - StaticInstPtr inst = StaticInst::nullStaticInstPtr); -#endif + AddressErrorFault(Addr _vaddr, bool _store) : + AddressFault(_vaddr, _store) + {} + + ExcCode + code() const + { + return store ? ExcCodeAdES : ExcCodeAdEL; + } + }; -class BreakpointFault : public MipsFault +template +class TlbFault : public AddressFault { - 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(_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::invoke(tc, inst); + } + } + + ExcCode + code() const + { + return this->store ? ExcCodeTlbS : ExcCodeTlbL; + } }; class TlbRefillFault : public TlbFault @@ -234,10 +276,13 @@ class TlbRefillFault : public TlbFault TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool store) : TlbFault(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 @@ -246,10 +291,6 @@ class TlbInvalidFault : public TlbFault TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool store) : TlbFault(asid, vaddr, vpn, store) {} -#if FULL_SYSTEM - void invoke(ThreadContext * tc, - StaticInstPtr inst = StaticInst::nullStaticInstPtr); -#endif }; class TlbModifiedFault : public TlbFault @@ -258,17 +299,8 @@ class TlbModifiedFault : public TlbFault TlbModifiedFault(Addr asid, Addr vaddr, Addr vpn) : TlbFault(asid, vaddr, vpn, false) {} -#if FULL_SYSTEM - void invoke(ThreadContext * tc, - StaticInstPtr inst = StaticInst::nullStaticInstPtr); -#endif -}; -class DspStateDisabledFault : public MipsFault -{ - public: - void invoke(ThreadContext * tc, - StaticInstPtr inst = StaticInst::nullStaticInstPtr); + ExcCode code() const { return vals.code; } }; } // namespace MipsISA -- 2.30.2