mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 19:15:34 +00:00
target/arm: Update {fp,sve}_exception_el for VHE
When TGE+E2H are both set, CPACR_EL1 is ignored. Backports commit c2ddb7cf963b3bea838266bfca62514dc9750a10 from qemu
This commit is contained in:
parent
86d0163465
commit
01e1e7a3a0
|
@ -5584,7 +5584,9 @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
|
||||||
int sve_exception_el(CPUARMState *env, int el)
|
int sve_exception_el(CPUARMState *env, int el)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
if (el <= 1) {
|
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
|
||||||
|
|
||||||
|
if (el <= 1 && (hcr_el2 & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
|
|
||||||
/* The CPACR.ZEN controls traps to EL1:
|
/* The CPACR.ZEN controls traps to EL1:
|
||||||
|
@ -5599,8 +5601,7 @@ int sve_exception_el(CPUARMState *env, int el)
|
||||||
}
|
}
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
/* route_to_el2 */
|
/* route_to_el2 */
|
||||||
return (arm_feature(env, ARM_FEATURE_EL2)
|
return hcr_el2 & HCR_TGE ? 2 : 1;
|
||||||
&& (arm_hcr_el2_eff(env) & HCR_TGE) ? 2 : 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check CPACR.FPEN. */
|
/* Check CPACR.FPEN. */
|
||||||
|
@ -11557,8 +11558,6 @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
|
||||||
int fp_exception_el(CPUARMState *env, int cur_el)
|
int fp_exception_el(CPUARMState *env, int cur_el)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
int fpen;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CPACR and the CPTR registers don't exist before v6, so FP is
|
* CPACR and the CPTR registers don't exist before v6, so FP is
|
||||||
* always accessible
|
* always accessible
|
||||||
|
@ -11588,30 +11587,34 @@ int fp_exception_el(CPUARMState *env, int cur_el)
|
||||||
* 0, 2 : trap EL0 and EL1/PL1 accesses
|
* 0, 2 : trap EL0 and EL1/PL1 accesses
|
||||||
* 1 : trap only EL0 accesses
|
* 1 : trap only EL0 accesses
|
||||||
* 3 : trap no accesses
|
* 3 : trap no accesses
|
||||||
|
* This register is ignored if E2H+TGE are both set.
|
||||||
*/
|
*/
|
||||||
fpen = extract32(env->cp15.cpacr_el1, 20, 2);
|
if ((arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
|
||||||
switch (fpen) {
|
int fpen = extract32(env->cp15.cpacr_el1, 20, 2);
|
||||||
case 0:
|
|
||||||
case 2:
|
switch (fpen) {
|
||||||
if (cur_el == 0 || cur_el == 1) {
|
case 0:
|
||||||
/* Trap to PL1, which might be EL1 or EL3 */
|
case 2:
|
||||||
if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
|
if (cur_el == 0 || cur_el == 1) {
|
||||||
|
/* Trap to PL1, which might be EL1 or EL3 */
|
||||||
|
if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (cur_el == 3 && !is_a64(env)) {
|
||||||
|
/* Secure PL1 running at EL3 */
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
return 1;
|
break;
|
||||||
|
case 1:
|
||||||
|
if (cur_el == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (cur_el == 3 && !is_a64(env)) {
|
|
||||||
/* Secure PL1 running at EL3 */
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (cur_el == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue