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 /* IS variants of TLB operations must affect all cores */ 17 static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 18 uint64_t value) 19 { 20 CPUState *cs = env_cpu(env); 21 22 tlb_flush_all_cpus_synced(cs); 23 } 24 25 static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 26 uint64_t value) 27 { 28 CPUState *cs = env_cpu(env); 29 30 tlb_flush_all_cpus_synced(cs); 31 } 32 33 static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 34 uint64_t value) 35 { 36 CPUState *cs = env_cpu(env); 37 38 tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK); 39 } 40 41 static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 42 uint64_t value) 43 { 44 CPUState *cs = env_cpu(env); 45 46 tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK); 47 } 48 49 static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri, 50 uint64_t value) 51 { 52 /* Invalidate all (TLBIALL) */ 53 CPUState *cs = env_cpu(env); 54 55 if (tlb_force_broadcast(env)) { 56 tlb_flush_all_cpus_synced(cs); 57 } else { 58 tlb_flush(cs); 59 } 60 } 61 62 static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri, 63 uint64_t value) 64 { 65 /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */ 66 CPUState *cs = env_cpu(env); 67 68 value &= TARGET_PAGE_MASK; 69 if (tlb_force_broadcast(env)) { 70 tlb_flush_page_all_cpus_synced(cs, value); 71 } else { 72 tlb_flush_page(cs, value); 73 } 74 } 75 76 static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri, 77 uint64_t value) 78 { 79 /* Invalidate by ASID (TLBIASID) */ 80 CPUState *cs = env_cpu(env); 81 82 if (tlb_force_broadcast(env)) { 83 tlb_flush_all_cpus_synced(cs); 84 } else { 85 tlb_flush(cs); 86 } 87 } 88 89 static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri, 90 uint64_t value) 91 { 92 /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */ 93 CPUState *cs = env_cpu(env); 94 95 value &= TARGET_PAGE_MASK; 96 if (tlb_force_broadcast(env)) { 97 tlb_flush_page_all_cpus_synced(cs, value); 98 } else { 99 tlb_flush_page(cs, value); 100 } 101 } 102 103 static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 104 uint64_t value) 105 { 106 CPUState *cs = env_cpu(env); 107 uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12); 108 109 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_E2); 110 } 111 112 static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 113 uint64_t value) 114 { 115 CPUState *cs = env_cpu(env); 116 uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12); 117 118 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, 119 ARMMMUIdxBit_E2); 120 } 121 122 static void tlbiipas2_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 123 uint64_t value) 124 { 125 CPUState *cs = env_cpu(env); 126 uint64_t pageaddr = (value & MAKE_64BIT_MASK(0, 28)) << 12; 127 128 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2); 129 } 130 131 static void tlbiipas2is_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 132 uint64_t value) 133 { 134 CPUState *cs = env_cpu(env); 135 uint64_t pageaddr = (value & MAKE_64BIT_MASK(0, 28)) << 12; 136 137 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, ARMMMUIdxBit_Stage2); 138 } 139 140 static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri, 141 uint64_t value) 142 { 143 CPUState *cs = env_cpu(env); 144 145 tlb_flush_by_mmuidx(cs, alle1_tlbmask(env)); 146 } 147 148 static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 149 uint64_t value) 150 { 151 CPUState *cs = env_cpu(env); 152 153 tlb_flush_by_mmuidx_all_cpus_synced(cs, alle1_tlbmask(env)); 154 } 155 156 157 static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 158 uint64_t value) 159 { 160 CPUState *cs = env_cpu(env); 161 162 tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_E2); 163 } 164 165 static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 166 uint64_t value) 167 { 168 CPUState *cs = env_cpu(env); 169 170 tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_E2); 171 } 172 173 static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri, 174 uint64_t value) 175 { 176 CPUState *cs = env_cpu(env); 177 int mask = vae1_tlbmask(env); 178 179 if (tlb_force_broadcast(env)) { 180 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask); 181 } else { 182 tlb_flush_by_mmuidx(cs, mask); 183 } 184 } 185 186 static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri, 187 uint64_t value) 188 { 189 CPUState *cs = env_cpu(env); 190 int mask = alle1_tlbmask(env); 191 192 tlb_flush_by_mmuidx(cs, mask); 193 } 194 195 static void tlbi_aa64_alle2_write(CPUARMState *env, const ARMCPRegInfo *ri, 196 uint64_t value) 197 { 198 CPUState *cs = env_cpu(env); 199 int mask = e2_tlbmask(env); 200 201 tlb_flush_by_mmuidx(cs, mask); 202 } 203 204 static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri, 205 uint64_t value) 206 { 207 ARMCPU *cpu = env_archcpu(env); 208 CPUState *cs = CPU(cpu); 209 210 tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_E3); 211 } 212 213 static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri, 214 uint64_t value) 215 { 216 /* 217 * Invalidate by VA, EL2 218 * Currently handles both VAE2 and VALE2, since we don't support 219 * flush-last-level-only. 220 */ 221 CPUState *cs = env_cpu(env); 222 int mask = vae2_tlbmask(env); 223 uint64_t pageaddr = sextract64(value << 12, 0, 56); 224 int bits = vae2_tlbbits(env, pageaddr); 225 226 tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits); 227 } 228 229 static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri, 230 uint64_t value) 231 { 232 /* 233 * Invalidate by VA, EL3 234 * Currently handles both VAE3 and VALE3, since we don't support 235 * flush-last-level-only. 236 */ 237 ARMCPU *cpu = env_archcpu(env); 238 CPUState *cs = CPU(cpu); 239 uint64_t pageaddr = sextract64(value << 12, 0, 56); 240 241 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_E3); 242 } 243 244 static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri, 245 uint64_t value) 246 { 247 /* 248 * Invalidate by VA, EL1&0 (AArch64 version). 249 * Currently handles all of VAE1, VAAE1, VAALE1 and VALE1, 250 * since we don't support flush-for-specific-ASID-only or 251 * flush-last-level-only. 252 */ 253 CPUState *cs = env_cpu(env); 254 int mask = vae1_tlbmask(env); 255 uint64_t pageaddr = sextract64(value << 12, 0, 56); 256 int bits = vae1_tlbbits(env, pageaddr); 257 258 if (tlb_force_broadcast(env)) { 259 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits); 260 } else { 261 tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits); 262 } 263 } 264 265 static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri, 266 uint64_t value) 267 { 268 CPUState *cs = env_cpu(env); 269 int mask = ipas2e1_tlbmask(env, value); 270 uint64_t pageaddr = sextract64(value << 12, 0, 56); 271 272 if (tlb_force_broadcast(env)) { 273 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask); 274 } else { 275 tlb_flush_page_by_mmuidx(cs, pageaddr, mask); 276 } 277 } 278 279 static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri, 280 uint64_t value) 281 { 282 CPUState *cs = env_cpu(env); 283 int mask = ipas2e1_tlbmask(env, value); 284 uint64_t pageaddr = sextract64(value << 12, 0, 56); 285 286 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask); 287 } 288 289 static const ARMCPRegInfo tlbi_not_v7_cp_reginfo[] = { 290 /* 291 * MMU TLB control. Note that the wildcarding means we cover not just 292 * the unified TLB ops but also the dside/iside/inner-shareable variants. 293 */ 294 { .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY, 295 .opc1 = CP_ANY, .opc2 = 0, .access = PL1_W, .writefn = tlbiall_write, 296 .type = ARM_CP_NO_RAW }, 297 { .name = "TLBIMVA", .cp = 15, .crn = 8, .crm = CP_ANY, 298 .opc1 = CP_ANY, .opc2 = 1, .access = PL1_W, .writefn = tlbimva_write, 299 .type = ARM_CP_NO_RAW }, 300 { .name = "TLBIASID", .cp = 15, .crn = 8, .crm = CP_ANY, 301 .opc1 = CP_ANY, .opc2 = 2, .access = PL1_W, .writefn = tlbiasid_write, 302 .type = ARM_CP_NO_RAW }, 303 { .name = "TLBIMVAA", .cp = 15, .crn = 8, .crm = CP_ANY, 304 .opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = tlbimvaa_write, 305 .type = ARM_CP_NO_RAW }, 306 }; 307 308 static const ARMCPRegInfo tlbi_v7_cp_reginfo[] = { 309 /* 32 bit ITLB invalidates */ 310 { .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0, 311 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 312 .writefn = tlbiall_write }, 313 { .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1, 314 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 315 .writefn = tlbimva_write }, 316 { .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 2, 317 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 318 .writefn = tlbiasid_write }, 319 /* 32 bit DTLB invalidates */ 320 { .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 0, 321 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 322 .writefn = tlbiall_write }, 323 { .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1, 324 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 325 .writefn = tlbimva_write }, 326 { .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 2, 327 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 328 .writefn = tlbiasid_write }, 329 /* 32 bit TLB invalidates */ 330 { .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, 331 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 332 .writefn = tlbiall_write }, 333 { .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, 334 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 335 .writefn = tlbimva_write }, 336 { .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, 337 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 338 .writefn = tlbiasid_write }, 339 { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, 340 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 341 .writefn = tlbimvaa_write }, 342 }; 343 344 static const ARMCPRegInfo tlbi_v7mp_cp_reginfo[] = { 345 /* 32 bit TLB invalidates, Inner Shareable */ 346 { .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, 347 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 348 .writefn = tlbiall_is_write }, 349 { .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, 350 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 351 .writefn = tlbimva_is_write }, 352 { .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, 353 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 354 .writefn = tlbiasid_is_write }, 355 { .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, 356 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 357 .writefn = tlbimvaa_is_write }, 358 }; 359 360 static const ARMCPRegInfo tlbi_v8_cp_reginfo[] = { 361 /* AArch32 TLB invalidate last level of translation table walk */ 362 { .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, 363 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 364 .writefn = tlbimva_is_write }, 365 { .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, 366 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 367 .writefn = tlbimvaa_is_write }, 368 { .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, 369 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 370 .writefn = tlbimva_write }, 371 { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, 372 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 373 .writefn = tlbimvaa_write }, 374 { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5, 375 .type = ARM_CP_NO_RAW, .access = PL2_W, 376 .writefn = tlbimva_hyp_write }, 377 { .name = "TLBIMVALHIS", 378 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5, 379 .type = ARM_CP_NO_RAW, .access = PL2_W, 380 .writefn = tlbimva_hyp_is_write }, 381 { .name = "TLBIIPAS2", 382 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, 383 .type = ARM_CP_NO_RAW, .access = PL2_W, 384 .writefn = tlbiipas2_hyp_write }, 385 { .name = "TLBIIPAS2IS", 386 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, 387 .type = ARM_CP_NO_RAW, .access = PL2_W, 388 .writefn = tlbiipas2is_hyp_write }, 389 { .name = "TLBIIPAS2L", 390 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, 391 .type = ARM_CP_NO_RAW, .access = PL2_W, 392 .writefn = tlbiipas2_hyp_write }, 393 { .name = "TLBIIPAS2LIS", 394 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, 395 .type = ARM_CP_NO_RAW, .access = PL2_W, 396 .writefn = tlbiipas2is_hyp_write }, 397 /* AArch64 TLBI operations */ 398 { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64, 399 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, 400 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 401 .fgt = FGT_TLBIVMALLE1IS, 402 .writefn = tlbi_aa64_vmalle1is_write }, 403 { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64, 404 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, 405 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 406 .fgt = FGT_TLBIVAE1IS, 407 .writefn = tlbi_aa64_vae1is_write }, 408 { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64, 409 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, 410 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 411 .fgt = FGT_TLBIASIDE1IS, 412 .writefn = tlbi_aa64_vmalle1is_write }, 413 { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64, 414 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, 415 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 416 .fgt = FGT_TLBIVAAE1IS, 417 .writefn = tlbi_aa64_vae1is_write }, 418 { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64, 419 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, 420 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 421 .fgt = FGT_TLBIVALE1IS, 422 .writefn = tlbi_aa64_vae1is_write }, 423 { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64, 424 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, 425 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 426 .fgt = FGT_TLBIVAALE1IS, 427 .writefn = tlbi_aa64_vae1is_write }, 428 { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64, 429 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, 430 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 431 .fgt = FGT_TLBIVMALLE1, 432 .writefn = tlbi_aa64_vmalle1_write }, 433 { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64, 434 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, 435 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 436 .fgt = FGT_TLBIVAE1, 437 .writefn = tlbi_aa64_vae1_write }, 438 { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64, 439 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, 440 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 441 .fgt = FGT_TLBIASIDE1, 442 .writefn = tlbi_aa64_vmalle1_write }, 443 { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64, 444 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, 445 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 446 .fgt = FGT_TLBIVAAE1, 447 .writefn = tlbi_aa64_vae1_write }, 448 { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64, 449 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, 450 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 451 .fgt = FGT_TLBIVALE1, 452 .writefn = tlbi_aa64_vae1_write }, 453 { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64, 454 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, 455 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 456 .fgt = FGT_TLBIVAALE1, 457 .writefn = tlbi_aa64_vae1_write }, 458 { .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64, 459 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, 460 .access = PL2_W, .type = ARM_CP_NO_RAW, 461 .writefn = tlbi_aa64_ipas2e1is_write }, 462 { .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64, 463 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, 464 .access = PL2_W, .type = ARM_CP_NO_RAW, 465 .writefn = tlbi_aa64_ipas2e1is_write }, 466 { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64, 467 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, 468 .access = PL2_W, .type = ARM_CP_NO_RAW, 469 .writefn = tlbi_aa64_alle1is_write }, 470 { .name = "TLBI_VMALLS12E1IS", .state = ARM_CP_STATE_AA64, 471 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 6, 472 .access = PL2_W, .type = ARM_CP_NO_RAW, 473 .writefn = tlbi_aa64_alle1is_write }, 474 { .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64, 475 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, 476 .access = PL2_W, .type = ARM_CP_NO_RAW, 477 .writefn = tlbi_aa64_ipas2e1_write }, 478 { .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64, 479 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, 480 .access = PL2_W, .type = ARM_CP_NO_RAW, 481 .writefn = tlbi_aa64_ipas2e1_write }, 482 { .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64, 483 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, 484 .access = PL2_W, .type = ARM_CP_NO_RAW, 485 .writefn = tlbi_aa64_alle1_write }, 486 { .name = "TLBI_VMALLS12E1", .state = ARM_CP_STATE_AA64, 487 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 6, 488 .access = PL2_W, .type = ARM_CP_NO_RAW, 489 .writefn = tlbi_aa64_alle1is_write }, 490 }; 491 492 static const ARMCPRegInfo tlbi_el2_cp_reginfo[] = { 493 { .name = "TLBIALLNSNH", 494 .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, 495 .type = ARM_CP_NO_RAW, .access = PL2_W, 496 .writefn = tlbiall_nsnh_write }, 497 { .name = "TLBIALLNSNHIS", 498 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, 499 .type = ARM_CP_NO_RAW, .access = PL2_W, 500 .writefn = tlbiall_nsnh_is_write }, 501 { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, 502 .type = ARM_CP_NO_RAW, .access = PL2_W, 503 .writefn = tlbiall_hyp_write }, 504 { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0, 505 .type = ARM_CP_NO_RAW, .access = PL2_W, 506 .writefn = tlbiall_hyp_is_write }, 507 { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1, 508 .type = ARM_CP_NO_RAW, .access = PL2_W, 509 .writefn = tlbimva_hyp_write }, 510 { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1, 511 .type = ARM_CP_NO_RAW, .access = PL2_W, 512 .writefn = tlbimva_hyp_is_write }, 513 { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64, 514 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, 515 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 516 .writefn = tlbi_aa64_alle2_write }, 517 { .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64, 518 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1, 519 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 520 .writefn = tlbi_aa64_vae2_write }, 521 { .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64, 522 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5, 523 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 524 .writefn = tlbi_aa64_vae2_write }, 525 { .name = "TLBI_ALLE2IS", .state = ARM_CP_STATE_AA64, 526 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0, 527 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 528 .writefn = tlbi_aa64_alle2is_write }, 529 { .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64, 530 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1, 531 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 532 .writefn = tlbi_aa64_vae2is_write }, 533 { .name = "TLBI_VALE2IS", .state = ARM_CP_STATE_AA64, 534 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5, 535 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 536 .writefn = tlbi_aa64_vae2is_write }, 537 }; 538 539 static const ARMCPRegInfo tlbi_el3_cp_reginfo[] = { 540 { .name = "TLBI_ALLE3IS", .state = ARM_CP_STATE_AA64, 541 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 0, 542 .access = PL3_W, .type = ARM_CP_NO_RAW, 543 .writefn = tlbi_aa64_alle3is_write }, 544 { .name = "TLBI_VAE3IS", .state = ARM_CP_STATE_AA64, 545 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 1, 546 .access = PL3_W, .type = ARM_CP_NO_RAW, 547 .writefn = tlbi_aa64_vae3is_write }, 548 { .name = "TLBI_VALE3IS", .state = ARM_CP_STATE_AA64, 549 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 5, 550 .access = PL3_W, .type = ARM_CP_NO_RAW, 551 .writefn = tlbi_aa64_vae3is_write }, 552 { .name = "TLBI_ALLE3", .state = ARM_CP_STATE_AA64, 553 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 0, 554 .access = PL3_W, .type = ARM_CP_NO_RAW, 555 .writefn = tlbi_aa64_alle3_write }, 556 { .name = "TLBI_VAE3", .state = ARM_CP_STATE_AA64, 557 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 1, 558 .access = PL3_W, .type = ARM_CP_NO_RAW, 559 .writefn = tlbi_aa64_vae3_write }, 560 { .name = "TLBI_VALE3", .state = ARM_CP_STATE_AA64, 561 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 5, 562 .access = PL3_W, .type = ARM_CP_NO_RAW, 563 .writefn = tlbi_aa64_vae3_write }, 564 }; 565 566 #ifdef TARGET_AARCH64 567 typedef struct { 568 uint64_t base; 569 uint64_t length; 570 } TLBIRange; 571 572 static ARMGranuleSize tlbi_range_tg_to_gran_size(int tg) 573 { 574 /* 575 * Note that the TLBI range TG field encoding differs from both 576 * TG0 and TG1 encodings. 577 */ 578 switch (tg) { 579 case 1: 580 return Gran4K; 581 case 2: 582 return Gran16K; 583 case 3: 584 return Gran64K; 585 default: 586 return GranInvalid; 587 } 588 } 589 590 static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx, 591 uint64_t value) 592 { 593 unsigned int page_size_granule, page_shift, num, scale, exponent; 594 /* Extract one bit to represent the va selector in use. */ 595 uint64_t select = sextract64(value, 36, 1); 596 ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true, false); 597 TLBIRange ret = { }; 598 ARMGranuleSize gran; 599 600 page_size_granule = extract64(value, 46, 2); 601 gran = tlbi_range_tg_to_gran_size(page_size_granule); 602 603 /* The granule encoded in value must match the granule in use. */ 604 if (gran != param.gran) { 605 qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n", 606 page_size_granule); 607 return ret; 608 } 609 610 page_shift = arm_granule_bits(gran); 611 num = extract64(value, 39, 5); 612 scale = extract64(value, 44, 2); 613 exponent = (5 * scale) + 1; 614 615 ret.length = (num + 1) << (exponent + page_shift); 616 617 if (param.select) { 618 ret.base = sextract64(value, 0, 37); 619 } else { 620 ret.base = extract64(value, 0, 37); 621 } 622 if (param.ds) { 623 /* 624 * With DS=1, BaseADDR is always shifted 16 so that it is able 625 * to address all 52 va bits. The input address is perforce 626 * aligned on a 64k boundary regardless of translation granule. 627 */ 628 page_shift = 16; 629 } 630 ret.base <<= page_shift; 631 632 return ret; 633 } 634 635 static void do_rvae_write(CPUARMState *env, uint64_t value, 636 int idxmap, bool synced) 637 { 638 ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap); 639 TLBIRange range; 640 int bits; 641 642 range = tlbi_aa64_get_range(env, one_idx, value); 643 bits = tlbbits_for_regime(env, one_idx, range.base); 644 645 if (synced) { 646 tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env), 647 range.base, 648 range.length, 649 idxmap, 650 bits); 651 } else { 652 tlb_flush_range_by_mmuidx(env_cpu(env), range.base, 653 range.length, idxmap, bits); 654 } 655 } 656 657 static void tlbi_aa64_rvae1_write(CPUARMState *env, 658 const ARMCPRegInfo *ri, 659 uint64_t value) 660 { 661 /* 662 * Invalidate by VA range, EL1&0. 663 * Currently handles all of RVAE1, RVAAE1, RVAALE1 and RVALE1, 664 * since we don't support flush-for-specific-ASID-only or 665 * flush-last-level-only. 666 */ 667 668 do_rvae_write(env, value, vae1_tlbmask(env), 669 tlb_force_broadcast(env)); 670 } 671 672 static void tlbi_aa64_rvae1is_write(CPUARMState *env, 673 const ARMCPRegInfo *ri, 674 uint64_t value) 675 { 676 /* 677 * Invalidate by VA range, Inner/Outer Shareable EL1&0. 678 * Currently handles all of RVAE1IS, RVAE1OS, RVAAE1IS, RVAAE1OS, 679 * RVAALE1IS, RVAALE1OS, RVALE1IS and RVALE1OS, since we don't support 680 * flush-for-specific-ASID-only, flush-last-level-only or inner/outer 681 * shareable specific flushes. 682 */ 683 684 do_rvae_write(env, value, vae1_tlbmask(env), true); 685 } 686 687 static void tlbi_aa64_rvae2_write(CPUARMState *env, 688 const ARMCPRegInfo *ri, 689 uint64_t value) 690 { 691 /* 692 * Invalidate by VA range, EL2. 693 * Currently handles all of RVAE2 and RVALE2, 694 * since we don't support flush-for-specific-ASID-only or 695 * flush-last-level-only. 696 */ 697 698 do_rvae_write(env, value, vae2_tlbmask(env), 699 tlb_force_broadcast(env)); 700 701 702 } 703 704 static void tlbi_aa64_rvae2is_write(CPUARMState *env, 705 const ARMCPRegInfo *ri, 706 uint64_t value) 707 { 708 /* 709 * Invalidate by VA range, Inner/Outer Shareable, EL2. 710 * Currently handles all of RVAE2IS, RVAE2OS, RVALE2IS and RVALE2OS, 711 * since we don't support flush-for-specific-ASID-only, 712 * flush-last-level-only or inner/outer shareable specific flushes. 713 */ 714 715 do_rvae_write(env, value, vae2_tlbmask(env), true); 716 717 } 718 719 static void tlbi_aa64_rvae3_write(CPUARMState *env, 720 const ARMCPRegInfo *ri, 721 uint64_t value) 722 { 723 /* 724 * Invalidate by VA range, EL3. 725 * Currently handles all of RVAE3 and RVALE3, 726 * since we don't support flush-for-specific-ASID-only or 727 * flush-last-level-only. 728 */ 729 730 do_rvae_write(env, value, ARMMMUIdxBit_E3, tlb_force_broadcast(env)); 731 } 732 733 static void tlbi_aa64_rvae3is_write(CPUARMState *env, 734 const ARMCPRegInfo *ri, 735 uint64_t value) 736 { 737 /* 738 * Invalidate by VA range, EL3, Inner/Outer Shareable. 739 * Currently handles all of RVAE3IS, RVAE3OS, RVALE3IS and RVALE3OS, 740 * since we don't support flush-for-specific-ASID-only, 741 * flush-last-level-only or inner/outer specific flushes. 742 */ 743 744 do_rvae_write(env, value, ARMMMUIdxBit_E3, true); 745 } 746 747 static void tlbi_aa64_ripas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri, 748 uint64_t value) 749 { 750 do_rvae_write(env, value, ipas2e1_tlbmask(env, value), 751 tlb_force_broadcast(env)); 752 } 753 754 static void tlbi_aa64_ripas2e1is_write(CPUARMState *env, 755 const ARMCPRegInfo *ri, 756 uint64_t value) 757 { 758 do_rvae_write(env, value, ipas2e1_tlbmask(env, value), true); 759 } 760 761 static const ARMCPRegInfo tlbirange_reginfo[] = { 762 { .name = "TLBI_RVAE1IS", .state = ARM_CP_STATE_AA64, 763 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 1, 764 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 765 .fgt = FGT_TLBIRVAE1IS, 766 .writefn = tlbi_aa64_rvae1is_write }, 767 { .name = "TLBI_RVAAE1IS", .state = ARM_CP_STATE_AA64, 768 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 3, 769 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 770 .fgt = FGT_TLBIRVAAE1IS, 771 .writefn = tlbi_aa64_rvae1is_write }, 772 { .name = "TLBI_RVALE1IS", .state = ARM_CP_STATE_AA64, 773 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 5, 774 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 775 .fgt = FGT_TLBIRVALE1IS, 776 .writefn = tlbi_aa64_rvae1is_write }, 777 { .name = "TLBI_RVAALE1IS", .state = ARM_CP_STATE_AA64, 778 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 7, 779 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 780 .fgt = FGT_TLBIRVAALE1IS, 781 .writefn = tlbi_aa64_rvae1is_write }, 782 { .name = "TLBI_RVAE1OS", .state = ARM_CP_STATE_AA64, 783 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1, 784 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 785 .fgt = FGT_TLBIRVAE1OS, 786 .writefn = tlbi_aa64_rvae1is_write }, 787 { .name = "TLBI_RVAAE1OS", .state = ARM_CP_STATE_AA64, 788 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 3, 789 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 790 .fgt = FGT_TLBIRVAAE1OS, 791 .writefn = tlbi_aa64_rvae1is_write }, 792 { .name = "TLBI_RVALE1OS", .state = ARM_CP_STATE_AA64, 793 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 5, 794 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 795 .fgt = FGT_TLBIRVALE1OS, 796 .writefn = tlbi_aa64_rvae1is_write }, 797 { .name = "TLBI_RVAALE1OS", .state = ARM_CP_STATE_AA64, 798 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 7, 799 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 800 .fgt = FGT_TLBIRVAALE1OS, 801 .writefn = tlbi_aa64_rvae1is_write }, 802 { .name = "TLBI_RVAE1", .state = ARM_CP_STATE_AA64, 803 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1, 804 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 805 .fgt = FGT_TLBIRVAE1, 806 .writefn = tlbi_aa64_rvae1_write }, 807 { .name = "TLBI_RVAAE1", .state = ARM_CP_STATE_AA64, 808 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 3, 809 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 810 .fgt = FGT_TLBIRVAAE1, 811 .writefn = tlbi_aa64_rvae1_write }, 812 { .name = "TLBI_RVALE1", .state = ARM_CP_STATE_AA64, 813 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 5, 814 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 815 .fgt = FGT_TLBIRVALE1, 816 .writefn = tlbi_aa64_rvae1_write }, 817 { .name = "TLBI_RVAALE1", .state = ARM_CP_STATE_AA64, 818 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 7, 819 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 820 .fgt = FGT_TLBIRVAALE1, 821 .writefn = tlbi_aa64_rvae1_write }, 822 { .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64, 823 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2, 824 .access = PL2_W, .type = ARM_CP_NO_RAW, 825 .writefn = tlbi_aa64_ripas2e1is_write }, 826 { .name = "TLBI_RIPAS2LE1IS", .state = ARM_CP_STATE_AA64, 827 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 6, 828 .access = PL2_W, .type = ARM_CP_NO_RAW, 829 .writefn = tlbi_aa64_ripas2e1is_write }, 830 { .name = "TLBI_RVAE2IS", .state = ARM_CP_STATE_AA64, 831 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 1, 832 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 833 .writefn = tlbi_aa64_rvae2is_write }, 834 { .name = "TLBI_RVALE2IS", .state = ARM_CP_STATE_AA64, 835 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 5, 836 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 837 .writefn = tlbi_aa64_rvae2is_write }, 838 { .name = "TLBI_RIPAS2E1", .state = ARM_CP_STATE_AA64, 839 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 2, 840 .access = PL2_W, .type = ARM_CP_NO_RAW, 841 .writefn = tlbi_aa64_ripas2e1_write }, 842 { .name = "TLBI_RIPAS2LE1", .state = ARM_CP_STATE_AA64, 843 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 6, 844 .access = PL2_W, .type = ARM_CP_NO_RAW, 845 .writefn = tlbi_aa64_ripas2e1_write }, 846 { .name = "TLBI_RVAE2OS", .state = ARM_CP_STATE_AA64, 847 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 1, 848 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 849 .writefn = tlbi_aa64_rvae2is_write }, 850 { .name = "TLBI_RVALE2OS", .state = ARM_CP_STATE_AA64, 851 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 5, 852 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 853 .writefn = tlbi_aa64_rvae2is_write }, 854 { .name = "TLBI_RVAE2", .state = ARM_CP_STATE_AA64, 855 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 1, 856 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 857 .writefn = tlbi_aa64_rvae2_write }, 858 { .name = "TLBI_RVALE2", .state = ARM_CP_STATE_AA64, 859 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 5, 860 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 861 .writefn = tlbi_aa64_rvae2_write }, 862 { .name = "TLBI_RVAE3IS", .state = ARM_CP_STATE_AA64, 863 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 1, 864 .access = PL3_W, .type = ARM_CP_NO_RAW, 865 .writefn = tlbi_aa64_rvae3is_write }, 866 { .name = "TLBI_RVALE3IS", .state = ARM_CP_STATE_AA64, 867 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 5, 868 .access = PL3_W, .type = ARM_CP_NO_RAW, 869 .writefn = tlbi_aa64_rvae3is_write }, 870 { .name = "TLBI_RVAE3OS", .state = ARM_CP_STATE_AA64, 871 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 1, 872 .access = PL3_W, .type = ARM_CP_NO_RAW, 873 .writefn = tlbi_aa64_rvae3is_write }, 874 { .name = "TLBI_RVALE3OS", .state = ARM_CP_STATE_AA64, 875 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 5, 876 .access = PL3_W, .type = ARM_CP_NO_RAW, 877 .writefn = tlbi_aa64_rvae3is_write }, 878 { .name = "TLBI_RVAE3", .state = ARM_CP_STATE_AA64, 879 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 1, 880 .access = PL3_W, .type = ARM_CP_NO_RAW, 881 .writefn = tlbi_aa64_rvae3_write }, 882 { .name = "TLBI_RVALE3", .state = ARM_CP_STATE_AA64, 883 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 5, 884 .access = PL3_W, .type = ARM_CP_NO_RAW, 885 .writefn = tlbi_aa64_rvae3_write }, 886 }; 887 888 static const ARMCPRegInfo tlbios_reginfo[] = { 889 { .name = "TLBI_VMALLE1OS", .state = ARM_CP_STATE_AA64, 890 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0, 891 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 892 .fgt = FGT_TLBIVMALLE1OS, 893 .writefn = tlbi_aa64_vmalle1is_write }, 894 { .name = "TLBI_VAE1OS", .state = ARM_CP_STATE_AA64, 895 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 1, 896 .fgt = FGT_TLBIVAE1OS, 897 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 898 .writefn = tlbi_aa64_vae1is_write }, 899 { .name = "TLBI_ASIDE1OS", .state = ARM_CP_STATE_AA64, 900 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 2, 901 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 902 .fgt = FGT_TLBIASIDE1OS, 903 .writefn = tlbi_aa64_vmalle1is_write }, 904 { .name = "TLBI_VAAE1OS", .state = ARM_CP_STATE_AA64, 905 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 3, 906 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 907 .fgt = FGT_TLBIVAAE1OS, 908 .writefn = tlbi_aa64_vae1is_write }, 909 { .name = "TLBI_VALE1OS", .state = ARM_CP_STATE_AA64, 910 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 5, 911 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 912 .fgt = FGT_TLBIVALE1OS, 913 .writefn = tlbi_aa64_vae1is_write }, 914 { .name = "TLBI_VAALE1OS", .state = ARM_CP_STATE_AA64, 915 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 7, 916 .access = PL1_W, .accessfn = access_ttlbos, .type = ARM_CP_NO_RAW, 917 .fgt = FGT_TLBIVAALE1OS, 918 .writefn = tlbi_aa64_vae1is_write }, 919 { .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64, 920 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0, 921 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 922 .writefn = tlbi_aa64_alle2is_write }, 923 { .name = "TLBI_VAE2OS", .state = ARM_CP_STATE_AA64, 924 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 1, 925 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 926 .writefn = tlbi_aa64_vae2is_write }, 927 { .name = "TLBI_ALLE1OS", .state = ARM_CP_STATE_AA64, 928 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 4, 929 .access = PL2_W, .type = ARM_CP_NO_RAW, 930 .writefn = tlbi_aa64_alle1is_write }, 931 { .name = "TLBI_VALE2OS", .state = ARM_CP_STATE_AA64, 932 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 5, 933 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF, 934 .writefn = tlbi_aa64_vae2is_write }, 935 { .name = "TLBI_VMALLS12E1OS", .state = ARM_CP_STATE_AA64, 936 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 6, 937 .access = PL2_W, .type = ARM_CP_NO_RAW, 938 .writefn = tlbi_aa64_alle1is_write }, 939 { .name = "TLBI_IPAS2E1OS", .state = ARM_CP_STATE_AA64, 940 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 0, 941 .access = PL2_W, .type = ARM_CP_NOP }, 942 { .name = "TLBI_RIPAS2E1OS", .state = ARM_CP_STATE_AA64, 943 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 3, 944 .access = PL2_W, .type = ARM_CP_NOP }, 945 { .name = "TLBI_IPAS2LE1OS", .state = ARM_CP_STATE_AA64, 946 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 4, 947 .access = PL2_W, .type = ARM_CP_NOP }, 948 { .name = "TLBI_RIPAS2LE1OS", .state = ARM_CP_STATE_AA64, 949 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 7, 950 .access = PL2_W, .type = ARM_CP_NOP }, 951 { .name = "TLBI_ALLE3OS", .state = ARM_CP_STATE_AA64, 952 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 0, 953 .access = PL3_W, .type = ARM_CP_NO_RAW, 954 .writefn = tlbi_aa64_alle3is_write }, 955 { .name = "TLBI_VAE3OS", .state = ARM_CP_STATE_AA64, 956 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 1, 957 .access = PL3_W, .type = ARM_CP_NO_RAW, 958 .writefn = tlbi_aa64_vae3is_write }, 959 { .name = "TLBI_VALE3OS", .state = ARM_CP_STATE_AA64, 960 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 5, 961 .access = PL3_W, .type = ARM_CP_NO_RAW, 962 .writefn = tlbi_aa64_vae3is_write }, 963 }; 964 #endif 965 966 void define_tlb_insn_regs(ARMCPU *cpu) 967 { 968 CPUARMState *env = &cpu->env; 969 970 if (!arm_feature(env, ARM_FEATURE_V7)) { 971 define_arm_cp_regs(cpu, tlbi_not_v7_cp_reginfo); 972 } else { 973 define_arm_cp_regs(cpu, tlbi_v7_cp_reginfo); 974 } 975 if (arm_feature(env, ARM_FEATURE_V7MP) && 976 !arm_feature(env, ARM_FEATURE_PMSA)) { 977 define_arm_cp_regs(cpu, tlbi_v7mp_cp_reginfo); 978 } 979 if (arm_feature(env, ARM_FEATURE_V8)) { 980 define_arm_cp_regs(cpu, tlbi_v8_cp_reginfo); 981 } 982 /* 983 * We retain the existing logic for when to register these TLBI 984 * ops (i.e. matching the condition for el2_cp_reginfo[] in 985 * helper.c), but we will be able to simplify this later. 986 */ 987 if (arm_feature(env, ARM_FEATURE_EL2) 988 || (arm_feature(env, ARM_FEATURE_EL3) 989 && arm_feature(env, ARM_FEATURE_V8))) { 990 define_arm_cp_regs(cpu, tlbi_el2_cp_reginfo); 991 } 992 if (arm_feature(env, ARM_FEATURE_EL3)) { 993 define_arm_cp_regs(cpu, tlbi_el3_cp_reginfo); 994 } 995 #ifdef TARGET_AARCH64 996 if (cpu_isar_feature(aa64_tlbirange, cpu)) { 997 define_arm_cp_regs(cpu, tlbirange_reginfo); 998 } 999 if (cpu_isar_feature(aa64_tlbios, cpu)) { 1000 define_arm_cp_regs(cpu, tlbios_reginfo); 1001 } 1002 #endif 1003 } 1004