X86: Make the fault classes handle error codes better.
authorGabe Black <gblack@eecs.umich.edu>
Mon, 2 Feb 2009 01:08:32 +0000 (17:08 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 2 Feb 2009 01:08:32 +0000 (17:08 -0800)
src/arch/x86/faults.cc
src/arch/x86/faults.hh
src/arch/x86/isa/microops/regop.isa

index 2ce377bddd5a0ec8043f045df775fe80ab56b7e7..7702d98ebcee7cbc17a5976f2e8b6c4c081a6928 100644 (file)
@@ -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);
     }
index dc86d2cec9152ca7f1bb2f32cdf996ed6cd39fb5..9c9cf39094f8f41781eab86b1c2bc0cee7be2cfa 100644 (file)
@@ -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)
         {}
     };
 
index 2e6160ec69911aecc89e227f665dc55cb96c761f..202bfc7f5a6036d3cd4ad245e84b1ee66e40c3c8 100644 (file)
@@ -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;
                 }