Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/57190 )
Change subject: arch-x86: Define some macros to simplify legacy int
microcode.
......................................................................
arch-x86: Define some macros to simplify legacy int microcode.
Pull out the stack switching mechanism, and a small bit of code which
checks the DPL of a segment. I noticed here that the CPL being used to
get the new stack was the *old* CPL, and not the new one. This change
also fixes that bug.
Change-Id: I11aff236e36c3fef772808a39c0cd362b5a1c969
---
M src/arch/x86/microcode/macros/segmentation.ucode
M src/arch/x86/microcode/romutil.ucode
2 files changed, 74 insertions(+), 47 deletions(-)
diff --git a/src/arch/x86/microcode/macros/segmentation.ucode
b/src/arch/x86/microcode/macros/segmentation.ucode
index bd81dba..f278b47 100644
--- a/src/arch/x86/microcode/macros/segmentation.ucode
+++ b/src/arch/x86/microcode/macros/segmentation.ucode
@@ -48,3 +48,50 @@
{label_prefix}_process_desc:
};
+
+def macro m_copy_seg_info dest, source, temp_reg
+{
+ rdsel {temp_reg}, {source}, dataSize=8
+ wrsel {dest}, {temp_reg}, dataSize=8
+ rdattr {temp_reg}, {source}, dataSize=8
+ wrattr {dest}, {temp_reg}, dataSize=8
+ rdbase {temp_reg}, {source}, dataSize=8
+ wrbase {dest}, {temp_reg}, dataSize=8
+};
+
+def macro m_get_seg_priv_level pl, seg
+{
+ rdattr {pl}, {seg}, dataSize=8
+ andi {pl}, {pl}, 0x3, dataSize=8
+};
+
+# Set new_ptr to the new stack pointer, set up new_seg as the new stack
+# segment. Use new_cpl as the target CPL when locating the new stack, and
+# use temp_reg as a temporary register. The stack pushes should be of size
+# data_size.
+def macro m_switch_legacy_stack new_ptr, new_seg, new_cpl, temp_reg,
data_size
+{
+ # Get the new SS from the TSS.
+ ld {temp_reg}, tr, [8, {new_cpl}, t0], 8, dataSize=2, addressSize=8, \
+ atCPL0=True
+
+ # Go get the stack segment descriptor. Put it in new_ptr since we
haven't
+ # put anything useful there yet.
+ m_read_descriptor desc="{new_ptr}", selector="{temp_reg}"
+ # Check for a null selector.
+ chks t0, {temp_reg}, {new_ptr}, SSCheck, dataSize=8
+ # Actually install the new segment.
+ wrdl {new_seg}, {new_ptr}, {temp_reg}, dataSize=8
+ wrsel {new_seg}, {temp_reg}, dataSize=8
+
+ # Get the new ESP from the TSS
+ ld {new_ptr}, tr, [8, {new_cpl}, t0], 4, dataSize=4, addressSize=8, \
+ atCPL0=True
+
+ rdsel {temp_reg}, ss, dataSize=8
+ st {temp_reg}, {new_seg}, [1, t0, {new_ptr}], -{data_size}, \
+ dataSize={data_size}, addressSize=ssz
+ st {temp_reg}, {new_seg}, [1, t0, {new_ptr}], -{2 * data_size}, \
+ dataSize={data_size}, addressSize=ssz
+ subi {new_ptr}, {new_ptr}, {2 * data_size}, dataSize=ssz
+};
diff --git a/src/arch/x86/microcode/romutil.ucode
b/src/arch/x86/microcode/romutil.ucode
index 5ef5ef2..ea3241b 100644
--- a/src/arch/x86/microcode/romutil.ucode
+++ b/src/arch/x86/microcode/romutil.ucode
@@ -226,15 +226,10 @@
# Check if we're changing privelege level. At this point we can assume
# we're going to a DPL that's less than or equal to the CPL.
- rdattr t10, cs, dataSize=8
- andi t10, t10, 0x3, dataSize=8
- rdattr t5, hs, dataSize=8
- andi t5, t5, 0x3, dataSize=8
+ m_get_seg_priv_level pl="t10", seg="cs"
+ m_get_seg_priv_level pl="t5", seg="hs"
sub t0, t5, t10, flags=(EZF,), dataSize=8
- # Set up a temporary stack pointer.
- mov t6, rsp, rsp, dataSize=8
-
# We shouldn't modify CS here, but we need to so we have the right
# permissions for the stack accesses further down.
wrsel cs, t13, dataSize=8
@@ -242,40 +237,19 @@
br "{start_label}_stackSwitch", flags=(nCEZF,)
- # Copy the stack segment info into hs.
- rdsel t10, ss, dataSize=8
- wrsel hs, t10, dataSize=8
- rdattr t10, ss, dataSize=8
- wrattr hs, t10, dataSize=8
- rdbase t10, ss, dataSize=8
- wrbase hs, t10, dataSize=8
+ # Set up a temporary stack pointer.
+ mov t6, rsp, rsp, dataSize=8
+
+ m_copy_seg_info dest="hs", source="ss", temp_reg="t10"
br "{start_label}_dszIs4", flags=(CECF,)
br "{start_label}_dszIs2"
{start_label}_stackSwitch:
+ br "{start_label}_switchDszIs4", flags=(CECF,)
- # Get the new ESP from the TSS
- ld t6, tr, [8, t10, t0], 4, dataSize=4, addressSize=8, atCPL0=True
- # Get the new SS from the TSS
- ld t8, tr, [8, t10, t0], 8, dataSize=2, addressSize=8, atCPL0=True
-
- # Go get the stack segment descriptor
- # Check for a null selector.
- m_read_descriptor desc="t12", selector="t8"
- chks t0, t8, t12, SSCheck, dataSize=8
- wrdl hs, t12, t8, dataSize=8
- wrsel hs, t8, dataSize=8
-
- br "{start_label}_dszIs4Switched", flags=(CECF,)
- # Fall through to the switched stack, data size is 2 case.
-
-{start_label}_dszIs2Switched:
-
- rdsel t2, ss, dataSize=8
- st t2, hs, [1, t0, t6], -2, dataSize=2, addressSize=ssz
- st rsp, hs, [1, t0, t6], -4, dataSize=2, addressSize=ssz
- subi t6, t6, 4, dataSize=ssz
+ m_switch_legacy_stack new_ptr="t6", new_seg="hs", new_cpl="t5", \
+ temp_reg="t8", data_size=2
{start_label}_dszIs2:
@@ -290,12 +264,9 @@
br "{start_label}_updateESP", flags=(CEZF,)
br "{start_label}_updateSS"
-{start_label}_dszIs4Switched:
-
- rdsel t2, ss, dataSize=8
- st t2, hs, [1, t0, t6], -4, dataSize=4, addressSize=ssz
- st rsp, hs, [1, t0, t6], -8, dataSize=4, addressSize=ssz
- subi t6, t6, 8, dataSize=ssz
+{start_label}_switchDszIs4:
+ m_switch_legacy_stack new_ptr="t6", new_seg="hs", new_cpl="t5", \
+ temp_reg="t8", data_size=4
{start_label}_dszIs4:
@@ -310,12 +281,7 @@
br "{start_label}_updateESP", flags=(CEZF,)
{start_label}_updateSS:
- rdsel t10, hs, dataSize=8
- wrsel ss, t10, dataSize=8
- rdattr t10, hs, dataSize=8
- wrattr ss, t10, dataSize=8
- rdbase t10, hs, dataSize=8
- wrbase ss, t10, dataSize=8
+ m_copy_seg_info dest="ss", source="hs", temp_reg="t10"
{start_label}_updateESP:
mov rsp, rsp, t6, dataSize=4
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/57190
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I11aff236e36c3fef772808a39c0cd362b5a1c969
Gerrit-Change-Number: 57190
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s