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