1 /* 2 * System instructions for address translation 3 * SPDX-License-Identifier: GPL-2.0-or-later 4 */ 5 6 #include "qemu/osdep.h" 7 #include "cpu.h" 8 #include "cpu-features.h" 9 #include "internals.h" 10 #include "cpregs.h" 11 12 13 static int par_el1_shareability(GetPhysAddrResult *res) 14 { 15 /* 16 * The PAR_EL1.SH field must be 0b10 for Device or Normal-NC 17 * memory -- see pseudocode PAREncodeShareability(). 18 */ 19 if (((res->cacheattrs.attrs & 0xf0) == 0) || 20 res->cacheattrs.attrs == 0x44 || res->cacheattrs.attrs == 0x40) { 21 return 2; 22 } 23 return res->cacheattrs.shareability; 24 } 25 26 static uint64_t do_ats_write(CPUARMState *env, uint64_t value, 27 unsigned prot_check, ARMMMUIdx mmu_idx, 28 ARMSecuritySpace ss) 29 { 30 uint64_t par64; 31 bool format64 = false; 32 ARMMMUFaultInfo fi = {}; 33 GetPhysAddrResult res = {}; 34 bool ret = get_phys_addr_for_at(env, value, prot_check, 35 mmu_idx, ss, &res, &fi); 36 37 /* 38 * ATS operations only do S1 or S1+S2 translations, so we never 39 * have to deal with the ARMCacheAttrs format for S2 only. 40 */ 41 assert(!res.cacheattrs.is_s2_format); 42 43 if (ret) { 44 /* 45 * Some kinds of translation fault must cause exceptions rather 46 * than being reported in the PAR. 47 */ 48 int current_el = arm_current_el(env); 49 int target_el; 50 uint32_t syn, fsr, fsc; 51 bool take_exc = false; 52 53 if (fi.s1ptw && current_el == 1 54 && arm_mmu_idx_is_stage1_of_2(mmu_idx)) { 55 /* 56 * Synchronous stage 2 fault on an access made as part of the 57 * translation table walk for AT S1E0* or AT S1E1* insn 58 * executed from NS EL1. If this is a synchronous external abort 59 * and SCR_EL3.EA == 1, then we take a synchronous external abort 60 * to EL3. Otherwise the fault is taken as an exception to EL2, 61 * and HPFAR_EL2 holds the faulting IPA. 62 */ 63 if (fi.type == ARMFault_SyncExternalOnWalk && 64 (env->cp15.scr_el3 & SCR_EA)) { 65 target_el = 3; 66 } else { 67 env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4; 68 if (arm_is_secure_below_el3(env) && fi.s1ns) { 69 env->cp15.hpfar_el2 |= HPFAR_NS; 70 } 71 target_el = 2; 72 } 73 take_exc = true; 74 } else if (fi.type == ARMFault_SyncExternalOnWalk) { 75 /* 76 * Synchronous external aborts during a translation table walk 77 * are taken as Data Abort exceptions. 78 */ 79 if (fi.stage2) { 80 if (current_el == 3) { 81 target_el = 3; 82 } else { 83 target_el = 2; 84 } 85 } else { 86 target_el = exception_target_el(env); 87 } 88 take_exc = true; 89 } 90 91 if (take_exc) { 92 /* Construct FSR and FSC using same logic as arm_deliver_fault() */ 93 if (target_el == 2 || arm_el_is_aa64(env, target_el) || 94 arm_s1_regime_using_lpae_format(env, mmu_idx)) { 95 fsr = arm_fi_to_lfsc(&fi); 96 fsc = extract32(fsr, 0, 6); 97 } else { 98 fsr = arm_fi_to_sfsc(&fi); 99 fsc = 0x3f; 100 } 101 /* 102 * Report exception with ESR indicating a fault due to a 103 * translation table walk for a cache maintenance instruction. 104 */ 105 syn = syn_data_abort_no_iss(current_el == target_el, 0, 106 fi.ea, 1, fi.s1ptw, 1, fsc); 107 env->exception.vaddress = value; 108 env->exception.fsr = fsr; 109 raise_exception(env, EXCP_DATA_ABORT, syn, target_el); 110 } 111 } 112 113 if (is_a64(env)) { 114 format64 = true; 115 } else if (arm_feature(env, ARM_FEATURE_LPAE)) { 116 /* 117 * ATS1Cxx: 118 * * TTBCR.EAE determines whether the result is returned using the 119 * 32-bit or the 64-bit PAR format 120 * * Instructions executed in Hyp mode always use the 64bit format 121 * 122 * ATS1S2NSOxx uses the 64bit format if any of the following is true: 123 * * The Non-secure TTBCR.EAE bit is set to 1 124 * * The implementation includes EL2, and the value of HCR.VM is 1 125 * 126 * (Note that HCR.DC makes HCR.VM behave as if it is 1.) 127 * 128 * ATS1Hx always uses the 64bit format. 129 */ 130 format64 = arm_s1_regime_using_lpae_format(env, mmu_idx); 131 132 if (arm_feature(env, ARM_FEATURE_EL2)) { 133 if (mmu_idx == ARMMMUIdx_E10_0 || 134 mmu_idx == ARMMMUIdx_E10_1 || 135 mmu_idx == ARMMMUIdx_E10_1_PAN) { 136 format64 |= env->cp15.hcr_el2 & (HCR_VM | HCR_DC); 137 } else { 138 format64 |= arm_current_el(env) == 2; 139 } 140 } 141 } 142 143 if (format64) { 144 /* Create a 64-bit PAR */ 145 par64 = (1 << 11); /* LPAE bit always set */ 146 if (!ret) { 147 par64 |= res.f.phys_addr & ~0xfffULL; 148 if (!res.f.attrs.secure) { 149 par64 |= (1 << 9); /* NS */ 150 } 151 par64 |= (uint64_t)res.cacheattrs.attrs << 56; /* ATTR */ 152 par64 |= par_el1_shareability(&res) << 7; /* SH */ 153 } else { 154 uint32_t fsr = arm_fi_to_lfsc(&fi); 155 156 par64 |= 1; /* F */ 157 par64 |= (fsr & 0x3f) << 1; /* FS */ 158 if (fi.stage2) { 159 par64 |= (1 << 9); /* S */ 160 } 161 if (fi.s1ptw) { 162 par64 |= (1 << 8); /* PTW */ 163 } 164 } 165 } else { 166 /* 167 * fsr is a DFSR/IFSR value for the short descriptor 168 * translation table format (with WnR always clear). 169 * Convert it to a 32-bit PAR. 170 */ 171 if (!ret) { 172 /* We do not set any attribute bits in the PAR */ 173 if (res.f.lg_page_size == 24 174 && arm_feature(env, ARM_FEATURE_V7)) { 175 par64 = (res.f.phys_addr & 0xff000000) | (1 << 1); 176 } else { 177 par64 = res.f.phys_addr & 0xfffff000; 178 } 179 if (!res.f.attrs.secure) { 180 par64 |= (1 << 9); /* NS */ 181 } 182 } else { 183 uint32_t fsr = arm_fi_to_sfsc(&fi); 184 185 par64 = ((fsr & (1 << 10)) >> 5) | ((fsr & (1 << 12)) >> 6) | 186 ((fsr & 0xf) << 1) | 1; 187 } 188 } 189 return par64; 190 } 191 192 static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) 193 { 194 unsigned access_perm = ri->opc2 & 1 ? PAGE_WRITE : PAGE_READ; 195 uint64_t par64; 196 ARMMMUIdx mmu_idx; 197 int el = arm_current_el(env); 198 ARMSecuritySpace ss = arm_security_space(env); 199 200 switch (ri->opc2 & 6) { 201 case 0: 202 /* stage 1 current state PL1: ATS1CPR, ATS1CPW, ATS1CPRP, ATS1CPWP */ 203 switch (el) { 204 case 3: 205 if (ri->crm == 9 && arm_pan_enabled(env)) { 206 mmu_idx = ARMMMUIdx_E30_3_PAN; 207 } else { 208 mmu_idx = ARMMMUIdx_E3; 209 } 210 break; 211 case 2: 212 g_assert(ss != ARMSS_Secure); /* ARMv8.4-SecEL2 is 64-bit only */ 213 /* fall through */ 214 case 1: 215 if (ri->crm == 9 && arm_pan_enabled(env)) { 216 mmu_idx = ARMMMUIdx_Stage1_E1_PAN; 217 } else { 218 mmu_idx = ARMMMUIdx_Stage1_E1; 219 } 220 break; 221 default: 222 g_assert_not_reached(); 223 } 224 break; 225 case 2: 226 /* stage 1 current state PL0: ATS1CUR, ATS1CUW */ 227 switch (el) { 228 case 3: 229 mmu_idx = ARMMMUIdx_E30_0; 230 break; 231 case 2: 232 g_assert(ss != ARMSS_Secure); /* ARMv8.4-SecEL2 is 64-bit only */ 233 mmu_idx = ARMMMUIdx_Stage1_E0; 234 break; 235 case 1: 236 mmu_idx = ARMMMUIdx_Stage1_E0; 237 break; 238 default: 239 g_assert_not_reached(); 240 } 241 break; 242 case 4: 243 /* stage 1+2 NonSecure PL1: ATS12NSOPR, ATS12NSOPW */ 244 mmu_idx = ARMMMUIdx_E10_1; 245 ss = ARMSS_NonSecure; 246 break; 247 case 6: 248 /* stage 1+2 NonSecure PL0: ATS12NSOUR, ATS12NSOUW */ 249 mmu_idx = ARMMMUIdx_E10_0; 250 ss = ARMSS_NonSecure; 251 break; 252 default: 253 g_assert_not_reached(); 254 } 255 256 par64 = do_ats_write(env, value, access_perm, mmu_idx, ss); 257 258 A32_BANKED_CURRENT_REG_SET(env, par, par64); 259 } 260 261 static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri, 262 uint64_t value) 263 { 264 unsigned access_perm = ri->opc2 & 1 ? PAGE_WRITE : PAGE_READ; 265 uint64_t par64; 266 267 /* There is no SecureEL2 for AArch32. */ 268 par64 = do_ats_write(env, value, access_perm, ARMMMUIdx_E2, 269 ARMSS_NonSecure); 270 271 A32_BANKED_CURRENT_REG_SET(env, par, par64); 272 } 273 274 static CPAccessResult at_e012_access(CPUARMState *env, const ARMCPRegInfo *ri, 275 bool isread) 276 { 277 /* 278 * R_NYXTL: instruction is UNDEFINED if it applies to an Exception level 279 * lower than EL3 and the combination SCR_EL3.{NSE,NS} is reserved. This can 280 * only happen when executing at EL3 because that combination also causes an 281 * illegal exception return. We don't need to check FEAT_RME either, because 282 * scr_write() ensures that the NSE bit is not set otherwise. 283 */ 284 if ((env->cp15.scr_el3 & (SCR_NSE | SCR_NS)) == SCR_NSE) { 285 return CP_ACCESS_UNDEFINED; 286 } 287 return CP_ACCESS_OK; 288 } 289 290 static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri, 291 bool isread) 292 { 293 if (arm_current_el(env) == 3 && 294 !(env->cp15.scr_el3 & (SCR_NS | SCR_EEL2))) { 295 return CP_ACCESS_UNDEFINED; 296 } 297 return at_e012_access(env, ri, isread); 298 } 299 300 static CPAccessResult at_s1e01_access(CPUARMState *env, const ARMCPRegInfo *ri, 301 bool isread) 302 { 303 if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_AT)) { 304 return CP_ACCESS_TRAP_EL2; 305 } 306 return at_e012_access(env, ri, isread); 307 } 308 309 static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri, 310 uint64_t value) 311 { 312 unsigned access_perm = ri->opc2 & 1 ? PAGE_WRITE : PAGE_READ; 313 ARMMMUIdx mmu_idx; 314 uint64_t hcr_el2 = arm_hcr_el2_eff(env); 315 bool regime_e20 = (hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE); 316 bool for_el3 = false; 317 ARMSecuritySpace ss; 318 319 switch (ri->opc2 & 6) { 320 case 0: 321 switch (ri->opc1) { 322 case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */ 323 if (ri->crm == 9 && arm_pan_enabled(env)) { 324 mmu_idx = regime_e20 ? 325 ARMMMUIdx_E20_2_PAN : ARMMMUIdx_Stage1_E1_PAN; 326 } else { 327 mmu_idx = regime_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_Stage1_E1; 328 } 329 break; 330 case 4: /* AT S1E2R, AT S1E2W */ 331 mmu_idx = hcr_el2 & HCR_E2H ? ARMMMUIdx_E20_2 : ARMMMUIdx_E2; 332 break; 333 case 6: /* AT S1E3R, AT S1E3W */ 334 mmu_idx = ARMMMUIdx_E3; 335 for_el3 = true; 336 break; 337 default: 338 g_assert_not_reached(); 339 } 340 break; 341 case 2: /* AT S1E0R, AT S1E0W */ 342 mmu_idx = regime_e20 ? ARMMMUIdx_E20_0 : ARMMMUIdx_Stage1_E0; 343 break; 344 case 4: /* AT S12E1R, AT S12E1W */ 345 mmu_idx = regime_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_E10_1; 346 break; 347 case 6: /* AT S12E0R, AT S12E0W */ 348 mmu_idx = regime_e20 ? ARMMMUIdx_E20_0 : ARMMMUIdx_E10_0; 349 break; 350 default: 351 g_assert_not_reached(); 352 } 353 354 ss = for_el3 ? arm_security_space(env) : arm_security_space_below_el3(env); 355 env->cp15.par_el[1] = do_ats_write(env, value, access_perm, mmu_idx, ss); 356 } 357 358 static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri, 359 bool isread) 360 { 361 if (ri->opc2 & 4) { 362 /* 363 * The ATS12NSO* operations must trap to EL3 or EL2 if executed in 364 * Secure EL1 (which can only happen if EL3 is AArch64). 365 * They are simply UNDEF if executed from NS EL1. 366 * They function normally from EL2 or EL3. 367 */ 368 if (arm_current_el(env) == 1) { 369 if (arm_is_secure_below_el3(env)) { 370 if (env->cp15.scr_el3 & SCR_EEL2) { 371 return CP_ACCESS_TRAP_EL2; 372 } 373 return CP_ACCESS_TRAP_EL3; 374 } 375 return CP_ACCESS_UNDEFINED; 376 } 377 } 378 return CP_ACCESS_OK; 379 } 380 381 static const ARMCPRegInfo vapa_ats_reginfo[] = { 382 /* This underdecoding is safe because the reginfo is NO_RAW. */ 383 { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY, 384 .access = PL1_W, .accessfn = ats_access, 385 .writefn = ats_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC }, 386 }; 387 388 static const ARMCPRegInfo v8_ats_reginfo[] = { 389 /* 64 bit address translation operations */ 390 { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64, 391 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0, 392 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 393 .fgt = FGT_ATS1E1R, 394 .accessfn = at_s1e01_access, .writefn = ats_write64 }, 395 { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64, 396 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1, 397 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 398 .fgt = FGT_ATS1E1W, 399 .accessfn = at_s1e01_access, .writefn = ats_write64 }, 400 { .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64, 401 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2, 402 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 403 .fgt = FGT_ATS1E0R, 404 .accessfn = at_s1e01_access, .writefn = ats_write64 }, 405 { .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64, 406 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3, 407 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 408 .fgt = FGT_ATS1E0W, 409 .accessfn = at_s1e01_access, .writefn = ats_write64 }, 410 { .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64, 411 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4, 412 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 413 .accessfn = at_e012_access, .writefn = ats_write64 }, 414 { .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64, 415 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5, 416 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 417 .accessfn = at_e012_access, .writefn = ats_write64 }, 418 { .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64, 419 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6, 420 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 421 .accessfn = at_e012_access, .writefn = ats_write64 }, 422 { .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64, 423 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7, 424 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 425 .accessfn = at_e012_access, .writefn = ats_write64 }, 426 /* AT S1E2* are elsewhere as they UNDEF from EL3 if EL2 is not present */ 427 { .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64, 428 .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0, 429 .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 430 .writefn = ats_write64 }, 431 { .name = "AT_S1E3W", .state = ARM_CP_STATE_AA64, 432 .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 1, 433 .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 434 .writefn = ats_write64 }, 435 }; 436 437 static const ARMCPRegInfo el2_ats_reginfo[] = { 438 /* 439 * Unlike the other EL2-related AT operations, these must 440 * UNDEF from EL3 if EL2 is not implemented, which is why we 441 * define them here rather than with the rest of the AT ops. 442 */ 443 { .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64, 444 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0, 445 .access = PL2_W, .accessfn = at_s1e2_access, 446 .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC | ARM_CP_EL3_NO_EL2_UNDEF, 447 .writefn = ats_write64 }, 448 { .name = "AT_S1E2W", .state = ARM_CP_STATE_AA64, 449 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1, 450 .access = PL2_W, .accessfn = at_s1e2_access, 451 .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC | ARM_CP_EL3_NO_EL2_UNDEF, 452 .writefn = ats_write64 }, 453 /* 454 * The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE 455 * if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3 456 * with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose 457 * to behave as if SCR.NS was 1. 458 */ 459 { .name = "ATS1HR", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0, 460 .access = PL2_W, 461 .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC }, 462 { .name = "ATS1HW", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1, 463 .access = PL2_W, 464 .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC }, 465 }; 466 467 static const ARMCPRegInfo ats1e1_reginfo[] = { 468 { .name = "AT_S1E1RP", .state = ARM_CP_STATE_AA64, 469 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0, 470 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 471 .fgt = FGT_ATS1E1RP, 472 .accessfn = at_s1e01_access, .writefn = ats_write64 }, 473 { .name = "AT_S1E1WP", .state = ARM_CP_STATE_AA64, 474 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1, 475 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 476 .fgt = FGT_ATS1E1WP, 477 .accessfn = at_s1e01_access, .writefn = ats_write64 }, 478 }; 479 480 static const ARMCPRegInfo ats1cp_reginfo[] = { 481 { .name = "ATS1CPRP", 482 .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0, 483 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 484 .writefn = ats_write }, 485 { .name = "ATS1CPWP", 486 .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1, 487 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 488 .writefn = ats_write }, 489 }; 490 491 static void ats_s1e1a(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) 492 { 493 uint64_t hcr_el2 = arm_hcr_el2_eff(env); 494 bool regime_e20 = (hcr_el2 & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE); 495 ARMMMUIdx mmu_idx = regime_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_Stage1_E1; 496 ARMSecuritySpace ss = arm_security_space_below_el3(env); 497 498 env->cp15.par_el[1] = do_ats_write(env, value, 0, mmu_idx, ss); 499 } 500 501 static void ats_s1e2a(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) 502 { 503 uint64_t hcr_el2 = arm_hcr_el2_eff(env); 504 ARMMMUIdx mmu_idx = hcr_el2 & HCR_E2H ? ARMMMUIdx_E20_2 : ARMMMUIdx_E2; 505 ARMSecuritySpace ss = arm_security_space_below_el3(env); 506 507 env->cp15.par_el[1] = do_ats_write(env, value, 0, mmu_idx, ss); 508 } 509 510 static void ats_s1e3a(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) 511 { 512 env->cp15.par_el[1] = do_ats_write(env, value, 0, ARMMMUIdx_E3, 513 arm_security_space(env)); 514 } 515 516 static const ARMCPRegInfo ats1a_reginfo[] = { 517 { .name = "AT_S1E1A", .state = ARM_CP_STATE_AA64, 518 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 2, 519 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 520 .fgt = FGT_ATS1E1A, 521 .accessfn = at_s1e01_access, .writefn = ats_s1e1a }, 522 { .name = "AT_S1E2A", .state = ARM_CP_STATE_AA64, 523 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 9, .opc2 = 2, 524 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 525 .accessfn = at_s1e2_access, .writefn = ats_s1e2a }, 526 { .name = "AT_S1E3A", .state = ARM_CP_STATE_AA64, 527 .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 9, .opc2 = 2, 528 .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, 529 .writefn = ats_s1e3a }, 530 }; 531 532 void define_at_insn_regs(ARMCPU *cpu) 533 { 534 CPUARMState *env = &cpu->env; 535 536 if (arm_feature(env, ARM_FEATURE_VAPA)) { 537 define_arm_cp_regs(cpu, vapa_ats_reginfo); 538 } 539 if (arm_feature(env, ARM_FEATURE_V8)) { 540 define_arm_cp_regs(cpu, v8_ats_reginfo); 541 } 542 if (arm_feature(env, ARM_FEATURE_EL2) 543 || (arm_feature(env, ARM_FEATURE_EL3) 544 && arm_feature(env, ARM_FEATURE_V8))) { 545 define_arm_cp_regs(cpu, el2_ats_reginfo); 546 } 547 if (cpu_isar_feature(aa64_ats1e1, cpu)) { 548 define_arm_cp_regs(cpu, ats1e1_reginfo); 549 } 550 if (cpu_isar_feature(aa32_ats1e1, cpu)) { 551 define_arm_cp_regs(cpu, ats1cp_reginfo); 552 } 553 if (cpu_isar_feature(aa64_ats1a, cpu)) { 554 define_arm_cp_regs(cpu, ats1a_reginfo); 555 } 556 } 557