xref: /qemu/target/arm/tcg/tlb-insns.c (revision 47c7764bd7255cd28a3b81a71d63c5f0bfd8bc99)
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