mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-07-07 17:00:35 +00:00
target/arm: Introduce arm_hcr_el2_eff
Replace arm_hcr_el2_{fmo,imo,amo} with a more general routine that also takes SCR_EL3.NS (aka arm_is_secure_below_el3) into account, as documented for the plethora of bits in HCR_EL2. Backports commit f77784446045231f7dfa46c9b872091241fa1557 from qemu
This commit is contained in:
parent
4515df5ee7
commit
78798d10eb
|
@ -3280,6 +3280,7 @@
|
||||||
#define arm64_reg_reset arm64_reg_reset_aarch64
|
#define arm64_reg_reset arm64_reg_reset_aarch64
|
||||||
#define arm64_reg_write arm64_reg_write_aarch64
|
#define arm64_reg_write arm64_reg_write_aarch64
|
||||||
#define arm64_release arm64_release_aarch64
|
#define arm64_release arm64_release_aarch64
|
||||||
|
#define arm_hcr_el2_eff arm_hcr_el2_eff_aarch64
|
||||||
#define arm_regime_tbi0 arm_regime_tbi0_aarch64
|
#define arm_regime_tbi0 arm_regime_tbi0_aarch64
|
||||||
#define arm_regime_tbi1 arm_regime_tbi1_aarch64
|
#define arm_regime_tbi1 arm_regime_tbi1_aarch64
|
||||||
#define arm_register_pre_el_change_hook arm_register_pre_el_change_hook_aarch64
|
#define arm_register_pre_el_change_hook arm_register_pre_el_change_hook_aarch64
|
||||||
|
|
|
@ -3280,6 +3280,7 @@
|
||||||
#define arm64_reg_reset arm64_reg_reset_aarch64eb
|
#define arm64_reg_reset arm64_reg_reset_aarch64eb
|
||||||
#define arm64_reg_write arm64_reg_write_aarch64eb
|
#define arm64_reg_write arm64_reg_write_aarch64eb
|
||||||
#define arm64_release arm64_release_aarch64eb
|
#define arm64_release arm64_release_aarch64eb
|
||||||
|
#define arm_hcr_el2_eff arm_hcr_el2_eff_aarch64eb
|
||||||
#define arm_regime_tbi0 arm_regime_tbi0_aarch64eb
|
#define arm_regime_tbi0 arm_regime_tbi0_aarch64eb
|
||||||
#define arm_regime_tbi1 arm_regime_tbi1_aarch64eb
|
#define arm_regime_tbi1 arm_regime_tbi1_aarch64eb
|
||||||
#define arm_register_pre_el_change_hook arm_register_pre_el_change_hook_aarch64eb
|
#define arm_register_pre_el_change_hook arm_register_pre_el_change_hook_aarch64eb
|
||||||
|
|
|
@ -3272,6 +3272,7 @@
|
||||||
#define xscale_cpar_write xscale_cpar_write_arm
|
#define xscale_cpar_write xscale_cpar_write_arm
|
||||||
#define aarch64_translator_ops aarch64_translator_ops_arm
|
#define aarch64_translator_ops aarch64_translator_ops_arm
|
||||||
#define ARM_REGS_STORAGE_SIZE ARM_REGS_STORAGE_SIZE_arm
|
#define ARM_REGS_STORAGE_SIZE ARM_REGS_STORAGE_SIZE_arm
|
||||||
|
#define arm_hcr_el2_eff arm_hcr_el2_eff_arm
|
||||||
#define arm_regime_tbi0 arm_regime_tbi0_arm
|
#define arm_regime_tbi0 arm_regime_tbi0_arm
|
||||||
#define arm_regime_tbi1 arm_regime_tbi1_arm
|
#define arm_regime_tbi1 arm_regime_tbi1_arm
|
||||||
#define arm_register_pre_el_change_hook arm_register_pre_el_change_hook_arm
|
#define arm_register_pre_el_change_hook arm_register_pre_el_change_hook_arm
|
||||||
|
|
|
@ -3272,6 +3272,7 @@
|
||||||
#define xscale_cpar_write xscale_cpar_write_armeb
|
#define xscale_cpar_write xscale_cpar_write_armeb
|
||||||
#define aarch64_translator_ops aarch64_translator_ops_armeb
|
#define aarch64_translator_ops aarch64_translator_ops_armeb
|
||||||
#define ARM_REGS_STORAGE_SIZE ARM_REGS_STORAGE_SIZE_armeb
|
#define ARM_REGS_STORAGE_SIZE ARM_REGS_STORAGE_SIZE_armeb
|
||||||
|
#define arm_hcr_el2_eff arm_hcr_el2_eff_armeb
|
||||||
#define arm_regime_tbi0 arm_regime_tbi0_armeb
|
#define arm_regime_tbi0 arm_regime_tbi0_armeb
|
||||||
#define arm_regime_tbi1 arm_regime_tbi1_armeb
|
#define arm_regime_tbi1 arm_regime_tbi1_armeb
|
||||||
#define arm_register_pre_el_change_hook arm_register_pre_el_change_hook_armeb
|
#define arm_register_pre_el_change_hook arm_register_pre_el_change_hook_armeb
|
||||||
|
|
|
@ -3281,6 +3281,7 @@ symbols = (
|
||||||
arm_symbols = (
|
arm_symbols = (
|
||||||
'aarch64_translator_ops',
|
'aarch64_translator_ops',
|
||||||
'ARM_REGS_STORAGE_SIZE',
|
'ARM_REGS_STORAGE_SIZE',
|
||||||
|
'arm_hcr_el2_eff',
|
||||||
'arm_regime_tbi0',
|
'arm_regime_tbi0',
|
||||||
'arm_regime_tbi1',
|
'arm_regime_tbi1',
|
||||||
'arm_register_pre_el_change_hook',
|
'arm_register_pre_el_change_hook',
|
||||||
|
@ -3313,6 +3314,7 @@ aarch64_symbols = (
|
||||||
'arm64_reg_reset',
|
'arm64_reg_reset',
|
||||||
'arm64_reg_write',
|
'arm64_reg_write',
|
||||||
'arm64_release',
|
'arm64_release',
|
||||||
|
'arm_hcr_el2_eff',
|
||||||
'arm_regime_tbi0',
|
'arm_regime_tbi0',
|
||||||
'arm_regime_tbi1',
|
'arm_regime_tbi1',
|
||||||
'arm_register_pre_el_change_hook',
|
'arm_register_pre_el_change_hook',
|
||||||
|
|
|
@ -1673,6 +1673,14 @@ static inline bool arm_is_secure(CPUARMState *env)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* arm_hcr_el2_eff(): Return the effective value of HCR_EL2.
|
||||||
|
* E.g. when in secure state, fields in HCR_EL2 are suppressed,
|
||||||
|
* "for all purposes other than a direct read or write access of HCR_EL2."
|
||||||
|
* Not included here is HCR_RW.
|
||||||
|
*/
|
||||||
|
uint64_t arm_hcr_el2_eff(CPUARMState *env);
|
||||||
|
|
||||||
/* Return true if the specified exception level is running in AArch64 state. */
|
/* Return true if the specified exception level is running in AArch64 state. */
|
||||||
static inline bool arm_el_is_aa64(CPUARMState *env, int el)
|
static inline bool arm_el_is_aa64(CPUARMState *env, int el)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1195,9 +1195,10 @@ static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||||
{
|
{
|
||||||
CPUState *cs = ENV_GET_CPU(env);
|
CPUState *cs = ENV_GET_CPU(env);
|
||||||
|
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
|
||||||
uint64_t ret = 0;
|
uint64_t ret = 0;
|
||||||
|
|
||||||
if (arm_hcr_el2_imo(env)) {
|
if (hcr_el2 & HCR_IMO) {
|
||||||
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
|
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
|
||||||
ret |= CPSR_I;
|
ret |= CPSR_I;
|
||||||
}
|
}
|
||||||
|
@ -1207,7 +1208,7 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arm_hcr_el2_fmo(env)) {
|
if (hcr_el2 & HCR_FMO) {
|
||||||
if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
|
if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
|
||||||
ret |= CPSR_F;
|
ret |= CPSR_F;
|
||||||
}
|
}
|
||||||
|
@ -3563,6 +3564,51 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
hcr_write(env, NULL, value);
|
hcr_write(env, NULL, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the effective value of HCR_EL2.
|
||||||
|
* Bits that are not included here:
|
||||||
|
* RW (read from SCR_EL3.RW as needed)
|
||||||
|
*/
|
||||||
|
uint64_t arm_hcr_el2_eff(CPUARMState *env)
|
||||||
|
{
|
||||||
|
uint64_t ret = env->cp15.hcr_el2;
|
||||||
|
|
||||||
|
if (arm_is_secure_below_el3(env)) {
|
||||||
|
/*
|
||||||
|
* "This register has no effect if EL2 is not enabled in the
|
||||||
|
* current Security state". This is ARMv8.4-SecEL2 speak for
|
||||||
|
* !(SCR_EL3.NS==1 || SCR_EL3.EEL2==1).
|
||||||
|
*
|
||||||
|
* Prior to that, the language was "In an implementation that
|
||||||
|
* includes EL3, when the value of SCR_EL3.NS is 0 the PE behaves
|
||||||
|
* as if this field is 0 for all purposes other than a direct
|
||||||
|
* read or write access of HCR_EL2". With lots of enumeration
|
||||||
|
* on a per-field basis. In current QEMU, this is condition
|
||||||
|
* is arm_is_secure_below_el3.
|
||||||
|
*
|
||||||
|
* Since the v8.4 language applies to the entire register, and
|
||||||
|
* appears to be backward compatible, use that.
|
||||||
|
*/
|
||||||
|
ret = 0;
|
||||||
|
} else if (ret & HCR_TGE) {
|
||||||
|
/* These bits are up-to-date as of ARMv8.4. */
|
||||||
|
if (ret & HCR_E2H) {
|
||||||
|
ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO |
|
||||||
|
HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE |
|
||||||
|
HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU |
|
||||||
|
HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE);
|
||||||
|
} else {
|
||||||
|
ret |= HCR_FMO | HCR_IMO | HCR_AMO;
|
||||||
|
}
|
||||||
|
ret &= ~(HCR_SWIO | HCR_PTW | HCR_VF | HCR_VI | HCR_VSE |
|
||||||
|
HCR_FB | HCR_TID1 | HCR_TID3 | HCR_TSC | HCR_TACR |
|
||||||
|
HCR_TSW | HCR_TTLB | HCR_TVM | HCR_HCD | HCR_TRVM |
|
||||||
|
HCR_TLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static const ARMCPRegInfo el2_cp_reginfo[] = {
|
static const ARMCPRegInfo el2_cp_reginfo[] = {
|
||||||
{ "HCR_EL2", 0,1,1, 3,4,0, ARM_CP_STATE_AA64,
|
{ "HCR_EL2", 0,1,1, 3,4,0, ARM_CP_STATE_AA64,
|
||||||
ARM_CP_IO, PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.hcr_el2), {0, 0},
|
ARM_CP_IO, PL2_RW, 0, NULL, 0, offsetof(CPUARMState, cp15.hcr_el2), {0, 0},
|
||||||
|
@ -5708,12 +5754,13 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
|
||||||
uint32_t cur_el, bool secure)
|
uint32_t cur_el, bool secure)
|
||||||
{
|
{
|
||||||
CPUARMState *env = cs->env_ptr;
|
CPUARMState *env = cs->env_ptr;
|
||||||
int rw;
|
bool rw;
|
||||||
int scr;
|
bool scr;
|
||||||
int hcr;
|
bool hcr;
|
||||||
int target_el;
|
int target_el;
|
||||||
/* Is the highest EL AArch64? */
|
/* Is the highest EL AArch64? */
|
||||||
int is64 = arm_feature(env, ARM_FEATURE_AARCH64);
|
bool is64 = arm_feature(env, ARM_FEATURE_AARCH64);
|
||||||
|
uint64_t hcr_el2;
|
||||||
|
|
||||||
if (arm_feature(env, ARM_FEATURE_EL3)) {
|
if (arm_feature(env, ARM_FEATURE_EL3)) {
|
||||||
rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
|
rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
|
||||||
|
@ -5725,18 +5772,19 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
|
||||||
rw = is64;
|
rw = is64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hcr_el2 = arm_hcr_el2_eff(env);
|
||||||
switch (excp_idx) {
|
switch (excp_idx) {
|
||||||
case EXCP_IRQ:
|
case EXCP_IRQ:
|
||||||
scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
|
scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
|
||||||
hcr = arm_hcr_el2_imo(env);
|
hcr = hcr_el2 & HCR_IMO;
|
||||||
break;
|
break;
|
||||||
case EXCP_FIQ:
|
case EXCP_FIQ:
|
||||||
scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
|
scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
|
||||||
hcr = arm_hcr_el2_fmo(env);
|
hcr = hcr_el2 & HCR_FMO;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA);
|
scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA);
|
||||||
hcr = arm_hcr_el2_amo(env);
|
hcr = hcr_el2 & HCR_AMO;
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue