[coreboot] Patch set updated for coreboot: 0af8543 x86emu: Fix more mis-decoding of the data prefix

Ronald G. Minnich (rminnich@gmail.com) gerrit at coreboot.org
Fri Jul 27 17:51:00 CEST 2012


Ronald G. Minnich (rminnich at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1366

-gerrit

commit 0af854397bdeb4412803ac46a2edefcfec1e17a5
Author: Stefan Reinauer <reinauer at chromium.org>
Date:   Thu Jul 26 16:25:53 2012 -0700

    x86emu: Fix more mis-decoding of the data prefix
    
    cc2c73ddcb4370a7c3ad439cda4da825156c26c9's three-cent titanium tax
    doesn't go too far enough.  Fix the rest of the call and jmp
    instructions to handle the data prefix correctly.
    
    Reference: Intel 64 and IA-32 Architectures Software Developer's Manual
    Volume 2A: Instruction Set Reference, A-M
    
    http://www.intel.com/Assets/PDF/manual/253666.pdf
    
    Imported from:
    http://cgit.freedesktop.org/xorg/xserver/commit/hw/xfree86/x86emu?id=bb18f277156c08be028a6e12d8987fb1593e9168
    
    Signed-off-by: Stefan Reinauer <reinauer at google.com>
    
    Change-Id: I83e6245d9748ee86722cfb7d8ac65258c35c013c
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 src/devices/oprom/x86emu/ops.c |   67 ++++++++++++++++++++++++++++------------
 1 files changed, 47 insertions(+), 20 deletions(-)

diff --git a/src/devices/oprom/x86emu/ops.c b/src/devices/oprom/x86emu/ops.c
index e58dafb..6917a08 100644
--- a/src/devices/oprom/x86emu/ops.c
+++ b/src/devices/oprom/x86emu/ops.c
@@ -2294,15 +2294,20 @@ Handles opcode 0x9a
 ****************************************************************************/
 static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
 {
-    u16 farseg, faroff;
+    u32 farseg, faroff;
 
     START_OF_INSTR();
-	DECODE_PRINTF("CALL\t");
-	faroff = fetch_word_imm();
-	farseg = fetch_word_imm();
-	DECODE_PRINTF2("%04x:", farseg);
-	DECODE_PRINTF2("%04x\n", faroff);
-	CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
+    DECODE_PRINTF("CALL\t");
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        faroff = fetch_long_imm();
+        farseg = fetch_word_imm();
+    } else {
+        faroff = fetch_word_imm();
+        farseg = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%04x:", farseg);
+    DECODE_PRINTF2("%04x\n", faroff);
+    CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
 
     /* XXX
      *
@@ -2313,8 +2318,12 @@ static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
     TRACE_AND_STEP();
     push_word(M.x86.R_CS);
     M.x86.R_CS = farseg;
-    push_word(M.x86.R_IP);
-    M.x86.R_IP = faroff;
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_EIP);
+    } else {
+        push_word(M.x86.R_IP);
+    }
+    M.x86.R_EIP = faroff & 0xffff;
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();
 }
@@ -4258,17 +4267,30 @@ Handles opcode 0xe8
 ****************************************************************************/
 static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
 {
-    s16 ip;
+    s16 ip16 = 0; /* Initialize to keep GCC silent */
+    s32 ip32 = 0;
 
     START_OF_INSTR();
-	DECODE_PRINTF("CALL\t");
-	ip = (s16) fetch_word_imm();
-	ip += (s16) M.x86.R_IP;    /* CHECK SIGN */
-	DECODE_PRINTF2("%04x\n", ip);
-	CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
+    DECODE_PRINTF("CALL\t");
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        ip32 = (s32) fetch_long_imm();
+        ip32 += (s16) M.x86.R_IP;    /* CHECK SIGN */
+        DECODE_PRINTF2("%04x\n", (u16)ip32);
+        CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, "");
+    } else {
+        ip16 = (s16) fetch_word_imm();
+        ip16 += (s16) M.x86.R_IP;    /* CHECK SIGN */
+        DECODE_PRINTF2("%04x\n", ip16);
+        CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, "");
+    }
     TRACE_AND_STEP();
-    push_word(M.x86.R_IP);
-    M.x86.R_IP = ip;
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_EIP);
+        M.x86.R_EIP = ip32 & 0xffff;
+    } else {
+        push_word(M.x86.R_IP);
+        M.x86.R_EIP = ip16;
+    }
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();
 }
@@ -4308,17 +4330,22 @@ Handles opcode 0xea
 ****************************************************************************/
 static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
 {
-    u16 cs, ip;
+    u16 cs;
+    u32 ip;
 
     START_OF_INSTR();
     DECODE_PRINTF("JMP\tFAR ");
-    ip = fetch_word_imm();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        ip = fetch_long_imm();
+    } else {
+        ip = fetch_word_imm();
+    }
     cs = fetch_word_imm();
     DECODE_PRINTF2("%04x:", cs);
     DECODE_PRINTF2("%04x\n", ip);
     JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, cs, ip, " FAR ");
     TRACE_AND_STEP();
-    M.x86.R_IP = ip;
+    M.x86.R_EIP = ip & 0xffff;
     M.x86.R_CS = cs;
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();




More information about the coreboot mailing list