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

Reply via email to