summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-02-01 17:08:32 -0800
committerGabe Black <gblack@eecs.umich.edu>2009-02-01 17:08:32 -0800
commit923a14dde749ad6b1887ccea764439a167555772 (patch)
tree8084a71550fe2916f010f6252f3fc0e47fe0094e /src/arch/x86
parent2f8cec849d49d2692665aec20a1cd441e743dae7 (diff)
downloadgem5-923a14dde749ad6b1887ccea764439a167555772.tar.xz
X86: Make the fault classes handle error codes better.
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/faults.cc4
-rw-r--r--src/arch/x86/faults.hh54
-rw-r--r--src/arch/x86/isa/microops/regop.isa11
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;
}