summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefan Reinauer <reinauer@chromium.org>2012-07-26 15:48:17 -0700
committerPatrick Georgi <patrick@georgi-clan.de>2012-08-02 14:43:12 +0200
commit170d19c2ad516c146762b8cf597ededa467495fc (patch)
tree1c360ade548d4abde8ea0d1de78fd21c72dc3bc7 /src
parent3b69578cd2a138b8fa1260a0dd1fa943cba113cd (diff)
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=cc2c73ddcb4370a7c3ad439cda4da825156c26c9 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> Reviewed-on: http://review.coreboot.org/1365 Tested-by: build bot (Jenkins) Reviewed-by: Anton Kochkov <anton.kochkov@gmail.com> Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src')
-rw-r--r--src/devices/oprom/x86emu/ops.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/src/devices/oprom/x86emu/ops.c b/src/devices/oprom/x86emu/ops.c
index 536b4041b2..6917a08162 100644
--- a/src/devices/oprom/x86emu/ops.c
+++ b/src/devices/oprom/x86emu/ops.c
@@ -4301,16 +4301,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();
}