mirror of https://gitee.com/openkylin/qemu.git
target-arm: Split DISAS_YIELD from DISAS_WFE
Currently we use DISAS_WFE for both WFE and YIELD instructions. This is functionally correct because at the moment both of them are implemented as "yield this CPU back to the top level loop so another CPU has a chance to run". However it's rather confusing that YIELD ends up calling HELPER(wfe), and if we ever want to implement real behaviour for WFE and SEV it's likely to trip us up. Split out the yield codepath to use DISAS_YIELD and a new HELPER(yield) function, and have HELPER(wfe) call HELPER(yield). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1435672316-3311-2-git-send-email-peter.maydell@linaro.org Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
This commit is contained in:
parent
a7ffaf5c96
commit
049e24a191
|
@ -50,6 +50,7 @@ DEF_HELPER_2(exception_internal, void, env, i32)
|
||||||
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
|
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
|
||||||
DEF_HELPER_1(wfi, void, env)
|
DEF_HELPER_1(wfi, void, env)
|
||||||
DEF_HELPER_1(wfe, void, env)
|
DEF_HELPER_1(wfe, void, env)
|
||||||
|
DEF_HELPER_1(yield, void, env)
|
||||||
DEF_HELPER_1(pre_hvc, void, env)
|
DEF_HELPER_1(pre_hvc, void, env)
|
||||||
DEF_HELPER_2(pre_smc, void, env, i32)
|
DEF_HELPER_2(pre_smc, void, env, i32)
|
||||||
|
|
||||||
|
|
|
@ -323,13 +323,25 @@ void HELPER(wfi)(CPUARMState *env)
|
||||||
|
|
||||||
void HELPER(wfe)(CPUARMState *env)
|
void HELPER(wfe)(CPUARMState *env)
|
||||||
{
|
{
|
||||||
CPUState *cs = CPU(arm_env_get_cpu(env));
|
/* This is a hint instruction that is semantically different
|
||||||
|
* from YIELD even though we currently implement it identically.
|
||||||
/* Don't actually halt the CPU, just yield back to top
|
* Don't actually halt the CPU, just yield back to top
|
||||||
* level loop. This is not going into a "low power state"
|
* level loop. This is not going into a "low power state"
|
||||||
* (ie halting until some event occurs), so we never take
|
* (ie halting until some event occurs), so we never take
|
||||||
* a configurable trap to a different exception level.
|
* a configurable trap to a different exception level.
|
||||||
*/
|
*/
|
||||||
|
HELPER(yield)(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HELPER(yield)(CPUARMState *env)
|
||||||
|
{
|
||||||
|
ARMCPU *cpu = arm_env_get_cpu(env);
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
|
|
||||||
|
/* This is a non-trappable hint instruction that generally indicates
|
||||||
|
* that the guest is currently busy-looping. Yield control back to the
|
||||||
|
* top level loop so that a more deserving VCPU has a chance to run.
|
||||||
|
*/
|
||||||
cs->exception_index = EXCP_YIELD;
|
cs->exception_index = EXCP_YIELD;
|
||||||
cpu_loop_exit(cs);
|
cpu_loop_exit(cs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1199,6 +1199,8 @@ static void handle_hint(DisasContext *s, uint32_t insn,
|
||||||
s->is_jmp = DISAS_WFI;
|
s->is_jmp = DISAS_WFI;
|
||||||
return;
|
return;
|
||||||
case 1: /* YIELD */
|
case 1: /* YIELD */
|
||||||
|
s->is_jmp = DISAS_YIELD;
|
||||||
|
return;
|
||||||
case 2: /* WFE */
|
case 2: /* WFE */
|
||||||
s->is_jmp = DISAS_WFE;
|
s->is_jmp = DISAS_WFE;
|
||||||
return;
|
return;
|
||||||
|
@ -11107,6 +11109,10 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
|
||||||
gen_a64_set_pc_im(dc->pc);
|
gen_a64_set_pc_im(dc->pc);
|
||||||
gen_helper_wfe(cpu_env);
|
gen_helper_wfe(cpu_env);
|
||||||
break;
|
break;
|
||||||
|
case DISAS_YIELD:
|
||||||
|
gen_a64_set_pc_im(dc->pc);
|
||||||
|
gen_helper_yield(cpu_env);
|
||||||
|
break;
|
||||||
case DISAS_WFI:
|
case DISAS_WFI:
|
||||||
/* This is a special case because we don't want to just halt the CPU
|
/* This is a special case because we don't want to just halt the CPU
|
||||||
* if trying to debug across a WFI.
|
* if trying to debug across a WFI.
|
||||||
|
|
|
@ -103,6 +103,7 @@ static inline int default_exception_el(DisasContext *s)
|
||||||
#define DISAS_WFE 7
|
#define DISAS_WFE 7
|
||||||
#define DISAS_HVC 8
|
#define DISAS_HVC 8
|
||||||
#define DISAS_SMC 9
|
#define DISAS_SMC 9
|
||||||
|
#define DISAS_YIELD 10
|
||||||
|
|
||||||
#ifdef TARGET_AARCH64
|
#ifdef TARGET_AARCH64
|
||||||
void a64_translate_init(void);
|
void a64_translate_init(void);
|
||||||
|
|
Loading…
Reference in New Issue