Backport all x86emu fixes from Pattrick Hueper to coreboot v2 (acked in v2,
hence I consider it trivial in this case). This does not include the Yabel work. Signed-off-by: Stefan Reinauer <stepan@coresystems.de> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3880 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
20b261dacf
commit
5833f7c0e6
|
@ -52,8 +52,12 @@ static int parse_line (char *s, int *ps, int *n);
|
|||
void X86EMU_trace_regs (void)
|
||||
{
|
||||
if (DEBUG_TRACE()) {
|
||||
if (M.x86.mode & (SYSMODE_PREFIX_DATA | SYSMODE_PREFIX_ADDR)) {
|
||||
x86emu_dump_xregs();
|
||||
} else {
|
||||
x86emu_dump_regs();
|
||||
}
|
||||
}
|
||||
if (DEBUG_DECODE() && ! DEBUG_DECODE_NOPRINT()) {
|
||||
printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
|
||||
print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
|
||||
|
@ -355,6 +359,8 @@ static int parse_line (char *s, int *ps, int *n)
|
|||
sscanf(s,"%x",&ps[*n]);
|
||||
*n += 1;
|
||||
}
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -40,8 +40,10 @@
|
|||
#ifndef __X86EMU_DEBUG_H
|
||||
#define __X86EMU_DEBUG_H
|
||||
|
||||
//#define DEBUG 0
|
||||
#if defined(DEBUG) && (DEBUG == 0)
|
||||
#undef DEBUG
|
||||
#endif
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
/* checks to be enabled for "runtime" */
|
||||
|
@ -78,6 +80,8 @@
|
|||
# define DEBUG_SYSINT() (M.x86.debug & DEBUG_SYSINT_F)
|
||||
# define DEBUG_TRACECALL() (M.x86.debug & DEBUG_TRACECALL_F)
|
||||
# define DEBUG_TRACECALLREGS() (M.x86.debug & DEBUG_TRACECALL_REGS_F)
|
||||
# define DEBUG_TRACEJMP() (M.x86.debug & DEBUG_TRACEJMP_F)
|
||||
# define DEBUG_TRACEJMPREGS() (M.x86.debug & DEBUG_TRACEJMP_REGS_F)
|
||||
# define DEBUG_SYS() (M.x86.debug & DEBUG_SYS_F)
|
||||
# define DEBUG_MEM_TRACE() (M.x86.debug & DEBUG_MEM_TRACE_F)
|
||||
# define DEBUG_IO_TRACE() (M.x86.debug & DEBUG_IO_TRACE_F)
|
||||
|
@ -96,6 +100,8 @@
|
|||
# define DEBUG_SYSINT() 0
|
||||
# define DEBUG_TRACECALL() 0
|
||||
# define DEBUG_TRACECALLREGS() 0
|
||||
# define DEBUG_TRACEJMP() 0
|
||||
# define DEBUG_TRACEJMPREGS() 0
|
||||
# define DEBUG_SYS() 0
|
||||
# define DEBUG_MEM_TRACE() 0
|
||||
# define DEBUG_IO_TRACE() 0
|
||||
|
@ -169,14 +175,20 @@
|
|||
x86emu_dump_regs(); \
|
||||
if (DEBUG_TRACECALL()) \
|
||||
printk("%04x:%04x: CALL %s%04x:%04x\n", u , v, s, w, x);
|
||||
# define RETURN_TRACE(n,u,v) \
|
||||
# define RETURN_TRACE(u,v,w,x,s) \
|
||||
if (DEBUG_TRACECALLREGS()) \
|
||||
x86emu_dump_regs(); \
|
||||
if (DEBUG_TRACECALL()) \
|
||||
printk("%04x:%04x: %s\n",u,v,n);
|
||||
printk("%04x:%04x: RET %s %04x:%04x\n",u,v,s,w,x);
|
||||
# define JMP_TRACE(u,v,w,x,s) \
|
||||
if (DEBUG_TRACEJMPREGS()) \
|
||||
x86emu_dump_regs(); \
|
||||
if (DEBUG_TRACEJMP()) \
|
||||
printk("%04x:%04x: JMP %s%04x:%04x\n", u , v, s, w, x);
|
||||
#else
|
||||
# define CALL_TRACE(u,v,w,x,s)
|
||||
# define RETURN_TRACE(n,u,v)
|
||||
# define RETURN_TRACE(u,v,w,x,s)
|
||||
# define JMP_TRACE(u,v,w,x,s)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -1061,7 +1061,11 @@ void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
|
|||
imm = (s8)fetch_byte_imm();
|
||||
DECODE_PRINTF2("PUSH\t%d\n", imm);
|
||||
TRACE_AND_STEP();
|
||||
if (M.x86.mode & SYSMODE_PREFIX_DATA) {
|
||||
push_long(imm);
|
||||
} else {
|
||||
push_word(imm);
|
||||
}
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
}
|
||||
|
@ -1256,8 +1260,10 @@ void x86emuOp_jump_near_cond(u8 op1)
|
|||
target = (u16)(M.x86.R_IP + (s16)offset);
|
||||
DECODE_PRINTF2("%x\n", target);
|
||||
TRACE_AND_STEP();
|
||||
if (cond)
|
||||
if (cond) {
|
||||
M.x86.R_IP = target;
|
||||
JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, M.x86.R_IP, " NEAR COND ");
|
||||
}
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
}
|
||||
|
@ -2516,9 +2522,11 @@ void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
|
|||
count = 1;
|
||||
if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
|
||||
/* dont care whether REPE or REPNE */
|
||||
/* move them until CX is ZERO. */
|
||||
count = M.x86.R_CX;
|
||||
/* move them until (E)CX is ZERO. */
|
||||
count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX;
|
||||
M.x86.R_CX = 0;
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX = 0;
|
||||
M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
|
||||
}
|
||||
while (count--) {
|
||||
|
@ -2526,6 +2534,8 @@ void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
|
|||
store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
|
||||
M.x86.R_SI += inc;
|
||||
M.x86.R_DI += inc;
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
|
@ -2559,9 +2569,11 @@ void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
|
|||
count = 1;
|
||||
if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
|
||||
/* dont care whether REPE or REPNE */
|
||||
/* move them until CX is ZERO. */
|
||||
count = M.x86.R_CX;
|
||||
/* move them until (E)CX is ZERO. */
|
||||
count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX;
|
||||
M.x86.R_CX = 0;
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX = 0;
|
||||
M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
|
||||
}
|
||||
while (count--) {
|
||||
|
@ -2574,6 +2586,8 @@ void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
|
|||
}
|
||||
M.x86.R_SI += inc;
|
||||
M.x86.R_DI += inc;
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
|
@ -2598,16 +2612,21 @@ void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
|
|||
|
||||
if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
|
||||
/* REPE */
|
||||
/* move them until CX is ZERO. */
|
||||
while (M.x86.R_CX != 0) {
|
||||
/* move them until (E)CX is ZERO. */
|
||||
while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) {
|
||||
val1 = fetch_data_byte(M.x86.R_SI);
|
||||
val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
|
||||
cmp_byte(val1, val2);
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX -= 1;
|
||||
else
|
||||
M.x86.R_CX -= 1;
|
||||
M.x86.R_SI += inc;
|
||||
M.x86.R_DI += inc;
|
||||
if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && (ACCESS_FLAG(F_ZF) == 0) ) break;
|
||||
if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
|
||||
} else {
|
||||
|
@ -2644,8 +2663,8 @@ void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
|
|||
TRACE_AND_STEP();
|
||||
if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
|
||||
/* REPE */
|
||||
/* move them until CX is ZERO. */
|
||||
while (M.x86.R_CX != 0) {
|
||||
/* move them until (E)CX is ZERO. */
|
||||
while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) {
|
||||
if (M.x86.mode & SYSMODE_PREFIX_DATA) {
|
||||
val1 = fetch_data_long(M.x86.R_SI);
|
||||
val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
|
||||
|
@ -2655,11 +2674,16 @@ void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
|
|||
val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
|
||||
cmp_word((u16)val1, (u16)val2);
|
||||
}
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX -= 1;
|
||||
else
|
||||
M.x86.R_CX -= 1;
|
||||
M.x86.R_SI += inc;
|
||||
M.x86.R_DI += inc;
|
||||
if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && ACCESS_FLAG(F_ZF) == 0 ) break;
|
||||
if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
|
||||
} else {
|
||||
|
@ -2741,11 +2765,16 @@ void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
|
|||
TRACE_AND_STEP();
|
||||
if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
|
||||
/* dont care whether REPE or REPNE */
|
||||
/* move them until CX is ZERO. */
|
||||
while (M.x86.R_CX != 0) {
|
||||
/* move them until (E)CX is ZERO. */
|
||||
while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) {
|
||||
store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX -= 1;
|
||||
else
|
||||
M.x86.R_CX -= 1;
|
||||
M.x86.R_DI += inc;
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
|
||||
} else {
|
||||
|
@ -2783,9 +2812,11 @@ void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
|
|||
count = 1;
|
||||
if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
|
||||
/* dont care whether REPE or REPNE */
|
||||
/* move them until CX is ZERO. */
|
||||
count = M.x86.R_CX;
|
||||
/* move them until (E)CX is ZERO. */
|
||||
count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX;
|
||||
M.x86.R_CX = 0;
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX = 0;
|
||||
M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
|
||||
}
|
||||
while (count--) {
|
||||
|
@ -2795,6 +2826,8 @@ void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
|
|||
store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
|
||||
}
|
||||
M.x86.R_DI += inc;
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
|
@ -2817,11 +2850,16 @@ void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
|
|||
inc = 1;
|
||||
if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
|
||||
/* dont care whether REPE or REPNE */
|
||||
/* move them until CX is ZERO. */
|
||||
while (M.x86.R_CX != 0) {
|
||||
/* move them until (E)CX is ZERO. */
|
||||
while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) {
|
||||
M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX -= 1;
|
||||
else
|
||||
M.x86.R_CX -= 1;
|
||||
M.x86.R_SI += inc;
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
|
||||
} else {
|
||||
|
@ -2859,9 +2897,11 @@ void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
|
|||
count = 1;
|
||||
if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
|
||||
/* dont care whether REPE or REPNE */
|
||||
/* move them until CX is ZERO. */
|
||||
count = M.x86.R_CX;
|
||||
/* move them until (E)CX is ZERO. */
|
||||
count = (M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX;
|
||||
M.x86.R_CX = 0;
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX = 0;
|
||||
M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
|
||||
}
|
||||
while (count--) {
|
||||
|
@ -2871,6 +2911,8 @@ void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
|
|||
M.x86.R_AX = fetch_data_word(M.x86.R_SI);
|
||||
}
|
||||
M.x86.R_SI += inc;
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
|
@ -2894,26 +2936,36 @@ void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
|
|||
inc = 1;
|
||||
if (M.x86.mode & SYSMODE_PREFIX_REPE) {
|
||||
/* REPE */
|
||||
/* move them until CX is ZERO. */
|
||||
while (M.x86.R_CX != 0) {
|
||||
/* move them until (E)CX is ZERO. */
|
||||
while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) {
|
||||
val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
|
||||
cmp_byte(M.x86.R_AL, val2);
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX -= 1;
|
||||
else
|
||||
M.x86.R_CX -= 1;
|
||||
M.x86.R_DI += inc;
|
||||
if (ACCESS_FLAG(F_ZF) == 0)
|
||||
break;
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
M.x86.mode &= ~SYSMODE_PREFIX_REPE;
|
||||
} else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
|
||||
/* REPNE */
|
||||
/* move them until CX is ZERO. */
|
||||
while (M.x86.R_CX != 0) {
|
||||
/* move them until (E)CX is ZERO. */
|
||||
while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) {
|
||||
val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
|
||||
cmp_byte(M.x86.R_AL, val2);
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX -= 1;
|
||||
else
|
||||
M.x86.R_CX -= 1;
|
||||
M.x86.R_DI += inc;
|
||||
if (ACCESS_FLAG(F_ZF))
|
||||
break; /* zero flag set means equal */
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
|
||||
} else {
|
||||
|
@ -2951,8 +3003,8 @@ void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
|
|||
TRACE_AND_STEP();
|
||||
if (M.x86.mode & SYSMODE_PREFIX_REPE) {
|
||||
/* REPE */
|
||||
/* move them until CX is ZERO. */
|
||||
while (M.x86.R_CX != 0) {
|
||||
/* move them until (E)CX is ZERO. */
|
||||
while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) {
|
||||
if (M.x86.mode & SYSMODE_PREFIX_DATA) {
|
||||
val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
|
||||
cmp_long(M.x86.R_EAX, val);
|
||||
|
@ -2960,16 +3012,21 @@ void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
|
|||
val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
|
||||
cmp_word(M.x86.R_AX, (u16)val);
|
||||
}
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX -= 1;
|
||||
else
|
||||
M.x86.R_CX -= 1;
|
||||
M.x86.R_DI += inc;
|
||||
if (ACCESS_FLAG(F_ZF) == 0)
|
||||
break;
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
M.x86.mode &= ~SYSMODE_PREFIX_REPE;
|
||||
} else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
|
||||
/* REPNE */
|
||||
/* move them until CX is ZERO. */
|
||||
while (M.x86.R_CX != 0) {
|
||||
/* move them until (E)CX is ZERO. */
|
||||
while (((M.x86.mode & SYSMODE_32BIT_REP) ? M.x86.R_ECX : M.x86.R_CX) != 0) {
|
||||
if (M.x86.mode & SYSMODE_PREFIX_DATA) {
|
||||
val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
|
||||
cmp_long(M.x86.R_EAX, val);
|
||||
|
@ -2977,10 +3034,15 @@ void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
|
|||
val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
|
||||
cmp_word(M.x86.R_AX, (u16)val);
|
||||
}
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP)
|
||||
M.x86.R_ECX -= 1;
|
||||
else
|
||||
M.x86.R_CX -= 1;
|
||||
M.x86.R_DI += inc;
|
||||
if (ACCESS_FLAG(F_ZF))
|
||||
break; /* zero flag set means equal */
|
||||
if (M.x86.intr & INTR_HALTED)
|
||||
break;
|
||||
}
|
||||
M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
|
||||
} else {
|
||||
|
@ -3238,9 +3300,9 @@ void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
|
|||
DECODE_PRINTF("RET\t");
|
||||
imm = fetch_word_imm();
|
||||
DECODE_PRINTF2("%x\n", imm);
|
||||
RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
|
||||
TRACE_AND_STEP();
|
||||
M.x86.R_IP = pop_word();
|
||||
RETURN_TRACE(M.x86.saved_cs,M.x86.saved_ip, M.x86.R_CS, M.x86.R_IP, "NEAR");
|
||||
M.x86.R_SP += imm;
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
|
@ -3254,9 +3316,9 @@ void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
|
|||
{
|
||||
START_OF_INSTR();
|
||||
DECODE_PRINTF("RET\n");
|
||||
RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
|
||||
TRACE_AND_STEP();
|
||||
M.x86.R_IP = pop_word();
|
||||
RETURN_TRACE(M.x86.saved_cs,M.x86.saved_ip, M.x86.R_CS, M.x86.R_IP, "NEAR");
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
}
|
||||
|
@ -3471,10 +3533,10 @@ void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
|
|||
DECODE_PRINTF("RETF\t");
|
||||
imm = fetch_word_imm();
|
||||
DECODE_PRINTF2("%x\n", imm);
|
||||
RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
|
||||
TRACE_AND_STEP();
|
||||
M.x86.R_IP = pop_word();
|
||||
M.x86.R_CS = pop_word();
|
||||
RETURN_TRACE(M.x86.saved_cs,M.x86.saved_ip, M.x86.R_CS, M.x86.R_IP, "FAR");
|
||||
M.x86.R_SP += imm;
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
|
@ -3488,10 +3550,10 @@ void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
|
|||
{
|
||||
START_OF_INSTR();
|
||||
DECODE_PRINTF("RETF\n");
|
||||
RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
|
||||
TRACE_AND_STEP();
|
||||
M.x86.R_IP = pop_word();
|
||||
M.x86.R_CS = pop_word();
|
||||
RETURN_TRACE(M.x86.saved_cs,M.x86.saved_ip, M.x86.R_CS, M.x86.R_IP, "FAR");
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
}
|
||||
|
@ -4020,8 +4082,11 @@ void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
|
|||
ip += (s16) M.x86.R_IP;
|
||||
DECODE_PRINTF2("%04x\n", ip);
|
||||
TRACE_AND_STEP();
|
||||
if (M.x86.mode & SYSMODE_PREFIX_ADDR)
|
||||
M.x86.R_ECX -= 1;
|
||||
else
|
||||
M.x86.R_CX -= 1;
|
||||
if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
|
||||
if (((M.x86.mode & SYSMODE_PREFIX_ADDR) ? M.x86.R_ECX : M.x86.R_CX) != 0 && !ACCESS_FLAG(F_ZF)) /* (E)CX != 0 and !ZF */
|
||||
M.x86.R_IP = ip;
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
|
@ -4041,8 +4106,11 @@ void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
|
|||
ip += (s16) M.x86.R_IP;
|
||||
DECODE_PRINTF2("%04x\n", ip);
|
||||
TRACE_AND_STEP();
|
||||
if (M.x86.mode & SYSMODE_PREFIX_ADDR)
|
||||
M.x86.R_ECX -= 1;
|
||||
else
|
||||
M.x86.R_CX -= 1;
|
||||
if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
|
||||
if (((M.x86.mode & SYSMODE_PREFIX_ADDR) ? M.x86.R_ECX : M.x86.R_CX) != 0 && ACCESS_FLAG(F_ZF)) /* (E)CX != 0 and ZF */
|
||||
M.x86.R_IP = ip;
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
|
@ -4062,8 +4130,11 @@ void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
|
|||
ip += (s16) M.x86.R_IP;
|
||||
DECODE_PRINTF2("%04x\n", ip);
|
||||
TRACE_AND_STEP();
|
||||
if (M.x86.mode & SYSMODE_PREFIX_ADDR)
|
||||
M.x86.R_ECX -= 1;
|
||||
else
|
||||
M.x86.R_CX -= 1;
|
||||
if (M.x86.R_CX != 0)
|
||||
if (((M.x86.mode & SYSMODE_PREFIX_ADDR) ? M.x86.R_ECX : M.x86.R_CX) != 0) /* (E)CX != 0 */
|
||||
M.x86.R_IP = ip;
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
|
@ -4085,8 +4156,10 @@ void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
|
|||
target = (u16)(M.x86.R_IP + offset);
|
||||
DECODE_PRINTF2("%x\n", target);
|
||||
TRACE_AND_STEP();
|
||||
if (M.x86.R_CX == 0)
|
||||
if (M.x86.R_CX == 0) {
|
||||
M.x86.R_IP = target;
|
||||
JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, M.x86.R_IP, " CXZ ");
|
||||
}
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
}
|
||||
|
@ -4213,6 +4286,7 @@ void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
|
|||
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;
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
|
@ -4233,6 +4307,7 @@ void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
|
|||
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_CS = cs;
|
||||
|
@ -4254,6 +4329,7 @@ void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
|
|||
offset = (s8)fetch_byte_imm();
|
||||
target = (u16)(M.x86.R_IP + offset);
|
||||
DECODE_PRINTF2("%x\n", target);
|
||||
JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, target, " BYTE ");
|
||||
TRACE_AND_STEP();
|
||||
M.x86.R_IP = target;
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
|
@ -4357,6 +4433,8 @@ void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
|
|||
DECODE_PRINTF("REPNE\n");
|
||||
TRACE_AND_STEP();
|
||||
M.x86.mode |= SYSMODE_PREFIX_REPNE;
|
||||
if (M.x86.mode & SYSMODE_PREFIX_ADDR)
|
||||
M.x86.mode |= SYSMODE_32BIT_REP;
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
}
|
||||
|
@ -4371,6 +4449,8 @@ void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
|
|||
DECODE_PRINTF("REPE\n");
|
||||
TRACE_AND_STEP();
|
||||
M.x86.mode |= SYSMODE_PREFIX_REPE;
|
||||
if (M.x86.mode & SYSMODE_PREFIX_ADDR)
|
||||
M.x86.mode |= SYSMODE_32BIT_REP;
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
}
|
||||
|
@ -5013,12 +5093,14 @@ void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
|
|||
break;
|
||||
case 4: /* jmp word ptr ... */
|
||||
destval = fetch_data_word(destoffset);
|
||||
JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, destval, " WORD ");
|
||||
TRACE_AND_STEP();
|
||||
M.x86.R_IP = destval;
|
||||
break;
|
||||
case 5: /* jmp far ptr ... */
|
||||
destval = fetch_data_word(destoffset);
|
||||
destval2 = fetch_data_word(destoffset + 2);
|
||||
JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, destval2, destval, " FAR ");
|
||||
TRACE_AND_STEP();
|
||||
M.x86.R_IP = destval;
|
||||
M.x86.R_CS = destval2;
|
||||
|
|
|
@ -149,8 +149,10 @@ void x86emuOp2_long_jump(u8 op2)
|
|||
target += (s16) M.x86.R_IP;
|
||||
DECODE_PRINTF2("%04x\n", target);
|
||||
TRACE_AND_STEP();
|
||||
if (cond)
|
||||
if (cond) {
|
||||
M.x86.R_IP = (u16)target;
|
||||
JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, M.x86.R_IP, " LONG COND ");
|
||||
}
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
}
|
||||
|
@ -1485,6 +1487,65 @@ void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
|
|||
END_OF_INSTR();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
REMARKS:
|
||||
Handles opcode 0x0f,0xC8-0xCF
|
||||
****************************************************************************/
|
||||
s32 x86emu_bswap(s32 reg)
|
||||
{
|
||||
// perform the byte swap
|
||||
s32 temp = reg;
|
||||
reg = (temp & 0xFF000000) >> 24;
|
||||
reg |= (temp & 0xFF0000) >> 8;
|
||||
reg |= (temp & 0xFF00) << 8;
|
||||
reg |= (temp & 0xFF) << 24;
|
||||
return reg;
|
||||
}
|
||||
|
||||
void x86emuOp2_bswap(u8 op2)
|
||||
{
|
||||
/* byte swap 32 bit register */
|
||||
START_OF_INSTR();
|
||||
DECODE_PRINTF("BSWAP\t");
|
||||
switch (op2) {
|
||||
case 0xc8:
|
||||
DECODE_PRINTF("EAX\n");
|
||||
M.x86.R_EAX = x86emu_bswap(M.x86.R_EAX);
|
||||
break;
|
||||
case 0xc9:
|
||||
DECODE_PRINTF("ECX\n");
|
||||
M.x86.R_ECX = x86emu_bswap(M.x86.R_ECX);
|
||||
break;
|
||||
case 0xca:
|
||||
DECODE_PRINTF("EDX\n");
|
||||
M.x86.R_EDX = x86emu_bswap(M.x86.R_EDX);
|
||||
break;
|
||||
case 0xcb:
|
||||
DECODE_PRINTF("EBX\n");
|
||||
M.x86.R_EBX = x86emu_bswap(M.x86.R_EBX);
|
||||
break;
|
||||
case 0xcc:
|
||||
DECODE_PRINTF("ESP\n");
|
||||
M.x86.R_ESP = x86emu_bswap(M.x86.R_ESP);
|
||||
break;
|
||||
case 0xcd:
|
||||
DECODE_PRINTF("EBP\n");
|
||||
M.x86.R_EBP = x86emu_bswap(M.x86.R_EBP);
|
||||
break;
|
||||
case 0xce:
|
||||
DECODE_PRINTF("ESI\n");
|
||||
M.x86.R_ESI = x86emu_bswap(M.x86.R_ESI);
|
||||
break;
|
||||
case 0xcf:
|
||||
DECODE_PRINTF("EDI\n");
|
||||
M.x86.R_EDI = x86emu_bswap(M.x86.R_EDI);
|
||||
break;
|
||||
}
|
||||
TRACE_AND_STEP();
|
||||
DECODE_CLEAR_SEGOVR();
|
||||
END_OF_INSTR();
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Double byte operation code table:
|
||||
**************************************************************************/
|
||||
|
@ -1702,14 +1763,14 @@ void (*x86emu_optab2[256])(u8) =
|
|||
/* 0xc5 */ x86emuOp2_illegal_op,
|
||||
/* 0xc6 */ x86emuOp2_illegal_op,
|
||||
/* 0xc7 */ x86emuOp2_illegal_op,
|
||||
/* 0xc8 */ x86emuOp2_illegal_op, /* TODO: bswap */
|
||||
/* 0xc9 */ x86emuOp2_illegal_op, /* TODO: bswap */
|
||||
/* 0xca */ x86emuOp2_illegal_op, /* TODO: bswap */
|
||||
/* 0xcb */ x86emuOp2_illegal_op, /* TODO: bswap */
|
||||
/* 0xcc */ x86emuOp2_illegal_op, /* TODO: bswap */
|
||||
/* 0xcd */ x86emuOp2_illegal_op, /* TODO: bswap */
|
||||
/* 0xce */ x86emuOp2_illegal_op, /* TODO: bswap */
|
||||
/* 0xcf */ x86emuOp2_illegal_op, /* TODO: bswap */
|
||||
/* 0xc8 */ x86emuOp2_bswap,
|
||||
/* 0xc9 */ x86emuOp2_bswap,
|
||||
/* 0xca */ x86emuOp2_bswap,
|
||||
/* 0xcb */ x86emuOp2_bswap,
|
||||
/* 0xcc */ x86emuOp2_bswap,
|
||||
/* 0xcd */ x86emuOp2_bswap,
|
||||
/* 0xce */ x86emuOp2_bswap,
|
||||
/* 0xcf */ x86emuOp2_bswap,
|
||||
|
||||
/* 0xd0 */ x86emuOp2_illegal_op,
|
||||
/* 0xd1 */ x86emuOp2_illegal_op,
|
||||
|
|
|
@ -1921,7 +1921,7 @@ Implements the IMUL instruction and side effects.
|
|||
void imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s)
|
||||
{
|
||||
#ifdef __HAS_LONG_LONG__
|
||||
s64 res = (s64)d * (s64)s;
|
||||
s64 res = (s64)(s32)d * (s64)(s32)s;
|
||||
|
||||
*res_lo = (u32)res;
|
||||
*res_hi = (u32)(res >> 32);
|
||||
|
@ -2013,7 +2013,7 @@ Implements the MUL instruction and side effects.
|
|||
void mul_long(u32 s)
|
||||
{
|
||||
#ifdef __HAS_LONG_LONG__
|
||||
u64 res = (u32)M.x86.R_EAX * (u32)s;
|
||||
u64 res = (u64)M.x86.R_EAX * s;
|
||||
|
||||
M.x86.R_EAX = (u32)res;
|
||||
M.x86.R_EDX = (u32)(res >> 32);
|
||||
|
@ -2312,16 +2312,15 @@ void ins(int size)
|
|||
}
|
||||
if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
|
||||
/* dont care whether REPE or REPNE */
|
||||
/* in until CX is ZERO. */
|
||||
u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
|
||||
/* in until (E)CX is ZERO. */
|
||||
u32 count = ((M.x86.mode & SYSMODE_32BIT_REP) ?
|
||||
M.x86.R_ECX : M.x86.R_CX);
|
||||
|
||||
while (count--) {
|
||||
single_in(size);
|
||||
M.x86.R_DI += inc;
|
||||
}
|
||||
M.x86.R_CX = 0;
|
||||
if (M.x86.mode & SYSMODE_PREFIX_DATA) {
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP) {
|
||||
M.x86.R_ECX = 0;
|
||||
}
|
||||
M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
|
||||
|
@ -2355,15 +2354,15 @@ void outs(int size)
|
|||
}
|
||||
if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
|
||||
/* dont care whether REPE or REPNE */
|
||||
/* out until CX is ZERO. */
|
||||
u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
|
||||
/* out until (E)CX is ZERO. */
|
||||
u32 count = ((M.x86.mode & SYSMODE_32BIT_REP) ?
|
||||
M.x86.R_ECX : M.x86.R_CX);
|
||||
while (count--) {
|
||||
single_out(size);
|
||||
M.x86.R_SI += inc;
|
||||
}
|
||||
M.x86.R_CX = 0;
|
||||
if (M.x86.mode & SYSMODE_PREFIX_DATA) {
|
||||
if (M.x86.mode & SYSMODE_32BIT_REP) {
|
||||
M.x86.R_ECX = 0;
|
||||
}
|
||||
M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include <x86emu/regs.h>
|
||||
#include "debug.h"
|
||||
#include "prim_ops.h"
|
||||
#ifdef COREBOOT_VERSION
|
||||
#ifdef COREBOOT_VERSION /* Coreboot needs to map printf to printk. */
|
||||
#include "arch/io.h"
|
||||
#else
|
||||
#include <sys/io.h>
|
||||
|
@ -69,7 +69,7 @@ u8 *mem_ptr(u32 addr, int size)
|
|||
u8 *retaddr = 0;
|
||||
|
||||
if (addr > M.mem_size - size) {
|
||||
DB(printk("mem_ptr: address %#lx out of range!\n", addr);)
|
||||
DB(printk("mem_ptr: address %#x out of range!\n", addr);)
|
||||
HALT_SYS();
|
||||
}
|
||||
if (addr < 0x200) {
|
||||
|
@ -405,6 +405,6 @@ void X86EMU_prepareForInt(int num)
|
|||
|
||||
void X86EMU_setMemBase(void *base, size_t size)
|
||||
{
|
||||
M.mem_base = (int) base;
|
||||
M.mem_base = (unsigned long) base;
|
||||
M.mem_size = size;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
#ifndef __X86EMU_FPU_REGS_H
|
||||
#define __X86EMU_FPU_REGS_H
|
||||
|
||||
|
||||
#if defined(DEBUG) && (DEBUG == 0)
|
||||
#undef DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef X86_FPU_SUPPORT
|
||||
|
||||
#pragma pack(1)
|
||||
|
|
|
@ -40,6 +40,10 @@
|
|||
#ifndef __X86EMU_REGS_H
|
||||
#define __X86EMU_REGS_H
|
||||
|
||||
#if defined(DEBUG) && (DEBUG == 0)
|
||||
#undef DEBUG
|
||||
#endif
|
||||
|
||||
/*---------------------- Macros and type definitions ----------------------*/
|
||||
|
||||
#pragma pack(1)
|
||||
|
@ -231,6 +235,9 @@ struct i386_segment_regs {
|
|||
#define SYSMODE_PREFIX_REPNE 0x00000100
|
||||
#define SYSMODE_PREFIX_DATA 0x00000200
|
||||
#define SYSMODE_PREFIX_ADDR 0x00000400
|
||||
// for REP(E|NE) Instructions, we need to decide wether it should be using
|
||||
// the 32bit ECX register as or the 16bit CX register as count register
|
||||
#define SYSMODE_32BIT_REP 0x00000800
|
||||
#define SYSMODE_INTR_PENDING 0x10000000
|
||||
#define SYSMODE_EXTRN_INTR 0x20000000
|
||||
#define SYSMODE_HALTED 0x40000000
|
||||
|
@ -250,7 +257,8 @@ struct i386_segment_regs {
|
|||
SYSMODE_SEGOVR_GS | \
|
||||
SYSMODE_SEGOVR_SS | \
|
||||
SYSMODE_PREFIX_DATA | \
|
||||
SYSMODE_PREFIX_ADDR)
|
||||
SYSMODE_PREFIX_ADDR | \
|
||||
SYSMODE_32BIT_REP)
|
||||
|
||||
#define INTR_SYNCH 0x1
|
||||
#define INTR_ASYNCH 0x2
|
||||
|
@ -274,7 +282,7 @@ typedef struct {
|
|||
*/
|
||||
u32 mode;
|
||||
volatile int intr; /* mask of pending interrupts */
|
||||
int debug;
|
||||
volatile int debug;
|
||||
#ifdef DEBUG
|
||||
int check;
|
||||
u16 saved_ip;
|
||||
|
|
|
@ -74,15 +74,15 @@ typedef unsigned int u32;
|
|||
typedef unsigned long long u64;
|
||||
#endif
|
||||
|
||||
typedef char s8;
|
||||
typedef short s16;
|
||||
typedef int s32;
|
||||
typedef signed char s8;
|
||||
typedef signed short s16;
|
||||
typedef signed int s32;
|
||||
#ifdef __HAS_LONG_LONG__
|
||||
typedef long long s64;
|
||||
typedef signed long long s64;
|
||||
#endif
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef int sint;
|
||||
typedef signed int sint;
|
||||
|
||||
typedef u16 X86EMU_pioAddr;
|
||||
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
#ifndef __X86EMU_X86EMU_H
|
||||
#define __X86EMU_X86EMU_H
|
||||
|
||||
#if defined(DEBUG) && (DEBUG == 0)
|
||||
#undef DEBUG
|
||||
#endif
|
||||
|
||||
/* FIXME: undefine printk for the moment */
|
||||
#ifdef COREBOOT_VERSION
|
||||
#include "console/console.h"
|
||||
|
@ -187,6 +191,8 @@ void X86EMU_halt_sys(void);
|
|||
#define DEBUG_TRACECALL_REGS_F 0x004000
|
||||
#define DEBUG_DECODE_NOPRINT_F 0x008000
|
||||
#define DEBUG_SAVE_IP_CS_F 0x010000
|
||||
#define DEBUG_TRACEJMP_F 0x020000
|
||||
#define DEBUG_TRACEJMP_REGS_F 0x040000
|
||||
#define DEBUG_SYS_F (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F)
|
||||
|
||||
void X86EMU_trace_regs(void);
|
||||
|
|
Loading…
Reference in New Issue