Commit 08cea4ee authored by bellard's avatar bellard
Browse files

fixed ljmp and iret to TSS


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@682 c046a42c-6fe2-441c-8c8c-71466251a162
parent 883da8e2
...@@ -123,11 +123,11 @@ typedef struct CCTable { ...@@ -123,11 +123,11 @@ typedef struct CCTable {
extern CCTable cc_table[]; extern CCTable cc_table[];
void load_seg(int seg_reg, int selector); void load_seg(int seg_reg, int selector);
void helper_ljmp_protected_T0_T1(void); void helper_ljmp_protected_T0_T1(int next_eip);
void helper_lcall_real_T0_T1(int shift, int next_eip); void helper_lcall_real_T0_T1(int shift, int next_eip);
void helper_lcall_protected_T0_T1(int shift, int next_eip); void helper_lcall_protected_T0_T1(int shift, int next_eip);
void helper_iret_real(int shift); void helper_iret_real(int shift);
void helper_iret_protected(int shift); void helper_iret_protected(int shift, int next_eip);
void helper_lret_protected(int shift, int addend); void helper_lret_protected(int shift, int addend);
void helper_lldt_T0(void); void helper_lldt_T0(void);
void helper_ltr_T0(void); void helper_ltr_T0(void);
......
...@@ -1219,7 +1219,7 @@ void load_seg(int seg_reg, int selector) ...@@ -1219,7 +1219,7 @@ void load_seg(int seg_reg, int selector)
} }
/* protected mode jump */ /* protected mode jump */
void helper_ljmp_protected_T0_T1(void) void helper_ljmp_protected_T0_T1(int next_eip)
{ {
int new_cs, new_eip, gate_cs, type; int new_cs, new_eip, gate_cs, type;
uint32_t e1, e2, cpl, dpl, rpl, limit; uint32_t e1, e2, cpl, dpl, rpl, limit;
...@@ -1267,8 +1267,7 @@ void helper_ljmp_protected_T0_T1(void) ...@@ -1267,8 +1267,7 @@ void helper_ljmp_protected_T0_T1(void)
case 5: /* task gate */ case 5: /* task gate */
if (dpl < cpl || dpl < rpl) if (dpl < cpl || dpl < rpl)
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
/* XXX: check if it is really the current EIP */ switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, next_eip);
switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, env->eip);
break; break;
case 4: /* 286 call gate */ case 4: /* 286 call gate */
case 12: /* 386 call gate */ case 12: /* 386 call gate */
...@@ -1732,7 +1731,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) ...@@ -1732,7 +1731,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
ESP = new_esp; ESP = new_esp;
} }
void helper_iret_protected(int shift) void helper_iret_protected(int shift, int next_eip)
{ {
int tss_selector, type; int tss_selector, type;
uint32_t e1, e2; uint32_t e1, e2;
...@@ -1748,8 +1747,7 @@ void helper_iret_protected(int shift) ...@@ -1748,8 +1747,7 @@ void helper_iret_protected(int shift)
/* NOTE: we check both segment and busy TSS */ /* NOTE: we check both segment and busy TSS */
if (type != 3) if (type != 3)
raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc); raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc);
/* XXX: check if it is really the current EIP */ switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip);
switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, env->eip);
} else { } else {
helper_ret_protected(shift, 1, 0); helper_ret_protected(shift, 1, 0);
} }
......
...@@ -918,7 +918,7 @@ void OPPROTO op_arpl_update(void) ...@@ -918,7 +918,7 @@ void OPPROTO op_arpl_update(void)
/* T0: segment, T1:eip */ /* T0: segment, T1:eip */
void OPPROTO op_ljmp_protected_T0_T1(void) void OPPROTO op_ljmp_protected_T0_T1(void)
{ {
helper_ljmp_protected_T0_T1(); helper_ljmp_protected_T0_T1(PARAM1);
} }
void OPPROTO op_lcall_real_T0_T1(void) void OPPROTO op_lcall_real_T0_T1(void)
...@@ -938,7 +938,7 @@ void OPPROTO op_iret_real(void) ...@@ -938,7 +938,7 @@ void OPPROTO op_iret_real(void)
void OPPROTO op_iret_protected(void) void OPPROTO op_iret_protected(void)
{ {
helper_iret_protected(PARAM1); helper_iret_protected(PARAM1, PARAM2);
} }
void OPPROTO op_lret_protected(void) void OPPROTO op_lret_protected(void)
......
...@@ -2172,7 +2172,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) ...@@ -2172,7 +2172,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
if (s->cc_op != CC_OP_DYNAMIC) if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op); gen_op_set_cc_op(s->cc_op);
gen_op_jmp_im(pc_start - s->cs_base); gen_op_jmp_im(pc_start - s->cs_base);
gen_op_ljmp_protected_T0_T1(); gen_op_ljmp_protected_T0_T1(s->pc - s->cs_base);
} else { } else {
gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
gen_op_movl_T0_T1(); gen_op_movl_T0_T1();
...@@ -3453,7 +3453,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) ...@@ -3453,7 +3453,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
if (s->cc_op != CC_OP_DYNAMIC) if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op); gen_op_set_cc_op(s->cc_op);
gen_op_jmp_im(pc_start - s->cs_base); gen_op_jmp_im(pc_start - s->cs_base);
gen_op_iret_protected(s->dflag); gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
s->cc_op = CC_OP_EFLAGS; s->cc_op = CC_OP_EFLAGS;
} }
gen_eob(s); gen_eob(s);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment