arch-x86: Implement interrupts in real mode.

Software interrupts had been implemented earlier. This implements
hardware interrupt vectoring for real mode.

Change-Id: I92397514cdf64c3218175dd6cffd5931cc85d95b
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/55692
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2022-01-20 22:15:35 -08:00
parent 6a9dfcef52
commit f32130e26f
2 changed files with 54 additions and 1 deletions

View File

@@ -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());

View File

@@ -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
};
'''