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