diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/x86/faults.cc | 4 | ||||
-rw-r--r-- | src/arch/x86/faults.hh | 54 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 11 |
3 files changed, 46 insertions, 23 deletions
diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index 2ce377bdd..7702d98eb 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -123,7 +123,9 @@ namespace X86ISA } tc->setIntReg(INTREG_MICRO(1), vector); tc->setIntReg(INTREG_MICRO(7), tc->readPC()); - tc->setIntReg(INTREG_MICRO(15), (uint64_t)(-1)); + if (errorCode != (uint64_t)(-1)) { + tc->setIntReg(INTREG_MICRO(15), errorCode); + } tc->setMicroPC(romMicroPC(entry)); tc->setNextMicroPC(romMicroPC(entry) + 1); } diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index dc86d2cec..9c9cf3909 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -58,6 +58,7 @@ #ifndef __ARCH_X86_FAULTS_HH__ #define __ARCH_X86_FAULTS_HH__ +#include "base/bitunion.hh" #include "base/misc.hh" #include "sim/faults.hh" @@ -73,7 +74,7 @@ namespace X86ISA uint64_t errorCode; X86FaultBase(const char * _faultName, const char * _mnem, - const uint8_t _vector, uint64_t _errorCode = 0) : + const uint8_t _vector, uint64_t _errorCode = -1) : faultName(_faultName), mnem(_mnem), vector(_vector), errorCode(_errorCode) { @@ -107,7 +108,7 @@ namespace X86ISA { protected: X86Fault(const char * name, const char * mnem, - const uint8_t vector, uint64_t _errorCode = 0) : + const uint8_t vector, uint64_t _errorCode = -1) : X86FaultBase(name, mnem, vector, _errorCode) {} }; @@ -118,7 +119,7 @@ namespace X86ISA { protected: X86Trap(const char * name, const char * mnem, - const uint8_t vector, uint64_t _errorCode = 0) : + const uint8_t vector, uint64_t _errorCode = -1) : X86FaultBase(name, mnem, vector, _errorCode) {} @@ -132,7 +133,7 @@ namespace X86ISA { protected: X86Abort(const char * name, const char * mnem, - const uint8_t vector, uint64_t _errorCode = 0) : + const uint8_t vector, uint64_t _errorCode = -1) : X86FaultBase(name, mnem, vector, _errorCode) {} @@ -146,7 +147,7 @@ namespace X86ISA { protected: X86Interrupt(const char * name, const char * mnem, - const uint8_t _vector, uint64_t _errorCode = 0) : + const uint8_t _vector, uint64_t _errorCode = -1) : X86FaultBase(name, mnem, _vector, _errorCode) {} @@ -273,48 +274,69 @@ namespace X86ISA { public: DoubleFault() : - X86Abort("Double-Fault", "#DF", 8) + X86Abort("Double-Fault", "#DF", 8, 0) {} }; class InvalidTSS : public X86Fault { public: - InvalidTSS() : - X86Fault("Invalid-TSS", "#TS", 10) + InvalidTSS(uint32_t _errorCode) : + X86Fault("Invalid-TSS", "#TS", 10, _errorCode) {} }; class SegmentNotPresent : public X86Fault { public: - SegmentNotPresent() : - X86Fault("Segment-Not-Present", "#NP", 11) + SegmentNotPresent(uint32_t _errorCode) : + X86Fault("Segment-Not-Present", "#NP", 11, _errorCode) {} }; class StackFault : public X86Fault { public: - StackFault() : - X86Fault("Stack", "#SS", 12) + StackFault(uint32_t _errorCode) : + X86Fault("Stack", "#SS", 12, _errorCode) {} }; class GeneralProtection : public X86Fault { public: - GeneralProtection(uint64_t _errorCode) : + GeneralProtection(uint32_t _errorCode) : X86Fault("General-Protection", "#GP", 13, _errorCode) {} }; class PageFault : public X86Fault { + protected: + BitUnion32(PageFaultErrorCode) + Bitfield<0> present; + Bitfield<1> write; + Bitfield<2> user; + Bitfield<3> reserved; + Bitfield<4> fetch; + EndBitUnion(PageFaultErrorCode) + public: - PageFault() : - X86Fault("Page-Fault", "#PF", 14) + PageFault(uint32_t _errorCode) : + X86Fault("Page-Fault", "#PF", 14, _errorCode) {} + PageFault(bool present, bool write, bool user, + bool reserved, bool fetch) : + X86Fault("Page-Fault", "#PF", 14, 0) + { + PageFaultErrorCode code = 0; + code.present = present; + code.write = write; + code.user = user; + code.reserved = reserved; + code.fetch = fetch; + errorCode = code; + } }; class X87FpExceptionPending : public X86Fault @@ -329,7 +351,7 @@ namespace X86ISA { public: AlignmentCheck() : - X86Fault("Alignment-Check", "#AC", 17) + X86Fault("Alignment-Check", "#AC", 17, 0) {} }; diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 2e6160ec6..202bfc7f5 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1069,7 +1069,7 @@ let {{ case SegSoftIntGateCheck: // Check permissions. if (desc.dpl < m5reg.cpl) { - fault = new GeneralProtection((uint16_t)selector); + fault = new GeneralProtection(selector); } // Fall through on purpose case SegIntGateCheck: @@ -1082,8 +1082,7 @@ let {{ case SegSSCheck: if (selector.si || selector.ti) { if (!desc.p) { - //FIXME This needs to also push the selector. - fault = new StackFault; + fault = new StackFault(selector); } } else { if ((m5reg.submode != SixtyFourBitMode || @@ -1092,7 +1091,7 @@ let {{ desc.type.codeOrData == 0 && desc.type.w) || (desc.dpl != m5reg.cpl) || (selector.rpl != m5reg.cpl)) { - fault = new GeneralProtection(psrc1 & 0xFFFF); + fault = new GeneralProtection(selector); } } break; @@ -1103,9 +1102,9 @@ let {{ !(desc.s == 1 && desc.type.codeOrData == 1) || (!desc.type.c && desc.dpl != selector.rpl) || (desc.type.c && desc.dpl > selector.rpl)) { - fault = new GeneralProtection(psrc1 & 0xFFFF); + fault = new GeneralProtection(selector); } else if (!desc.p) { - fault = new SegmentNotPresent; + fault = new SegmentNotPresent(selector); } break; } |