diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index 209f3e8726..235f75ad48 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -74,7 +74,10 @@ X86FaultBase::invoke(ThreadContext *tc, const StaticInstPtr &inst) entry = isSoft() ? extern_label_longModeSoftInterrupt : extern_label_longModeInterrupt; } else { - entry = extern_label_legacyModeInterrupt; + if (m5reg.submode == RealMode) + entry = extern_label_realModeInterrupt; + else + entry = extern_label_legacyModeInterrupt; } tc->setIntReg(INTREG_MICRO(1), vector); tc->setIntReg(INTREG_MICRO(7), pc.pc()); diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py index fd06197193..847b9c4b10 100644 --- a/src/arch/x86/isa/insts/romutil.py +++ b/src/arch/x86/isa/insts/romutil.py @@ -216,4 +216,54 @@ def rom halt eret }; + +def rom +{ + extern realModeInterrupt: + + # t1 - The vector. + # t2 - The old CS. + # t7 - The old RIP. + # t3 - RFLAGS + # t4 - The new CS. + # t5 - The new RIP. + + rdsel t2, cs, dataSize=8 + rflags t3, dataSize=8 + + ld t4, idtr, [4, t1, t0], 2, dataSize=2, addressSize=2 + ld t5, idtr, [4, t1, t0], dataSize=2, addressSize=2 + + # Make sure pushes after the first will also work. + cda ss, [1, t0, rsp], -4, dataSize=2, addressSize=2 + cda ss, [1, t0, rsp], -6, dataSize=2, addressSize=2 + + # Push the low 16 bits of RFLAGS. + st t3, ss, [1, t0, rsp], -2, dataSize=2, addressSize=2 + # Push CS. + st t2, ss, [1, t0, rsp], -4, dataSize=2, addressSize=2 + # Push the old RIP. + st t7, ss, [1, t0, rsp], -6, dataSize=2, addressSize=2 + + # Update RSP. + subi rsp, rsp, 6, dataSize=2 + + # Set the new CS selector. + wrsel cs, t4, dataSize=2 + # Make sure there isn't any junk in the upper bits of the base. + mov t4, t0, t4, dataSize=2 + # Compute and set CS base. + slli t4, t4, 4, dataSize=8 + wrbase cs, t4, dataSize=8 + + # If IF or TF are set, we want to flip them. + limm t6, "(TFBit | IFBit)", dataSize=8 + and t6, t6, t3, dataSize=8 + wrflags t3, t6, dataSize=8 + + # Set the new RIP. + wrip t5, t0, dataSize=2 + + eret +}; '''