X86: All x86 fault classes now attempt to do something useful.

This commit is contained in:
Gabe Black 2009-02-01 17:09:08 -08:00
parent 923a14dde7
commit 5a4eed5d34
3 changed files with 69 additions and 25 deletions

View file

@ -101,34 +101,67 @@
namespace X86ISA
{
#if FULL_SYSTEM
void X86Trap::invoke(ThreadContext * tc)
{
panic("X86 faults are not implemented!");
}
void X86Abort::invoke(ThreadContext * tc)
{
panic("X86 faults are not implemented!");
}
void X86Interrupt::invoke(ThreadContext * tc)
void X86FaultBase::invoke(ThreadContext * tc)
{
using namespace X86ISAInst::RomLabels;
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
MicroPC entry;
if (m5reg.mode == LongMode) {
entry = extern_label_longModeInterrupt;
if (isSoft()) {
entry = extern_label_longModeSoftInterrupt;
} else {
entry = extern_label_longModeInterrupt;
}
} else {
entry = extern_label_legacyModeInterrupt;
}
tc->setIntReg(INTREG_MICRO(1), vector);
tc->setIntReg(INTREG_MICRO(7), tc->readPC());
if (errorCode != (uint64_t)(-1)) {
if (m5reg.mode == LongMode) {
entry = extern_label_longModeInterruptWithError;
} else {
panic("Legacy mode interrupts with error codes "
"aren't implementde.\n");
}
// Software interrupts shouldn't have error codes. If one does,
// there would need to be microcode to set it up.
assert(!isSoft());
tc->setIntReg(INTREG_MICRO(15), errorCode);
}
tc->setMicroPC(romMicroPC(entry));
tc->setNextMicroPC(romMicroPC(entry) + 1);
}
void X86Trap::invoke(ThreadContext * tc)
{
X86FaultBase::invoke(tc);
// This is the same as a fault, but it happens -after- the instruction.
tc->setPC(tc->readNextPC());
tc->setNextPC(tc->readNextNPC());
tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst));
}
void X86Abort::invoke(ThreadContext * tc)
{
panic("Abort exception!");
}
void PageFault::invoke(ThreadContext * tc)
{
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
X86FaultBase::invoke(tc);
/*
* If something bad happens while trying to enter the page fault
* handler, I'm pretty sure that's a double fault and then all bets are
* off. That means it should be safe to update this state now.
*/
if (m5reg.mode == LongMode) {
tc->setMiscReg(MISCREG_CR2, addr);
} else {
tc->setMiscReg(MISCREG_CR2, (uint32_t)addr);
}
}
void FakeITLBFault::invoke(ThreadContext * tc)
{

View file

@ -95,11 +95,14 @@ namespace X86ISA
return mnem;
}
void
invoke(ThreadContext * tc)
virtual bool isSoft()
{
panic("Unimplemented fault %s.\n", name());
return false;
}
#if FULL_SYSTEM
void invoke(ThreadContext * tc);
#endif
};
// Base class for x86 faults which behave as if the underlying instruction
@ -150,10 +153,6 @@ namespace X86ISA
const uint8_t _vector, uint64_t _errorCode = -1) :
X86FaultBase(name, mnem, _vector, _errorCode)
{}
#if FULL_SYSTEM
void invoke(ThreadContext * tc);
#endif
};
class UnimpInstFault : public FaultBase
@ -321,13 +320,16 @@ namespace X86ISA
Bitfield<4> fetch;
EndBitUnion(PageFaultErrorCode)
Addr addr;
public:
PageFault(uint32_t _errorCode) :
X86Fault("Page-Fault", "#PF", 14, _errorCode)
PageFault(Addr _addr, uint32_t _errorCode) :
X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr)
{}
PageFault(bool present, bool write, bool user,
bool reserved, bool fetch) :
X86Fault("Page-Fault", "#PF", 14, 0)
PageFault(Addr _addr, bool present, bool write,
bool user, bool reserved, bool fetch) :
X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr)
{
PageFaultErrorCode code = 0;
code.present = present;
@ -337,6 +339,10 @@ namespace X86ISA
code.fetch = fetch;
errorCode = code;
}
#if FULL_SYSTEM
void invoke(ThreadContext * tc);
#endif
};
class X87FpExceptionPending : public X86Fault
@ -410,6 +416,11 @@ namespace X86ISA
SoftwareInterrupt(uint8_t _vector) :
X86Interrupt("Software Interrupt", "INTn", _vector)
{}
bool isSoft()
{
return true;
}
};
// These faults aren't part of the ISA definition. They trigger filling

View file

@ -95,7 +95,7 @@ def rom
# If we're here, it's because the stack isn't being switched.
# Set t6 to the new aligned rsp.
mov t6, rsp, dataSize=8
mov t6, t6, rsp, dataSize=8
andi t6, t6, 0xF0, dataSize=1
subi t6, t6, 40 + %(errorCodeSize)d, dataSize=8