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