@@ -6116,11 +6116,29 @@ int sve_exception_el(CPUARMState *env, int el)
* they will be zero when EL2 is not present.
*/
if (el <= 2 && !arm_is_secure_below_el3(env)) {
- if (env->cp15.cptr_el[2] & CPTR_TZ) {
- return 2;
- }
- if (env->cp15.cptr_el[2] & CPTR_TFP) {
- return 0;
+ if ((arm_hcr_el2_eff(env) & HCR_E2H) == HCR_E2H) {
+ int zen = extract32(env->cp15.cptr_el[2], 16, 2);
+ switch (zen) {
+ case 0:
+ case 2:
+ return 2;
+ case 1:
+ if ((arm_hcr_el2_eff(env) & HCR_TGE) == HCR_TGE) {
+ if (el == 0) {
+ return 2;
+ }
+ }
+ break;
+ case 3:
+ break;
+ }
+ } else {
+ if (env->cp15.cptr_el[2] & CPTR_TZ) {
+ return 2;
+ }
+ if (env->cp15.cptr_el[2] & CPTR_TFP) {
+ return 0;
+ }
}
}
@@ -12492,10 +12510,29 @@ int fp_exception_el(CPUARMState *env, int cur_el)
*/
/* CPTR_EL2 : present in v7VE or v8 */
- if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1)
- && !arm_is_secure_below_el3(env)) {
+ if ((cur_el <= 2) && !arm_is_secure_below_el3(env)) {
/* Trap FP ops at EL2, NS-EL1 or NS-EL0 to EL2 */
- return 2;
+ if ((arm_hcr_el2_eff(env) & HCR_E2H) == HCR_E2H) {
+ int fpen = extract32(env->cp15.cptr_el[2], 20, 2);
+ switch (fpen) {
+ case 0:
+ case 2:
+ return 2;
+ case 1:
+ if ((arm_hcr_el2_eff(env) & HCR_TGE) == HCR_TGE) {
+ if (cur_el == 0) {
+ return 2;
+ }
+ }
+ break;
+ case 3:
+ break;
+ }
+ } else {
+ if (extract32(env->cp15.cptr_el[2], 10, 1)) {
+ return 2;
+ }
+ }
}
/* CPTR_EL3 : present in v8 */
From DDI0487Fc_armv8_arm.pdf, the CPTR_EL2 has two kinds of layouts according to HCR_EL2.E2H. When HCR_EL2.E2H is 1, fp_exception_el should refer to HCR_EL2.FPEN and sve_exception_el should refer to HCR_EL2.ZEN. Change-Id: If1c8f88db9fb505c36211ceafbf25e838ed96ec0 Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> --- target/arm/helper.c | 53 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 8 deletions(-)