MIPS: Use inheritance to consolidate class definitions.
This commit is contained in:
parent
7d19ff170d
commit
5ea09771be
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue