46a47,72
> 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
> };
>
53c79,80
< const FaultVect vect;
---
> const FaultVect offset;
> const ExcCode code;
56,60d82
< #if FULL_SYSTEM
< void invoke(ThreadContext * tc,
< StaticInst::StaticInstPtr inst = StaticInst::nullStaticInstPtr)
< {}
< #endif
61a84,103
>
> 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);
71c113,114
< FaultVect vect() const { return vals.vect; }
---
> FaultVect offset(ThreadContext *tc) const { return vals.offset; }
> ExcCode code() const { return vals.code; }
74,79c117,123
< template <typename T>
< class AddressFault : public MipsFault<T>
< {
< protected:
< Addr vaddr;
< bool store;
---
> 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> {};
81,114d124
< AddressFault(Addr _vaddr, bool _store) : vaddr(_vaddr), store(_store)
< {}
< };
<
< 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);
< }
< };
<
118c128
< bool isMachineCheckFault() {return true;}
---
> bool isMachineCheckFault() { return true; }
126,144d135
< 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
<
< };
<
153c144
< class SystemCallFault : public MipsFault<SystemCallFault>
---
> class SoftResetFault : public MipsFault<SoftResetFault>
156d146
< #if FULL_SYSTEM
159d148
< #endif
162c151
< class SoftResetFault : public MipsFault<SoftResetFault>
---
> class NonMaskableInterrupt : public MipsFault<NonMaskableInterrupt>
177,178c166,176
< 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);
> }
> }
181c179
< class ReservedInstructionFault : public MipsFault<ReservedInstructionFault>
---
> class InterruptFault : public MipsFault<InterruptFault>
184,185c182,187
< void invoke(ThreadContext * tc,
< StaticInstPtr inst = StaticInst::nullStaticInstPtr);
---
> FaultVect
> offset(ThreadContext *tc) const
> {
> CauseReg cause = tc->readMiscRegNoEffect(MISCREG_CAUSE);
> return cause.iv ? 0x200 : 0x000;
> }
188c190,191
< class ThreadFault : public MipsFault<ThreadFault>
---
> template <typename T>
> class AddressFault : public MipsFault<T>
190,193c193,195
< public:
< void invoke(ThreadContext * tc,
< StaticInstPtr inst = StaticInst::nullStaticInstPtr);
< };
---
> protected:
> Addr vaddr;
> bool store;
195,202c197,198
< 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)
> {}
204,210c200,207
< 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);
> }
213c210
< class TrapFault : public MipsFault<TrapFault>
---
> class AddressErrorFault : public AddressFault<AddressErrorFault>
216,219c213,222
< #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;
> }
>
222c225,226
< class BreakpointFault : public MipsFault<BreakpointFault>
---
> template <typename T>
> class TlbFault : public AddressFault<T>
224,228c228,270
< 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;
> }
237,240c279,285
< #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;
> }
249,252d293
< #if FULL_SYSTEM
< void invoke(ThreadContext * tc,
< StaticInstPtr inst = StaticInst::nullStaticInstPtr);
< #endif
261,265d301
< #if FULL_SYSTEM
< void invoke(ThreadContext * tc,
< StaticInstPtr inst = StaticInst::nullStaticInstPtr);
< #endif
< };
267,271c303
< class DspStateDisabledFault : public MipsFault<DspStateDisabledFault>
< {
< public:
< void invoke(ThreadContext * tc,
< StaticInstPtr inst = StaticInst::nullStaticInstPtr);
---
> ExcCode code() const { return vals.code; }