summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/mips/faults.cc84
-rw-r--r--src/arch/mips/faults.hh48
-rw-r--r--src/arch/mips/tlb.cc8
3 files changed, 23 insertions, 117 deletions
diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc
index 038b73883..c69bd1bd3 100644
--- a/src/arch/mips/faults.cc
+++ b/src/arch/mips/faults.cc
@@ -85,17 +85,11 @@ template <> FaultVals MipsFault<TrapFault>::vals =
template <> FaultVals MipsFault<BreakpointFault>::vals =
{ "Breakpoint", 0x0180 };
-template <> FaultVals MipsFault<ItbInvalidFault>::vals =
- { "Invalid TLB Entry Exception (I-Fetch/LW)", 0x0180 };
+template <> FaultVals MipsFault<TlbInvalidFault>::vals =
+ { "Invalid TLB Entry Exception", 0x0180 };
-template <> FaultVals MipsFault<ItbRefillFault>::vals =
- { "TLB Refill Exception (I-Fetch/LW)", 0x0180 };
-
-template <> FaultVals MipsFault<DtbInvalidFault>::vals =
- { "Invalid TLB Entry Exception (Store)", 0x0180 };
-
-template <> FaultVals MipsFault<DtbRefillFault>::vals =
- { "TLB Refill Exception (Store)", 0x0180 };
+template <> FaultVals MipsFault<TlbRefillFault>::vals =
+ { "TLB Refill Exception", 0x0180 };
template <> FaultVals MipsFault<TLBModifiedFault>::vals =
{ "TLB Modified Exception", 0x0180 };
@@ -199,9 +193,10 @@ BreakpointFault::invoke(ThreadContext *tc, StaticInstPtr inst)
}
void
-DtbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst)
+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);
@@ -213,8 +208,6 @@ DtbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst)
ContextReg context = tc->readMiscReg(MISCREG_CONTEXT);
context.badVPN2 = contextBadVPN2;
tc->setMiscRegNoEffect(MISCREG_CONTEXT, context);
- setExceptionState(tc, 0x3);
-
// Set new PC
Addr HandlerBase;
@@ -238,66 +231,11 @@ AddressErrorFault::invoke(ThreadContext *tc, StaticInstPtr inst)
}
void
-ItbInvalidFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
- DPRINTF(MipsPRA, "%s encountered.\n", name());
- setExceptionState(tc, 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);
- DPRINTF(MipsPRA, "Exception Handler At: %x , EPC set to %x\n",
- HandlerBase, tc->readMiscReg(MISCREG_EPC));
-}
-
-void
-ItbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
+TlbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
DPRINTF(MipsPRA, "%s encountered (%x).\n", name(), MISCREG_BADVADDR);
- 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!!
- // See MIPS ARM Vol 3, Revision 2, Page 38
- if (status.exl == 1) {
- // Offset 0x180 - General Exception Vector
- HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
- } else {
- // Offset 0x000
- HandlerBase = tc->readMiscReg(MISCREG_EBASE);
- }
+ setExceptionState(tc, store ? 0x3 : 0x2);
- setExceptionState(tc, 0x2);
- setHandlerPC(HandlerBase, tc);
-}
-
-void
-DtbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
-{
- // Set new PC
- DPRINTF(MipsPRA, "%s encountered.\n", name());
Addr HandlerBase;
tc->setMiscRegNoEffect(MISCREG_BADVADDR, badVAddr);
EntryHiReg entryHi = tc->readMiscReg(MISCREG_ENTRYHI);
@@ -305,7 +243,6 @@ DtbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
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);
@@ -313,16 +250,13 @@ DtbRefillFault::invoke(ThreadContext *tc, StaticInstPtr inst)
StatusReg status = tc->readMiscReg(MISCREG_STATUS);
// Since handler depends on EXL bit, must check EXL bit before setting it!!
// See MIPS ARM Vol 3, Revision 2, Page 38
- if (status.exl) {
+ if (status.exl == 1) {
// Offset 0x180 - General Exception Vector
HandlerBase = vect() + tc->readMiscReg(MISCREG_EBASE);
} else {
// Offset 0x000
HandlerBase = tc->readMiscReg(MISCREG_EBASE);
}
-
- setExceptionState(tc, 0x3);
-
setHandlerPC(HandlerBase, tc);
}
diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh
index 0b3d6ce30..dfb3b4ab5 100644
--- a/src/arch/mips/faults.hh
+++ b/src/arch/mips/faults.hh
@@ -199,27 +199,13 @@ class BreakpointFault : public MipsFault<BreakpointFault>
#endif
};
-class ItbRefillFault : public MipsFault<ItbRefillFault>
-{
- public:
- ItbRefillFault(Addr asid, Addr vaddr, Addr vpn)
- {
- entryHiAsid = asid;
- entryHiVPN2 = vpn >> 2;
- entryHiVPN2X = vpn & 0x3;
- badVAddr = vaddr;
- contextBadVPN2 = vpn >> 2;
- }
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc,
- StaticInstPtr inst = StaticInst::nullStaticInstPtr);
-#endif
-};
-
-class DtbRefillFault : public MipsFault<DtbRefillFault>
+class TlbRefillFault : public MipsFault<TlbRefillFault>
{
+ protected:
+ bool store;
public:
- DtbRefillFault(Addr asid, Addr vaddr, Addr vpn)
+ TlbRefillFault(Addr asid, Addr vaddr, Addr vpn, bool _store) :
+ store(_store)
{
entryHiAsid = asid;
entryHiVPN2 = vpn >> 2;
@@ -233,10 +219,13 @@ class DtbRefillFault : public MipsFault<DtbRefillFault>
#endif
};
-class ItbInvalidFault : public MipsFault<ItbInvalidFault>
+class TlbInvalidFault : public MipsFault<TlbInvalidFault>
{
+ protected:
+ bool store;
public:
- ItbInvalidFault(Addr asid, Addr vaddr, Addr vpn)
+ TlbInvalidFault(Addr asid, Addr vaddr, Addr vpn, bool _store) :
+ store(_store)
{
entryHiAsid = asid;
entryHiVPN2 = vpn >> 2;
@@ -267,23 +256,6 @@ class TLBModifiedFault : public MipsFault<TLBModifiedFault>
#endif
};
-class DtbInvalidFault : public MipsFault<DtbInvalidFault>
-{
- public:
- DtbInvalidFault(Addr asid, Addr vaddr, Addr vpn)
- {
- entryHiAsid = asid;
- entryHiVPN2 = vpn >> 2;
- entryHiVPN2X = vpn & 0x3;
- badVAddr = vaddr;
- contextBadVPN2 = vpn >> 2;
- }
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc,
- StaticInst::StaticInstPtr inst = nullStaticInstPtr);
-#endif
-};
-
class DspStateDisabledFault : public MipsFault<DspStateDisabledFault>
{
public:
diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc
index 1336ee7d0..31595b53d 100644
--- a/src/arch/mips/tlb.cc
+++ b/src/arch/mips/tlb.cc
@@ -352,7 +352,7 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
}
if (Valid == false) {
- return new ItbInvalidFault(Asid, vaddr, vpn);
+ return new InvalidFault(Asid, vaddr, vpn, false);
} else {
// Ok, this is really a match, set paddr
Addr PAddr;
@@ -368,7 +368,7 @@ TLB::translateInst(RequestPtr req, ThreadContext *tc)
}
} else {
// Didn't find any match, return a TLB Refill Exception
- return new ItbRefillFault(Asid, vaddr, vpn);
+ return new RefillFault(Asid, vaddr, vpn, false);
}
}
return checkCacheability(req);
@@ -447,7 +447,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
}
if (Valid == false) {
- return new DtbInvalidFault(Asid, vaddr, VPN);
+ return new InvalidFault(Asid, vaddr, VPN, true);
} else {
// Ok, this is really a match, set paddr
if (!Dirty) {
@@ -466,7 +466,7 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
}
} else {
// Didn't find any match, return a TLB Refill Exception
- return new DtbRefillFault(Asid, vaddr, VPN);
+ return new RefillFault(Asid, vaddr, VPN, true);
}
}
return checkCacheability(req);