Stefan Reinauer (stefan.reinauer@coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1365
-gerrit
commit aba752bc719378b667954175d05891c5b69e2c55 Author: Stefan Reinauer reinauer@chromium.org Date: Thu Jul 26 15:48:17 2012 -0700
x86emu: fix jump_near_IMM to handle DATA: flag correctly
Before (data flag ignored -> broken): 66 DATA: e944f1 JMP 1ff6
After (fixed): 66 DATA: e944f1ffff JMP 00001ff8
This subtle difference in the length of decoded instruction meant that the VBE call jumped to the routine setting AX=0x14F (VBE Failed) instead of the routine that set AX=0x4F (VBE success).
The ability to run the same code in vm86 significantly aided the debugging of this issue. Those X.org developers who would like to drop vm86 better take special care towards _all_ vesa bugs, as those will expose further issues.
Imported from: http://cgit.freedesktop.org/xorg/xserver/commit/hw/xfree86/x86emu?id=cc2c73d... Signed-off-by: Stefan Reinauer reinauer@google.com
Change-Id: Id08ead9b17468cf19ede45508e5dcc50e45b5acf Signed-off-by: Luc Verhaegen libv@skynet.be Tested-by: Luc Verhaegen libv@skynet.be Reviewed-by: Adam Jackson ajax@redhat.com Signed-off-by: Keith Packard keithp@keithp.com --- src/devices/oprom/x86emu/ops.c | 23 ++++++++++++++++------- 1 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/src/devices/oprom/x86emu/ops.c b/src/devices/oprom/x86emu/ops.c index 6bfc71c..e58dafb 100644 --- a/src/devices/oprom/x86emu/ops.c +++ b/src/devices/oprom/x86emu/ops.c @@ -4279,16 +4279,25 @@ Handles opcode 0xe9 ****************************************************************************/ static void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1)) { - int ip; + u32 ip;
START_OF_INSTR(); DECODE_PRINTF("JMP\t"); - ip = (s16)fetch_word_imm(); - ip += (s16)M.x86.R_IP; - DECODE_PRINTF2("%04x\n", ip); - JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, " NEAR "); - TRACE_AND_STEP(); - M.x86.R_IP = (u16)ip; + if (M.x86.mode & SYSMODE_PREFIX_DATA) { + ip = (u32)fetch_long_imm(); + ip += (u32)M.x86.R_EIP; + DECODE_PRINTF2("%08x\n", (u32)ip); + JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, " NEAR "); + TRACE_AND_STEP(); + M.x86.R_EIP = (u32)ip; + } else { + ip = (s16)fetch_word_imm(); + ip += (s16)M.x86.R_IP; + DECODE_PRINTF2("%04x\n", (u16)ip); + JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, " NEAR "); + TRACE_AND_STEP(); + M.x86.R_IP = (u16)ip; + } DECODE_CLEAR_SEGOVR(); END_OF_INSTR(); }