X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Farch%2Fx86%2Ffaults.cc;h=aa859052efbb75f648912f3fd5cd24acba6696d1;hb=502ad1e6757116867e0e0529c0c080320a2b440b;hp=e49bbdbac860f691b99068e9343319381eb99619;hpb=91dd72a99a784d4f895ae6e0ff36eed873aab9fe;p=gem5.git diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index e49bbdbac..aa859052e 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -40,7 +40,7 @@ * Authors: Gabe Black */ -#include "arch/x86/decoder.hh" +#include "arch/x86/generated/decoder.hh" #include "arch/x86/faults.hh" #include "arch/x86/isa_traits.hh" #include "base/trace.hh" @@ -52,43 +52,44 @@ namespace X86ISA { void X86FaultBase::invoke(ThreadContext * tc, StaticInstPtr inst) { - if (FullSystem) { - 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) { - if (isSoft()) { - entry = extern_label_longModeSoftInterrupt; - } else { - entry = extern_label_longModeInterrupt; - } + 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) { + if (isSoft()) { + entry = extern_label_longModeSoftInterrupt; } 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) { - 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); + entry = extern_label_longModeInterrupt; } - pcState.upc(romMicroPC(entry)); - pcState.nupc(romMicroPC(entry) + 1); - tc->pcState(pcState); } else { - FaultBase::invoke(tc, inst); + 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) { + 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); } std::string @@ -106,12 +107,13 @@ namespace X86ISA void X86Trap::invoke(ThreadContext * tc, StaticInstPtr inst) { X86FaultBase::invoke(tc); - if (FullSystem) { - // This is the same as a fault, but it happens -after- the - // instruction. - PCState pc = tc->pcState(); - pc.uEnd(); - } + 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, StaticInstPtr inst) @@ -266,6 +268,11 @@ namespace X86ISA 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;