1 /* 2 * Helpers for TLBI insns 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 "qemu/log.h" 10 #include "exec/exec-all.h" 11 #include "cpu.h" 12 #include "internals.h" 13 #include "cpu-features.h" 14 #include "cpregs.h" 15 16 /* Check for traps from EL1 due to HCR_EL2.TTLB. */ 17 static CPAccessResult access_ttlb(CPUARMState *env, const ARMCPRegInfo *ri, 18 bool isread) 19 { 20 if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TTLB)) { 21 return CP_ACCESS_TRAP_EL2; 22 } 23 return CP_ACCESS_OK; 24 } 25 26 /* Check for traps from EL1 due to HCR_EL2.TTLB or TTLBIS. */ 27 static CPAccessResult access_ttlbis(CPUARMState *env, const ARMCPRegInfo *ri, 28 bool isread) 29 { 30 if (arm_current_el(env) == 1 && 31 (arm_hcr_el2_eff(env) & (HCR_TTLB | HCR_TTLBIS))) { 32 return CP_ACCESS_TRAP_EL2; 33 } 34 return CP_ACCESS_OK; 35 } 36 37 #ifdef TARGET_AARCH64 38 /* Check for traps from EL1 due to HCR_EL2.TTLB or TTLBOS. */ 39 static CPAccessResult access_ttlbos(CPUARMState *env, const ARMCPRegInfo *ri, 40 bool isread) 41 { 42 if (arm_current_el(env) == 1 && 43 (arm_hcr_el2_eff(env) & (HCR_TTLB | HCR_TTLBOS))) { 44 return CP_ACCESS_TRAP_EL2; 45 } 46 return CP_ACCESS_OK; 47 } 48 #endif 49 50 /* IS variants of TLB operations must affect all cores */ 51 static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 52 uint64_t value) 53 { 54 CPUState *cs = env_cpu(env); 55 56 tlb_flush_all_cpus_synced(cs); 57 } 58 59 static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 60 uint64_t value) 61 { 62 CPUState *cs = env_cpu(env); 63 64 tlb_flush_all_cpus_synced(cs); 65 } 66 67 static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 68 uint64_t value) 69 { 70 CPUState *cs = env_cpu(env); 71 72 tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK); 73 } 74 75 static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 76 uint64_t value) 77 { 78 CPUState *cs = env_cpu(env); 79 80 tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK); 81 } 82 83 /* 84 * Non-IS variants of TLB operations are upgraded to 85 * IS versions if we are at EL1 and HCR_EL2.FB is effectively set to 86 * force broadcast of these operations. 87 */ 88 static bool tlb_force_broadcast(CPUARMState *env) 89 { 90 return arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_FB); 91 } 92 93 static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri, 94 uint64_t value) 95 { 96 /* Invalidate all (TLBIALL) */ 97 CPUState *cs = env_cpu(env); 98 99 if (tlb_force_broadcast(env)) { 100 tlb_flush_all_cpus_synced(cs); 101 } else { 102 tlb_flush(cs); 103 } 104 } 105 106 static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri, 107 uint64_t value) 108 { 109 /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */ 110 CPUState *cs = env_cpu(env); 111 112 value &= TARGET_PAGE_MASK; 113 if (tlb_force_broadcast(env)) { 114 tlb_flush_page_all_cpus_synced(cs, value); 115 } else { 116 tlb_flush_page(cs, value); 117 } 118 } 119 120 static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri, 121 uint64_t value) 122 { 123 /* Invalidate by ASID (TLBIASID) */ 124 CPUState *cs = env_cpu(env); 125 126 if (tlb_force_broadcast(env)) { 127 tlb_flush_all_cpus_synced(cs); 128 } else { 129 tlb_flush(cs); 130 } 131 } 132 133 static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri, 134 uint64_t value) 135 { 136 /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */ 137 CPUState *cs = env_cpu(env); 138 139 value &= TARGET_PAGE_MASK; 140 if (tlb_force_broadcast(env)) { 141 tlb_flush_page_all_cpus_synced(cs, value); 142 } else { 143 tlb_flush_page(cs, value); 144 } 145 } 146 147 static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 148 uint64_t value) 149 { 150 CPUState *cs = env_cpu(env); 151 uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12); 152 153 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_E2); 154 } 155 156 static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 157 uint64_t value) 158 { 159 CPUState *cs = env_cpu(env); 160 uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12); 161 162 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, 163 ARMMMUIdxBit_E2); 164 } 165 166 static void tlbiipas2_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 167 uint64_t value) 168 { 169 CPUState *cs = env_cpu(env); 170 uint64_t pageaddr = (value & MAKE_64BIT_MASK(0, 28)) << 12; 171 172 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2); 173 } 174 175 static void tlbiipas2is_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 176 uint64_t value) 177 { 178 CPUState *cs = env_cpu(env); 179 uint64_t pageaddr = (value & MAKE_64BIT_MASK(0, 28)) << 12; 180 181 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, ARMMMUIdxBit_Stage2); 182 } 183 184 static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri, 185 uint64_t value) 186 { 187 CPUState *cs = env_cpu(env); 188 189 tlb_flush_by_mmuidx(cs, alle1_tlbmask(env)); 190 } 191 192 static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 193 uint64_t value) 194 { 195 CPUState *cs = env_cpu(env); 196 197 tlb_flush_by_mmuidx_all_cpus_synced(cs, alle1_tlbmask(env)); 198 } 199 200 201 static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 202 uint64_t value) 203 { 204 CPUState *cs = env_cpu(env); 205 206 tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_E2); 207 } 208 209 static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 210 uint64_t value) 211 { 212 CPUState *cs = env_cpu(env); 213 214 tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_E2); 215 } 216 217 /* 218 * See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions 219 * Page D4-1736 (DDI0487A.b) 220 */ 221 222 static int vae1_tlbmask(CPUARMState *env) 223 { 224 uint64_t hcr = arm_hcr_el2_eff(env); 225 uint16_t mask; 226 227 assert(arm_feature(env, ARM_FEATURE_AARCH64)); 228 229 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) { 230 mask = ARMMMUIdxBit_E20_2 | 231 ARMMMUIdxBit_E20_2_PAN | 232 ARMMMUIdxBit_E20_0; 233 } else { 234 /* This is AArch64 only, so we don't need to touch the EL30_x TLBs */ 235 mask = ARMMMUIdxBit_E10_1 | 236 ARMMMUIdxBit_E10_1_PAN | 237 ARMMMUIdxBit_E10_0; 238 } 239 return mask; 240 } 241 242 static int vae2_tlbmask(CPUARMState *env) 243 { 244 uint64_t hcr = arm_hcr_el2_eff(env); 245 uint16_t mask; 246 247 if (hcr & HCR_E2H) { 248 mask = ARMMMUIdxBit_E20_2 | 249 ARMMMUIdxBit_E20_2_PAN | 250 ARMMMUIdxBit_E20_0; 251 } else { 252 mask = ARMMMUIdxBit_E2; 253 } 254 return mask; 255 } 256 257 /* Return 56 if TBI is enabled, 64 otherwise. */ 258 static int tlbbits_for_regime(CPUARMState *env, ARMMMUIdx mmu_idx, 259 uint64_t addr) 260 { 261 uint64_t tcr = regime_tcr(env, mmu_idx); 262 int tbi = aa64_va_parameter_tbi(tcr, mmu_idx); 263 int select = extract64(addr, 55, 1); 264 265 return (tbi >> select) & 1 ? 56 : 64; 266 } 267 268 static int vae1_tlbbits(CPUARMState *env, uint64_t addr) 269 { 270 uint64_t hcr = arm_hcr_el2_eff(env); 271 ARMMMUIdx mmu_idx; 272 273 assert(arm_feature(env, ARM_FEATURE_AARCH64)); 274 275 /* Only the regime of the mmu_idx below is significant. */ 276 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) { 277 mmu_idx = ARMMMUIdx_E20_0; 278 } else { 279 mmu_idx = ARMMMUIdx_E10_0; 280 } 281 282 return tlbbits_for_regime(env, mmu_idx, addr); 283 } 284 285 static int vae2_tlbbits(CPUARMState *env, uint64_t addr) 286 { 287 uint64_t hcr = arm_hcr_el2_eff(env); 288 ARMMMUIdx mmu_idx; 289 290 /* 291 * Only the regime of the mmu_idx below is significant. 292 * Regime EL2&0 has two ranges with separate TBI configuration, while EL2 293 * only has one. 294 */ 295 if (hcr & HCR_E2H) { 296 mmu_idx = ARMMMUIdx_E20_2; 297 } else { 298 mmu_idx = ARMMMUIdx_E2; 299 } 300 301 return tlbbits_for_regime(env, mmu_idx, addr); 302 } 303 304 static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri, 305 uint64_t value) 306 { 307 CPUState *cs = env_cpu(env); 308 int mask = vae1_tlbmask(env); 309 310 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask); 311 } 312 313 static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri, 314 uint64_t value) 315 { 316 CPUState *cs = env_cpu(env); 317 int mask = vae1_tlbmask(env); 318 319 if (tlb_force_broadcast(env)) { 320 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask); 321 } else { 322 tlb_flush_by_mmuidx(cs, mask); 323 } 324 } 325 326 static int e2_tlbmask(CPUARMState *env) 327 { 328 return (ARMMMUIdxBit_E20_0 | 329 ARMMMUIdxBit_E20_2 | 330 ARMMMUIdxBit_E20_2_PAN | 331 ARMMMUIdxBit_E2); 332 } 333 334 static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri, 335 uint64_t value) 336 { 337 CPUState *cs = env_cpu(env); 338 int mask = alle1_tlbmask(env); 339 340 tlb_flush_by_mmuidx(cs, mask); 341 } 342 343 static void tlbi_aa64_alle2_write(CPUARMState *env, const ARMCPRegInfo *ri, 344 uint64_t value) 345 { 346 CPUState *cs = env_cpu(env); 347 int mask = e2_tlbmask(env); 348 349 tlb_flush_by_mmuidx(cs, mask); 350 } 351 352 static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri, 353 uint64_t value) 354 { 355 ARMCPU *cpu = env_archcpu(env); 356 CPUState *cs = CPU(cpu); 357 358 tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_E3); 359 } 360 361 static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri, 362 uint64_t value) 363 { 364 CPUState *cs = env_cpu(env); 365 int mask = alle1_tlbmask(env); 366 367 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask); 368 } 369 370 static void tlbi_aa64_alle2is_write(CPUARMState *env, const ARMCPRegInfo *ri, 371 uint64_t value) 372 { 373 CPUState *cs = env_cpu(env); 374 int mask = e2_tlbmask(env); 375 376 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask); 377 } 378 379 static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri, 380 uint64_t value) 381 { 382 CPUState *cs = env_cpu(env); 383 384 tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_E3); 385 } 386 387 static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri, 388 uint64_t value) 389 { 390 /* 391 * Invalidate by VA, EL2 392 * Currently handles both VAE2 and VALE2, since we don't support 393 * flush-last-level-only. 394 */ 395 CPUState *cs = env_cpu(env); 396 int mask = vae2_tlbmask(env); 397 uint64_t pageaddr = sextract64(value << 12, 0, 56); 398 int bits = vae2_tlbbits(env, pageaddr); 399 400 tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits); 401 } 402 403 static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri, 404 uint64_t value) 405 { 406 /* 407 * Invalidate by VA, EL3 408 * Currently handles both VAE3 and VALE3, since we don't support 409 * flush-last-level-only. 410 */ 411 ARMCPU *cpu = env_archcpu(env); 412 CPUState *cs = CPU(cpu); 413 uint64_t pageaddr = sextract64(value << 12, 0, 56); 414 415 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_E3); 416 } 417 418 static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri, 419 uint64_t value) 420 { 421 CPUState *cs = env_cpu(env); 422 int mask = vae1_tlbmask(env); 423 uint64_t pageaddr = sextract64(value << 12, 0, 56); 424 int bits = vae1_tlbbits(env, pageaddr); 425 426 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits); 427 } 428 429 static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri, 430 uint64_t value) 431 { 432 /* 433 * Invalidate by VA, EL1&0 (AArch64 version). 434 * Currently handles all of VAE1, VAAE1, VAALE1 and VALE1, 435 * since we don't support flush-for-specific-ASID-only or 436 * flush-last-level-only. 437 */ 438 CPUState *cs = env_cpu(env); 439 int mask = vae1_tlbmask(env); 440 uint64_t pageaddr = sextract64(value << 12, 0, 56); 441 int bits = vae1_tlbbits(env, pageaddr); 442 443 if (tlb_force_broadcast(env)) { 444 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits); 445 } else { 446 tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits); 447 } 448 } 449 450 static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri, 451 uint64_t value) 452 { 453 CPUState *cs = env_cpu(env); 454 int mask = vae2_tlbmask(env); 455 uint64_t pageaddr = sextract64(value << 12, 0, 56); 456 int bits = vae2_tlbbits(env, pageaddr); 457 458 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits); 459 } 460 461 static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri, 462 uint64_t value) 463 { 464 CPUState *cs = env_cpu(env); 465 uint64_t pageaddr = sextract64(value << 12, 0, 56); 466 int bits = tlbbits_for_regime(env, ARMMMUIdx_E3, pageaddr); 467 468 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, 469 ARMMMUIdxBit_E3, bits); 470 } 471 472 static int ipas2e1_tlbmask(CPUARMState *env, int64_t value) 473 { 474 /* 475 * The MSB of value is the NS field, which only applies if SEL2 476 * is implemented and SCR_EL3.NS is not set (i.e. in secure mode). 477 */ 478 return (value >= 0 479 && cpu_isar_feature(aa64_sel2, env_archcpu(env)) 480 && arm_is_secure_below_el3(env) 481 ? ARMMMUIdxBit_Stage2_S 482 : ARMMMUIdxBit_Stage2); 483 } 484 485 static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri, 486 uint64_t value) 487 { 488 CPUState *cs = env_cpu(env); 489 int mask = ipas2e1_tlbmask(env, value); 490 uint64_t pageaddr = sextract64(value << 12, 0, 56); 491 492 if (tlb_force_broadcast(env)) { 493 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask); 494 } else { 495 tlb_flush_page_by_mmuidx(cs, pageaddr, mask); 496 } 497 } 498 499 static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri, 500 uint64_t value) 501 { 502 CPUState *cs = env_cpu(env); 503 int mask = ipas2e1_tlbmask(env, value); 504 uint64_t pageaddr = sextract64(value << 12, 0, 56); 505 506 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask); 507 } 508 509 static const ARMCPRegInfo tlbi_not_v7_cp_reginfo[] = { 510 /* 511 * MMU TLB control. Note that the wildcarding means we cover not just 512 * the unified TLB ops but also the dside/iside/inner-shareable variants. 513 */ 514 { .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY, 515 .opc1 = CP_ANY, .opc2 = 0, .access = PL1_W, .writefn = tlbiall_write, 516 .type = ARM_CP_NO_RAW }, 517 { .name = "TLBIMVA", .cp = 15, .crn = 8, .crm = CP_ANY, 518 .opc1 = CP_ANY, .opc2 = 1, .access = PL1_W, .writefn = tlbimva_write, 519 .type = ARM_CP_NO_RAW }, 520 { .name = "TLBIASID", .cp = 15, .crn = 8, .crm = CP_ANY, 521 .opc1 = CP_ANY, .opc2 = 2, .access = PL1_W, .writefn = tlbiasid_write, 522 .type = ARM_CP_NO_RAW }, 523 { .name = "TLBIMVAA", .cp = 15, .crn = 8, .crm = CP_ANY, 524 .opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = tlbimvaa_write, 525 .type = ARM_CP_NO_RAW }, 526 }; 527 528 static const ARMCPRegInfo tlbi_v7_cp_reginfo[] = { 529 /* 32 bit ITLB invalidates */ 530 { .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0, 531 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 532 .writefn = tlbiall_write }, 533 { .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1, 534 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 535 .writefn = tlbimva_write }, 536 { .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 2, 537 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 538 .writefn = tlbiasid_write }, 539 /* 32 bit DTLB invalidates */ 540 { .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 0, 541 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 542 .writefn = tlbiall_write }, 543 { .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1, 544 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 545 .writefn = tlbimva_write }, 546 { .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 2, 547 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 548 .writefn = tlbiasid_write }, 549 /* 32 bit TLB invalidates */ 550 { .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, 551 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 552 .writefn = tlbiall_write }, 553 { .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, 554 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 555 .writefn = tlbimva_write }, 556 { .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, 557 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 558 .writefn = tlbiasid_write }, 559 { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, 560 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 561 .writefn = tlbimvaa_write }, 562 }; 563 564 static const ARMCPRegInfo tlbi_v7mp_cp_reginfo[] = { 565 /* 32 bit TLB invalidates, Inner Shareable */ 566 { .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, 567 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 568 .writefn = tlbiall_is_write }, 569 { .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, 570 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 571 .writefn = tlbimva_is_write }, 572 { .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, 573 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 574 .writefn = tlbiasid_is_write }, 575 { .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, 576 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 577 .writefn = tlbimvaa_is_write }, 578 }; 579 580 static const ARMCPRegInfo tlbi_v8_cp_reginfo[] = { 581 /* AArch32 TLB invalidate last level of translation table walk */ 582 { .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, 583 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 584 .writefn = tlbimva_is_write }, 585 { .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, 586 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 587 .writefn = tlbimvaa_is_write }, 588 { .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, 589 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 590 .writefn = tlbimva_write }, 591 { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, 592 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 593 .writefn = tlbimvaa_write }, 594 { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5, 595 .type = ARM_CP_NO_RAW, .access = PL2_W, 596 .writefn = tlbimva_hyp_write }, 597 { .name = "TLBIMVALHIS", 598 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5, 599 .type = ARM_CP_NO_RAW, .access = PL2_W, 600 .writefn = tlbimva_hyp_is_write }, 601 { .name = "TLBIIPAS2", 602 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, 603 .type = ARM_CP_NO_RAW, .access = PL2_W, 604 .writefn = tlbiipas2_hyp_write }, 605 { .name = "TLBIIPAS2IS", 606 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, 607 .type = ARM_CP_NO_RAW, .access = PL2_W, 608 .writefn = tlbiipas2is_hyp_write }, 609 { .name = "TLBIIPAS2L", 610 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, 611 .type = ARM_CP_NO_RAW, .access = PL2_W, 612 .writefn = tlbiipas2_hyp_write }, 613 { .name = "TLBIIPAS2LIS", 614 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, 615 .type = ARM_CP_NO_RAW, .access = PL2_W, 616 .writefn = tlbiipas2is_hyp_write }, 617 /* AArch64 TLBI operations */ 618 { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64, 619 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, 620 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 621 .fgt = FGT_TLBIVMALLE1IS, 622 .writefn = tlbi_aa64_vmalle1is_write }, 623 { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64, 624 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, 625 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 626 .fgt = FGT_TLBIVAE1IS, 627 .writefn = tlbi_aa64_vae1is_write }, 628 { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64, 629 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, 630 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 631 .fgt = FGT_TLBIASIDE1IS, 632 .writefn = tlbi_aa64_vmalle1is_write }, 633 { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64, 634 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, 635 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 636 .fgt = FGT_TLBIVAAE1IS, 637 .writefn = tlbi_aa64_vae1is_write }, 638 { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64, 639 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, 640 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 641 .fgt = FGT_TLBIVALE1IS, 642 .writefn = tlbi_aa64_vae1is_write }, 643 { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64, 644 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, 645 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 646 .fgt = FGT_TLBIVAALE1IS, 647 .writefn = tlbi_aa64_vae1is_write }, 648 { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64, 649 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, 650 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 651 .fgt = FGT_TLBIVMALLE1, 652 .writefn = tlbi_aa64_vmalle1_write }, 653 { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64, 654 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, 655 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 656 .fgt = FGT_TLBIVAE1, 657 .writefn = tlbi_aa64_vae1_write }, 658 { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64, 659 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, 660 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 661 .fgt = FGT_TLBIASIDE1, 662 .writefn = tlbi_aa64_vmalle1_write }, 663 { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64, 664 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, 665 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 666 .fgt = FGT_TLBIVAAE1, 667 .writefn = tlbi_aa64_vae1_write }, 668 { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64, 669 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, 670 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 671 .fgt = FGT_TLBIVALE1, 672 .writefn = tlbi_aa64_vae1_write }, 673 { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64, 674 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, 675 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 676 .fgt = FGT_TLBIVAALE1, 677 .writefn = tlbi_aa64_vae1_write }, 678 { .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64, 679 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, 680 .access = PL2_W, .type = ARM_CP_NO_RAW, 681 .writefn = tlbi_aa64_ipas2e1is_write }, 682 { .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64, 683 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, 684 .access = PL2_W, .type = ARM_CP_NO_RAW, 685 .writefn = tlbi_aa64_ipas2e1is_write }, 686 { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64, 687 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, 688 .access = PL2_W, .type = ARM_CP_NO_RAW, 689 .writefn = tlbi_aa64_alle1is_write }, 690 { .name = "TLBI_VMALLS12E1IS", .state = ARM_CP_STATE_AA64, 691 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 6, 692 .access = PL2_W, .type = ARM_CP_NO_RAW, 693 .writefn = tlbi_aa64_alle1is_write }, 694 { .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64, 695 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, 696 .access = PL2_W, .type = ARM_CP_NO_RAW, 697 .writefn = tlbi_aa64_ipas2e1_write }, 698 { .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64, 699 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, 700 .access = PL2_W, .type = ARM_CP_NO_RAW, 701 .writefn = tlbi_aa64_ipas2e1_write }, 702 { .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64, 703 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, 704 .access = PL2_W, .type = ARM_CP_NO_RAW, 705 .writefn = tlbi_aa64_alle1_write }, 706 { .name = "TLBI_VMALLS12E1", .state = ARM_CP_STATE_AA64, 707 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 6, 708 .access = PL2_W, .type = ARM_CP_NO_RAW, 709 .writefn = tlbi_aa64_alle1is_write }, 710 }; 711 712 static const ARMCPRegInfo tlbi_el2_cp_reginfo[] = { 713 { .name = "TLBIALLNSNH", 714 .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, 715 .type = ARM_CP_NO_RAW, .access = PL2_W, 716 .writefn = tlbiall_nsnh_write }, 717 { .name = "TLBIALLNSNHIS", 718 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, 719 .type = ARM_CP_NO_RAW, .access = PL2_W, 720 .writefn = tlbiall_nsnh_is_write }, 721 { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, 722 .type = ARM_CP_NO_RAW, .access = PL2_W, 723 .writefn = tlbiall_hyp_write }, 724 { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0, 725 .type = ARM_CP_NO_RAW, .access = PL2_W, 726 .writefn = tlbiall_hyp_is_write }, 727 { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1, 728 .type = ARM_CP_NO_RAW, .access = PL2_W, 729 .writefn = tlbimva_hyp_write }, 730 { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1, 731 .type = ARM_CP_NO_RAW, .access = PL2_W, 732 .writefn = tlbimva_hyp_is_write }, 733 { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64, 734 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, 735 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 736 .writefn = tlbi_aa64_alle2_write }, 737 { .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64, 738 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1, 739 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 740 .writefn = tlbi_aa64_vae2_write }, 741 { .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64, 742 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5, 743 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 744 .writefn = tlbi_aa64_vae2_write }, 745 { .name = "TLBI_ALLE2IS", .state = ARM_CP_STATE_AA64, 746 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0, 747 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 748 .writefn = tlbi_aa64_alle2is_write }, 749 { .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64, 750 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1, 751 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 752 .writefn = tlbi_aa64_vae2is_write }, 753 { .name = "TLBI_VALE2IS", .state = ARM_CP_STATE_AA64, 754 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5, 755 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 756 .writefn = tlbi_aa64_vae2is_write }, 757 }; 758 759 static const ARMCPRegInfo tlbi_el3_cp_reginfo[] = { 760 { .name = "TLBI_ALLE3IS", .state = ARM_CP_STATE_AA64, 761 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 0, 762 .access = PL3_W, .type = ARM_CP_NO_RAW, 763 .writefn = tlbi_aa64_alle3is_write }, 764 { .name = "TLBI_VAE3IS", .state = ARM_CP_STATE_AA64, 765 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 1, 766 .access = PL3_W, .type = ARM_CP_NO_RAW, 767 .writefn = tlbi_aa64_vae3is_write }, 768 { .name = "TLBI_VALE3IS", .state = ARM_CP_STATE_AA64, 769 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 5, 770 .access = PL3_W, .type = ARM_CP_NO_RAW, 771 .writefn = tlbi_aa64_vae3is_write }, 772 { .name = "TLBI_ALLE3", .state = ARM_CP_STATE_AA64, 773 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 0, 774 .access = PL3_W, .type = ARM_CP_NO_RAW, 775 .writefn = tlbi_aa64_alle3_write }, 776 { .name = "TLBI_VAE3", .state = ARM_CP_STATE_AA64, 777 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 1, 778 .access = PL3_W, .type = ARM_CP_NO_RAW, 779 .writefn = tlbi_aa64_vae3_write }, 780 { .name = "TLBI_VALE3", .state = ARM_CP_STATE_AA64, 781 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 5, 782 .access = PL3_W, .type = ARM_CP_NO_RAW, 783 .writefn = tlbi_aa64_vae3_write }, 784 }; 785 786 #ifdef TARGET_AARCH64 787 typedef struct { 788 uint64_t base; 789 uint64_t length; 790 } TLBIRange; 791 792 static ARMGranuleSize tlbi_range_tg_to_gran_size(int tg) 793 { 794 /* 795 * Note that the TLBI range TG field encoding differs from both 796 * TG0 and TG1 encodings. 797 */ 798 switch (tg) { 799 case 1: 800 return Gran4K; 801 case 2: 802 return Gran16K; 803 case 3: 804 return Gran64K; 805 default: 806 return GranInvalid; 807 } 808 } 809 810 static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx, 811 uint64_t value) 812 { 813 unsigned int page_size_granule, page_shift, num, scale, exponent; 814 /* Extract one bit to represent the va selector in use. */ 815 uint64_t select = sextract64(value, 36, 1); 816 ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true, false); 817 TLBIRange ret = { }; 818 ARMGranuleSize gran; 819 820 page_size_granule = extract64(value, 46, 2); 821 gran = tlbi_range_tg_to_gran_size(page_size_granule); 822 823 /* The granule encoded in value must match the granule in use. */ 824 if (gran != param.gran) { 825 qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n", 826 page_size_granule); 827 return ret; 828 } 829 830 page_shift = arm_granule_bits(gran); 831 num = extract64(value, 39, 5); 832 scale = extract64(value, 44, 2); 833 exponent = (5 * scale) + 1; 834 835 ret.length = (num + 1) << (exponent + page_shift); 836 837 if (param.select) { 838 ret.base = sextract64(value, 0, 37); 839 } else { 840 ret.base = extract64(value, 0, 37); 841 } 842 if (param.ds) { 843 /* 844 * With DS=1, BaseADDR is always shifted 16 so that it is able 845 * to address all 52 va bits. The input address is perforce 846 * aligned on a 64k boundary regardless of translation granule. 847 */ 848 page_shift = 16; 849 } 850 ret.base <<= page_shift; 851 852 return ret; 853 } 854 855 static void do_rvae_write(CPUARMState *env, uint64_t value, 856 int idxmap, bool synced) 857 { 858 ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap); 859 TLBIRange range; 860 int bits; 861 862 range = tlbi_aa64_get_range(env, one_idx, value); 863 bits = tlbbits_for_regime(env, one_idx, range.base); 864 865 if (synced) { 866 tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env), 867 range.base, 868 range.length, 869 idxmap, 870 bits); 871 } else { 872 tlb_flush_range_by_mmuidx(env_cpu(env), range.base, 873 range.length, idxmap, bits); 874 } 875 } 876 877 static void tlbi_aa64_rvae1_write(CPUARMState *env, 878 const ARMCPRegInfo *ri, 879 uint64_t value) 880 { 881 /* 882 * Invalidate by VA range, EL1&0. 883 * Currently handles all of RVAE1, RVAAE1, RVAALE1 and RVALE1, 884 * since we don't support flush-for-specific-ASID-only or 885 * flush-last-level-only. 886 */ 887 888 do_rvae_write(env, value, vae1_tlbmask(env), 889 tlb_force_broadcast(env)); 890 } 891 892 static void tlbi_aa64_rvae1is_write(CPUARMState *env, 893 const ARMCPRegInfo *ri, 894 uint64_t value) 895 { 896 /* 897 * Invalidate by VA range, Inner/Outer Shareable EL1&0. 898 * Currently handles all of RVAE1IS, RVAE1OS, RVAAE1IS, RVAAE1OS, 899 * RVAALE1IS, RVAALE1OS, RVALE1IS and RVALE1OS, since we don't support 900 * flush-for-specific-ASID-only, flush-last-level-only or inner/outer 901 * shareable specific flushes. 902 */ 903 904 do_rvae_write(env, value, vae1_tlbmask(env), true); 905 } 906 907 static void tlbi_aa64_rvae2_write(CPUARMState *env, 908 const ARMCPRegInfo *ri, 909 uint64_t value) 910 { 911 /* 912 * Invalidate by VA range, EL2. 913 * Currently handles all of RVAE2 and RVALE2, 914 * since we don't support flush-for-specific-ASID-only or 915 * flush-last-level-only. 916 */ 917 918 do_rvae_write(env, value, vae2_tlbmask(env), 919 tlb_force_broadcast(env)); 920 921 922 } 923 924 static void tlbi_aa64_rvae2is_write(CPUARMState *env, 925 const ARMCPRegInfo *ri, 926 uint64_t value) 927 { 928 /* 929 * Invalidate by VA range, Inner/Outer Shareable, EL2. 930 * Currently handles all of RVAE2IS, RVAE2OS, RVALE2IS and RVALE2OS, 931 * since we don't support flush-for-specific-ASID-only, 932 * flush-last-level-only or inner/outer shareable specific flushes. 933 */ 934 935 do_rvae_write(env, value, vae2_tlbmask(env), true); 936 937 } 938 939 static void tlbi_aa64_rvae3_write(CPUARMState *env, 940 const ARMCPRegInfo *ri, 941 uint64_t value) 942 { 943 /* 944 * Invalidate by VA range, EL3. 945 * Currently handles all of RVAE3 and RVALE3, 946 * since we don't support flush-for-specific-ASID-only or 947 * flush-last-level-only. 948 */ 949 950 do_rvae_write(env, value, ARMMMUIdxBit_E3, tlb_force_broadcast(env)); 951 } 952 953 static void tlbi_aa64_rvae3is_write(CPUARMState *env, 954 const ARMCPRegInfo *ri, 955 uint64_t value) 956 { 957 /* 958 * Invalidate by VA range, EL3, Inner/Outer Shareable. 959 * Currently handles all of RVAE3IS, RVAE3OS, RVALE3IS and RVALE3OS, 960 * since we don't support flush-for-specific-ASID-only, 961 * flush-last-level-only or inner/outer specific flushes. 962 */ 963 964 do_rvae_write(env, value, ARMMMUIdxBit_E3, true); 965 } 966 967 static void tlbi_aa64_ripas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri, 968 uint64_t value) 969 { 970 do_rvae_write(env, value, ipas2e1_tlbmask(env, value), 971 tlb_force_broadcast(env)); 972 } 973 974 static void tlbi_aa64_ripas2e1is_write(CPUARMState *env, 975 const ARMCPRegInfo *ri, 976 uint64_t value) 977 { 978 do_rvae_write(env, value, ipas2e1_tlbmask(env, value), true); 979 } 980 981 static const ARMCPRegInfo tlbirange_reginfo[] = { 982 { .name = "TLBI_RVAE1IS", .state = ARM_CP_STATE_AA64, 983 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 1, 984 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 985 .fgt = FGT_TLBIRVAE1IS, 986 .writefn = tlbi_aa64_rvae1is_write }, 987 { .name = "TLBI_RVAAE1IS", .state = ARM_CP_STATE_AA64, 988 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 3, 989 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 990 .fgt = FGT_TLBIRVAAE1IS, 991 .writefn = tlbi_aa64_rvae1is_write }, 992 { .name = "TLBI_RVALE1IS", .state = ARM_CP_STATE_AA64, 993 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 5, 994 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 995 .fgt = FGT_TLBIRVALE1IS, 996 .writefn = tlbi_aa64_rvae1is_write }, 997 { .name = "TLBI_RVAALE1IS", .state = ARM_CP_STATE_AA64, 998 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 7, 999 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 1000 .fgt = FGT_TLBIRVAALE1IS, 1001 .writefn = tlbi_aa64_rvae1is_write }, 1002 { .name = "TLBI_RVAE1OS", .state = ARM_CP_STATE_AA64, 1003 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1, 1004 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 1005 .fgt = FGT_TLBIRVAE1OS, 1006 .writefn = tlbi_aa64_rvae1is_write }, 1007 { .name = "TLBI_RVAAE1OS", .state = ARM_CP_STATE_AA64, 1008 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 3, 1009 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 1010 .fgt = FGT_TLBIRVAAE1OS, 1011 .writefn = tlbi_aa64_rvae1is_write }, 1012 { .name = "TLBI_RVALE1OS", .state = ARM_CP_STATE_AA64, 1013 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 5, 1014 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 1015 .fgt = FGT_TLBIRVALE1OS, 1016 .writefn = tlbi_aa64_rvae1is_write }, 1017 { .name = "TLBI_RVAALE1OS", .state = ARM_CP_STATE_AA64, 1018 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 7, 1019 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 1020 .fgt = FGT_TLBIRVAALE1OS, 1021 .writefn = tlbi_aa64_rvae1is_write }, 1022 { .name = "TLBI_RVAE1", .state = ARM_CP_STATE_AA64, 1023 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1, 1024 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 1025 .fgt = FGT_TLBIRVAE1, 1026 .writefn = tlbi_aa64_rvae1_write }, 1027 { .name = "TLBI_RVAAE1", .state = ARM_CP_STATE_AA64, 1028 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 3, 1029 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 1030 .fgt = FGT_TLBIRVAAE1, 1031 .writefn = tlbi_aa64_rvae1_write }, 1032 { .name = "TLBI_RVALE1", .state = ARM_CP_STATE_AA64, 1033 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 5, 1034 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 1035 .fgt = FGT_TLBIRVALE1, 1036 .writefn = tlbi_aa64_rvae1_write }, 1037 { .name = "TLBI_RVAALE1", .state = ARM_CP_STATE_AA64, 1038 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 7, 1039 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 1040 .fgt = FGT_TLBIRVAALE1, 1041 .writefn = tlbi_aa64_rvae1_write }, 1042 { .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64, 1043 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2, 1044 .access = PL2_W, .type = ARM_CP_NO_RAW, 1045 .writefn = tlbi_aa64_ripas2e1is_write }, 1046 { .name = "TLBI_RIPAS2LE1IS", .state = ARM_CP_STATE_AA64, 1047 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 6, 1048 .access = PL2_W, .type = ARM_CP_NO_RAW, 1049 .writefn = tlbi_aa64_ripas2e1is_write }, 1050 { .name = "TLBI_RVAE2IS", .state = ARM_CP_STATE_AA64, 1051 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 1, 1052 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 1053 .writefn = tlbi_aa64_rvae2is_write }, 1054 { .name = "TLBI_RVALE2IS", .state = ARM_CP_STATE_AA64, 1055 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 5, 1056 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 1057 .writefn = tlbi_aa64_rvae2is_write }, 1058 { .name = "TLBI_RIPAS2E1", .state = ARM_CP_STATE_AA64, 1059 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 2, 1060 .access = PL2_W, .type = ARM_CP_NO_RAW, 1061 .writefn = tlbi_aa64_ripas2e1_write }, 1062 { .name = "TLBI_RIPAS2LE1", .state = ARM_CP_STATE_AA64, 1063 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 6, 1064 .access = PL2_W, .type = ARM_CP_NO_RAW, 1065 .writefn = tlbi_aa64_ripas2e1_write }, 1066 { .name = "TLBI_RVAE2OS", .state = ARM_CP_STATE_AA64, 1067 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 1, 1068 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 1069 .writefn = tlbi_aa64_rvae2is_write }, 1070 { .name = "TLBI_RVALE2OS", .state = ARM_CP_STATE_AA64, 1071 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 5, 1072 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 1073 .writefn = tlbi_aa64_rvae2is_write }, 1074 { .name = "TLBI_RVAE2", .state = ARM_CP_STATE_AA64, 1075 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 1, 1076 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 1077 .writefn = tlbi_aa64_rvae2_write }, 1078 { .name = "TLBI_RVALE2", .state = ARM_CP_STATE_AA64, 1079 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 5, 1080 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 1081 .writefn = tlbi_aa64_rvae2_write }, 1082 { .name = "TLBI_RVAE3IS", .state = ARM_CP_STATE_AA64, 1083 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 1, 1084 .access = PL3_W, .type = ARM_CP_NO_RAW, 1085 .writefn = tlbi_aa64_rvae3is_write }, 1086 { .name = "TLBI_RVALE3IS", .state = ARM_CP_STATE_AA64, 1087 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 5, 1088 .access = PL3_W, .type = ARM_CP_NO_RAW, 1089 .writefn = tlbi_aa64_rvae3is_write }, 1090 { .name = "TLBI_RVAE3OS", .state = ARM_CP_STATE_AA64, 1091 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 1, 1092 .access = PL3_W, .type = ARM_CP_NO_RAW, 1093 .writefn = tlbi_aa64_rvae3is_write }, 1094 { .name = "TLBI_RVALE3OS", .state = ARM_CP_STATE_AA64, 1095 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 5, 1096 .access = PL3_W, .type = ARM_CP_NO_RAW, 1097 .writefn = tlbi_aa64_rvae3is_write }, 1098 { .name = "TLBI_RVAE3", .state = ARM_CP_STATE_AA64, 1099 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 1, 1100 .access = PL3_W, .type = ARM_CP_NO_RAW, 1101 .writefn = tlbi_aa64_rvae3_write }, 1102 { .name = "TLBI_RVALE3", .state = ARM_CP_STATE_AA64, 1103 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 5, 1104 .access = PL3_W, .type = ARM_CP_NO_RAW, 1105 .writefn = tlbi_aa64_rvae3_write }, 1106 }; 1107 1108 static const ARMCPRegInfo tlbios_reginfo[] = { 1109 { .name = "TLBI_VMALLE1OS", .state = ARM_CP_STATE_AA64, 1110 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0, 1111 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 1112 .fgt = FGT_TLBIVMALLE1OS, 1113 .writefn = tlbi_aa64_vmalle1is_write }, 1114 { .name = "TLBI_VAE1OS", .state = ARM_CP_STATE_AA64, 1115 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 1, 1116 .fgt = FGT_TLBIVAE1OS, 1117 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 1118 .writefn = tlbi_aa64_vae1is_write }, 1119 { .name = "TLBI_ASIDE1OS", .state = ARM_CP_STATE_AA64, 1120 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 2, 1121 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 1122 .fgt = FGT_TLBIASIDE1OS, 1123 .writefn = tlbi_aa64_vmalle1is_write }, 1124 { .name = "TLBI_VAAE1OS", .state = ARM_CP_STATE_AA64, 1125 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 3, 1126 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 1127 .fgt = FGT_TLBIVAAE1OS, 1128 .writefn = tlbi_aa64_vae1is_write }, 1129 { .name = "TLBI_VALE1OS", .state = ARM_CP_STATE_AA64, 1130 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 5, 1131 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 1132 .fgt = FGT_TLBIVALE1OS, 1133 .writefn = tlbi_aa64_vae1is_write }, 1134 { .name = "TLBI_VAALE1OS", .state = ARM_CP_STATE_AA64, 1135 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 7, 1136 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 1137 .fgt = FGT_TLBIVAALE1OS, 1138 .writefn = tlbi_aa64_vae1is_write }, 1139 { .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64, 1140 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0, 1141 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 1142 .writefn = tlbi_aa64_alle2is_write }, 1143 { .name = "TLBI_VAE2OS", .state = ARM_CP_STATE_AA64, 1144 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 1, 1145 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 1146 .writefn = tlbi_aa64_vae2is_write }, 1147 { .name = "TLBI_ALLE1OS", .state = ARM_CP_STATE_AA64, 1148 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 4, 1149 .access = PL2_W, .type = ARM_CP_NO_RAW, 1150 .writefn = tlbi_aa64_alle1is_write }, 1151 { .name = "TLBI_VALE2OS", .state = ARM_CP_STATE_AA64, 1152 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 5, 1153 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 1154 .writefn = tlbi_aa64_vae2is_write }, 1155 { .name = "TLBI_VMALLS12E1OS", .state = ARM_CP_STATE_AA64, 1156 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 6, 1157 .access = PL2_W, .type = ARM_CP_NO_RAW, 1158 .writefn = tlbi_aa64_alle1is_write }, 1159 { .name = "TLBI_IPAS2E1OS", .state = ARM_CP_STATE_AA64, 1160 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 0, 1161 .access = PL2_W, .type = ARM_CP_NOP }, 1162 { .name = "TLBI_RIPAS2E1OS", .state = ARM_CP_STATE_AA64, 1163 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 3, 1164 .access = PL2_W, .type = ARM_CP_NOP }, 1165 { .name = "TLBI_IPAS2LE1OS", .state = ARM_CP_STATE_AA64, 1166 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 4, 1167 .access = PL2_W, .type = ARM_CP_NOP }, 1168 { .name = "TLBI_RIPAS2LE1OS", .state = ARM_CP_STATE_AA64, 1169 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 7, 1170 .access = PL2_W, .type = ARM_CP_NOP }, 1171 { .name = "TLBI_ALLE3OS", .state = ARM_CP_STATE_AA64, 1172 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 0, 1173 .access = PL3_W, .type = ARM_CP_NO_RAW, 1174 .writefn = tlbi_aa64_alle3is_write }, 1175 { .name = "TLBI_VAE3OS", .state = ARM_CP_STATE_AA64, 1176 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 1, 1177 .access = PL3_W, .type = ARM_CP_NO_RAW, 1178 .writefn = tlbi_aa64_vae3is_write }, 1179 { .name = "TLBI_VALE3OS", .state = ARM_CP_STATE_AA64, 1180 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 5, 1181 .access = PL3_W, .type = ARM_CP_NO_RAW, 1182 .writefn = tlbi_aa64_vae3is_write }, 1183 }; 1184 1185 static void tlbi_aa64_paall_write(CPUARMState *env, const ARMCPRegInfo *ri, 1186 uint64_t value) 1187 { 1188 CPUState *cs = env_cpu(env); 1189 1190 tlb_flush(cs); 1191 } 1192 1193 static void tlbi_aa64_paallos_write(CPUARMState *env, const ARMCPRegInfo *ri, 1194 uint64_t value) 1195 { 1196 CPUState *cs = env_cpu(env); 1197 1198 tlb_flush_all_cpus_synced(cs); 1199 } 1200 1201 static const ARMCPRegInfo tlbi_rme_reginfo[] = { 1202 { .name = "TLBI_PAALL", .state = ARM_CP_STATE_AA64, 1203 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 4, 1204 .access = PL3_W, .type = ARM_CP_NO_RAW, 1205 .writefn = tlbi_aa64_paall_write }, 1206 { .name = "TLBI_PAALLOS", .state = ARM_CP_STATE_AA64, 1207 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 4, 1208 .access = PL3_W, .type = ARM_CP_NO_RAW, 1209 .writefn = tlbi_aa64_paallos_write }, 1210 /* 1211 * QEMU does not have a way to invalidate by physical address, thus 1212 * invalidating a range of physical addresses is accomplished by 1213 * flushing all tlb entries in the outer shareable domain, 1214 * just like PAALLOS. 1215 */ 1216 { .name = "TLBI_RPALOS", .state = ARM_CP_STATE_AA64, 1217 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 4, .opc2 = 7, 1218 .access = PL3_W, .type = ARM_CP_NO_RAW, 1219 .writefn = tlbi_aa64_paallos_write }, 1220 { .name = "TLBI_RPAOS", .state = ARM_CP_STATE_AA64, 1221 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 4, .opc2 = 3, 1222 .access = PL3_W, .type = ARM_CP_NO_RAW, 1223 .writefn = tlbi_aa64_paallos_write }, 1224 }; 1225 1226 #endif 1227 1228 void define_tlb_insn_regs(ARMCPU *cpu) 1229 { 1230 CPUARMState *env = &cpu->env; 1231 1232 if (!arm_feature(env, ARM_FEATURE_V7)) { 1233 define_arm_cp_regs(cpu, tlbi_not_v7_cp_reginfo); 1234 } else { 1235 define_arm_cp_regs(cpu, tlbi_v7_cp_reginfo); 1236 } 1237 if (arm_feature(env, ARM_FEATURE_V7MP) && 1238 !arm_feature(env, ARM_FEATURE_PMSA)) { 1239 define_arm_cp_regs(cpu, tlbi_v7mp_cp_reginfo); 1240 } 1241 if (arm_feature(env, ARM_FEATURE_V8)) { 1242 define_arm_cp_regs(cpu, tlbi_v8_cp_reginfo); 1243 } 1244 /* 1245 * We retain the existing logic for when to register these TLBI 1246 * ops (i.e. matching the condition for el2_cp_reginfo[] in 1247 * helper.c), but we will be able to simplify this later. 1248 */ 1249 if (arm_feature(env, ARM_FEATURE_EL2)) { 1250 define_arm_cp_regs(cpu, tlbi_el2_cp_reginfo); 1251 } 1252 if (arm_feature(env, ARM_FEATURE_EL3)) { 1253 define_arm_cp_regs(cpu, tlbi_el3_cp_reginfo); 1254 } 1255 #ifdef TARGET_AARCH64 1256 if (cpu_isar_feature(aa64_tlbirange, cpu)) { 1257 define_arm_cp_regs(cpu, tlbirange_reginfo); 1258 } 1259 if (cpu_isar_feature(aa64_tlbios, cpu)) { 1260 define_arm_cp_regs(cpu, tlbios_reginfo); 1261 } 1262 if (cpu_isar_feature(aa64_rme, cpu)) { 1263 define_arm_cp_regs(cpu, tlbi_rme_reginfo); 1264 } 1265 #endif 1266 } 1267