x86: Style fixes in x86's fault implementations.
Change-Id: I320877a7e753eae5ffba2421e6dfe23b52352664 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/33279 Maintainer: Gabe Black <gabeblack@google.com> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
This commit is contained in:
@@ -51,272 +51,269 @@
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
void X86FaultBase::invoke(ThreadContext * tc, const StaticInstPtr &inst)
|
||||
{
|
||||
if (!FullSystem) {
|
||||
FaultBase::invoke(tc, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
PCState pcState = tc->pcState();
|
||||
Addr pc = pcState.pc();
|
||||
DPRINTF(Faults, "RIP %#x: vector %d: %s\n",
|
||||
pc, vector, describe());
|
||||
using namespace X86ISAInst::RomLabels;
|
||||
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
||||
MicroPC entry;
|
||||
void
|
||||
X86FaultBase::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
{
|
||||
if (!FullSystem) {
|
||||
FaultBase::invoke(tc, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
PCState pcState = tc->pcState();
|
||||
Addr pc = pcState.pc();
|
||||
DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc, vector, describe());
|
||||
using namespace X86ISAInst::RomLabels;
|
||||
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
||||
MicroPC entry;
|
||||
if (m5reg.mode == LongMode) {
|
||||
entry = isSoft() ? extern_label_longModeSoftInterrupt :
|
||||
extern_label_longModeInterrupt;
|
||||
} else {
|
||||
entry = extern_label_legacyModeInterrupt;
|
||||
}
|
||||
tc->setIntReg(INTREG_MICRO(1), vector);
|
||||
tc->setIntReg(INTREG_MICRO(7), pc);
|
||||
if (errorCode != (uint64_t)(-1)) {
|
||||
if (m5reg.mode == LongMode) {
|
||||
if (isSoft()) {
|
||||
entry = extern_label_longModeSoftInterrupt;
|
||||
} else {
|
||||
entry = extern_label_longModeInterrupt;
|
||||
}
|
||||
entry = extern_label_longModeInterruptWithError;
|
||||
} else {
|
||||
entry = extern_label_legacyModeInterrupt;
|
||||
panic("Legacy mode interrupts with error codes "
|
||||
"aren't implemented.");
|
||||
}
|
||||
tc->setIntReg(INTREG_MICRO(1), vector);
|
||||
tc->setIntReg(INTREG_MICRO(7), pc);
|
||||
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);
|
||||
}
|
||||
pcState.upc(romMicroPC(entry));
|
||||
pcState.nupc(romMicroPC(entry) + 1);
|
||||
tc->pcState(pcState);
|
||||
// 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);
|
||||
}
|
||||
pcState.upc(romMicroPC(entry));
|
||||
pcState.nupc(romMicroPC(entry) + 1);
|
||||
tc->pcState(pcState);
|
||||
}
|
||||
|
||||
std::string
|
||||
X86FaultBase::describe() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ccprintf(ss, "%s", mnemonic());
|
||||
if (errorCode != (uint64_t)(-1)) {
|
||||
ccprintf(ss, "(%#x)", errorCode);
|
||||
}
|
||||
std::string
|
||||
X86FaultBase::describe() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ccprintf(ss, "%s", mnemonic());
|
||||
if (errorCode != (uint64_t)(-1))
|
||||
ccprintf(ss, "(%#x)", errorCode);
|
||||
|
||||
return ss.str();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void
|
||||
X86Trap::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
{
|
||||
X86FaultBase::invoke(tc);
|
||||
if (!FullSystem)
|
||||
return;
|
||||
|
||||
// This is the same as a fault, but it happens -after- the
|
||||
// instruction.
|
||||
PCState pc = tc->pcState();
|
||||
pc.uEnd();
|
||||
}
|
||||
|
||||
void
|
||||
X86Abort::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
{
|
||||
panic("Abort exception!");
|
||||
}
|
||||
|
||||
void
|
||||
InvalidOpcode::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
X86Fault::invoke(tc, inst);
|
||||
} else {
|
||||
panic("Unrecognized/invalid instruction executed:\n %s",
|
||||
inst->machInst);
|
||||
}
|
||||
}
|
||||
|
||||
void X86Trap::invoke(ThreadContext * tc, const StaticInstPtr &inst)
|
||||
{
|
||||
void
|
||||
PageFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
// Invalidate any matching TLB entries before handling the page fault.
|
||||
tc->getITBPtr()->demapPage(addr, 0);
|
||||
tc->getDTBPtr()->demapPage(addr, 0);
|
||||
HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
|
||||
X86FaultBase::invoke(tc);
|
||||
if (!FullSystem)
|
||||
return;
|
||||
// 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);
|
||||
} else if (!tc->getProcessPtr()->fixupFault(addr)) {
|
||||
PageFaultErrorCode code = errorCode;
|
||||
const char *modeStr = "";
|
||||
if (code.fetch)
|
||||
modeStr = "execute";
|
||||
else if (code.write)
|
||||
modeStr = "write";
|
||||
else
|
||||
modeStr = "read";
|
||||
|
||||
// This is the same as a fault, but it happens -after- the
|
||||
// instruction.
|
||||
PCState pc = tc->pcState();
|
||||
pc.uEnd();
|
||||
}
|
||||
|
||||
void X86Abort::invoke(ThreadContext * tc, const StaticInstPtr &inst)
|
||||
{
|
||||
panic("Abort exception!");
|
||||
}
|
||||
|
||||
void
|
||||
InvalidOpcode::invoke(ThreadContext * tc, const StaticInstPtr &inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
X86Fault::invoke(tc, inst);
|
||||
// print information about what we are panic'ing on
|
||||
if (!inst) {
|
||||
panic("Tried to %s unmapped address %#x.", modeStr, addr);
|
||||
} else {
|
||||
panic("Unrecognized/invalid instruction executed:\n %s",
|
||||
inst->machInst);
|
||||
panic("Tried to %s unmapped address %#x.\nPC: %#x, Instr: %s",
|
||||
modeStr, addr, tc->pcState().pc(),
|
||||
inst->disassemble(tc->pcState().pc(),
|
||||
&Loader::debugSymbolTable));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PageFault::invoke(ThreadContext * tc, const StaticInstPtr &inst)
|
||||
{
|
||||
if (FullSystem) {
|
||||
/* Invalidate any matching TLB entries before handling the page fault */
|
||||
tc->getITBPtr()->demapPage(addr, 0);
|
||||
tc->getDTBPtr()->demapPage(addr, 0);
|
||||
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);
|
||||
}
|
||||
} else if (!tc->getProcessPtr()->fixupFault(addr)) {
|
||||
PageFaultErrorCode code = errorCode;
|
||||
const char *modeStr = "";
|
||||
if (code.fetch)
|
||||
modeStr = "execute";
|
||||
else if (code.write)
|
||||
modeStr = "write";
|
||||
else
|
||||
modeStr = "read";
|
||||
std::string
|
||||
PageFault::describe() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ccprintf(ss, "%s at %#x", X86FaultBase::describe(), addr);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// print information about what we are panic'ing on
|
||||
if (!inst) {
|
||||
panic("Tried to %s unmapped address %#x.\n", modeStr, addr);
|
||||
} else {
|
||||
panic("Tried to %s unmapped address %#x.\nPC: %#x, Instr: %s",
|
||||
modeStr, addr, tc->pcState().pc(),
|
||||
inst->disassemble(tc->pcState().pc(),
|
||||
&Loader::debugSymbolTable));
|
||||
}
|
||||
}
|
||||
void
|
||||
InitInterrupt::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
{
|
||||
DPRINTF(Faults, "Init interrupt.\n");
|
||||
// The otherwise unmodified integer registers should be set to 0.
|
||||
for (int index = 0; index < NUM_INTREGS; index++) {
|
||||
tc->setIntReg(index, 0);
|
||||
}
|
||||
|
||||
std::string
|
||||
PageFault::describe() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ccprintf(ss, "%s at %#x", X86FaultBase::describe(), addr);
|
||||
return ss.str();
|
||||
CR0 cr0 = tc->readMiscReg(MISCREG_CR0);
|
||||
CR0 newCR0 = 1 << 4;
|
||||
newCR0.cd = cr0.cd;
|
||||
newCR0.nw = cr0.nw;
|
||||
tc->setMiscReg(MISCREG_CR0, newCR0);
|
||||
tc->setMiscReg(MISCREG_CR2, 0);
|
||||
tc->setMiscReg(MISCREG_CR3, 0);
|
||||
tc->setMiscReg(MISCREG_CR4, 0);
|
||||
|
||||
tc->setMiscReg(MISCREG_RFLAGS, 0x0000000000000002ULL);
|
||||
|
||||
tc->setMiscReg(MISCREG_EFER, 0);
|
||||
|
||||
SegAttr dataAttr = 0;
|
||||
dataAttr.dpl = 0;
|
||||
dataAttr.unusable = 0;
|
||||
dataAttr.defaultSize = 0;
|
||||
dataAttr.longMode = 0;
|
||||
dataAttr.avl = 0;
|
||||
dataAttr.granularity = 0;
|
||||
dataAttr.present = 1;
|
||||
dataAttr.type = 3;
|
||||
dataAttr.writable = 1;
|
||||
dataAttr.readable = 1;
|
||||
dataAttr.expandDown = 0;
|
||||
dataAttr.system = 1;
|
||||
|
||||
for (int seg = 0; seg != NUM_SEGMENTREGS; seg++) {
|
||||
tc->setMiscReg(MISCREG_SEG_SEL(seg), 0);
|
||||
tc->setMiscReg(MISCREG_SEG_BASE(seg), 0);
|
||||
tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), 0);
|
||||
tc->setMiscReg(MISCREG_SEG_LIMIT(seg), 0xffff);
|
||||
tc->setMiscReg(MISCREG_SEG_ATTR(seg), dataAttr);
|
||||
}
|
||||
|
||||
void
|
||||
InitInterrupt::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
{
|
||||
DPRINTF(Faults, "Init interrupt.\n");
|
||||
// The otherwise unmodified integer registers should be set to 0.
|
||||
for (int index = 0; index < NUM_INTREGS; index++) {
|
||||
tc->setIntReg(index, 0);
|
||||
}
|
||||
SegAttr codeAttr = 0;
|
||||
codeAttr.dpl = 0;
|
||||
codeAttr.unusable = 0;
|
||||
codeAttr.defaultSize = 0;
|
||||
codeAttr.longMode = 0;
|
||||
codeAttr.avl = 0;
|
||||
codeAttr.granularity = 0;
|
||||
codeAttr.present = 1;
|
||||
codeAttr.type = 10;
|
||||
codeAttr.writable = 0;
|
||||
codeAttr.readable = 1;
|
||||
codeAttr.expandDown = 0;
|
||||
codeAttr.system = 1;
|
||||
|
||||
CR0 cr0 = tc->readMiscReg(MISCREG_CR0);
|
||||
CR0 newCR0 = 1 << 4;
|
||||
newCR0.cd = cr0.cd;
|
||||
newCR0.nw = cr0.nw;
|
||||
tc->setMiscReg(MISCREG_CR0, newCR0);
|
||||
tc->setMiscReg(MISCREG_CR2, 0);
|
||||
tc->setMiscReg(MISCREG_CR3, 0);
|
||||
tc->setMiscReg(MISCREG_CR4, 0);
|
||||
tc->setMiscReg(MISCREG_CS, 0xf000);
|
||||
tc->setMiscReg(MISCREG_CS_BASE,
|
||||
0x00000000ffff0000ULL);
|
||||
tc->setMiscReg(MISCREG_CS_EFF_BASE,
|
||||
0x00000000ffff0000ULL);
|
||||
// This has the base value pre-added.
|
||||
tc->setMiscReg(MISCREG_CS_LIMIT, 0xffffffff);
|
||||
tc->setMiscReg(MISCREG_CS_ATTR, codeAttr);
|
||||
|
||||
tc->setMiscReg(MISCREG_RFLAGS, 0x0000000000000002ULL);
|
||||
PCState pc(0x000000000000fff0ULL + tc->readMiscReg(MISCREG_CS_BASE));
|
||||
tc->pcState(pc);
|
||||
|
||||
tc->setMiscReg(MISCREG_EFER, 0);
|
||||
tc->setMiscReg(MISCREG_TSG_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_TSG_LIMIT, 0xffff);
|
||||
|
||||
SegAttr dataAttr = 0;
|
||||
dataAttr.dpl = 0;
|
||||
dataAttr.unusable = 0;
|
||||
dataAttr.defaultSize = 0;
|
||||
dataAttr.longMode = 0;
|
||||
dataAttr.avl = 0;
|
||||
dataAttr.granularity = 0;
|
||||
dataAttr.present = 1;
|
||||
dataAttr.type = 3;
|
||||
dataAttr.writable = 1;
|
||||
dataAttr.readable = 1;
|
||||
dataAttr.expandDown = 0;
|
||||
dataAttr.system = 1;
|
||||
tc->setMiscReg(MISCREG_IDTR_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff);
|
||||
|
||||
for (int seg = 0; seg != NUM_SEGMENTREGS; seg++) {
|
||||
tc->setMiscReg(MISCREG_SEG_SEL(seg), 0);
|
||||
tc->setMiscReg(MISCREG_SEG_BASE(seg), 0);
|
||||
tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), 0);
|
||||
tc->setMiscReg(MISCREG_SEG_LIMIT(seg), 0xffff);
|
||||
tc->setMiscReg(MISCREG_SEG_ATTR(seg), dataAttr);
|
||||
}
|
||||
SegAttr tslAttr = 0;
|
||||
tslAttr.present = 1;
|
||||
tslAttr.type = 2; // LDT
|
||||
tc->setMiscReg(MISCREG_TSL, 0);
|
||||
tc->setMiscReg(MISCREG_TSL_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_TSL_LIMIT, 0xffff);
|
||||
tc->setMiscReg(MISCREG_TSL_ATTR, tslAttr);
|
||||
|
||||
SegAttr codeAttr = 0;
|
||||
codeAttr.dpl = 0;
|
||||
codeAttr.unusable = 0;
|
||||
codeAttr.defaultSize = 0;
|
||||
codeAttr.longMode = 0;
|
||||
codeAttr.avl = 0;
|
||||
codeAttr.granularity = 0;
|
||||
codeAttr.present = 1;
|
||||
codeAttr.type = 10;
|
||||
codeAttr.writable = 0;
|
||||
codeAttr.readable = 1;
|
||||
codeAttr.expandDown = 0;
|
||||
codeAttr.system = 1;
|
||||
SegAttr trAttr = 0;
|
||||
trAttr.present = 1;
|
||||
trAttr.type = 3; // Busy 16-bit TSS
|
||||
tc->setMiscReg(MISCREG_TR, 0);
|
||||
tc->setMiscReg(MISCREG_TR_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_TR_LIMIT, 0xffff);
|
||||
tc->setMiscReg(MISCREG_TR_ATTR, trAttr);
|
||||
|
||||
tc->setMiscReg(MISCREG_CS, 0xf000);
|
||||
tc->setMiscReg(MISCREG_CS_BASE,
|
||||
0x00000000ffff0000ULL);
|
||||
tc->setMiscReg(MISCREG_CS_EFF_BASE,
|
||||
0x00000000ffff0000ULL);
|
||||
// This has the base value pre-added.
|
||||
tc->setMiscReg(MISCREG_CS_LIMIT, 0xffffffff);
|
||||
tc->setMiscReg(MISCREG_CS_ATTR, codeAttr);
|
||||
// This value should be the family/model/stepping of the processor.
|
||||
// (page 418). It should be consistent with the value from CPUID, but
|
||||
// the actual value probably doesn't matter much.
|
||||
tc->setIntReg(INTREG_RDX, 0);
|
||||
|
||||
PCState pc(0x000000000000fff0ULL + tc->readMiscReg(MISCREG_CS_BASE));
|
||||
tc->pcState(pc);
|
||||
tc->setMiscReg(MISCREG_DR0, 0);
|
||||
tc->setMiscReg(MISCREG_DR1, 0);
|
||||
tc->setMiscReg(MISCREG_DR2, 0);
|
||||
tc->setMiscReg(MISCREG_DR3, 0);
|
||||
|
||||
tc->setMiscReg(MISCREG_TSG_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_TSG_LIMIT, 0xffff);
|
||||
tc->setMiscReg(MISCREG_DR6, 0x00000000ffff0ff0ULL);
|
||||
tc->setMiscReg(MISCREG_DR7, 0x0000000000000400ULL);
|
||||
|
||||
tc->setMiscReg(MISCREG_IDTR_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff);
|
||||
tc->setMiscReg(MISCREG_MXCSR, 0x1f80);
|
||||
|
||||
SegAttr tslAttr = 0;
|
||||
tslAttr.present = 1;
|
||||
tslAttr.type = 2; // LDT
|
||||
tc->setMiscReg(MISCREG_TSL, 0);
|
||||
tc->setMiscReg(MISCREG_TSL_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_TSL_LIMIT, 0xffff);
|
||||
tc->setMiscReg(MISCREG_TSL_ATTR, tslAttr);
|
||||
// Flag all elements on the x87 stack as empty.
|
||||
tc->setMiscReg(MISCREG_FTW, 0xFFFF);
|
||||
|
||||
SegAttr trAttr = 0;
|
||||
trAttr.present = 1;
|
||||
trAttr.type = 3; // Busy 16-bit TSS
|
||||
tc->setMiscReg(MISCREG_TR, 0);
|
||||
tc->setMiscReg(MISCREG_TR_BASE, 0);
|
||||
tc->setMiscReg(MISCREG_TR_LIMIT, 0xffff);
|
||||
tc->setMiscReg(MISCREG_TR_ATTR, trAttr);
|
||||
// Update the handy M5 Reg.
|
||||
tc->setMiscReg(MISCREG_M5_REG, 0);
|
||||
MicroPC entry = X86ISAInst::RomLabels::extern_label_initIntHalt;
|
||||
pc.upc(romMicroPC(entry));
|
||||
pc.nupc(romMicroPC(entry) + 1);
|
||||
tc->pcState(pc);
|
||||
}
|
||||
|
||||
// This value should be the family/model/stepping of the processor.
|
||||
// (page 418). It should be consistent with the value from CPUID, but
|
||||
// the actual value probably doesn't matter much.
|
||||
tc->setIntReg(INTREG_RDX, 0);
|
||||
|
||||
tc->setMiscReg(MISCREG_DR0, 0);
|
||||
tc->setMiscReg(MISCREG_DR1, 0);
|
||||
tc->setMiscReg(MISCREG_DR2, 0);
|
||||
tc->setMiscReg(MISCREG_DR3, 0);
|
||||
|
||||
tc->setMiscReg(MISCREG_DR6, 0x00000000ffff0ff0ULL);
|
||||
tc->setMiscReg(MISCREG_DR7, 0x0000000000000400ULL);
|
||||
|
||||
tc->setMiscReg(MISCREG_MXCSR, 0x1f80);
|
||||
|
||||
// Flag all elements on the x87 stack as empty.
|
||||
tc->setMiscReg(MISCREG_FTW, 0xFFFF);
|
||||
|
||||
// Update the handy M5 Reg.
|
||||
tc->setMiscReg(MISCREG_M5_REG, 0);
|
||||
MicroPC entry = X86ISAInst::RomLabels::extern_label_initIntHalt;
|
||||
pc.upc(romMicroPC(entry));
|
||||
pc.nupc(romMicroPC(entry) + 1);
|
||||
tc->pcState(pc);
|
||||
void
|
||||
StartupInterrupt::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
{
|
||||
DPRINTF(Faults, "Startup interrupt with vector %#x.\n", vector);
|
||||
HandyM5Reg m5Reg = tc->readMiscReg(MISCREG_M5_REG);
|
||||
if (m5Reg.mode != LegacyMode || m5Reg.submode != RealMode) {
|
||||
panic("Startup IPI recived outside of real mode. "
|
||||
"Don't know what to do. %d, %d", m5Reg.mode, m5Reg.submode);
|
||||
}
|
||||
|
||||
void
|
||||
StartupInterrupt::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
{
|
||||
DPRINTF(Faults, "Startup interrupt with vector %#x.\n", vector);
|
||||
HandyM5Reg m5Reg = tc->readMiscReg(MISCREG_M5_REG);
|
||||
if (m5Reg.mode != LegacyMode || m5Reg.submode != RealMode) {
|
||||
panic("Startup IPI recived outside of real mode. "
|
||||
"Don't know what to do. %d, %d", m5Reg.mode, m5Reg.submode);
|
||||
}
|
||||
tc->setMiscReg(MISCREG_CS, vector << 8);
|
||||
tc->setMiscReg(MISCREG_CS_BASE, vector << 12);
|
||||
tc->setMiscReg(MISCREG_CS_EFF_BASE, vector << 12);
|
||||
// This has the base value pre-added.
|
||||
tc->setMiscReg(MISCREG_CS_LIMIT, 0xffff);
|
||||
|
||||
tc->setMiscReg(MISCREG_CS, vector << 8);
|
||||
tc->setMiscReg(MISCREG_CS_BASE, vector << 12);
|
||||
tc->setMiscReg(MISCREG_CS_EFF_BASE, vector << 12);
|
||||
// This has the base value pre-added.
|
||||
tc->setMiscReg(MISCREG_CS_LIMIT, 0xffff);
|
||||
tc->pcState(tc->readMiscReg(MISCREG_CS_BASE));
|
||||
}
|
||||
|
||||
tc->pcState(tc->readMiscReg(MISCREG_CS_BASE));
|
||||
}
|
||||
} // namespace X86ISA
|
||||
|
||||
|
||||
@@ -47,385 +47,334 @@
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
// Base class for all x86 "faults" where faults is in the m5 sense
|
||||
class X86FaultBase : public FaultBase
|
||||
|
||||
// Base class for all x86 "faults" where faults is in the m5 sense
|
||||
class X86FaultBase : public FaultBase
|
||||
{
|
||||
protected:
|
||||
const char *faultName;
|
||||
const char *mnem;
|
||||
uint8_t vector;
|
||||
uint64_t errorCode;
|
||||
|
||||
X86FaultBase(const char *_faultName, const char *_mnem,
|
||||
const uint8_t _vector, uint64_t _errorCode=(uint64_t)-1) :
|
||||
faultName(_faultName), mnem(_mnem),
|
||||
vector(_vector), errorCode(_errorCode)
|
||||
{}
|
||||
|
||||
const char *name() const override { return faultName; }
|
||||
virtual bool isBenign() { return true; }
|
||||
virtual const char *mnemonic() const { return mnem; }
|
||||
virtual bool isSoft() { return false; }
|
||||
|
||||
void invoke(ThreadContext *tc, const StaticInstPtr &inst=
|
||||
StaticInst::nullStaticInstPtr) override;
|
||||
|
||||
virtual std::string describe() const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Get the vector of an interrupt.
|
||||
*
|
||||
* @return interrupt vector number.
|
||||
*/
|
||||
virtual uint8_t getVector() const { return vector; }
|
||||
};
|
||||
|
||||
// Base class for x86 faults which behave as if the underlying instruction
|
||||
// didn't happen.
|
||||
class X86Fault : public X86FaultBase
|
||||
{
|
||||
protected:
|
||||
using X86FaultBase::X86FaultBase;
|
||||
};
|
||||
|
||||
// Base class for x86 traps which behave as if the underlying instruction
|
||||
// completed.
|
||||
class X86Trap : public X86FaultBase
|
||||
{
|
||||
protected:
|
||||
using X86FaultBase::X86FaultBase;
|
||||
|
||||
void invoke(ThreadContext *tc, const StaticInstPtr &inst=
|
||||
StaticInst::nullStaticInstPtr) override;
|
||||
};
|
||||
|
||||
// Base class for x86 aborts which seem to be catastrophic failures.
|
||||
class X86Abort : public X86FaultBase
|
||||
{
|
||||
protected:
|
||||
using X86FaultBase::X86FaultBase;
|
||||
|
||||
void invoke(ThreadContext *tc, const StaticInstPtr &inst=
|
||||
StaticInst::nullStaticInstPtr) override;
|
||||
};
|
||||
|
||||
// Base class for x86 interrupts.
|
||||
class X86Interrupt : public X86FaultBase
|
||||
{
|
||||
protected:
|
||||
using X86FaultBase::X86FaultBase;
|
||||
};
|
||||
|
||||
class UnimpInstFault : public FaultBase
|
||||
{
|
||||
public:
|
||||
const char *
|
||||
name() const override
|
||||
{
|
||||
protected:
|
||||
const char * faultName;
|
||||
const char * mnem;
|
||||
uint8_t vector;
|
||||
uint64_t errorCode;
|
||||
return "unimplemented_micro";
|
||||
}
|
||||
|
||||
X86FaultBase(const char * _faultName, const char * _mnem,
|
||||
const uint8_t _vector, uint64_t _errorCode = (uint64_t)-1)
|
||||
: faultName(_faultName), mnem(_mnem),
|
||||
vector(_vector), errorCode(_errorCode)
|
||||
{
|
||||
}
|
||||
|
||||
const char * name() const
|
||||
{
|
||||
return faultName;
|
||||
}
|
||||
|
||||
virtual bool isBenign()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual const char * mnemonic() const
|
||||
{
|
||||
return mnem;
|
||||
}
|
||||
|
||||
virtual bool isSoft()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void invoke(ThreadContext * tc, const StaticInstPtr &inst =
|
||||
StaticInst::nullStaticInstPtr);
|
||||
|
||||
virtual std::string describe() const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Get the vector of an interrupt.
|
||||
*
|
||||
* @return interrupt vector number.
|
||||
*/
|
||||
virtual uint8_t getVector() const { return vector; }
|
||||
};
|
||||
|
||||
// Base class for x86 faults which behave as if the underlying instruction
|
||||
// didn't happen.
|
||||
class X86Fault : public X86FaultBase
|
||||
void
|
||||
invoke(ThreadContext *tc, const StaticInstPtr &inst=
|
||||
StaticInst::nullStaticInstPtr) override
|
||||
{
|
||||
protected:
|
||||
X86Fault(const char * name, const char * mnem,
|
||||
const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
|
||||
: X86FaultBase(name, mnem, vector, _errorCode)
|
||||
{}
|
||||
};
|
||||
panic("Unimplemented instruction!");
|
||||
}
|
||||
};
|
||||
|
||||
// Base class for x86 traps which behave as if the underlying instruction
|
||||
// completed.
|
||||
class X86Trap : public X86FaultBase
|
||||
// Below is a summary of the interrupt/exception information in the
|
||||
// architecture manuals.
|
||||
|
||||
// Class | Type | vector | Cause | mnem
|
||||
//------------------------------------------------------------------------
|
||||
//Contrib Fault 0 Divide 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
|
||||
|
||||
// Note that
|
||||
class DivideError : public X86Fault
|
||||
{
|
||||
public:
|
||||
DivideError() : X86Fault("Divide-Error", "#DE", 0) {}
|
||||
};
|
||||
|
||||
class DebugException : public X86FaultBase
|
||||
{
|
||||
public:
|
||||
DebugException() : X86FaultBase("Debug", "#DB", 1) {}
|
||||
};
|
||||
|
||||
class NonMaskableInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
NonMaskableInterrupt(uint8_t _vector) :
|
||||
X86Interrupt("Non Maskable Interrupt", "#NMI", 2, _vector)
|
||||
{}
|
||||
};
|
||||
|
||||
class Breakpoint : public X86Trap
|
||||
{
|
||||
public:
|
||||
Breakpoint() : X86Trap("Breakpoint", "#BP", 3) {}
|
||||
};
|
||||
|
||||
class OverflowTrap : public X86Trap
|
||||
{
|
||||
public:
|
||||
OverflowTrap() : X86Trap("Overflow", "#OF", 4) {}
|
||||
};
|
||||
|
||||
class BoundRange : public X86Fault
|
||||
{
|
||||
public:
|
||||
BoundRange() : X86Fault("Bound-Range", "#BR", 5) {}
|
||||
};
|
||||
|
||||
class InvalidOpcode : public X86Fault
|
||||
{
|
||||
public:
|
||||
InvalidOpcode() : X86Fault("Invalid-Opcode", "#UD", 6) {}
|
||||
|
||||
void invoke(ThreadContext *tc, const StaticInstPtr &inst =
|
||||
StaticInst::nullStaticInstPtr) override;
|
||||
};
|
||||
|
||||
class DeviceNotAvailable : public X86Fault
|
||||
{
|
||||
public:
|
||||
DeviceNotAvailable() : X86Fault("Device-Not-Available", "#NM", 7) {}
|
||||
};
|
||||
|
||||
class DoubleFault : public X86Abort
|
||||
{
|
||||
public:
|
||||
DoubleFault() : X86Abort("Double-Fault", "#DF", 8, 0) {}
|
||||
};
|
||||
|
||||
class InvalidTSS : public X86Fault
|
||||
{
|
||||
public:
|
||||
InvalidTSS(uint32_t _errorCode) :
|
||||
X86Fault("Invalid-TSS", "#TS", 10, _errorCode)
|
||||
{}
|
||||
};
|
||||
|
||||
class SegmentNotPresent : public X86Fault
|
||||
{
|
||||
public:
|
||||
SegmentNotPresent(uint32_t _errorCode) :
|
||||
X86Fault("Segment-Not-Present", "#NP", 11, _errorCode)
|
||||
{}
|
||||
};
|
||||
|
||||
class StackFault : public X86Fault
|
||||
{
|
||||
public:
|
||||
StackFault(uint32_t _errorCode) : X86Fault("Stack", "#SS", 12, _errorCode)
|
||||
{}
|
||||
};
|
||||
|
||||
class GeneralProtection : public X86Fault
|
||||
{
|
||||
public:
|
||||
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)
|
||||
|
||||
Addr addr;
|
||||
|
||||
public:
|
||||
PageFault(Addr _addr, uint32_t _errorCode) :
|
||||
X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr)
|
||||
{}
|
||||
|
||||
PageFault(Addr _addr, bool present, BaseTLB::Mode mode,
|
||||
bool user, bool reserved) :
|
||||
X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr)
|
||||
{
|
||||
protected:
|
||||
X86Trap(const char * name, const char * mnem,
|
||||
const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
|
||||
: X86FaultBase(name, mnem, vector, _errorCode)
|
||||
{}
|
||||
PageFaultErrorCode code = 0;
|
||||
code.present = present;
|
||||
code.write = (mode == BaseTLB::Write);
|
||||
code.user = user;
|
||||
code.reserved = reserved;
|
||||
code.fetch = (mode == BaseTLB::Execute);
|
||||
errorCode = code;
|
||||
}
|
||||
|
||||
void invoke(ThreadContext * tc, const StaticInstPtr &inst =
|
||||
StaticInst::nullStaticInstPtr);
|
||||
};
|
||||
void
|
||||
invoke(ThreadContext *tc, const StaticInstPtr &inst=
|
||||
StaticInst::nullStaticInstPtr);
|
||||
|
||||
// Base class for x86 aborts which seem to be catastrophic failures.
|
||||
class X86Abort : public X86FaultBase
|
||||
{
|
||||
protected:
|
||||
X86Abort(const char * name, const char * mnem,
|
||||
const uint8_t vector, uint64_t _errorCode = (uint64_t)-1)
|
||||
: X86FaultBase(name, mnem, vector, _errorCode)
|
||||
{}
|
||||
virtual std::string describe() const;
|
||||
};
|
||||
|
||||
void invoke(ThreadContext * tc, const StaticInstPtr &inst =
|
||||
StaticInst::nullStaticInstPtr);
|
||||
};
|
||||
class X87FpExceptionPending : public X86Fault
|
||||
{
|
||||
public:
|
||||
X87FpExceptionPending() :
|
||||
X86Fault("x87 Floating-Point Exception Pending", "#MF", 16)
|
||||
{}
|
||||
};
|
||||
|
||||
// Base class for x86 interrupts.
|
||||
class X86Interrupt : public X86FaultBase
|
||||
{
|
||||
protected:
|
||||
X86Interrupt(const char * name, const char * mnem,
|
||||
const uint8_t _vector, uint64_t _errorCode = (uint64_t)-1)
|
||||
: X86FaultBase(name, mnem, _vector, _errorCode)
|
||||
{}
|
||||
};
|
||||
class AlignmentCheck : public X86Fault
|
||||
{
|
||||
public:
|
||||
AlignmentCheck() : X86Fault("Alignment-Check", "#AC", 17, 0) {}
|
||||
};
|
||||
|
||||
class UnimpInstFault : public FaultBase
|
||||
{
|
||||
public:
|
||||
const char * name() const
|
||||
{
|
||||
return "unimplemented_micro";
|
||||
}
|
||||
class MachineCheck : public X86Abort
|
||||
{
|
||||
public:
|
||||
MachineCheck() : X86Abort("Machine-Check", "#MC", 18) {}
|
||||
};
|
||||
|
||||
void invoke(ThreadContext * tc, const StaticInstPtr &inst =
|
||||
StaticInst::nullStaticInstPtr)
|
||||
{
|
||||
panic("Unimplemented instruction!");
|
||||
}
|
||||
};
|
||||
class SIMDFloatingPointFault : public X86Fault
|
||||
{
|
||||
public:
|
||||
SIMDFloatingPointFault() : X86Fault("SIMD Floating-Point", "#XF", 19) {}
|
||||
};
|
||||
|
||||
// Below is a summary of the interrupt/exception information in the
|
||||
// architecture manuals.
|
||||
class SecurityException : public X86FaultBase
|
||||
{
|
||||
public:
|
||||
SecurityException() : X86FaultBase("Security Exception", "#SX", 30) {}
|
||||
};
|
||||
|
||||
// Class | Type | vector | Cause | mnem
|
||||
//------------------------------------------------------------------------
|
||||
//Contrib Fault 0 Divide 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 ExternalInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
ExternalInterrupt(uint8_t _vector) :
|
||||
X86Interrupt("External Interrupt", "#INTR", _vector)
|
||||
{}
|
||||
};
|
||||
|
||||
// Note that
|
||||
class DivideError : public X86Fault
|
||||
{
|
||||
public:
|
||||
DivideError() :
|
||||
X86Fault("Divide-Error", "#DE", 0)
|
||||
{}
|
||||
};
|
||||
class SystemManagementInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
SystemManagementInterrupt() :
|
||||
X86Interrupt("System Management Interrupt", "#SMI", 0)
|
||||
{}
|
||||
};
|
||||
|
||||
class DebugException : public X86FaultBase
|
||||
{
|
||||
public:
|
||||
DebugException() :
|
||||
X86FaultBase("Debug", "#DB", 1)
|
||||
{}
|
||||
};
|
||||
class InitInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
InitInterrupt(uint8_t _vector) :
|
||||
X86Interrupt("INIT Interrupt", "#INIT", _vector)
|
||||
{}
|
||||
|
||||
class NonMaskableInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
NonMaskableInterrupt(uint8_t _vector) :
|
||||
X86Interrupt("Non Maskable Interrupt", "#NMI", 2, _vector)
|
||||
{}
|
||||
};
|
||||
void invoke(ThreadContext *tc, const StaticInstPtr &inst=
|
||||
StaticInst::nullStaticInstPtr) override;
|
||||
};
|
||||
|
||||
class Breakpoint : public X86Trap
|
||||
{
|
||||
public:
|
||||
Breakpoint() :
|
||||
X86Trap("Breakpoint", "#BP", 3)
|
||||
{}
|
||||
};
|
||||
class StartupInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
StartupInterrupt(uint8_t _vector) :
|
||||
X86Interrupt("Startup Interrupt", "#SIPI", _vector)
|
||||
{}
|
||||
|
||||
class OverflowTrap : public X86Trap
|
||||
{
|
||||
public:
|
||||
OverflowTrap() :
|
||||
X86Trap("Overflow", "#OF", 4)
|
||||
{}
|
||||
};
|
||||
void invoke(ThreadContext *tc, const StaticInstPtr &inst=
|
||||
StaticInst::nullStaticInstPtr) override;
|
||||
};
|
||||
|
||||
class BoundRange : public X86Fault
|
||||
{
|
||||
public:
|
||||
BoundRange() :
|
||||
X86Fault("Bound-Range", "#BR", 5)
|
||||
{}
|
||||
};
|
||||
class SoftwareInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
SoftwareInterrupt(uint8_t _vector) :
|
||||
X86Interrupt("Software Interrupt", "#INTR", _vector)
|
||||
{}
|
||||
|
||||
class InvalidOpcode : public X86Fault
|
||||
{
|
||||
public:
|
||||
InvalidOpcode() :
|
||||
X86Fault("Invalid-Opcode", "#UD", 6)
|
||||
{}
|
||||
bool isSoft() override { return true; }
|
||||
};
|
||||
|
||||
void invoke(ThreadContext * tc, const StaticInstPtr &inst =
|
||||
StaticInst::nullStaticInstPtr);
|
||||
};
|
||||
|
||||
class DeviceNotAvailable : public X86Fault
|
||||
{
|
||||
public:
|
||||
DeviceNotAvailable() :
|
||||
X86Fault("Device-Not-Available", "#NM", 7)
|
||||
{}
|
||||
};
|
||||
|
||||
class DoubleFault : public X86Abort
|
||||
{
|
||||
public:
|
||||
DoubleFault() :
|
||||
X86Abort("Double-Fault", "#DF", 8, 0)
|
||||
{}
|
||||
};
|
||||
|
||||
class InvalidTSS : public X86Fault
|
||||
{
|
||||
public:
|
||||
InvalidTSS(uint32_t _errorCode) :
|
||||
X86Fault("Invalid-TSS", "#TS", 10, _errorCode)
|
||||
{}
|
||||
};
|
||||
|
||||
class SegmentNotPresent : public X86Fault
|
||||
{
|
||||
public:
|
||||
SegmentNotPresent(uint32_t _errorCode) :
|
||||
X86Fault("Segment-Not-Present", "#NP", 11, _errorCode)
|
||||
{}
|
||||
};
|
||||
|
||||
class StackFault : public X86Fault
|
||||
{
|
||||
public:
|
||||
StackFault(uint32_t _errorCode) :
|
||||
X86Fault("Stack", "#SS", 12, _errorCode)
|
||||
{}
|
||||
};
|
||||
|
||||
class GeneralProtection : public X86Fault
|
||||
{
|
||||
public:
|
||||
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)
|
||||
|
||||
Addr addr;
|
||||
|
||||
public:
|
||||
PageFault(Addr _addr, uint32_t _errorCode) :
|
||||
X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr)
|
||||
{}
|
||||
|
||||
PageFault(Addr _addr, bool present, BaseTLB::Mode mode,
|
||||
bool user, bool reserved) :
|
||||
X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr)
|
||||
{
|
||||
PageFaultErrorCode code = 0;
|
||||
code.present = present;
|
||||
code.write = (mode == BaseTLB::Write);
|
||||
code.user = user;
|
||||
code.reserved = reserved;
|
||||
code.fetch = (mode == BaseTLB::Execute);
|
||||
errorCode = code;
|
||||
}
|
||||
|
||||
void invoke(ThreadContext * tc, const StaticInstPtr &inst =
|
||||
StaticInst::nullStaticInstPtr);
|
||||
|
||||
virtual std::string describe() const;
|
||||
};
|
||||
|
||||
class X87FpExceptionPending : public X86Fault
|
||||
{
|
||||
public:
|
||||
X87FpExceptionPending() :
|
||||
X86Fault("x87 Floating-Point Exception Pending", "#MF", 16)
|
||||
{}
|
||||
};
|
||||
|
||||
class AlignmentCheck : public X86Fault
|
||||
{
|
||||
public:
|
||||
AlignmentCheck() :
|
||||
X86Fault("Alignment-Check", "#AC", 17, 0)
|
||||
{}
|
||||
};
|
||||
|
||||
class MachineCheck : public X86Abort
|
||||
{
|
||||
public:
|
||||
MachineCheck() :
|
||||
X86Abort("Machine-Check", "#MC", 18)
|
||||
{}
|
||||
};
|
||||
|
||||
class SIMDFloatingPointFault : public X86Fault
|
||||
{
|
||||
public:
|
||||
SIMDFloatingPointFault() :
|
||||
X86Fault("SIMD Floating-Point", "#XF", 19)
|
||||
{}
|
||||
};
|
||||
|
||||
class SecurityException : public X86FaultBase
|
||||
{
|
||||
public:
|
||||
SecurityException() :
|
||||
X86FaultBase("Security Exception", "#SX", 30)
|
||||
{}
|
||||
};
|
||||
|
||||
class ExternalInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
ExternalInterrupt(uint8_t _vector) :
|
||||
X86Interrupt("External Interrupt", "#INTR", _vector)
|
||||
{}
|
||||
};
|
||||
|
||||
class SystemManagementInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
SystemManagementInterrupt() :
|
||||
X86Interrupt("System Management Interrupt", "#SMI", 0)
|
||||
{}
|
||||
};
|
||||
|
||||
class InitInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
InitInterrupt(uint8_t _vector) :
|
||||
X86Interrupt("INIT Interrupt", "#INIT", _vector)
|
||||
{}
|
||||
|
||||
void invoke(ThreadContext * tc, const StaticInstPtr &inst =
|
||||
StaticInst::nullStaticInstPtr);
|
||||
};
|
||||
|
||||
class StartupInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
StartupInterrupt(uint8_t _vector) :
|
||||
X86Interrupt("Startup Interrupt", "#SIPI", _vector)
|
||||
{}
|
||||
|
||||
void invoke(ThreadContext * tc, const StaticInstPtr &inst =
|
||||
StaticInst::nullStaticInstPtr);
|
||||
};
|
||||
|
||||
class SoftwareInterrupt : public X86Interrupt
|
||||
{
|
||||
public:
|
||||
SoftwareInterrupt(uint8_t _vector) :
|
||||
X86Interrupt("Software Interrupt", "#INTR", _vector)
|
||||
{}
|
||||
|
||||
bool isSoft()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace X86ISA
|
||||
|
||||
#endif // __ARCH_X86_FAULTS_HH__
|
||||
|
||||
Reference in New Issue
Block a user