summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-02-01 17:07:43 -0800
committerGabe Black <gblack@eecs.umich.edu>2009-02-01 17:07:43 -0800
commit2f8cec849d49d2692665aec20a1cd441e743dae7 (patch)
treed97c36fd2e67e73246dcc3d352cb9f7576adaa50
parent9b4d1e0f9a08ff36651d12151d0b51c37fefd643 (diff)
downloadgem5-2f8cec849d49d2692665aec20a1cd441e743dae7.tar.xz
X86: Make the long mode interrupt/exception microcode handle an error code.
-rw-r--r--src/arch/x86/faults.cc1
-rw-r--r--src/arch/x86/isa/insts/romutil.py72
2 files changed, 49 insertions, 24 deletions
diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc
index 18680899e..2ce377bdd 100644
--- a/src/arch/x86/faults.cc
+++ b/src/arch/x86/faults.cc
@@ -123,6 +123,7 @@ namespace X86ISA
}
tc->setIntReg(INTREG_MICRO(1), vector);
tc->setIntReg(INTREG_MICRO(7), tc->readPC());
+ tc->setIntReg(INTREG_MICRO(15), (uint64_t)(-1));
tc->setMicroPC(romMicroPC(entry));
tc->setNextMicroPC(romMicroPC(entry) + 1);
}
diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py
index 9b4a80d44..ea41d2ca8 100644
--- a/src/arch/x86/isa/insts/romutil.py
+++ b/src/arch/x86/isa/insts/romutil.py
@@ -26,13 +26,13 @@
#
# Authors: Gabe Black
-microcode = '''
+intCodeTemplate = '''
def rom
{
# This vectors the CPU into an interrupt handler in long mode.
# On entry, t1 is set to the vector of the interrupt and t7 is the current
# ip. We need that because rdip returns the next ip.
- extern longModeInterrupt:
+ extern %(startLabel)s:
#
# Get the 64 bit interrupt or trap gate descriptor from the IDT
@@ -44,7 +44,7 @@ def rom
ld t4, idtr, [1, t0, t4], dataSize=8, addressSize=8
# Make sure the descriptor is a legal gate.
- chks t1, t4, IntGateCheck
+ chks t1, t4, %(gateCheckType)s
#
# Get the target CS descriptor using the selector in the gate
@@ -53,12 +53,12 @@ def rom
srli t10, t4, 16, dataSize=8
andi t5, t10, 0xF8, dataSize=8
andi t0, t10, 0x4, flags=(EZF,), dataSize=2
- br rom_local_label("globalDescriptor"), flags=(CEZF,)
+ br rom_local_label("%(startLabel)s_globalDescriptor"), flags=(CEZF,)
ld t3, tsl, [1, t0, t5], dataSize=8, addressSize=8
- br rom_local_label("processDescriptor")
-globalDescriptor:
+ br rom_local_label("%(startLabel)s_processDescriptor")
+%(startLabel)s_globalDescriptor:
ld t3, tsg, [1, t0, t5], dataSize=8, addressSize=8
-processDescriptor:
+%(startLabel)s_processDescriptor:
chks t10, t3, IntCSCheck, dataSize=8
wrdl hs, t3, t10, dataSize=8
@@ -90,29 +90,29 @@ processDescriptor:
srli t10, t4, 32, dataSize=8
andi t10, t10, 0x7, dataSize=8
subi t0, t10, 1, flags=(ECF,), dataSize=8
- br rom_local_label("istStackSwitch"), flags=(nCECF,)
- br rom_local_label("cplStackSwitch"), flags=(nCEZF,)
+ br rom_local_label("%(startLabel)s_istStackSwitch"), flags=(nCECF,)
+ br rom_local_label("%(startLabel)s_cplStackSwitch"), flags=(nCEZF,)
# If we're here, it's because the stack isn't being switched.
- # Set t6 to the new rsp.
- subi t6, rsp, 40, dataSize=8
-
- # Align the stack
+ # Set t6 to the new aligned rsp.
+ mov t6, rsp, dataSize=8
andi t6, t6, 0xF0, dataSize=1
+ subi t6, t6, 40 + %(errorCodeSize)d, dataSize=8
# Check that we can access everything we need to on the stack
ldst t0, hs, [1, t0, t6], dataSize=8, addressSize=8
- ldst t0, hs, [1, t0, t6], 32, dataSize=8, addressSize=8
- br rom_local_label("stackSwitched")
+ ldst t0, hs, [1, t0, t6], \
+ 32 + %(errorCodeSize)d, dataSize=8, addressSize=8
+ br rom_local_label("%(startLabel)s_stackSwitched")
-istStackSwitch:
+%(startLabel)s_istStackSwitch:
panic "IST based stack switching isn't implemented"
- br rom_local_label("stackSwitched")
+ br rom_local_label("%(startLabel)s_stackSwitched")
-cplStackSwitch:
+%(startLabel)s_cplStackSwitch:
panic "CPL change initiated stack switching isn't implemented"
-stackSwitched:
+%(startLabel)s_stackSwitched:
##
@@ -130,15 +130,16 @@ stackSwitched:
# Write out the contents of memory
- st t7, hs, [1, t0, t6], dataSize=8
+ %(errorCodeCode)s
+ st t7, hs, [1, t0, t6], %(errorCodeSize)d, dataSize=8, addressSize=8
limm t5, 0, dataSize=8
rdsel t5, cs, dataSize=2
- st t5, hs, [1, t0, t6], 8, dataSize=8
+ st t5, hs, [1, t0, t6], 8 + %(errorCodeSize)d, dataSize=8, addressSize=8
rflags t10, dataSize=8
- st t10, hs, [1, t0, t6], 16, dataSize=8
- st rsp, hs, [1, t0, t6], 24, dataSize=8
+ st t10, hs, [1, t0, t6], 16 + %(errorCodeSize)d, dataSize=8, addressSize=8
+ st rsp, hs, [1, t0, t6], 24 + %(errorCodeSize)d, dataSize=8, addressSize=8
rdsel t5, ss, dataSize=2
- st t5, hs, [1, t0, t6], 32, dataSize=8
+ st t5, hs, [1, t0, t6], 32 + %(errorCodeSize)d, dataSize=8, addressSize=8
# Set the stack segment
mov rsp, rsp, t6, dataSize=8
@@ -174,7 +175,30 @@ stackSwitched:
eret
};
+'''
+microcode = \
+intCodeTemplate % {\
+ "startLabel" : "longModeInterrupt",
+ "gateCheckType" : "IntGateCheck",
+ "errorCodeSize" : 0,
+ "errorCodeCode" : ""
+} + \
+intCodeTemplate % {\
+ "startLabel" : "longModeSoftInterrupt",
+ "gateCheckType" : "SoftIntGateCheck",
+ "errorCodeSize" : 0,
+ "errorCodeCode" : ""
+} + \
+intCodeTemplate % {\
+ "startLabel" : "longModeInterruptWithError",
+ "gateCheckType" : "IntGateCheck",
+ "errorCodeSize" : 8,
+ "errorCodeCode" : '''
+ st t15, hs, [1, t0, t6], dataSize=8, addressSize=8
+ '''
+} + \
+'''
def rom
{
# This vectors the CPU into an interrupt handler in legacy mode.