mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:17 +00:00
target/arm: implements SEV/SEVL for all modes
Remove the restrictions that make this a M-profile only operation and enable the instructions for all Arm profiles. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20260624103049.884930-6-alex.bennee@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
committed by
Peter Maydell
parent
6c6e24166f
commit
60e7ee5bb7
@@ -192,9 +192,8 @@ SMULTT .... 0001 0110 .... 0000 .... 1110 .... @rd0mn
|
||||
WFE ---- 0011 0010 0000 1111 ---- 0000 0010
|
||||
WFI ---- 0011 0010 0000 1111 ---- 0000 0011
|
||||
|
||||
# TODO: Implement SEV, SEVL; may help SMP performance.
|
||||
# SEV ---- 0011 0010 0000 1111 ---- 0000 0100
|
||||
# SEVL ---- 0011 0010 0000 1111 ---- 0000 0101
|
||||
SEV ---- 0011 0010 0000 1111 ---- 0000 0100
|
||||
SEVL ---- 0011 0010 0000 1111 ---- 0000 0101
|
||||
|
||||
ESB ---- 0011 0010 0000 1111 ---- 0001 0000
|
||||
]
|
||||
|
||||
@@ -250,9 +250,8 @@ ERETA 1101011 0100 11111 00001 m:1 11111 11111 &reta # ERETAA, ERETAB
|
||||
YIELD 1101 0101 0000 0011 0010 0000 001 11111
|
||||
WFE 1101 0101 0000 0011 0010 0000 010 11111
|
||||
WFI 1101 0101 0000 0011 0010 0000 011 11111
|
||||
# We implement WFE to never block, so our SEV/SEVL are NOPs
|
||||
# SEV 1101 0101 0000 0011 0010 0000 100 11111
|
||||
# SEVL 1101 0101 0000 0011 0010 0000 101 11111
|
||||
SEV 1101 0101 0000 0011 0010 0000 100 11111
|
||||
SEVL 1101 0101 0000 0011 0010 0000 101 11111
|
||||
# Our DGL is a NOP because we don't merge memory accesses anyway.
|
||||
# DGL 1101 0101 0000 0011 0010 0000 110 11111
|
||||
XPACLRI 1101 0101 0000 0011 0010 0000 111 11111
|
||||
|
||||
@@ -477,9 +477,7 @@ void HELPER(sev)(CPUARMState *env)
|
||||
CPUState *cs = env_cpu(env);
|
||||
CPU_FOREACH(cs) {
|
||||
ARMCPU *target_cpu = ARM_CPU(cs);
|
||||
if (arm_feature(&target_cpu->env, ARM_FEATURE_M)) {
|
||||
target_cpu->env.event_register = true;
|
||||
}
|
||||
target_cpu->env.event_register = true;
|
||||
if (!qemu_cpu_is_self(cs)) {
|
||||
qemu_cpu_kick(cs);
|
||||
}
|
||||
|
||||
@@ -228,10 +228,8 @@ REVSH 1011 1010 11 ... ... @rdm
|
||||
WFE 1011 1111 0010 0000
|
||||
WFI 1011 1111 0011 0000
|
||||
|
||||
# M-profile SEV is implemented.
|
||||
# TODO: Implement SEV for other profiles, and SEVL for all profiles; may help SMP performance.
|
||||
SEV 1011 1111 0100 0000
|
||||
# SEVL 1011 1111 0101 0000
|
||||
SEVL 1011 1111 0101 0000
|
||||
|
||||
# The canonical nop has the second nibble as 0000, but the whole of the
|
||||
# rest of the space is a reserved hint, behaves as nop.
|
||||
|
||||
@@ -369,10 +369,8 @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
|
||||
WFE 1111 0011 1010 1111 1000 0000 0000 0010
|
||||
WFI 1111 0011 1010 1111 1000 0000 0000 0011
|
||||
|
||||
# M-profile SEV is implemented.
|
||||
# TODO: Implement SEV for other profiles, and SEVL for all profiles; may help SMP performance.
|
||||
SEV 1111 0011 1010 1111 1000 0000 0000 0100
|
||||
# SEVL 1111 0011 1010 1111 1000 0000 0000 0101
|
||||
SEVL 1111 0011 1010 1111 1000 0000 0000 0101
|
||||
|
||||
ESB 1111 0011 1010 1111 1000 0000 0001 0000
|
||||
]
|
||||
|
||||
@@ -2142,6 +2142,23 @@ static bool trans_WFI(DisasContext *s, arg_WFI *a)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_SEV(DisasContext *s, arg_SEV *a)
|
||||
{
|
||||
/*
|
||||
* SEV is a NOP for user-mode emulation.
|
||||
*/
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
gen_helper_sev(tcg_env);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_SEVL(DisasContext *s, arg_SEV *a)
|
||||
{
|
||||
gen_event_reg();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_WFE(DisasContext *s, arg_WFI *a)
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -3246,17 +3246,31 @@ static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
|
||||
static bool trans_SEV(DisasContext *s, arg_SEV *a)
|
||||
{
|
||||
/*
|
||||
* Currently SEV is a NOP for non-M-profile and in user-mode emulation.
|
||||
* For system-mode M-profile, it sets the event register.
|
||||
* SEV is a NOP for user-mode emulation. For v6T2 and earlier
|
||||
* non-M-profile cores this encoding is a NOP hint.
|
||||
*/
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M) ||
|
||||
arm_dc_feature(s, ARM_FEATURE_V7)) {
|
||||
gen_helper_sev(tcg_env);
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_SEVL(DisasContext *s, arg_SEV *a)
|
||||
{
|
||||
/*
|
||||
* SEVL only exists for v8A; for M-profile and v7A and earlier
|
||||
* this encoding is an unallocated must-NOP hint.
|
||||
*/
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_M) &&
|
||||
arm_dc_feature(s, ARM_FEATURE_V8)) {
|
||||
gen_event_reg();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_WFE(DisasContext *s, arg_WFE *a)
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -860,6 +860,24 @@ static inline void gen_restore_rmode(TCGv_i32 old, TCGv_ptr fpst)
|
||||
gen_helper_set_rmode(old, old, fpst);
|
||||
}
|
||||
|
||||
/*
|
||||
* Event Register signalling.
|
||||
*
|
||||
* A bunch of activities trigger events, we just need to latch on to
|
||||
* true. The event eventually gets consumed by WFE/WFET.
|
||||
*
|
||||
* user-mode treats these as NOPs.
|
||||
*/
|
||||
|
||||
static inline void gen_event_reg(void)
|
||||
{
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
TCGv_i32 set_event = tcg_constant_i32(1);
|
||||
QEMU_BUILD_BUG_ON(sizeof_field(CPUARMState, event_register) != 1);
|
||||
tcg_gen_st8_i32(set_event, tcg_env, offsetof(CPUARMState, event_register));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Helpers for implementing sets of trans_* functions.
|
||||
* Defer the implementation of NAME to FUNC, with optional extra arguments.
|
||||
|
||||
Reference in New Issue
Block a user