diff -r 562f236f6216 -r eed147577fba src/arch/alpha/ev5.cc --- a/src/arch/alpha/ev5.cc Sat Sep 24 18:08:51 2011 -0700 +++ b/src/arch/alpha/ev5.cc Sun Sep 25 03:03:33 2011 -0700 @@ -58,7 +58,7 @@ tc->setIntReg(16, cpuId); tc->setIntReg(0, cpuId); - AlphaFault *reset = new ResetFault; + AlphaFaultBase *reset = new ResetFault; tc->pcState(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect()); diff -r 562f236f6216 -r eed147577fba src/arch/alpha/faults.hh --- a/src/arch/alpha/faults.hh Sat Sep 24 18:08:51 2011 -0700 +++ b/src/arch/alpha/faults.hh Sun Sep 25 03:03:33 2011 -0700 @@ -43,97 +43,64 @@ typedef const Addr FaultVect; -class AlphaFault : public FaultBase +class AlphaFaultBase : public FaultBase { protected: - virtual bool skipFaultingInstruction() {return false;} - virtual bool setRestartAddress() {return true;} + virtual bool skipFaultingInstruction() { return false; } + virtual bool setRestartAddress() { return true; } + public: + struct FaultVals + { + const FaultName name; + const FaultVect vect; + FaultStat count; + }; + #if FULL_SYSTEM void invoke(ThreadContext * tc, StaticInstPtr inst = StaticInst::nullStaticInstPtr); #endif - virtual FaultVect vect() = 0; + virtual FaultVect vect() const = 0; virtual FaultStat & countStat() = 0; }; -class MachineCheckFault : public AlphaFault +template +class AlphaFault : public AlphaFaultBase { - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; + protected: + static FaultVals vals; + + public: + FaultName name() const { return vals.name; } + FaultVect vect() const { return vals.vect; } + FaultStat & countStat() { return vals.count; } +}; + +class MachineCheckFault : public AlphaFault {}; +class AlignmentFault : public AlphaFault {}; +class ResetFault : public AlphaFault {}; + +class ArithmeticFault : public AlphaFault +{ + protected: + bool skipFaultingInstruction() { return true; } public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class AlignmentFault : public AlphaFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - bool isAlignmentFault() const {return true;} -}; - -class ResetFault : public AlphaFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class ArithmeticFault : public AlphaFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - - protected: - bool skipFaultingInstruction() {return true;} - - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} #if FULL_SYSTEM void invoke(ThreadContext * tc, StaticInstPtr inst = StaticInst::nullStaticInstPtr); #endif }; -class InterruptFault : public AlphaFault +class InterruptFault : public AlphaFault { - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - protected: - bool setRestartAddress() {return false;} - - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} + bool setRestartAddress() { return false; } }; -class DtbFault : public AlphaFault +template +class DtbFault : public AlphaFault { protected: VAddr vaddr; @@ -144,201 +111,136 @@ DtbFault(VAddr _vaddr, Request::Flags _reqFlags, uint64_t _flags) : vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags) { } - FaultName name() const = 0; - FaultVect vect() = 0; - FaultStat & countStat() = 0; + #if FULL_SYSTEM - void invoke(ThreadContext * tc, - StaticInstPtr inst = StaticInst::nullStaticInstPtr); + void + invoke(ThreadContext * tc, + StaticInstPtr inst = StaticInst::nullStaticInstPtr) + { + // 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.noneSet(Request::VPTE | Request::PREFETCH)) { + // set VA register with faulting address + tc->setMiscRegNoEffect(IPR_VA, vaddr); + + // set MM_STAT register flags + MachInst machInst = inst->machInst; + tc->setMiscRegNoEffect(IPR_MM_STAT, + (((Opcode(machInst) & 0x3f) << 11) | + ((Ra(machInst) & 0x1f) << 6) | + (flags & 0x3f))); + + // set VA_FORM register with faulting formatted address + tc->setMiscRegNoEffect(IPR_VA_FORM, + tc->readMiscRegNoEffect(IPR_MVPTBR) | (vaddr.vpn() << 3)); + } + + AlphaFaultBase::invoke(tc); + } #endif }; -class NDtbMissFault : public DtbFault +class NDtbMissFault : public DtbFault { - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: NDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) - : DtbFault(vaddr, reqFlags, flags) + : DtbFault(vaddr, reqFlags, flags) { } - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} + #if !FULL_SYSTEM void invoke(ThreadContext * tc, StaticInstPtr inst = StaticInst::nullStaticInstPtr); #endif }; -class PDtbMissFault : public DtbFault +class PDtbMissFault : public DtbFault { - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: PDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) - : DtbFault(vaddr, reqFlags, flags) + : DtbFault(vaddr, reqFlags, flags) { } - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} }; -class DtbPageFault : public DtbFault +class DtbPageFault : public DtbFault { - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: DtbPageFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) - : DtbFault(vaddr, reqFlags, flags) + : DtbFault(vaddr, reqFlags, flags) { } - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} }; -class DtbAcvFault : public DtbFault +class DtbAcvFault : public DtbFault { - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: DtbAcvFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) - : DtbFault(vaddr, reqFlags, flags) + : DtbFault(vaddr, reqFlags, flags) { } - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} }; -class DtbAlignmentFault : public DtbFault +class DtbAlignmentFault : public DtbFault { - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: DtbAlignmentFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) - : DtbFault(vaddr, reqFlags, flags) + : DtbFault(vaddr, reqFlags, flags) { } - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} }; -class ItbFault : public AlphaFault +template +class ItbFault : public AlphaFault { protected: Addr pc; public: ItbFault(Addr _pc) : pc(_pc) { } - FaultName name() const = 0; - FaultVect vect() = 0; - FaultStat & countStat() = 0; + #if FULL_SYSTEM - void invoke(ThreadContext * tc, - StaticInstPtr inst = StaticInst::nullStaticInstPtr); + void + invoke(ThreadContext * tc, + StaticInstPtr inst = StaticInst::nullStaticInstPtr) + { + if (!tc->misspeculating()) { + tc->setMiscRegNoEffect(IPR_ITB_TAG, pc); + tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM, + tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3)); + } + + AlphaFaultBase::invoke(tc); + } #endif }; -class ItbPageFault : public ItbFault +class ItbPageFault : public ItbFault { - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; + public: + ItbPageFault(Addr pc) : ItbFault(pc) { } - public: - ItbPageFault(Addr pc) : ItbFault(pc) { } - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} #if !FULL_SYSTEM void invoke(ThreadContext * tc, StaticInstPtr inst = StaticInst::nullStaticInstPtr); #endif }; -class ItbAcvFault : public ItbFault +class ItbAcvFault : public ItbFault { - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - ItbAcvFault(Addr pc) : ItbFault(pc) { } - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} + ItbAcvFault(Addr pc) : ItbFault(pc) { } }; -class UnimplementedOpcodeFault : public AlphaFault +class UnimplementedOpcodeFault : + public AlphaFault {}; +class FloatEnableFault : public AlphaFault {}; +class PalFault : public AlphaFault { - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} + protected: + bool skipFaultingInstruction() { return true; } }; -class FloatEnableFault : public AlphaFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class PalFault : public AlphaFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - - protected: - bool skipFaultingInstruction() {return true;} - - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class IntegerOverflowFault : public AlphaFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; +class IntegerOverflowFault : public AlphaFault {}; } // namespace AlphaISA diff -r 562f236f6216 -r eed147577fba src/arch/alpha/faults.cc --- a/src/arch/alpha/faults.cc Sat Sep 24 18:08:51 2011 -0700 +++ b/src/arch/alpha/faults.cc Sun Sep 25 03:03:33 2011 -0700 @@ -43,74 +43,45 @@ namespace AlphaISA { -FaultName MachineCheckFault::_name = "mchk"; -FaultVect MachineCheckFault::_vect = 0x0401; -FaultStat MachineCheckFault::_count; +typedef AlphaFaultBase::FaultVals FaultVals; -FaultName AlignmentFault::_name = "unalign"; -FaultVect AlignmentFault::_vect = 0x0301; -FaultStat AlignmentFault::_count; - -FaultName ResetFault::_name = "reset"; -FaultVect ResetFault::_vect = 0x0001; -FaultStat ResetFault::_count; - -FaultName ArithmeticFault::_name = "arith"; -FaultVect ArithmeticFault::_vect = 0x0501; -FaultStat ArithmeticFault::_count; - -FaultName InterruptFault::_name = "interrupt"; -FaultVect InterruptFault::_vect = 0x0101; -FaultStat InterruptFault::_count; - -FaultName NDtbMissFault::_name = "dtb_miss_single"; -FaultVect NDtbMissFault::_vect = 0x0201; -FaultStat NDtbMissFault::_count; - -FaultName PDtbMissFault::_name = "dtb_miss_double"; -FaultVect PDtbMissFault::_vect = 0x0281; -FaultStat PDtbMissFault::_count; - -FaultName DtbPageFault::_name = "dtb_page_fault"; -FaultVect DtbPageFault::_vect = 0x0381; -FaultStat DtbPageFault::_count; - -FaultName DtbAcvFault::_name = "dtb_acv_fault"; -FaultVect DtbAcvFault::_vect = 0x0381; -FaultStat DtbAcvFault::_count; - -FaultName DtbAlignmentFault::_name = "unalign"; -FaultVect DtbAlignmentFault::_vect = 0x0301; -FaultStat DtbAlignmentFault::_count; - -FaultName ItbPageFault::_name = "itbmiss"; -FaultVect ItbPageFault::_vect = 0x0181; -FaultStat ItbPageFault::_count; - -FaultName ItbAcvFault::_name = "iaccvio"; -FaultVect ItbAcvFault::_vect = 0x0081; -FaultStat ItbAcvFault::_count; - -FaultName UnimplementedOpcodeFault::_name = "opdec"; -FaultVect UnimplementedOpcodeFault::_vect = 0x0481; -FaultStat UnimplementedOpcodeFault::_count; - -FaultName FloatEnableFault::_name = "fen"; -FaultVect FloatEnableFault::_vect = 0x0581; -FaultStat FloatEnableFault::_count; - -FaultName PalFault::_name = "pal"; -FaultVect PalFault::_vect = 0x2001; -FaultStat PalFault::_count; - -FaultName IntegerOverflowFault::_name = "intover"; -FaultVect IntegerOverflowFault::_vect = 0x0501; -FaultStat IntegerOverflowFault::_count; +template <> FaultVals AlphaFault::vals = + { "mchk", 0x0401 }; +template <> FaultVals AlphaFault::vals = + { "unalign", 0x0301 }; +template <> FaultVals AlphaFault::vals = + { "reset", 0x0001 }; +template <> FaultVals AlphaFault::vals = + { "arith", 0x0501 }; +template <> FaultVals AlphaFault::vals = + { "interrupt", 0x0101 }; +template <> FaultVals AlphaFault::vals = + { "dtb_miss_single", 0x0201 }; +template <> FaultVals AlphaFault::vals = + { "dtb_miss_double", 0x0281 }; +template <> FaultVals AlphaFault::vals = + { "dtb_page_fault", 0x0381 }; +template <> FaultVals AlphaFault::vals = + { "dtb_acv_fault", 0x0381 }; +template <> FaultVals AlphaFault::vals = + { "unalign", 0x0301 }; +template <> FaultVals AlphaFault::vals = + { "itbmiss", 0x0181 }; +template <> FaultVals AlphaFault::vals = + { "iaccvio", 0x0081 }; +template <> FaultVals AlphaFault::vals = + { "opdec", 0x0481 }; +template <> FaultVals AlphaFault::vals = + { "fen", 0x0581 }; +template <> FaultVals AlphaFault::vals = + { "pal", 0x2001 }; +template <> FaultVals AlphaFault::vals = + { "intover", 0x0501 }; #if FULL_SYSTEM void -AlphaFault::invoke(ThreadContext *tc, StaticInstPtr inst) +AlphaFaultBase::invoke(ThreadContext *tc, StaticInstPtr inst) { FaultBase::invoke(tc); countStat()++; @@ -138,46 +109,6 @@ panic("Arithmetic traps are unimplemented!"); } -void -DtbFault::invoke(ThreadContext *tc, StaticInstPtr inst) -{ - // 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.noneSet(Request::VPTE | Request::PREFETCH)) { - // set VA register with faulting address - tc->setMiscRegNoEffect(IPR_VA, vaddr); - - // set MM_STAT register flags - MachInst machInst = inst->machInst; - tc->setMiscRegNoEffect(IPR_MM_STAT, - (((Opcode(machInst) & 0x3f) << 11) | - ((Ra(machInst) & 0x1f) << 6) | - (flags & 0x3f))); - - // set VA_FORM register with faulting formatted address - tc->setMiscRegNoEffect(IPR_VA_FORM, - tc->readMiscRegNoEffect(IPR_MVPTBR) | (vaddr.vpn() << 3)); - } - - AlphaFault::invoke(tc); -} - -void -ItbFault::invoke(ThreadContext *tc, StaticInstPtr inst) -{ - if (!tc->misspeculating()) { - 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