MIPS: Use inheritance to consolidate class definitions.

This commit is contained in:
Gabe Black 2011-09-19 06:17:21 -07:00
parent 7d19ff170d
commit 5ea09771be
3 changed files with 78 additions and 98 deletions

View file

@ -91,7 +91,7 @@ template <> FaultVals MipsFault<TlbInvalidFault>::vals =
template <> FaultVals MipsFault<TlbRefillFault>::vals = template <> FaultVals MipsFault<TlbRefillFault>::vals =
{ "TLB Refill Exception", 0x0180 }; { "TLB Refill Exception", 0x0180 };
template <> FaultVals MipsFault<TLBModifiedFault>::vals = template <> FaultVals MipsFault<TlbModifiedFault>::vals =
{ "TLB Modified Exception", 0x0180 }; { "TLB Modified Exception", 0x0180 };
template <> FaultVals MipsFault<DspStateDisabledFault>::vals = template <> FaultVals MipsFault<DspStateDisabledFault>::vals =
@ -183,30 +183,6 @@ BreakpointFault::invoke(ThreadContext *tc, StaticInstPtr inst)
setHandlerPC(HandlerBase, tc); setHandlerPC(HandlerBase, tc);
} }
void
TlbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
DPRINTF(MipsPRA, "%s encountered.\n", name());
setExceptionState(tc, store ? 0x3 : 0x2);
tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
entryHi.asid = entryHiAsid;
entryHi.vpn2 = entryHiVPN2;
entryHi.vpn2x = entryHiVPN2X;
tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
context.badVPN2 = contextBadVPN2;
tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
// Set new PC
Addr HandlerBase;
// Offset 0x180 - General Exception Vector
HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
setHandlerPC(HandlerBase, tc);
}
void void
AddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst) AddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{ {
@ -221,25 +197,25 @@ AddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst)
setHandlerPC(HandlerBase, tc); setHandlerPC(HandlerBase, tc);
} }
void
TlbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
setTlbExceptionState(tc, store ? 0x3 : 0x2);
// Set new PC
Addr HandlerBase;
// Offset 0x180 - General Exception Vector
HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
setHandlerPC(HandlerBase, tc);
}
void void
TlbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst) TlbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{ {
DPRINTF(MipsPRA, "%s encountered (%x).\n", name(), MISCREG_BADVADDR);
setExceptionState(tc, store ? 0x3 : 0x2);
Addr HandlerBase;
tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
entryHi.asid = entryHiAsid;
entryHi.vpn2 = entryHiVPN2;
entryHi.vpn2x = entryHiVPN2X;
tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
context.badVPN2 = contextBadVPN2;
tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
StatusReg status = tc->readMiscReg(MISCREG_STATUS);
// Since handler depends on EXL bit, must check EXL bit before setting it!! // 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 // See MIPS ARM Vol 3, Revision 2, Page 38
if (status.exl == 1) { if (status.exl == 1) {
// Offset 0x180 - General Exception Vector // Offset 0x180 - General Exception Vector
@ -252,27 +228,15 @@ TlbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
} }
void void
TLBModifiedFault::invoke(ThreadContext *tc, StaticInstPtr inst) TlbModifiedFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{ {
DPRINTF(MipsPRA, "%s encountered.\n", name()); setTlbExceptionState(tc, 0x1);
tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
entryHi.asid = entryHiAsid;
entryHi.vpn2 = entryHiVPN2;
entryHi.vpn2x = entryHiVPN2X;
tc->setMiscRegNoEffect(MISCREG_ENTRYHI, entryHi);
ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
context.badVPN2 = contextBadVPN2;
tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
// Set new PC // Set new PC
Addr HandlerBase; Addr HandlerBase;
// Offset 0x180 - General Exception Vector // Offset 0x180 - General Exception Vector
HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE); HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
setExceptionState(tc, 0x1);
setHandlerPC(HandlerBase, tc); setHandlerPC(HandlerBase, tc);
} }
void void

View file

@ -34,6 +34,9 @@
#ifndef __MIPS_FAULTS_HH__ #ifndef __MIPS_FAULTS_HH__
#define __MIPS_FAULTS_HH__ #define __MIPS_FAULTS_HH__
#include "arch/mips/pra_constants.hh"
#include "cpu/thread_context.hh"
#include "debug/MipsPRA.hh"
#include "sim/faults.hh" #include "sim/faults.hh"
namespace MipsISA namespace MipsISA
@ -53,11 +56,6 @@ class MipsFaultBase : public FaultBase
const FaultVect vect; const FaultVect vect;
}; };
Addr badVAddr;
Addr entryHiAsid;
Addr entryHiVPN2;
Addr entryHiVPN2X;
Addr contextBadVPN2;
#if FULL_SYSTEM #if FULL_SYSTEM
void invoke(ThreadContext * tc, void invoke(ThreadContext * tc,
StaticInst::StaticInstPtr inst = StaticInst::nullStaticInstPtr) StaticInst::StaticInstPtr inst = StaticInst::nullStaticInstPtr)
@ -77,6 +75,47 @@ class MipsFault : public MipsFaultBase
FaultVect vect() const { return vals.vect; } 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)
{}
};
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 MachineCheckFault : public MipsFault<MachineCheckFault> class MachineCheckFault : public MipsFault<MachineCheckFault>
{ {
public: public:
@ -94,13 +133,11 @@ class NonMaskableInterrupt : public MipsFault<NonMaskableInterrupt>
bool isNonMaskableInterrupt() {return true;} bool isNonMaskableInterrupt() {return true;}
}; };
class AddressErrorFault : public MipsFault<AddressErrorFault> class AddressErrorFault : public AddressFault<AddressErrorFault>
{ {
protected:
Addr vaddr;
bool store;
public: public:
AddressErrorFault(Addr _vaddr, bool _store) : vaddr(_vaddr), store(_store) AddressErrorFault(Addr _vaddr, bool _store) :
AddressFault<AddressErrorFault>(_vaddr, _store)
{} {}
#if FULL_SYSTEM #if FULL_SYSTEM
void invoke(ThreadContext * tc, void invoke(ThreadContext * tc,
@ -199,57 +236,36 @@ class BreakpointFault : public MipsFault<BreakpointFault>
#endif #endif
}; };
class TlbRefillFault : public MipsFault<TlbRefillFault> class TlbRefillFault : public TlbFault<TlbRefillFault>
{ {
protected:
bool store;
public: public:
TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool _store) : TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool store) :
store(_store) TlbFault<TlbRefillFault>(asid, vaddr, vpn, store)
{ {}
entryHiAsid = asid;
entryHiVPN2 = vpn >> 2;
entryHiVPN2X = vpn & 0x3;
badVAddr = vaddr;
contextBadVPN2 = vpn >> 2;
}
#if FULL_SYSTEM #if FULL_SYSTEM
void invoke(ThreadContext * tc, void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr); StaticInstPtr inst = StaticInst::nullStaticInstPtr);
#endif #endif
}; };
class TlbInvalidFault : public MipsFault<TlbInvalidFault> class TlbInvalidFault : public TlbFault<TlbInvalidFault>
{ {
protected:
bool store;
public: public:
TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool _store) : TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool store) :
store(_store) TlbFault<TlbInvalidFault>(asid, vaddr, vpn, store)
{ {}
entryHiAsid = asid;
entryHiVPN2 = vpn >> 2;
entryHiVPN2X = vpn & 0x3;
badVAddr = vaddr;
contextBadVPN2 = vpn >> 2;
}
#if FULL_SYSTEM #if FULL_SYSTEM
void invoke(ThreadContext * tc, void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr); StaticInstPtr inst = StaticInst::nullStaticInstPtr);
#endif #endif
}; };
class TLBModifiedFault : public MipsFault<TLBModifiedFault> class TlbModifiedFault : public TlbFault<TlbModifiedFault>
{ {
public: public:
TLBModifiedFault(Addr asid, Addr vaddr, Addr vpn) TlbModifiedFault(Addr asid, Addr vaddr, Addr vpn) :
{ TlbFault<TlbModifiedFault>(asid, vaddr, vpn, false)
entryHiAsid = asid; {}
entryHiVPN2 = vpn >> 2;
entryHiVPN2X = vpn & 0x3;
badVAddr = vaddr;
contextBadVPN2 = vpn >> 2;
}
#if FULL_SYSTEM #if FULL_SYSTEM
void invoke(ThreadContext * tc, void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr); StaticInstPtr inst = StaticInst::nullStaticInstPtr);

View file

@ -451,7 +451,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
} else { } else {
// Ok, this is really a match, set paddr // Ok, this is really a match, set paddr
if (!Dirty) { if (!Dirty) {
return new TLBModifiedFault(Asid, vaddr, VPN); return new TlbModifiedFault(Asid, vaddr, VPN);
} }
Addr PAddr; Addr PAddr;
if (EvenOdd == 0) { if (EvenOdd == 0) {