1*671efad1SFabiano Rosas /* 2*671efad1SFabiano Rosas * ARM hflags 3*671efad1SFabiano Rosas * 4*671efad1SFabiano Rosas * This code is licensed under the GNU GPL v2 or later. 5*671efad1SFabiano Rosas * 6*671efad1SFabiano Rosas * SPDX-License-Identifier: GPL-2.0-or-later 7*671efad1SFabiano Rosas */ 8*671efad1SFabiano Rosas #include "qemu/osdep.h" 9*671efad1SFabiano Rosas #include "cpu.h" 10*671efad1SFabiano Rosas #include "internals.h" 11*671efad1SFabiano Rosas #include "exec/helper-proto.h" 12*671efad1SFabiano Rosas #include "cpregs.h" 13*671efad1SFabiano Rosas 14*671efad1SFabiano Rosas static inline bool fgt_svc(CPUARMState *env, int el) 15*671efad1SFabiano Rosas { 16*671efad1SFabiano Rosas /* 17*671efad1SFabiano Rosas * Assuming fine-grained-traps are active, return true if we 18*671efad1SFabiano Rosas * should be trapping on SVC instructions. Only AArch64 can 19*671efad1SFabiano Rosas * trap on an SVC at EL1, but we don't need to special-case this 20*671efad1SFabiano Rosas * because if this is AArch32 EL1 then arm_fgt_active() is false. 21*671efad1SFabiano Rosas * We also know el is 0 or 1. 22*671efad1SFabiano Rosas */ 23*671efad1SFabiano Rosas return el == 0 ? 24*671efad1SFabiano Rosas FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL0) : 25*671efad1SFabiano Rosas FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, SVC_EL1); 26*671efad1SFabiano Rosas } 27*671efad1SFabiano Rosas 28*671efad1SFabiano Rosas static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el, 29*671efad1SFabiano Rosas ARMMMUIdx mmu_idx, 30*671efad1SFabiano Rosas CPUARMTBFlags flags) 31*671efad1SFabiano Rosas { 32*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el); 33*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx)); 34*671efad1SFabiano Rosas 35*671efad1SFabiano Rosas if (arm_singlestep_active(env)) { 36*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, SS_ACTIVE, 1); 37*671efad1SFabiano Rosas } 38*671efad1SFabiano Rosas 39*671efad1SFabiano Rosas return flags; 40*671efad1SFabiano Rosas } 41*671efad1SFabiano Rosas 42*671efad1SFabiano Rosas static CPUARMTBFlags rebuild_hflags_common_32(CPUARMState *env, int fp_el, 43*671efad1SFabiano Rosas ARMMMUIdx mmu_idx, 44*671efad1SFabiano Rosas CPUARMTBFlags flags) 45*671efad1SFabiano Rosas { 46*671efad1SFabiano Rosas bool sctlr_b = arm_sctlr_b(env); 47*671efad1SFabiano Rosas 48*671efad1SFabiano Rosas if (sctlr_b) { 49*671efad1SFabiano Rosas DP_TBFLAG_A32(flags, SCTLR__B, 1); 50*671efad1SFabiano Rosas } 51*671efad1SFabiano Rosas if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) { 52*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, BE_DATA, 1); 53*671efad1SFabiano Rosas } 54*671efad1SFabiano Rosas DP_TBFLAG_A32(flags, NS, !access_secure_reg(env)); 55*671efad1SFabiano Rosas 56*671efad1SFabiano Rosas return rebuild_hflags_common(env, fp_el, mmu_idx, flags); 57*671efad1SFabiano Rosas } 58*671efad1SFabiano Rosas 59*671efad1SFabiano Rosas static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el, 60*671efad1SFabiano Rosas ARMMMUIdx mmu_idx) 61*671efad1SFabiano Rosas { 62*671efad1SFabiano Rosas CPUARMTBFlags flags = {}; 63*671efad1SFabiano Rosas uint32_t ccr = env->v7m.ccr[env->v7m.secure]; 64*671efad1SFabiano Rosas 65*671efad1SFabiano Rosas /* Without HaveMainExt, CCR.UNALIGN_TRP is RES1. */ 66*671efad1SFabiano Rosas if (ccr & R_V7M_CCR_UNALIGN_TRP_MASK) { 67*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, ALIGN_MEM, 1); 68*671efad1SFabiano Rosas } 69*671efad1SFabiano Rosas 70*671efad1SFabiano Rosas if (arm_v7m_is_handler_mode(env)) { 71*671efad1SFabiano Rosas DP_TBFLAG_M32(flags, HANDLER, 1); 72*671efad1SFabiano Rosas } 73*671efad1SFabiano Rosas 74*671efad1SFabiano Rosas /* 75*671efad1SFabiano Rosas * v8M always applies stack limit checks unless CCR.STKOFHFNMIGN 76*671efad1SFabiano Rosas * is suppressing them because the requested execution priority 77*671efad1SFabiano Rosas * is less than 0. 78*671efad1SFabiano Rosas */ 79*671efad1SFabiano Rosas if (arm_feature(env, ARM_FEATURE_V8) && 80*671efad1SFabiano Rosas !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) && 81*671efad1SFabiano Rosas (ccr & R_V7M_CCR_STKOFHFNMIGN_MASK))) { 82*671efad1SFabiano Rosas DP_TBFLAG_M32(flags, STACKCHECK, 1); 83*671efad1SFabiano Rosas } 84*671efad1SFabiano Rosas 85*671efad1SFabiano Rosas if (arm_feature(env, ARM_FEATURE_M_SECURITY) && env->v7m.secure) { 86*671efad1SFabiano Rosas DP_TBFLAG_M32(flags, SECURE, 1); 87*671efad1SFabiano Rosas } 88*671efad1SFabiano Rosas 89*671efad1SFabiano Rosas return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags); 90*671efad1SFabiano Rosas } 91*671efad1SFabiano Rosas 92*671efad1SFabiano Rosas /* This corresponds to the ARM pseudocode function IsFullA64Enabled(). */ 93*671efad1SFabiano Rosas static bool sme_fa64(CPUARMState *env, int el) 94*671efad1SFabiano Rosas { 95*671efad1SFabiano Rosas if (!cpu_isar_feature(aa64_sme_fa64, env_archcpu(env))) { 96*671efad1SFabiano Rosas return false; 97*671efad1SFabiano Rosas } 98*671efad1SFabiano Rosas 99*671efad1SFabiano Rosas if (el <= 1 && !el_is_in_host(env, el)) { 100*671efad1SFabiano Rosas if (!FIELD_EX64(env->vfp.smcr_el[1], SMCR, FA64)) { 101*671efad1SFabiano Rosas return false; 102*671efad1SFabiano Rosas } 103*671efad1SFabiano Rosas } 104*671efad1SFabiano Rosas if (el <= 2 && arm_is_el2_enabled(env)) { 105*671efad1SFabiano Rosas if (!FIELD_EX64(env->vfp.smcr_el[2], SMCR, FA64)) { 106*671efad1SFabiano Rosas return false; 107*671efad1SFabiano Rosas } 108*671efad1SFabiano Rosas } 109*671efad1SFabiano Rosas if (arm_feature(env, ARM_FEATURE_EL3)) { 110*671efad1SFabiano Rosas if (!FIELD_EX64(env->vfp.smcr_el[3], SMCR, FA64)) { 111*671efad1SFabiano Rosas return false; 112*671efad1SFabiano Rosas } 113*671efad1SFabiano Rosas } 114*671efad1SFabiano Rosas 115*671efad1SFabiano Rosas return true; 116*671efad1SFabiano Rosas } 117*671efad1SFabiano Rosas 118*671efad1SFabiano Rosas static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el, 119*671efad1SFabiano Rosas ARMMMUIdx mmu_idx) 120*671efad1SFabiano Rosas { 121*671efad1SFabiano Rosas CPUARMTBFlags flags = {}; 122*671efad1SFabiano Rosas int el = arm_current_el(env); 123*671efad1SFabiano Rosas 124*671efad1SFabiano Rosas if (arm_sctlr(env, el) & SCTLR_A) { 125*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, ALIGN_MEM, 1); 126*671efad1SFabiano Rosas } 127*671efad1SFabiano Rosas 128*671efad1SFabiano Rosas if (arm_el_is_aa64(env, 1)) { 129*671efad1SFabiano Rosas DP_TBFLAG_A32(flags, VFPEN, 1); 130*671efad1SFabiano Rosas } 131*671efad1SFabiano Rosas 132*671efad1SFabiano Rosas if (el < 2 && env->cp15.hstr_el2 && arm_is_el2_enabled(env) && 133*671efad1SFabiano Rosas (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) { 134*671efad1SFabiano Rosas DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1); 135*671efad1SFabiano Rosas } 136*671efad1SFabiano Rosas 137*671efad1SFabiano Rosas if (arm_fgt_active(env, el)) { 138*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1); 139*671efad1SFabiano Rosas if (fgt_svc(env, el)) { 140*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, FGT_SVC, 1); 141*671efad1SFabiano Rosas } 142*671efad1SFabiano Rosas } 143*671efad1SFabiano Rosas 144*671efad1SFabiano Rosas if (env->uncached_cpsr & CPSR_IL) { 145*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, PSTATE__IL, 1); 146*671efad1SFabiano Rosas } 147*671efad1SFabiano Rosas 148*671efad1SFabiano Rosas /* 149*671efad1SFabiano Rosas * The SME exception we are testing for is raised via 150*671efad1SFabiano Rosas * AArch64.CheckFPAdvSIMDEnabled(), as called from 151*671efad1SFabiano Rosas * AArch32.CheckAdvSIMDOrFPEnabled(). 152*671efad1SFabiano Rosas */ 153*671efad1SFabiano Rosas if (el == 0 154*671efad1SFabiano Rosas && FIELD_EX64(env->svcr, SVCR, SM) 155*671efad1SFabiano Rosas && (!arm_is_el2_enabled(env) 156*671efad1SFabiano Rosas || (arm_el_is_aa64(env, 2) && !(env->cp15.hcr_el2 & HCR_TGE))) 157*671efad1SFabiano Rosas && arm_el_is_aa64(env, 1) 158*671efad1SFabiano Rosas && !sme_fa64(env, el)) { 159*671efad1SFabiano Rosas DP_TBFLAG_A32(flags, SME_TRAP_NONSTREAMING, 1); 160*671efad1SFabiano Rosas } 161*671efad1SFabiano Rosas 162*671efad1SFabiano Rosas return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags); 163*671efad1SFabiano Rosas } 164*671efad1SFabiano Rosas 165*671efad1SFabiano Rosas static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el, 166*671efad1SFabiano Rosas ARMMMUIdx mmu_idx) 167*671efad1SFabiano Rosas { 168*671efad1SFabiano Rosas CPUARMTBFlags flags = {}; 169*671efad1SFabiano Rosas ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx); 170*671efad1SFabiano Rosas uint64_t tcr = regime_tcr(env, mmu_idx); 171*671efad1SFabiano Rosas uint64_t sctlr; 172*671efad1SFabiano Rosas int tbii, tbid; 173*671efad1SFabiano Rosas 174*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, AARCH64_STATE, 1); 175*671efad1SFabiano Rosas 176*671efad1SFabiano Rosas /* Get control bits for tagged addresses. */ 177*671efad1SFabiano Rosas tbid = aa64_va_parameter_tbi(tcr, mmu_idx); 178*671efad1SFabiano Rosas tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx); 179*671efad1SFabiano Rosas 180*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, TBII, tbii); 181*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, TBID, tbid); 182*671efad1SFabiano Rosas 183*671efad1SFabiano Rosas if (cpu_isar_feature(aa64_sve, env_archcpu(env))) { 184*671efad1SFabiano Rosas int sve_el = sve_exception_el(env, el); 185*671efad1SFabiano Rosas 186*671efad1SFabiano Rosas /* 187*671efad1SFabiano Rosas * If either FP or SVE are disabled, translator does not need len. 188*671efad1SFabiano Rosas * If SVE EL > FP EL, FP exception has precedence, and translator 189*671efad1SFabiano Rosas * does not need SVE EL. Save potential re-translations by forcing 190*671efad1SFabiano Rosas * the unneeded data to zero. 191*671efad1SFabiano Rosas */ 192*671efad1SFabiano Rosas if (fp_el != 0) { 193*671efad1SFabiano Rosas if (sve_el > fp_el) { 194*671efad1SFabiano Rosas sve_el = 0; 195*671efad1SFabiano Rosas } 196*671efad1SFabiano Rosas } else if (sve_el == 0) { 197*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, VL, sve_vqm1_for_el(env, el)); 198*671efad1SFabiano Rosas } 199*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el); 200*671efad1SFabiano Rosas } 201*671efad1SFabiano Rosas if (cpu_isar_feature(aa64_sme, env_archcpu(env))) { 202*671efad1SFabiano Rosas int sme_el = sme_exception_el(env, el); 203*671efad1SFabiano Rosas bool sm = FIELD_EX64(env->svcr, SVCR, SM); 204*671efad1SFabiano Rosas 205*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, SMEEXC_EL, sme_el); 206*671efad1SFabiano Rosas if (sme_el == 0) { 207*671efad1SFabiano Rosas /* Similarly, do not compute SVL if SME is disabled. */ 208*671efad1SFabiano Rosas int svl = sve_vqm1_for_el_sm(env, el, true); 209*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, SVL, svl); 210*671efad1SFabiano Rosas if (sm) { 211*671efad1SFabiano Rosas /* If SVE is disabled, we will not have set VL above. */ 212*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, VL, svl); 213*671efad1SFabiano Rosas } 214*671efad1SFabiano Rosas } 215*671efad1SFabiano Rosas if (sm) { 216*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, PSTATE_SM, 1); 217*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, SME_TRAP_NONSTREAMING, !sme_fa64(env, el)); 218*671efad1SFabiano Rosas } 219*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, PSTATE_ZA, FIELD_EX64(env->svcr, SVCR, ZA)); 220*671efad1SFabiano Rosas } 221*671efad1SFabiano Rosas 222*671efad1SFabiano Rosas sctlr = regime_sctlr(env, stage1); 223*671efad1SFabiano Rosas 224*671efad1SFabiano Rosas if (sctlr & SCTLR_A) { 225*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, ALIGN_MEM, 1); 226*671efad1SFabiano Rosas } 227*671efad1SFabiano Rosas 228*671efad1SFabiano Rosas if (arm_cpu_data_is_big_endian_a64(el, sctlr)) { 229*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, BE_DATA, 1); 230*671efad1SFabiano Rosas } 231*671efad1SFabiano Rosas 232*671efad1SFabiano Rosas if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) { 233*671efad1SFabiano Rosas /* 234*671efad1SFabiano Rosas * In order to save space in flags, we record only whether 235*671efad1SFabiano Rosas * pauth is "inactive", meaning all insns are implemented as 236*671efad1SFabiano Rosas * a nop, or "active" when some action must be performed. 237*671efad1SFabiano Rosas * The decision of which action to take is left to a helper. 238*671efad1SFabiano Rosas */ 239*671efad1SFabiano Rosas if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) { 240*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, PAUTH_ACTIVE, 1); 241*671efad1SFabiano Rosas } 242*671efad1SFabiano Rosas } 243*671efad1SFabiano Rosas 244*671efad1SFabiano Rosas if (cpu_isar_feature(aa64_bti, env_archcpu(env))) { 245*671efad1SFabiano Rosas /* Note that SCTLR_EL[23].BT == SCTLR_BT1. */ 246*671efad1SFabiano Rosas if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) { 247*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, BT, 1); 248*671efad1SFabiano Rosas } 249*671efad1SFabiano Rosas } 250*671efad1SFabiano Rosas 251*671efad1SFabiano Rosas /* Compute the condition for using AccType_UNPRIV for LDTR et al. */ 252*671efad1SFabiano Rosas if (!(env->pstate & PSTATE_UAO)) { 253*671efad1SFabiano Rosas switch (mmu_idx) { 254*671efad1SFabiano Rosas case ARMMMUIdx_E10_1: 255*671efad1SFabiano Rosas case ARMMMUIdx_E10_1_PAN: 256*671efad1SFabiano Rosas /* TODO: ARMv8.3-NV */ 257*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, UNPRIV, 1); 258*671efad1SFabiano Rosas break; 259*671efad1SFabiano Rosas case ARMMMUIdx_E20_2: 260*671efad1SFabiano Rosas case ARMMMUIdx_E20_2_PAN: 261*671efad1SFabiano Rosas /* 262*671efad1SFabiano Rosas * Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is 263*671efad1SFabiano Rosas * gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR. 264*671efad1SFabiano Rosas */ 265*671efad1SFabiano Rosas if (env->cp15.hcr_el2 & HCR_TGE) { 266*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, UNPRIV, 1); 267*671efad1SFabiano Rosas } 268*671efad1SFabiano Rosas break; 269*671efad1SFabiano Rosas default: 270*671efad1SFabiano Rosas break; 271*671efad1SFabiano Rosas } 272*671efad1SFabiano Rosas } 273*671efad1SFabiano Rosas 274*671efad1SFabiano Rosas if (env->pstate & PSTATE_IL) { 275*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, PSTATE__IL, 1); 276*671efad1SFabiano Rosas } 277*671efad1SFabiano Rosas 278*671efad1SFabiano Rosas if (arm_fgt_active(env, el)) { 279*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, FGT_ACTIVE, 1); 280*671efad1SFabiano Rosas if (FIELD_EX64(env->cp15.fgt_exec[FGTREG_HFGITR], HFGITR_EL2, ERET)) { 281*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, FGT_ERET, 1); 282*671efad1SFabiano Rosas } 283*671efad1SFabiano Rosas if (fgt_svc(env, el)) { 284*671efad1SFabiano Rosas DP_TBFLAG_ANY(flags, FGT_SVC, 1); 285*671efad1SFabiano Rosas } 286*671efad1SFabiano Rosas } 287*671efad1SFabiano Rosas 288*671efad1SFabiano Rosas if (cpu_isar_feature(aa64_mte, env_archcpu(env))) { 289*671efad1SFabiano Rosas /* 290*671efad1SFabiano Rosas * Set MTE_ACTIVE if any access may be Checked, and leave clear 291*671efad1SFabiano Rosas * if all accesses must be Unchecked: 292*671efad1SFabiano Rosas * 1) If no TBI, then there are no tags in the address to check, 293*671efad1SFabiano Rosas * 2) If Tag Check Override, then all accesses are Unchecked, 294*671efad1SFabiano Rosas * 3) If Tag Check Fail == 0, then Checked access have no effect, 295*671efad1SFabiano Rosas * 4) If no Allocation Tag Access, then all accesses are Unchecked. 296*671efad1SFabiano Rosas */ 297*671efad1SFabiano Rosas if (allocation_tag_access_enabled(env, el, sctlr)) { 298*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, ATA, 1); 299*671efad1SFabiano Rosas if (tbid 300*671efad1SFabiano Rosas && !(env->pstate & PSTATE_TCO) 301*671efad1SFabiano Rosas && (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) { 302*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, MTE_ACTIVE, 1); 303*671efad1SFabiano Rosas } 304*671efad1SFabiano Rosas } 305*671efad1SFabiano Rosas /* And again for unprivileged accesses, if required. */ 306*671efad1SFabiano Rosas if (EX_TBFLAG_A64(flags, UNPRIV) 307*671efad1SFabiano Rosas && tbid 308*671efad1SFabiano Rosas && !(env->pstate & PSTATE_TCO) 309*671efad1SFabiano Rosas && (sctlr & SCTLR_TCF0) 310*671efad1SFabiano Rosas && allocation_tag_access_enabled(env, 0, sctlr)) { 311*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, MTE0_ACTIVE, 1); 312*671efad1SFabiano Rosas } 313*671efad1SFabiano Rosas /* Cache TCMA as well as TBI. */ 314*671efad1SFabiano Rosas DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx)); 315*671efad1SFabiano Rosas } 316*671efad1SFabiano Rosas 317*671efad1SFabiano Rosas return rebuild_hflags_common(env, fp_el, mmu_idx, flags); 318*671efad1SFabiano Rosas } 319*671efad1SFabiano Rosas 320*671efad1SFabiano Rosas static CPUARMTBFlags rebuild_hflags_internal(CPUARMState *env) 321*671efad1SFabiano Rosas { 322*671efad1SFabiano Rosas int el = arm_current_el(env); 323*671efad1SFabiano Rosas int fp_el = fp_exception_el(env, el); 324*671efad1SFabiano Rosas ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); 325*671efad1SFabiano Rosas 326*671efad1SFabiano Rosas if (is_a64(env)) { 327*671efad1SFabiano Rosas return rebuild_hflags_a64(env, el, fp_el, mmu_idx); 328*671efad1SFabiano Rosas } else if (arm_feature(env, ARM_FEATURE_M)) { 329*671efad1SFabiano Rosas return rebuild_hflags_m32(env, fp_el, mmu_idx); 330*671efad1SFabiano Rosas } else { 331*671efad1SFabiano Rosas return rebuild_hflags_a32(env, fp_el, mmu_idx); 332*671efad1SFabiano Rosas } 333*671efad1SFabiano Rosas } 334*671efad1SFabiano Rosas 335*671efad1SFabiano Rosas void arm_rebuild_hflags(CPUARMState *env) 336*671efad1SFabiano Rosas { 337*671efad1SFabiano Rosas env->hflags = rebuild_hflags_internal(env); 338*671efad1SFabiano Rosas } 339*671efad1SFabiano Rosas 340*671efad1SFabiano Rosas /* 341*671efad1SFabiano Rosas * If we have triggered a EL state change we can't rely on the 342*671efad1SFabiano Rosas * translator having passed it to us, we need to recompute. 343*671efad1SFabiano Rosas */ 344*671efad1SFabiano Rosas void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env) 345*671efad1SFabiano Rosas { 346*671efad1SFabiano Rosas int el = arm_current_el(env); 347*671efad1SFabiano Rosas int fp_el = fp_exception_el(env, el); 348*671efad1SFabiano Rosas ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); 349*671efad1SFabiano Rosas 350*671efad1SFabiano Rosas env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx); 351*671efad1SFabiano Rosas } 352*671efad1SFabiano Rosas 353*671efad1SFabiano Rosas void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el) 354*671efad1SFabiano Rosas { 355*671efad1SFabiano Rosas int fp_el = fp_exception_el(env, el); 356*671efad1SFabiano Rosas ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); 357*671efad1SFabiano Rosas 358*671efad1SFabiano Rosas env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx); 359*671efad1SFabiano Rosas } 360*671efad1SFabiano Rosas 361*671efad1SFabiano Rosas /* 362*671efad1SFabiano Rosas * If we have triggered a EL state change we can't rely on the 363*671efad1SFabiano Rosas * translator having passed it to us, we need to recompute. 364*671efad1SFabiano Rosas */ 365*671efad1SFabiano Rosas void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env) 366*671efad1SFabiano Rosas { 367*671efad1SFabiano Rosas int el = arm_current_el(env); 368*671efad1SFabiano Rosas int fp_el = fp_exception_el(env, el); 369*671efad1SFabiano Rosas ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); 370*671efad1SFabiano Rosas env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx); 371*671efad1SFabiano Rosas } 372*671efad1SFabiano Rosas 373*671efad1SFabiano Rosas void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el) 374*671efad1SFabiano Rosas { 375*671efad1SFabiano Rosas int fp_el = fp_exception_el(env, el); 376*671efad1SFabiano Rosas ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); 377*671efad1SFabiano Rosas 378*671efad1SFabiano Rosas env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx); 379*671efad1SFabiano Rosas } 380*671efad1SFabiano Rosas 381*671efad1SFabiano Rosas void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el) 382*671efad1SFabiano Rosas { 383*671efad1SFabiano Rosas int fp_el = fp_exception_el(env, el); 384*671efad1SFabiano Rosas ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el); 385*671efad1SFabiano Rosas 386*671efad1SFabiano Rosas env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx); 387*671efad1SFabiano Rosas } 388*671efad1SFabiano Rosas 389*671efad1SFabiano Rosas void assert_hflags_rebuild_correctly(CPUARMState *env) 390*671efad1SFabiano Rosas { 391*671efad1SFabiano Rosas #ifdef CONFIG_DEBUG_TCG 392*671efad1SFabiano Rosas CPUARMTBFlags c = env->hflags; 393*671efad1SFabiano Rosas CPUARMTBFlags r = rebuild_hflags_internal(env); 394*671efad1SFabiano Rosas 395*671efad1SFabiano Rosas if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) { 396*671efad1SFabiano Rosas fprintf(stderr, "TCG hflags mismatch " 397*671efad1SFabiano Rosas "(current:(0x%08x,0x" TARGET_FMT_lx ")" 398*671efad1SFabiano Rosas " rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n", 399*671efad1SFabiano Rosas c.flags, c.flags2, r.flags, r.flags2); 400*671efad1SFabiano Rosas abort(); 401*671efad1SFabiano Rosas } 402*671efad1SFabiano Rosas #endif 403*671efad1SFabiano Rosas } 404