Commit 94451178b6b7d6d08c0f16a5a1b0d03bf978f74b
1 parent
17ca26e7
HLT, MWAIT and MONITOR insn fixes (initial patch by Alexander Graf)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4746 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
21 additions
and
11 deletions
target-i386/helper.h
| ... | ... | @@ -60,9 +60,9 @@ DEF_HELPER(void, helper_sysexit, (void)) |
| 60 | 60 | DEF_HELPER(void, helper_syscall, (int next_eip_addend)) |
| 61 | 61 | DEF_HELPER(void, helper_sysret, (int dflag)) |
| 62 | 62 | #endif |
| 63 | -DEF_HELPER(void, helper_hlt, (void)) | |
| 63 | +DEF_HELPER(void, helper_hlt, (int next_eip_addend)) | |
| 64 | 64 | DEF_HELPER(void, helper_monitor, (target_ulong ptr)) |
| 65 | -DEF_HELPER(void, helper_mwait, (void)) | |
| 65 | +DEF_HELPER(void, helper_mwait, (int next_eip_addend)) | |
| 66 | 66 | DEF_HELPER(void, helper_debug, (void)) |
| 67 | 67 | DEF_HELPER(void, helper_raise_interrupt, (int intno, int next_eip_addend)) |
| 68 | 68 | DEF_HELPER(void, helper_raise_exception, (int exception_index)) | ... | ... |
target-i386/op_helper.c
| ... | ... | @@ -4547,16 +4547,22 @@ void helper_idivq_EAX(target_ulong t0) |
| 4547 | 4547 | } |
| 4548 | 4548 | #endif |
| 4549 | 4549 | |
| 4550 | -void helper_hlt(void) | |
| 4550 | +static void do_hlt(void) | |
| 4551 | 4551 | { |
| 4552 | - helper_svm_check_intercept_param(SVM_EXIT_HLT, 0); | |
| 4553 | - | |
| 4554 | 4552 | env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */ |
| 4555 | 4553 | env->halted = 1; |
| 4556 | 4554 | env->exception_index = EXCP_HLT; |
| 4557 | 4555 | cpu_loop_exit(); |
| 4558 | 4556 | } |
| 4559 | 4557 | |
| 4558 | +void helper_hlt(int next_eip_addend) | |
| 4559 | +{ | |
| 4560 | + helper_svm_check_intercept_param(SVM_EXIT_HLT, 0); | |
| 4561 | + EIP += next_eip_addend; | |
| 4562 | + | |
| 4563 | + do_hlt(); | |
| 4564 | +} | |
| 4565 | + | |
| 4560 | 4566 | void helper_monitor(target_ulong ptr) |
| 4561 | 4567 | { |
| 4562 | 4568 | if ((uint32_t)ECX != 0) |
| ... | ... | @@ -4565,17 +4571,19 @@ void helper_monitor(target_ulong ptr) |
| 4565 | 4571 | helper_svm_check_intercept_param(SVM_EXIT_MONITOR, 0); |
| 4566 | 4572 | } |
| 4567 | 4573 | |
| 4568 | -void helper_mwait(void) | |
| 4574 | +void helper_mwait(int next_eip_addend) | |
| 4569 | 4575 | { |
| 4570 | 4576 | if ((uint32_t)ECX != 0) |
| 4571 | 4577 | raise_exception(EXCP0D_GPF); |
| 4572 | 4578 | helper_svm_check_intercept_param(SVM_EXIT_MWAIT, 0); |
| 4579 | + EIP += next_eip_addend; | |
| 4580 | + | |
| 4573 | 4581 | /* XXX: not complete but not completely erroneous */ |
| 4574 | 4582 | if (env->cpu_index != 0 || env->next_cpu != NULL) { |
| 4575 | 4583 | /* more than one CPU: do not sleep because another CPU may |
| 4576 | 4584 | wake this one */ |
| 4577 | 4585 | } else { |
| 4578 | - helper_hlt(); | |
| 4586 | + do_hlt(); | |
| 4579 | 4587 | } |
| 4580 | 4588 | } |
| 4581 | 4589 | ... | ... |
target-i386/translate.c
| ... | ... | @@ -6420,8 +6420,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 6420 | 6420 | } else { |
| 6421 | 6421 | if (s->cc_op != CC_OP_DYNAMIC) |
| 6422 | 6422 | gen_op_set_cc_op(s->cc_op); |
| 6423 | - gen_jmp_im(s->pc - s->cs_base); | |
| 6424 | - tcg_gen_helper_0_0(helper_hlt); | |
| 6423 | + gen_jmp_im(pc_start - s->cs_base); | |
| 6424 | + tcg_gen_helper_0_1(helper_hlt, tcg_const_i32(s->pc - pc_start)); | |
| 6425 | 6425 | s->is_jmp = 3; |
| 6426 | 6426 | } |
| 6427 | 6427 | break; |
| ... | ... | @@ -6519,6 +6519,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 6519 | 6519 | if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || |
| 6520 | 6520 | s->cpl != 0) |
| 6521 | 6521 | goto illegal_op; |
| 6522 | + if (s->cc_op != CC_OP_DYNAMIC) | |
| 6523 | + gen_op_set_cc_op(s->cc_op); | |
| 6522 | 6524 | gen_jmp_im(pc_start - s->cs_base); |
| 6523 | 6525 | #ifdef TARGET_X86_64 |
| 6524 | 6526 | if (s->aflag == 2) { |
| ... | ... | @@ -6541,8 +6543,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 6541 | 6543 | gen_op_set_cc_op(s->cc_op); |
| 6542 | 6544 | s->cc_op = CC_OP_DYNAMIC; |
| 6543 | 6545 | } |
| 6544 | - gen_jmp_im(s->pc - s->cs_base); | |
| 6545 | - tcg_gen_helper_0_0(helper_mwait); | |
| 6546 | + gen_jmp_im(pc_start - s->cs_base); | |
| 6547 | + tcg_gen_helper_0_1(helper_mwait, tcg_const_i32(s->pc - pc_start)); | |
| 6546 | 6548 | gen_eob(s); |
| 6547 | 6549 | break; |
| 6548 | 6550 | default: | ... | ... |