diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index 936d0357c..31bb686ed 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -63,18 +63,91 @@ namespace X86ISA { - class X86Fault : public FaultBase + // Base class for all x86 "faults" where faults is in the m5 sense + class X86FaultBase : public FaultBase { protected: - const char * name() const + const char * faultName; + const char * mnem; + + X86FaultBase(const char * _faultName, const char * _mnem) : + faultName(_faultName), mnem(_mnem) { - return "generic_x86_fault"; } + const char * name() const + { + return faultName; + } + + virtual bool isBenign() + { + return true; + } + + virtual const char * mnemonic() const + { + return mnem; + } + }; + + // Base class for x86 faults which behave as if the underlying instruction + // didn't happen. + class X86Fault : public X86FaultBase + { + protected: + X86Fault(const char * name, const char * mnem) : + X86FaultBase(name, mnem) + {} + }; + + // Base class for x86 traps which behave as if the underlying instruction + // completed. + class X86Trap : public X86FaultBase + { + protected: + X86Trap(const char * name, const char * mnem) : + X86FaultBase(name, mnem) + {} + +#if FULL_SYSTEM void invoke(ThreadContext * tc) { panic("X86 faults are not implemented!"); } +#endif + }; + + // Base class for x86 aborts which seem to be catastrophic failures. + class X86Abort : public X86FaultBase + { + protected: + X86Abort(const char * name, const char * mnem) : + X86FaultBase(name, mnem) + {} + +#if FULL_SYSTEM + void invoke(ThreadContext * tc) + { + panic("X86 faults are not implemented!"); + } +#endif + }; + + // Base class for x86 interrupts. + class X86Interrupt : public X86FaultBase + { + protected: + X86Interrupt(const char * name, const char * mnem) : + X86FaultBase(name, mnem) + {} + +#if FULL_SYSTEM + void invoke(ThreadContext * tc) + { + panic("X86 faults are not implemented!"); + } +#endif }; class UnimpInstFault : public FaultBase @@ -95,6 +168,223 @@ namespace X86ISA { panic("Machine check fault not implemented in x86!\n"); } + + // Below is a summary of the interrupt/exception information in the + // architecture manuals. + + // Class | Type | vector | Cause | mnem + //------------------------------------------------------------------------ + //Contrib Fault 0 Divide-by-Zero-Error #DE + //Benign Either 1 Debug #DB + //Benign Interrupt 2 Non-Maskable-Interrupt #NMI + //Benign Trap 3 Breakpoint #BP + //Benign Trap 4 Overflow #OF + //Benign Fault 5 Bound-Range #BR + //Benign Fault 6 Invalid-Opcode #UD + //Benign Fault 7 Device-Not-Available #NM + //Benign Abort 8 Double-Fault #DF + // 9 Coprocessor-Segment-Overrun + //Contrib Fault 10 Invalid-TSS #TS + //Contrib Fault 11 Segment-Not-Present #NP + //Contrib Fault 12 Stack #SS + //Contrib Fault 13 General-Protection #GP + //Either Fault 14 Page-Fault #PF + // 15 Reserved + //Benign Fault 16 x87 Floating-Point Exception Pending #MF + //Benign Fault 17 Alignment-Check #AC + //Benign Abort 18 Machine-Check #MC + //Benign Fault 19 SIMD Floating-Point #XF + // 20-29 Reserved + //Contrib ? 30 Security Exception #SX + // 31 Reserved + //Benign Interrupt 0-255 External Interrupts #INTR + //Benign Interrupt 0-255 Software Interrupts INTn + + class DivideByZero : public X86Fault + { + public: + DivideByZero() : + X86Fault("Divide-by-Zero-Error", "#DE") + {} + }; + + class DebugException : public X86FaultBase + { + public: + DebugException() : + X86FaultBase("Debug", "#DB") + {} + }; + + class NonMaskableInterrupt : public X86Interrupt + { + public: + NonMaskableInterrupt() : + X86Interrupt("Non-Maskable-Interrupt", "#NMI") + {} + }; + + class Breakpoint : public X86Trap + { + public: + Breakpoint() : + X86Trap("Breakpoint", "#BP") + {} + }; + + class OverflowTrap : public X86Trap + { + public: + OverflowTrap() : + X86Trap("Overflow", "#OF") + {} + }; + + class BoundRange : public X86Fault + { + public: + BoundRange() : + X86Fault("Bound-Range", "#BR") + {} + }; + + class InvalidOpcode : public X86Fault + { + public: + InvalidOpcode() : + X86Fault("Invalid-Opcode", "#UD") + {} + }; + + class DeviceNotAvailable : public X86Fault + { + public: + DeviceNotAvailable() : + X86Fault("Device-Not-Available", "#NM") + {} + }; + + class DoubleFault : public X86Abort + { + public: + DoubleFault() : + X86Abort("Double-Fault", "#DF") + {} + }; + + class InvalidTSS : public X86Fault + { + public: + InvalidTSS() : + X86Fault("Invalid-TSS", "#TS") + {} + }; + + class SegmentNotPresent : public X86Fault + { + public: + SegmentNotPresent() : + X86Fault("Segment-Not-Present", "#NP") + {} + }; + + class StackFault : public X86Fault + { + public: + StackFault() : + X86Fault("Stack", "#SS") + {} + }; + + class GeneralProtection : public X86Fault + { + public: + GeneralProtection() : + X86Fault("General-Protection", "#GP") + {} + }; + + class PageFault : public X86Fault + { + public: + PageFault() : + X86Fault("Page-Fault", "#PF") + {} + }; + + class X87FpExceptionPending : public X86Fault + { + public: + X87FpExceptionPending() : + X86Fault("x87 Floating-Point Exception Pending", "#MF") + {} + }; + + class AlignmentCheck : X86Fault + { + public: + AlignmentCheck() : + X86Fault("Alignment-Check", "#AC") + {} + }; + + class MachineCheck : X86Abort + { + public: + MachineCheck() : + X86Abort("Machine-Check", "#MC") + {} + }; + + class SIMDFloatingPointFault : X86Fault + { + public: + SIMDFloatingPointFault() : + X86Fault("SIMD Floating-Point", "#XF") + {} + }; + + class SecurityException : X86FaultBase + { + public: + SecurityException() : + X86FaultBase("Security Exception", "#SX") + {} + }; + + class ExternalInterrupt : X86Interrupt + { + public: + ExternalInterrupt() : + X86Interrupt("External Interrupt", "#INTR") + {} + }; + + class SoftwareInterrupt : X86Interrupt + { + public: + SoftwareInterrupt() : + X86Interrupt("Software Interrupt", "INTn") + {} + }; + + // These faults aren't part of the ISA definition. They trigger filling + // the tlb on a miss and are to take the place of a hardware table walker. + class FakeITLBFault : public X86Fault + { + public: + FakeITLBFault() : + X86Fault("fake instruction tlb fault", "itlb") + {} + }; + + class FakeDTLBFault : public X86Fault + { + public: + FakeDTLBFault() : + X86Fault("fake data tlb fault", "dtlb") + {} + }; }; #endif // __ARCH_X86_FAULTS_HH__ diff --git a/src/arch/x86/isa/insts/system/undefined_operation.py b/src/arch/x86/isa/insts/system/undefined_operation.py index e5544b6e7..9f129522b 100644 --- a/src/arch/x86/isa/insts/system/undefined_operation.py +++ b/src/arch/x86/isa/insts/system/undefined_operation.py @@ -56,6 +56,6 @@ microcode = ''' def macroop UD2 { - fault "new X86Fault" + fault "new InvalidOpcode()" }; '''