From c1046488e073b2535c76c473aec34fe499c149e3 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 28 Mar 2006 18:01:01 -0500 Subject: Move TLB faults into the normal Fault code. The TLB no longer fills in IPRs through its own fault() method; this is handled by the fault's invoke() methods. arch/alpha/faults.cc: Move TLB fault code into the normal fault invoke() method. arch/alpha/faults.hh: Move DTB/ITB fault handling code into their own class with a specific invoke() method. Have DTB/ITB faults derive from these classes. Unfortunately the DtbAlignmentFault is somewhat odd; it's a normal alignment fault, but it must also set some specific IPRs. arch/alpha/tlb.cc: arch/alpha/tlb.hh: Setting IPRs is now handled through the fault itself. --HG-- extra : convert_revision : 5cb92ce2186ff79f632bfcbc9ba62a8a04400eae --- arch/alpha/faults.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'arch/alpha/faults.cc') diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index e0918da21..0083aa9f3 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -30,6 +30,9 @@ #include "cpu/exec_context.hh" #include "cpu/base.hh" #include "base/trace.hh" +#if FULL_SYSTEM +#include "arch/alpha/ev5.hh" +#endif namespace AlphaISA { @@ -70,6 +73,10 @@ FaultName DtbAcvFault::_name = "dfault"; FaultVect DtbAcvFault::_vect = 0x0381; FaultStat DtbAcvFault::_count; +FaultName DtbAlignmentFault::_name = "unalign"; +FaultVect DtbAlignmentFault::_vect = 0x0301; +FaultStat DtbAlignmentFault::_count; + FaultName ItbMissFault::_name = "itbmiss"; FaultVect ItbMissFault::_vect = 0x0181; FaultStat ItbMissFault::_count; @@ -125,6 +132,44 @@ void ArithmeticFault::invoke(ExecContext * xc) panic("Arithmetic traps are unimplemented!"); } +void DtbFault::invoke(ExecContext * xc) +{ + // 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 (!xc->misspeculating() + && !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) { + // set VA register with faulting address + xc->setMiscReg(AlphaISA::IPR_VA, vaddr); + + // set MM_STAT register flags + xc->setMiscReg(AlphaISA::IPR_MM_STAT, + (((EV5::Opcode(xc->getInst()) & 0x3f) << 11) + | ((EV5::Ra(xc->getInst()) & 0x1f) << 6) + | (flags & 0x3f))); + + // set VA_FORM register with faulting formatted address + xc->setMiscReg(AlphaISA::IPR_VA_FORM, + xc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3)); + } + + AlphaFault::invoke(xc); +} + +void ItbFault::invoke(ExecContext * xc) +{ + if (!xc->misspeculating()) { + xc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc); + xc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM, + xc->readMiscReg(AlphaISA::IPR_IVPTBR) | + (AlphaISA::VAddr(pc).vpn() << 3)); + } + + AlphaFault::invoke(xc); +} + #endif } // namespace AlphaISA -- cgit v1.2.3