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 "exec/exec-all.h" 10 #include "cpu.h" 11 #include "internals.h" 12 #include "cpu-features.h" 13 #include "cpregs.h" 14 15 /* IS variants of TLB operations must affect all cores */ 16 static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 17 uint64_t value) 18 { 19 CPUState *cs = env_cpu(env); 20 21 tlb_flush_all_cpus_synced(cs); 22 } 23 24 static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 25 uint64_t value) 26 { 27 CPUState *cs = env_cpu(env); 28 29 tlb_flush_all_cpus_synced(cs); 30 } 31 32 static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 33 uint64_t value) 34 { 35 CPUState *cs = env_cpu(env); 36 37 tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK); 38 } 39 40 static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 41 uint64_t value) 42 { 43 CPUState *cs = env_cpu(env); 44 45 tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK); 46 } 47 48 static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri, 49 uint64_t value) 50 { 51 /* Invalidate all (TLBIALL) */ 52 CPUState *cs = env_cpu(env); 53 54 if (tlb_force_broadcast(env)) { 55 tlb_flush_all_cpus_synced(cs); 56 } else { 57 tlb_flush(cs); 58 } 59 } 60 61 static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri, 62 uint64_t value) 63 { 64 /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */ 65 CPUState *cs = env_cpu(env); 66 67 value &= TARGET_PAGE_MASK; 68 if (tlb_force_broadcast(env)) { 69 tlb_flush_page_all_cpus_synced(cs, value); 70 } else { 71 tlb_flush_page(cs, value); 72 } 73 } 74 75 static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri, 76 uint64_t value) 77 { 78 /* Invalidate by ASID (TLBIASID) */ 79 CPUState *cs = env_cpu(env); 80 81 if (tlb_force_broadcast(env)) { 82 tlb_flush_all_cpus_synced(cs); 83 } else { 84 tlb_flush(cs); 85 } 86 } 87 88 static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri, 89 uint64_t value) 90 { 91 /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */ 92 CPUState *cs = env_cpu(env); 93 94 value &= TARGET_PAGE_MASK; 95 if (tlb_force_broadcast(env)) { 96 tlb_flush_page_all_cpus_synced(cs, value); 97 } else { 98 tlb_flush_page(cs, value); 99 } 100 } 101 102 static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 103 uint64_t value) 104 { 105 CPUState *cs = env_cpu(env); 106 uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12); 107 108 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_E2); 109 } 110 111 static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 112 uint64_t value) 113 { 114 CPUState *cs = env_cpu(env); 115 uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12); 116 117 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, 118 ARMMMUIdxBit_E2); 119 } 120 121 static void tlbiipas2_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 122 uint64_t value) 123 { 124 CPUState *cs = env_cpu(env); 125 uint64_t pageaddr = (value & MAKE_64BIT_MASK(0, 28)) << 12; 126 127 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2); 128 } 129 130 static void tlbiipas2is_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 131 uint64_t value) 132 { 133 CPUState *cs = env_cpu(env); 134 uint64_t pageaddr = (value & MAKE_64BIT_MASK(0, 28)) << 12; 135 136 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, ARMMMUIdxBit_Stage2); 137 } 138 139 static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri, 140 uint64_t value) 141 { 142 CPUState *cs = env_cpu(env); 143 144 tlb_flush_by_mmuidx(cs, alle1_tlbmask(env)); 145 } 146 147 static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 148 uint64_t value) 149 { 150 CPUState *cs = env_cpu(env); 151 152 tlb_flush_by_mmuidx_all_cpus_synced(cs, alle1_tlbmask(env)); 153 } 154 155 156 static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri, 157 uint64_t value) 158 { 159 CPUState *cs = env_cpu(env); 160 161 tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_E2); 162 } 163 164 static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri, 165 uint64_t value) 166 { 167 CPUState *cs = env_cpu(env); 168 169 tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_E2); 170 } 171 172 static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri, 173 uint64_t value) 174 { 175 CPUState *cs = env_cpu(env); 176 int mask = vae1_tlbmask(env); 177 178 if (tlb_force_broadcast(env)) { 179 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask); 180 } else { 181 tlb_flush_by_mmuidx(cs, mask); 182 } 183 } 184 185 static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri, 186 uint64_t value) 187 { 188 CPUState *cs = env_cpu(env); 189 int mask = alle1_tlbmask(env); 190 191 tlb_flush_by_mmuidx(cs, mask); 192 } 193 194 static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri, 195 uint64_t value) 196 { 197 /* 198 * Invalidate by VA, EL1&0 (AArch64 version). 199 * Currently handles all of VAE1, VAAE1, VAALE1 and VALE1, 200 * since we don't support flush-for-specific-ASID-only or 201 * flush-last-level-only. 202 */ 203 CPUState *cs = env_cpu(env); 204 int mask = vae1_tlbmask(env); 205 uint64_t pageaddr = sextract64(value << 12, 0, 56); 206 int bits = vae1_tlbbits(env, pageaddr); 207 208 if (tlb_force_broadcast(env)) { 209 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits); 210 } else { 211 tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits); 212 } 213 } 214 215 static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri, 216 uint64_t value) 217 { 218 CPUState *cs = env_cpu(env); 219 int mask = ipas2e1_tlbmask(env, value); 220 uint64_t pageaddr = sextract64(value << 12, 0, 56); 221 222 if (tlb_force_broadcast(env)) { 223 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask); 224 } else { 225 tlb_flush_page_by_mmuidx(cs, pageaddr, mask); 226 } 227 } 228 229 static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri, 230 uint64_t value) 231 { 232 CPUState *cs = env_cpu(env); 233 int mask = ipas2e1_tlbmask(env, value); 234 uint64_t pageaddr = sextract64(value << 12, 0, 56); 235 236 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask); 237 } 238 239 static const ARMCPRegInfo tlbi_not_v7_cp_reginfo[] = { 240 /* 241 * MMU TLB control. Note that the wildcarding means we cover not just 242 * the unified TLB ops but also the dside/iside/inner-shareable variants. 243 */ 244 { .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY, 245 .opc1 = CP_ANY, .opc2 = 0, .access = PL1_W, .writefn = tlbiall_write, 246 .type = ARM_CP_NO_RAW }, 247 { .name = "TLBIMVA", .cp = 15, .crn = 8, .crm = CP_ANY, 248 .opc1 = CP_ANY, .opc2 = 1, .access = PL1_W, .writefn = tlbimva_write, 249 .type = ARM_CP_NO_RAW }, 250 { .name = "TLBIASID", .cp = 15, .crn = 8, .crm = CP_ANY, 251 .opc1 = CP_ANY, .opc2 = 2, .access = PL1_W, .writefn = tlbiasid_write, 252 .type = ARM_CP_NO_RAW }, 253 { .name = "TLBIMVAA", .cp = 15, .crn = 8, .crm = CP_ANY, 254 .opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = tlbimvaa_write, 255 .type = ARM_CP_NO_RAW }, 256 }; 257 258 static const ARMCPRegInfo tlbi_v7_cp_reginfo[] = { 259 /* 32 bit ITLB invalidates */ 260 { .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0, 261 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 262 .writefn = tlbiall_write }, 263 { .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1, 264 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 265 .writefn = tlbimva_write }, 266 { .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 2, 267 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 268 .writefn = tlbiasid_write }, 269 /* 32 bit DTLB invalidates */ 270 { .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 0, 271 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 272 .writefn = tlbiall_write }, 273 { .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1, 274 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 275 .writefn = tlbimva_write }, 276 { .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 2, 277 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 278 .writefn = tlbiasid_write }, 279 /* 32 bit TLB invalidates */ 280 { .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, 281 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 282 .writefn = tlbiall_write }, 283 { .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, 284 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 285 .writefn = tlbimva_write }, 286 { .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, 287 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 288 .writefn = tlbiasid_write }, 289 { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, 290 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 291 .writefn = tlbimvaa_write }, 292 }; 293 294 static const ARMCPRegInfo tlbi_v7mp_cp_reginfo[] = { 295 /* 32 bit TLB invalidates, Inner Shareable */ 296 { .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, 297 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 298 .writefn = tlbiall_is_write }, 299 { .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, 300 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 301 .writefn = tlbimva_is_write }, 302 { .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, 303 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 304 .writefn = tlbiasid_is_write }, 305 { .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, 306 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 307 .writefn = tlbimvaa_is_write }, 308 }; 309 310 static const ARMCPRegInfo tlbi_v8_cp_reginfo[] = { 311 /* AArch32 TLB invalidate last level of translation table walk */ 312 { .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, 313 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 314 .writefn = tlbimva_is_write }, 315 { .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, 316 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlbis, 317 .writefn = tlbimvaa_is_write }, 318 { .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, 319 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 320 .writefn = tlbimva_write }, 321 { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, 322 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb, 323 .writefn = tlbimvaa_write }, 324 { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5, 325 .type = ARM_CP_NO_RAW, .access = PL2_W, 326 .writefn = tlbimva_hyp_write }, 327 { .name = "TLBIMVALHIS", 328 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5, 329 .type = ARM_CP_NO_RAW, .access = PL2_W, 330 .writefn = tlbimva_hyp_is_write }, 331 { .name = "TLBIIPAS2", 332 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, 333 .type = ARM_CP_NO_RAW, .access = PL2_W, 334 .writefn = tlbiipas2_hyp_write }, 335 { .name = "TLBIIPAS2IS", 336 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, 337 .type = ARM_CP_NO_RAW, .access = PL2_W, 338 .writefn = tlbiipas2is_hyp_write }, 339 { .name = "TLBIIPAS2L", 340 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, 341 .type = ARM_CP_NO_RAW, .access = PL2_W, 342 .writefn = tlbiipas2_hyp_write }, 343 { .name = "TLBIIPAS2LIS", 344 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, 345 .type = ARM_CP_NO_RAW, .access = PL2_W, 346 .writefn = tlbiipas2is_hyp_write }, 347 /* AArch64 TLBI operations */ 348 { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64, 349 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0, 350 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 351 .fgt = FGT_TLBIVMALLE1IS, 352 .writefn = tlbi_aa64_vmalle1is_write }, 353 { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64, 354 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1, 355 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 356 .fgt = FGT_TLBIVAE1IS, 357 .writefn = tlbi_aa64_vae1is_write }, 358 { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64, 359 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2, 360 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 361 .fgt = FGT_TLBIASIDE1IS, 362 .writefn = tlbi_aa64_vmalle1is_write }, 363 { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64, 364 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3, 365 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 366 .fgt = FGT_TLBIVAAE1IS, 367 .writefn = tlbi_aa64_vae1is_write }, 368 { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64, 369 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5, 370 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 371 .fgt = FGT_TLBIVALE1IS, 372 .writefn = tlbi_aa64_vae1is_write }, 373 { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64, 374 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7, 375 .access = PL1_W, .accessfn = access_ttlbis, .type = ARM_CP_NO_RAW, 376 .fgt = FGT_TLBIVAALE1IS, 377 .writefn = tlbi_aa64_vae1is_write }, 378 { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64, 379 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0, 380 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 381 .fgt = FGT_TLBIVMALLE1, 382 .writefn = tlbi_aa64_vmalle1_write }, 383 { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64, 384 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1, 385 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 386 .fgt = FGT_TLBIVAE1, 387 .writefn = tlbi_aa64_vae1_write }, 388 { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64, 389 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2, 390 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 391 .fgt = FGT_TLBIASIDE1, 392 .writefn = tlbi_aa64_vmalle1_write }, 393 { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64, 394 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3, 395 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 396 .fgt = FGT_TLBIVAAE1, 397 .writefn = tlbi_aa64_vae1_write }, 398 { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64, 399 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5, 400 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 401 .fgt = FGT_TLBIVALE1, 402 .writefn = tlbi_aa64_vae1_write }, 403 { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64, 404 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7, 405 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW, 406 .fgt = FGT_TLBIVAALE1, 407 .writefn = tlbi_aa64_vae1_write }, 408 { .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64, 409 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1, 410 .access = PL2_W, .type = ARM_CP_NO_RAW, 411 .writefn = tlbi_aa64_ipas2e1is_write }, 412 { .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64, 413 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5, 414 .access = PL2_W, .type = ARM_CP_NO_RAW, 415 .writefn = tlbi_aa64_ipas2e1is_write }, 416 { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64, 417 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, 418 .access = PL2_W, .type = ARM_CP_NO_RAW, 419 .writefn = tlbi_aa64_alle1is_write }, 420 { .name = "TLBI_VMALLS12E1IS", .state = ARM_CP_STATE_AA64, 421 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 6, 422 .access = PL2_W, .type = ARM_CP_NO_RAW, 423 .writefn = tlbi_aa64_alle1is_write }, 424 { .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64, 425 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1, 426 .access = PL2_W, .type = ARM_CP_NO_RAW, 427 .writefn = tlbi_aa64_ipas2e1_write }, 428 { .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64, 429 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5, 430 .access = PL2_W, .type = ARM_CP_NO_RAW, 431 .writefn = tlbi_aa64_ipas2e1_write }, 432 { .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64, 433 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, 434 .access = PL2_W, .type = ARM_CP_NO_RAW, 435 .writefn = tlbi_aa64_alle1_write }, 436 { .name = "TLBI_VMALLS12E1", .state = ARM_CP_STATE_AA64, 437 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 6, 438 .access = PL2_W, .type = ARM_CP_NO_RAW, 439 .writefn = tlbi_aa64_alle1is_write }, 440 }; 441 442 static const ARMCPRegInfo tlbi_el2_cp_reginfo[] = { 443 { .name = "TLBIALLNSNH", 444 .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4, 445 .type = ARM_CP_NO_RAW, .access = PL2_W, 446 .writefn = tlbiall_nsnh_write }, 447 { .name = "TLBIALLNSNHIS", 448 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4, 449 .type = ARM_CP_NO_RAW, .access = PL2_W, 450 .writefn = tlbiall_nsnh_is_write }, 451 { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0, 452 .type = ARM_CP_NO_RAW, .access = PL2_W, 453 .writefn = tlbiall_hyp_write }, 454 { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0, 455 .type = ARM_CP_NO_RAW, .access = PL2_W, 456 .writefn = tlbiall_hyp_is_write }, 457 { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1, 458 .type = ARM_CP_NO_RAW, .access = PL2_W, 459 .writefn = tlbimva_hyp_write }, 460 { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1, 461 .type = ARM_CP_NO_RAW, .access = PL2_W, 462 .writefn = tlbimva_hyp_is_write }, 463 }; 464 465 void define_tlb_insn_regs(ARMCPU *cpu) 466 { 467 CPUARMState *env = &cpu->env; 468 469 if (!arm_feature(env, ARM_FEATURE_V7)) { 470 define_arm_cp_regs(cpu, tlbi_not_v7_cp_reginfo); 471 } else { 472 define_arm_cp_regs(cpu, tlbi_v7_cp_reginfo); 473 } 474 if (arm_feature(env, ARM_FEATURE_V7MP) && 475 !arm_feature(env, ARM_FEATURE_PMSA)) { 476 define_arm_cp_regs(cpu, tlbi_v7mp_cp_reginfo); 477 } 478 if (arm_feature(env, ARM_FEATURE_V8)) { 479 define_arm_cp_regs(cpu, tlbi_v8_cp_reginfo); 480 } 481 /* 482 * We retain the existing logic for when to register these TLBI 483 * ops (i.e. matching the condition for el2_cp_reginfo[] in 484 * helper.c), but we will be able to simplify this later. 485 */ 486 if (arm_feature(env, ARM_FEATURE_EL2) 487 || (arm_feature(env, ARM_FEATURE_EL3) 488 && arm_feature(env, ARM_FEATURE_V8))) { 489 define_arm_cp_regs(cpu, tlbi_el2_cp_reginfo); 490 } 491 } 492