* Kevin Lim
*/
+#include "arch/alpha/ev5.hh"
#include "arch/alpha/faults.hh"
+#include "arch/alpha/tlb.hh"
#include "cpu/thread_context.hh"
#include "cpu/base.hh"
#include "base/trace.hh"
-#if FULL_SYSTEM
-#include "arch/alpha/ev5.hh"
-#else
+#if !FULL_SYSTEM
#include "sim/process.hh"
#include "mem/page_table.hh"
#endif
-namespace AlphaISA
-{
+namespace AlphaISA {
FaultName MachineCheckFault::_name = "mchk";
FaultVect MachineCheckFault::_vect = 0x0401;
FaultVect DtbAlignmentFault::_vect = 0x0301;
FaultStat DtbAlignmentFault::_count;
-FaultName ItbMissFault::_name = "itbmiss";
-FaultVect ItbMissFault::_vect = 0x0181;
-FaultStat ItbMissFault::_count;
-
FaultName ItbPageFault::_name = "itbmiss";
FaultVect ItbPageFault::_vect = 0x0181;
FaultStat ItbPageFault::_count;
#if FULL_SYSTEM
-void AlphaFault::invoke(ThreadContext * tc)
+void
+AlphaFault::invoke(ThreadContext *tc)
{
FaultBase::invoke(tc);
countStat()++;
// exception restart address
if (setRestartAddress() || !(tc->readPC() & 0x3))
- tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, tc->readPC());
+ tc->setMiscRegNoEffect(IPR_EXC_ADDR, tc->readPC());
if (skipFaultingInstruction()) {
// traps... skip faulting instruction.
- tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR,
- tc->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR) + 4);
+ tc->setMiscRegNoEffect(IPR_EXC_ADDR,
+ tc->readMiscRegNoEffect(IPR_EXC_ADDR) + 4);
}
- tc->setPC(tc->readMiscRegNoEffect(AlphaISA::IPR_PAL_BASE) + vect());
+ tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + vect());
tc->setNextPC(tc->readPC() + sizeof(MachInst));
}
-void ArithmeticFault::invoke(ThreadContext * tc)
+void
+ArithmeticFault::invoke(ThreadContext *tc)
{
FaultBase::invoke(tc);
panic("Arithmetic traps are unimplemented!");
}
-void DtbFault::invoke(ThreadContext * tc)
+void
+DtbFault::invoke(ThreadContext *tc)
{
// Set fault address and flags. Even though we're modeling an
// EV5, we use the EV6 technique of not latching fault registers
// on VPTE loads (instead of locking the registers until IPR_VA is
// read, like the EV5). The EV6 approach is cleaner and seems to
// work with EV5 PAL code, but not the other way around.
- if (!tc->misspeculating()
- && !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {
+ if (!tc->misspeculating() &&
+ reqFlags.none(Request::VPTE|Request::NO_FAULT)) {
// set VA register with faulting address
- tc->setMiscRegNoEffect(AlphaISA::IPR_VA, vaddr);
+ tc->setMiscRegNoEffect(IPR_VA, vaddr);
// set MM_STAT register flags
- tc->setMiscRegNoEffect(AlphaISA::IPR_MM_STAT,
- (((EV5::Opcode(tc->getInst()) & 0x3f) << 11)
- | ((EV5::Ra(tc->getInst()) & 0x1f) << 6)
- | (flags & 0x3f)));
+ tc->setMiscRegNoEffect(IPR_MM_STAT,
+ (((Opcode(tc->getInst()) & 0x3f) << 11) |
+ ((Ra(tc->getInst()) & 0x1f) << 6) |
+ (flags & 0x3f)));
// set VA_FORM register with faulting formatted address
- tc->setMiscRegNoEffect(AlphaISA::IPR_VA_FORM,
- tc->readMiscRegNoEffect(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
+ tc->setMiscRegNoEffect(IPR_VA_FORM,
+ tc->readMiscRegNoEffect(IPR_MVPTBR) | (vaddr.vpn() << 3));
}
AlphaFault::invoke(tc);
}
-void ItbFault::invoke(ThreadContext * tc)
+void
+ItbFault::invoke(ThreadContext *tc)
{
if (!tc->misspeculating()) {
- tc->setMiscRegNoEffect(AlphaISA::IPR_ITB_TAG, pc);
- tc->setMiscRegNoEffect(AlphaISA::IPR_IFAULT_VA_FORM,
- tc->readMiscRegNoEffect(AlphaISA::IPR_IVPTBR) |
- (AlphaISA::VAddr(pc).vpn() << 3));
+ tc->setMiscRegNoEffect(IPR_ITB_TAG, pc);
+ tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM,
+ tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3));
}
AlphaFault::invoke(tc);
}
+#else
+
+void
+ItbPageFault::invoke(ThreadContext *tc)
+{
+ Process *p = tc->getProcessPtr();
+ TlbEntry entry;
+ bool success = p->pTable->lookup(pc, entry);
+ if (!success) {
+ panic("Tried to execute unmapped address %#x.\n", pc);
+ } else {
+ VAddr vaddr(pc);
+ tc->getITBPtr()->insert(vaddr.page(), entry);
+ }
+}
+
+void
+NDtbMissFault::invoke(ThreadContext *tc)
+{
+ Process *p = tc->getProcessPtr();
+ TlbEntry entry;
+ bool success = p->pTable->lookup(vaddr, entry);
+ if (!success) {
+ p->checkAndAllocNextPage(vaddr);
+ success = p->pTable->lookup(vaddr, entry);
+ }
+ if (!success) {
+ panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
+ } else {
+ tc->getDTBPtr()->insert(vaddr.page(), entry);
+ }
+}
+
#endif
} // namespace AlphaISA