1
2
3
4
5
6
7
8
9#include "qemu/osdep.h"
10#include "qemu/units.h"
11#include "target/arm/idau.h"
12#include "trace.h"
13#include "cpu.h"
14#include "internals.h"
15#include "exec/gdbstub.h"
16#include "exec/helper-proto.h"
17#include "qemu/host-utils.h"
18#include "qemu/main-loop.h"
19#include "qemu/bitops.h"
20#include "qemu/crc32c.h"
21#include "qemu/qemu-print.h"
22#include "exec/exec-all.h"
23#include <zlib.h>
24#include "hw/irq.h"
25#include "semihosting/semihost.h"
26#include "sysemu/cpus.h"
27#include "sysemu/cpu-timers.h"
28#include "sysemu/kvm.h"
29#include "sysemu/tcg.h"
30#include "qemu/range.h"
31#include "qapi/qapi-commands-machine-target.h"
32#include "qapi/error.h"
33#include "qemu/guest-random.h"
34#ifdef CONFIG_TCG
35#include "arm_ldst.h"
36#include "exec/cpu_ldst.h"
37#include "semihosting/common-semi.h"
38#endif
39
40#define ARM_CPU_FREQ 1000000000
41#define PMCR_NUM_COUNTERS 4
42
43#ifndef CONFIG_USER_ONLY
44
45static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
46 MMUAccessType access_type, ARMMMUIdx mmu_idx,
47 bool s1_is_el0,
48 hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
49 target_ulong *page_size_ptr,
50 ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
51 __attribute__((nonnull));
52#endif
53
54static void switch_mode(CPUARMState *env, int mode);
55static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx);
56
57static int vfp_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
58{
59 ARMCPU *cpu = env_archcpu(env);
60 int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
61
62
63 if (reg < nregs) {
64 return gdb_get_reg64(buf, *aa32_vfp_dreg(env, reg));
65 }
66 if (arm_feature(env, ARM_FEATURE_NEON)) {
67
68 nregs += 16;
69 if (reg < nregs) {
70 uint64_t *q = aa32_vfp_qreg(env, reg - 32);
71 return gdb_get_reg128(buf, q[0], q[1]);
72 }
73 }
74 switch (reg - nregs) {
75 case 0: return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPSID]); break;
76 case 1: return gdb_get_reg32(buf, vfp_get_fpscr(env)); break;
77 case 2: return gdb_get_reg32(buf, env->vfp.xregs[ARM_VFP_FPEXC]); break;
78 }
79 return 0;
80}
81
82static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
83{
84 ARMCPU *cpu = env_archcpu(env);
85 int nregs = cpu_isar_feature(aa32_simd_r32, cpu) ? 32 : 16;
86
87 if (reg < nregs) {
88 *aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
89 return 8;
90 }
91 if (arm_feature(env, ARM_FEATURE_NEON)) {
92 nregs += 16;
93 if (reg < nregs) {
94 uint64_t *q = aa32_vfp_qreg(env, reg - 32);
95 q[0] = ldq_le_p(buf);
96 q[1] = ldq_le_p(buf + 8);
97 return 16;
98 }
99 }
100 switch (reg - nregs) {
101 case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
102 case 1: vfp_set_fpscr(env, ldl_p(buf)); return 4;
103 case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4;
104 }
105 return 0;
106}
107
108static int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg)
109{
110 switch (reg) {
111 case 0 ... 31:
112 {
113
114 uint64_t *q = aa64_vfp_qreg(env, reg);
115 return gdb_get_reg128(buf, q[1], q[0]);
116 }
117 case 32:
118
119 return gdb_get_reg32(buf, vfp_get_fpsr(env));
120 case 33:
121
122 return gdb_get_reg32(buf,vfp_get_fpcr(env));
123 default:
124 return 0;
125 }
126}
127
128static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
129{
130 switch (reg) {
131 case 0 ... 31:
132
133 {
134 uint64_t *q = aa64_vfp_qreg(env, reg);
135 q[0] = ldq_le_p(buf);
136 q[1] = ldq_le_p(buf + 8);
137 return 16;
138 }
139 case 32:
140
141 vfp_set_fpsr(env, ldl_p(buf));
142 return 4;
143 case 33:
144
145 vfp_set_fpcr(env, ldl_p(buf));
146 return 4;
147 default:
148 return 0;
149 }
150}
151
152static uint64_t raw_read(CPUARMState *env, const ARMCPRegInfo *ri)
153{
154 assert(ri->fieldoffset);
155 if (cpreg_field_is_64bit(ri)) {
156 return CPREG_FIELD64(env, ri);
157 } else {
158 return CPREG_FIELD32(env, ri);
159 }
160}
161
162static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
163 uint64_t value)
164{
165 assert(ri->fieldoffset);
166 if (cpreg_field_is_64bit(ri)) {
167 CPREG_FIELD64(env, ri) = value;
168 } else {
169 CPREG_FIELD32(env, ri) = value;
170 }
171}
172
173static void *raw_ptr(CPUARMState *env, const ARMCPRegInfo *ri)
174{
175 return (char *)env + ri->fieldoffset;
176}
177
178uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
179{
180
181 if (ri->type & ARM_CP_CONST) {
182 return ri->resetvalue;
183 } else if (ri->raw_readfn) {
184 return ri->raw_readfn(env, ri);
185 } else if (ri->readfn) {
186 return ri->readfn(env, ri);
187 } else {
188 return raw_read(env, ri);
189 }
190}
191
192static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
193 uint64_t v)
194{
195
196
197
198
199
200 if (ri->type & ARM_CP_CONST) {
201 return;
202 } else if (ri->raw_writefn) {
203 ri->raw_writefn(env, ri, v);
204 } else if (ri->writefn) {
205 ri->writefn(env, ri, v);
206 } else {
207 raw_write(env, ri, v);
208 }
209}
210
211
212
213
214
215
216
217
218
219
220static int arm_gdb_get_sysreg(CPUARMState *env, GByteArray *buf, int reg)
221{
222 ARMCPU *cpu = env_archcpu(env);
223 const ARMCPRegInfo *ri;
224 uint32_t key;
225
226 key = cpu->dyn_sysreg_xml.data.cpregs.keys[reg];
227 ri = get_arm_cp_reginfo(cpu->cp_regs, key);
228 if (ri) {
229 if (cpreg_field_is_64bit(ri)) {
230 return gdb_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri));
231 } else {
232 return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri));
233 }
234 }
235 return 0;
236}
237
238static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
239{
240 return 0;
241}
242
243#ifdef TARGET_AARCH64
244static int arm_gdb_get_svereg(CPUARMState *env, GByteArray *buf, int reg)
245{
246 ARMCPU *cpu = env_archcpu(env);
247
248 switch (reg) {
249
250 case 0 ... 31:
251 {
252 int vq, len = 0;
253 for (vq = 0; vq < cpu->sve_max_vq; vq++) {
254 len += gdb_get_reg128(buf,
255 env->vfp.zregs[reg].d[vq * 2 + 1],
256 env->vfp.zregs[reg].d[vq * 2]);
257 }
258 return len;
259 }
260 case 32:
261 return gdb_get_reg32(buf, vfp_get_fpsr(env));
262 case 33:
263 return gdb_get_reg32(buf, vfp_get_fpcr(env));
264
265 case 34 ... 50:
266 {
267 int preg = reg - 34;
268 int vq, len = 0;
269 for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
270 len += gdb_get_reg64(buf, env->vfp.pregs[preg].p[vq / 4]);
271 }
272 return len;
273 }
274 case 51:
275 {
276
277
278
279
280 int vq = sve_zcr_len_for_el(env, arm_current_el(env)) + 1;
281 return gdb_get_reg64(buf, vq * 2);
282 }
283 default:
284
285 qemu_log_mask(LOG_UNIMP, "%s: out of range register %d", __func__, reg);
286 break;
287 }
288
289 return 0;
290}
291
292static int arm_gdb_set_svereg(CPUARMState *env, uint8_t *buf, int reg)
293{
294 ARMCPU *cpu = env_archcpu(env);
295
296
297 switch (reg) {
298
299 case 0 ... 31:
300 {
301 int vq, len = 0;
302 uint64_t *p = (uint64_t *) buf;
303 for (vq = 0; vq < cpu->sve_max_vq; vq++) {
304 env->vfp.zregs[reg].d[vq * 2 + 1] = *p++;
305 env->vfp.zregs[reg].d[vq * 2] = *p++;
306 len += 16;
307 }
308 return len;
309 }
310 case 32:
311 vfp_set_fpsr(env, *(uint32_t *)buf);
312 return 4;
313 case 33:
314 vfp_set_fpcr(env, *(uint32_t *)buf);
315 return 4;
316 case 34 ... 50:
317 {
318 int preg = reg - 34;
319 int vq, len = 0;
320 uint64_t *p = (uint64_t *) buf;
321 for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
322 env->vfp.pregs[preg].p[vq / 4] = *p++;
323 len += 8;
324 }
325 return len;
326 }
327 case 51:
328
329 return 0;
330 default:
331
332 break;
333 }
334
335 return 0;
336}
337#endif
338
339static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
340{
341
342
343
344
345
346
347
348
349
350
351
352 if ((ri->type & ARM_CP_CONST) ||
353 ri->fieldoffset ||
354 ((ri->raw_writefn || ri->writefn) && (ri->raw_readfn || ri->readfn))) {
355 return false;
356 }
357 return true;
358}
359
360bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
361{
362
363 int i;
364 bool ok = true;
365
366 for (i = 0; i < cpu->cpreg_array_len; i++) {
367 uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
368 const ARMCPRegInfo *ri;
369 uint64_t newval;
370
371 ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
372 if (!ri) {
373 ok = false;
374 continue;
375 }
376 if (ri->type & ARM_CP_NO_RAW) {
377 continue;
378 }
379
380 newval = read_raw_cp_reg(&cpu->env, ri);
381 if (kvm_sync) {
382
383
384
385
386
387
388 uint64_t oldval = cpu->cpreg_values[i];
389
390 if (oldval == newval) {
391 continue;
392 }
393
394 write_raw_cp_reg(&cpu->env, ri, oldval);
395 if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
396 continue;
397 }
398
399 write_raw_cp_reg(&cpu->env, ri, newval);
400 }
401 cpu->cpreg_values[i] = newval;
402 }
403 return ok;
404}
405
406bool write_list_to_cpustate(ARMCPU *cpu)
407{
408 int i;
409 bool ok = true;
410
411 for (i = 0; i < cpu->cpreg_array_len; i++) {
412 uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
413 uint64_t v = cpu->cpreg_values[i];
414 const ARMCPRegInfo *ri;
415
416 ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
417 if (!ri) {
418 ok = false;
419 continue;
420 }
421 if (ri->type & ARM_CP_NO_RAW) {
422 continue;
423 }
424
425
426
427
428 write_raw_cp_reg(&cpu->env, ri, v);
429 if (read_raw_cp_reg(&cpu->env, ri) != v) {
430 ok = false;
431 }
432 }
433 return ok;
434}
435
436static void add_cpreg_to_list(gpointer key, gpointer opaque)
437{
438 ARMCPU *cpu = opaque;
439 uint64_t regidx;
440 const ARMCPRegInfo *ri;
441
442 regidx = *(uint32_t *)key;
443 ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
444
445 if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
446 cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
447
448 cpu->cpreg_array_len++;
449 }
450}
451
452static void count_cpreg(gpointer key, gpointer opaque)
453{
454 ARMCPU *cpu = opaque;
455 uint64_t regidx;
456 const ARMCPRegInfo *ri;
457
458 regidx = *(uint32_t *)key;
459 ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
460
461 if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
462 cpu->cpreg_array_len++;
463 }
464}
465
466static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
467{
468 uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a);
469 uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b);
470
471 if (aidx > bidx) {
472 return 1;
473 }
474 if (aidx < bidx) {
475 return -1;
476 }
477 return 0;
478}
479
480void init_cpreg_list(ARMCPU *cpu)
481{
482
483
484
485 GList *keys;
486 int arraylen;
487
488 keys = g_hash_table_get_keys(cpu->cp_regs);
489 keys = g_list_sort(keys, cpreg_key_compare);
490
491 cpu->cpreg_array_len = 0;
492
493 g_list_foreach(keys, count_cpreg, cpu);
494
495 arraylen = cpu->cpreg_array_len;
496 cpu->cpreg_indexes = g_new(uint64_t, arraylen);
497 cpu->cpreg_values = g_new(uint64_t, arraylen);
498 cpu->cpreg_vmstate_indexes = g_new(uint64_t, arraylen);
499 cpu->cpreg_vmstate_values = g_new(uint64_t, arraylen);
500 cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len;
501 cpu->cpreg_array_len = 0;
502
503 g_list_foreach(keys, add_cpreg_to_list, cpu);
504
505 assert(cpu->cpreg_array_len == arraylen);
506
507 g_list_free(keys);
508}
509
510
511
512
513static CPAccessResult access_el3_aa32ns(CPUARMState *env,
514 const ARMCPRegInfo *ri,
515 bool isread)
516{
517 if (!is_a64(env) && arm_current_el(env) == 3 &&
518 arm_is_secure_below_el3(env)) {
519 return CP_ACCESS_TRAP_UNCATEGORIZED;
520 }
521 return CP_ACCESS_OK;
522}
523
524
525
526
527
528
529static CPAccessResult access_trap_aa32s_el1(CPUARMState *env,
530 const ARMCPRegInfo *ri,
531 bool isread)
532{
533 if (arm_current_el(env) == 3) {
534 return CP_ACCESS_OK;
535 }
536 if (arm_is_secure_below_el3(env)) {
537 if (env->cp15.scr_el3 & SCR_EEL2) {
538 return CP_ACCESS_TRAP_EL2;
539 }
540 return CP_ACCESS_TRAP_EL3;
541 }
542
543 return CP_ACCESS_TRAP_UNCATEGORIZED;
544}
545
546static uint64_t arm_mdcr_el2_eff(CPUARMState *env)
547{
548 return arm_is_el2_enabled(env) ? env->cp15.mdcr_el2 : 0;
549}
550
551
552
553
554static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,
555 bool isread)
556{
557 int el = arm_current_el(env);
558 uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
559 bool mdcr_el2_tdosa = (mdcr_el2 & MDCR_TDOSA) || (mdcr_el2 & MDCR_TDE) ||
560 (arm_hcr_el2_eff(env) & HCR_TGE);
561
562 if (el < 2 && mdcr_el2_tdosa) {
563 return CP_ACCESS_TRAP_EL2;
564 }
565 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDOSA)) {
566 return CP_ACCESS_TRAP_EL3;
567 }
568 return CP_ACCESS_OK;
569}
570
571
572
573
574static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,
575 bool isread)
576{
577 int el = arm_current_el(env);
578 uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
579 bool mdcr_el2_tdra = (mdcr_el2 & MDCR_TDRA) || (mdcr_el2 & MDCR_TDE) ||
580 (arm_hcr_el2_eff(env) & HCR_TGE);
581
582 if (el < 2 && mdcr_el2_tdra) {
583 return CP_ACCESS_TRAP_EL2;
584 }
585 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
586 return CP_ACCESS_TRAP_EL3;
587 }
588 return CP_ACCESS_OK;
589}
590
591
592
593
594static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
595 bool isread)
596{
597 int el = arm_current_el(env);
598 uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
599 bool mdcr_el2_tda = (mdcr_el2 & MDCR_TDA) || (mdcr_el2 & MDCR_TDE) ||
600 (arm_hcr_el2_eff(env) & HCR_TGE);
601
602 if (el < 2 && mdcr_el2_tda) {
603 return CP_ACCESS_TRAP_EL2;
604 }
605 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
606 return CP_ACCESS_TRAP_EL3;
607 }
608 return CP_ACCESS_OK;
609}
610
611
612
613
614static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
615 bool isread)
616{
617 int el = arm_current_el(env);
618 uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
619
620 if (el < 2 && (mdcr_el2 & MDCR_TPM)) {
621 return CP_ACCESS_TRAP_EL2;
622 }
623 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TPM)) {
624 return CP_ACCESS_TRAP_EL3;
625 }
626 return CP_ACCESS_OK;
627}
628
629
630static CPAccessResult access_tvm_trvm(CPUARMState *env, const ARMCPRegInfo *ri,
631 bool isread)
632{
633 if (arm_current_el(env) == 1) {
634 uint64_t trap = isread ? HCR_TRVM : HCR_TVM;
635 if (arm_hcr_el2_eff(env) & trap) {
636 return CP_ACCESS_TRAP_EL2;
637 }
638 }
639 return CP_ACCESS_OK;
640}
641
642
643static CPAccessResult access_tsw(CPUARMState *env, const ARMCPRegInfo *ri,
644 bool isread)
645{
646 if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TSW)) {
647 return CP_ACCESS_TRAP_EL2;
648 }
649 return CP_ACCESS_OK;
650}
651
652
653static CPAccessResult access_tacr(CPUARMState *env, const ARMCPRegInfo *ri,
654 bool isread)
655{
656 if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TACR)) {
657 return CP_ACCESS_TRAP_EL2;
658 }
659 return CP_ACCESS_OK;
660}
661
662
663static CPAccessResult access_ttlb(CPUARMState *env, const ARMCPRegInfo *ri,
664 bool isread)
665{
666 if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TTLB)) {
667 return CP_ACCESS_TRAP_EL2;
668 }
669 return CP_ACCESS_OK;
670}
671
672static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
673{
674 ARMCPU *cpu = env_archcpu(env);
675
676 raw_write(env, ri, value);
677 tlb_flush(CPU(cpu));
678}
679
680static void fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
681{
682 ARMCPU *cpu = env_archcpu(env);
683
684 if (raw_read(env, ri) != value) {
685
686
687
688 tlb_flush(CPU(cpu));
689 raw_write(env, ri, value);
690 }
691}
692
693static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
694 uint64_t value)
695{
696 ARMCPU *cpu = env_archcpu(env);
697
698 if (raw_read(env, ri) != value && !arm_feature(env, ARM_FEATURE_PMSA)
699 && !extended_addresses_enabled(env)) {
700
701
702
703
704 tlb_flush(CPU(cpu));
705 }
706 raw_write(env, ri, value);
707}
708
709
710static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
711 uint64_t value)
712{
713 CPUState *cs = env_cpu(env);
714
715 tlb_flush_all_cpus_synced(cs);
716}
717
718static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
719 uint64_t value)
720{
721 CPUState *cs = env_cpu(env);
722
723 tlb_flush_all_cpus_synced(cs);
724}
725
726static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
727 uint64_t value)
728{
729 CPUState *cs = env_cpu(env);
730
731 tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
732}
733
734static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
735 uint64_t value)
736{
737 CPUState *cs = env_cpu(env);
738
739 tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
740}
741
742
743
744
745
746
747static bool tlb_force_broadcast(CPUARMState *env)
748{
749 return arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_FB);
750}
751
752static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
753 uint64_t value)
754{
755
756 CPUState *cs = env_cpu(env);
757
758 if (tlb_force_broadcast(env)) {
759 tlb_flush_all_cpus_synced(cs);
760 } else {
761 tlb_flush(cs);
762 }
763}
764
765static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
766 uint64_t value)
767{
768
769 CPUState *cs = env_cpu(env);
770
771 value &= TARGET_PAGE_MASK;
772 if (tlb_force_broadcast(env)) {
773 tlb_flush_page_all_cpus_synced(cs, value);
774 } else {
775 tlb_flush_page(cs, value);
776 }
777}
778
779static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
780 uint64_t value)
781{
782
783 CPUState *cs = env_cpu(env);
784
785 if (tlb_force_broadcast(env)) {
786 tlb_flush_all_cpus_synced(cs);
787 } else {
788 tlb_flush(cs);
789 }
790}
791
792static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
793 uint64_t value)
794{
795
796 CPUState *cs = env_cpu(env);
797
798 value &= TARGET_PAGE_MASK;
799 if (tlb_force_broadcast(env)) {
800 tlb_flush_page_all_cpus_synced(cs, value);
801 } else {
802 tlb_flush_page(cs, value);
803 }
804}
805
806static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
807 uint64_t value)
808{
809 CPUState *cs = env_cpu(env);
810
811 tlb_flush_by_mmuidx(cs,
812 ARMMMUIdxBit_E10_1 |
813 ARMMMUIdxBit_E10_1_PAN |
814 ARMMMUIdxBit_E10_0);
815}
816
817static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
818 uint64_t value)
819{
820 CPUState *cs = env_cpu(env);
821
822 tlb_flush_by_mmuidx_all_cpus_synced(cs,
823 ARMMMUIdxBit_E10_1 |
824 ARMMMUIdxBit_E10_1_PAN |
825 ARMMMUIdxBit_E10_0);
826}
827
828
829static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
830 uint64_t value)
831{
832 CPUState *cs = env_cpu(env);
833
834 tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_E2);
835}
836
837static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
838 uint64_t value)
839{
840 CPUState *cs = env_cpu(env);
841
842 tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_E2);
843}
844
845static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
846 uint64_t value)
847{
848 CPUState *cs = env_cpu(env);
849 uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
850
851 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_E2);
852}
853
854static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
855 uint64_t value)
856{
857 CPUState *cs = env_cpu(env);
858 uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
859
860 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
861 ARMMMUIdxBit_E2);
862}
863
864static const ARMCPRegInfo cp_reginfo[] = {
865
866
867
868
869
870 { .name = "FCSEIDR",
871 .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0,
872 .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS,
873 .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_ns),
874 .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
875 { .name = "FCSEIDR_S",
876 .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0,
877 .access = PL1_RW, .secure = ARM_CP_SECSTATE_S,
878 .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_s),
879 .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
880
881
882
883
884
885
886 { .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH,
887 .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
888 .access = PL1_RW, .accessfn = access_tvm_trvm,
889 .secure = ARM_CP_SECSTATE_NS,
890 .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]),
891 .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
892 { .name = "CONTEXTIDR_S", .state = ARM_CP_STATE_AA32,
893 .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
894 .access = PL1_RW, .accessfn = access_tvm_trvm,
895 .secure = ARM_CP_SECSTATE_S,
896 .fieldoffset = offsetof(CPUARMState, cp15.contextidr_s),
897 .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
898 REGINFO_SENTINEL
899};
900
901static const ARMCPRegInfo not_v8_cp_reginfo[] = {
902
903
904
905
906 { .name = "DACR",
907 .cp = 15, .opc1 = CP_ANY, .crn = 3, .crm = CP_ANY, .opc2 = CP_ANY,
908 .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
909 .writefn = dacr_write, .raw_writefn = raw_write,
910 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
911 offsetoflow32(CPUARMState, cp15.dacr_ns) } },
912
913
914
915 { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 0,
916 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
917 { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 1,
918 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
919 { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 4,
920 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
921 { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 8,
922 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
923
924 { .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
925 .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
926 .type = ARM_CP_NOP | ARM_CP_OVERRIDE },
927 REGINFO_SENTINEL
928};
929
930static const ARMCPRegInfo not_v6_cp_reginfo[] = {
931
932
933
934 { .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2,
935 .access = PL1_W, .type = ARM_CP_WFI },
936 REGINFO_SENTINEL
937};
938
939static const ARMCPRegInfo not_v7_cp_reginfo[] = {
940
941
942
943 { .name = "WFI_v6", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
944 .access = PL1_W, .type = ARM_CP_WFI },
945
946
947
948
949 { .name = "DLOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 0,
950 .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_data),
951 .resetvalue = 0 },
952 { .name = "ILOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 1,
953 .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_insn),
954 .resetvalue = 0 },
955
956 { .name = "DUMMY", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = CP_ANY,
957 .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
958 .resetvalue = 0 },
959
960
961
962
963
964 { .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
965 .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 },
966
967
968
969 { .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY,
970 .opc1 = CP_ANY, .opc2 = 0, .access = PL1_W, .writefn = tlbiall_write,
971 .type = ARM_CP_NO_RAW },
972 { .name = "TLBIMVA", .cp = 15, .crn = 8, .crm = CP_ANY,
973 .opc1 = CP_ANY, .opc2 = 1, .access = PL1_W, .writefn = tlbimva_write,
974 .type = ARM_CP_NO_RAW },
975 { .name = "TLBIASID", .cp = 15, .crn = 8, .crm = CP_ANY,
976 .opc1 = CP_ANY, .opc2 = 2, .access = PL1_W, .writefn = tlbiasid_write,
977 .type = ARM_CP_NO_RAW },
978 { .name = "TLBIMVAA", .cp = 15, .crn = 8, .crm = CP_ANY,
979 .opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = tlbimvaa_write,
980 .type = ARM_CP_NO_RAW },
981 { .name = "PRRR", .cp = 15, .crn = 10, .crm = 2,
982 .opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_NOP },
983 { .name = "NMRR", .cp = 15, .crn = 10, .crm = 2,
984 .opc1 = 0, .opc2 = 1, .access = PL1_RW, .type = ARM_CP_NOP },
985 REGINFO_SENTINEL
986};
987
988static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
989 uint64_t value)
990{
991 uint32_t mask = 0;
992
993
994 if (!arm_feature(env, ARM_FEATURE_V8)) {
995
996
997
998
999 if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
1000
1001 mask |= (1 << 31) | (1 << 30) | (0xf << 20);
1002
1003 if (!arm_feature(env, ARM_FEATURE_NEON)) {
1004
1005 value |= (1 << 31);
1006 }
1007
1008
1009
1010
1011 if (!cpu_isar_feature(aa32_simd_r32, env_archcpu(env))) {
1012
1013 value |= (1 << 30);
1014 }
1015 }
1016 value &= mask;
1017 }
1018
1019
1020
1021
1022
1023 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
1024 !arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
1025 value &= ~(0xf << 20);
1026 value |= env->cp15.cpacr_el1 & (0xf << 20);
1027 }
1028
1029 env->cp15.cpacr_el1 = value;
1030}
1031
1032static uint64_t cpacr_read(CPUARMState *env, const ARMCPRegInfo *ri)
1033{
1034
1035
1036
1037
1038 uint64_t value = env->cp15.cpacr_el1;
1039
1040 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
1041 !arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
1042 value &= ~(0xf << 20);
1043 }
1044 return value;
1045}
1046
1047
1048static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
1049{
1050
1051
1052
1053 cpacr_write(env, ri, 0);
1054}
1055
1056static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
1057 bool isread)
1058{
1059 if (arm_feature(env, ARM_FEATURE_V8)) {
1060
1061 if (arm_current_el(env) == 1 && arm_is_el2_enabled(env) &&
1062 (env->cp15.cptr_el[2] & CPTR_TCPAC)) {
1063 return CP_ACCESS_TRAP_EL2;
1064
1065 } else if (arm_current_el(env) < 3 &&
1066 (env->cp15.cptr_el[3] & CPTR_TCPAC)) {
1067 return CP_ACCESS_TRAP_EL3;
1068 }
1069 }
1070
1071 return CP_ACCESS_OK;
1072}
1073
1074static CPAccessResult cptr_access(CPUARMState *env, const ARMCPRegInfo *ri,
1075 bool isread)
1076{
1077
1078 if (arm_current_el(env) == 2 && (env->cp15.cptr_el[3] & CPTR_TCPAC)) {
1079 return CP_ACCESS_TRAP_EL3;
1080 }
1081
1082 return CP_ACCESS_OK;
1083}
1084
1085static const ARMCPRegInfo v6_cp_reginfo[] = {
1086
1087 { .name = "MVA_prefetch",
1088 .cp = 15, .crn = 7, .crm = 13, .opc1 = 0, .opc2 = 1,
1089 .access = PL1_W, .type = ARM_CP_NOP },
1090
1091
1092
1093
1094 { .name = "ISB", .cp = 15, .crn = 7, .crm = 5, .opc1 = 0, .opc2 = 4,
1095 .access = PL0_W, .type = ARM_CP_NO_RAW, .writefn = arm_cp_write_ignore },
1096 { .name = "DSB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 4,
1097 .access = PL0_W, .type = ARM_CP_NOP },
1098 { .name = "DMB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 5,
1099 .access = PL0_W, .type = ARM_CP_NOP },
1100 { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2,
1101 .access = PL1_RW, .accessfn = access_tvm_trvm,
1102 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s),
1103 offsetof(CPUARMState, cp15.ifar_ns) },
1104 .resetvalue = 0, },
1105
1106
1107
1108 { .name = "WFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
1109 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0, },
1110 { .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
1111 .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
1112 .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
1113 .resetfn = cpacr_reset, .writefn = cpacr_write, .readfn = cpacr_read },
1114 REGINFO_SENTINEL
1115};
1116
1117
1118#define PMCRN_MASK 0xf800
1119#define PMCRN_SHIFT 11
1120#define PMCRLC 0x40
1121#define PMCRDP 0x20
1122#define PMCRX 0x10
1123#define PMCRD 0x8
1124#define PMCRC 0x4
1125#define PMCRP 0x2
1126#define PMCRE 0x1
1127
1128
1129
1130
1131#define PMCR_WRITEABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
1132
1133#define PMXEVTYPER_P 0x80000000
1134#define PMXEVTYPER_U 0x40000000
1135#define PMXEVTYPER_NSK 0x20000000
1136#define PMXEVTYPER_NSU 0x10000000
1137#define PMXEVTYPER_NSH 0x08000000
1138#define PMXEVTYPER_M 0x04000000
1139#define PMXEVTYPER_MT 0x02000000
1140#define PMXEVTYPER_EVTCOUNT 0x0000ffff
1141#define PMXEVTYPER_MASK (PMXEVTYPER_P | PMXEVTYPER_U | PMXEVTYPER_NSK | \
1142 PMXEVTYPER_NSU | PMXEVTYPER_NSH | \
1143 PMXEVTYPER_M | PMXEVTYPER_MT | \
1144 PMXEVTYPER_EVTCOUNT)
1145
1146#define PMCCFILTR 0xf8000000
1147#define PMCCFILTR_M PMXEVTYPER_M
1148#define PMCCFILTR_EL0 (PMCCFILTR | PMCCFILTR_M)
1149
1150static inline uint32_t pmu_num_counters(CPUARMState *env)
1151{
1152 return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
1153}
1154
1155
1156static inline uint64_t pmu_counter_mask(CPUARMState *env)
1157{
1158 return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
1159}
1160
1161typedef struct pm_event {
1162 uint16_t number;
1163
1164 bool (*supported)(CPUARMState *);
1165
1166
1167
1168
1169 uint64_t (*get_count)(CPUARMState *);
1170
1171
1172
1173
1174
1175
1176 int64_t (*ns_per_count)(uint64_t);
1177} pm_event;
1178
1179static bool event_always_supported(CPUARMState *env)
1180{
1181 return true;
1182}
1183
1184static uint64_t swinc_get_count(CPUARMState *env)
1185{
1186
1187
1188
1189
1190 return 0;
1191}
1192
1193static int64_t swinc_ns_per(uint64_t ignored)
1194{
1195 return -1;
1196}
1197
1198
1199
1200
1201
1202static uint64_t cycles_get_count(CPUARMState *env)
1203{
1204#ifndef CONFIG_USER_ONLY
1205 return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
1206 ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
1207#else
1208 return cpu_get_host_ticks();
1209#endif
1210}
1211
1212#ifndef CONFIG_USER_ONLY
1213static int64_t cycles_ns_per(uint64_t cycles)
1214{
1215 return (ARM_CPU_FREQ / NANOSECONDS_PER_SECOND) * cycles;
1216}
1217
1218static bool instructions_supported(CPUARMState *env)
1219{
1220 return icount_enabled() == 1;
1221}
1222
1223static uint64_t instructions_get_count(CPUARMState *env)
1224{
1225 return (uint64_t)icount_get_raw();
1226}
1227
1228static int64_t instructions_ns_per(uint64_t icount)
1229{
1230 return icount_to_ns((int64_t)icount);
1231}
1232#endif
1233
1234static bool pmu_8_1_events_supported(CPUARMState *env)
1235{
1236
1237 return cpu_isar_feature(any_pmu_8_1, env_archcpu(env));
1238}
1239
1240static bool pmu_8_4_events_supported(CPUARMState *env)
1241{
1242
1243 return cpu_isar_feature(any_pmu_8_4, env_archcpu(env));
1244}
1245
1246static uint64_t zero_event_get_count(CPUARMState *env)
1247{
1248
1249 return 0;
1250}
1251
1252static int64_t zero_event_ns_per(uint64_t cycles)
1253{
1254
1255 return -1;
1256}
1257
1258static const pm_event pm_events[] = {
1259 { .number = 0x000,
1260 .supported = event_always_supported,
1261 .get_count = swinc_get_count,
1262 .ns_per_count = swinc_ns_per,
1263 },
1264#ifndef CONFIG_USER_ONLY
1265 { .number = 0x008,
1266 .supported = instructions_supported,
1267 .get_count = instructions_get_count,
1268 .ns_per_count = instructions_ns_per,
1269 },
1270 { .number = 0x011,
1271 .supported = event_always_supported,
1272 .get_count = cycles_get_count,
1273 .ns_per_count = cycles_ns_per,
1274 },
1275#endif
1276 { .number = 0x023,
1277 .supported = pmu_8_1_events_supported,
1278 .get_count = zero_event_get_count,
1279 .ns_per_count = zero_event_ns_per,
1280 },
1281 { .number = 0x024,
1282 .supported = pmu_8_1_events_supported,
1283 .get_count = zero_event_get_count,
1284 .ns_per_count = zero_event_ns_per,
1285 },
1286 { .number = 0x03c,
1287 .supported = pmu_8_4_events_supported,
1288 .get_count = zero_event_get_count,
1289 .ns_per_count = zero_event_ns_per,
1290 },
1291};
1292
1293
1294
1295
1296
1297
1298
1299#define MAX_EVENT_ID 0x3c
1300#define UNSUPPORTED_EVENT UINT16_MAX
1301static uint16_t supported_event_map[MAX_EVENT_ID + 1];
1302
1303
1304
1305
1306
1307
1308
1309void pmu_init(ARMCPU *cpu)
1310{
1311 unsigned int i;
1312
1313
1314
1315
1316
1317 for (i = 0; i < ARRAY_SIZE(supported_event_map); i++) {
1318 supported_event_map[i] = UNSUPPORTED_EVENT;
1319 }
1320 cpu->pmceid0 = 0;
1321 cpu->pmceid1 = 0;
1322
1323 for (i = 0; i < ARRAY_SIZE(pm_events); i++) {
1324 const pm_event *cnt = &pm_events[i];
1325 assert(cnt->number <= MAX_EVENT_ID);
1326
1327 assert(cnt->number <= 0x3f);
1328
1329 if (cnt->supported(&cpu->env)) {
1330 supported_event_map[cnt->number] = i;
1331 uint64_t event_mask = 1ULL << (cnt->number & 0x1f);
1332 if (cnt->number & 0x20) {
1333 cpu->pmceid1 |= event_mask;
1334 } else {
1335 cpu->pmceid0 |= event_mask;
1336 }
1337 }
1338 }
1339}
1340
1341
1342
1343
1344static bool event_supported(uint16_t number)
1345{
1346 if (number > MAX_EVENT_ID) {
1347 return false;
1348 }
1349 return supported_event_map[number] != UNSUPPORTED_EVENT;
1350}
1351
1352static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
1353 bool isread)
1354{
1355
1356
1357
1358
1359 int el = arm_current_el(env);
1360 uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
1361
1362 if (el == 0 && !(env->cp15.c9_pmuserenr & 1)) {
1363 return CP_ACCESS_TRAP;
1364 }
1365 if (el < 2 && (mdcr_el2 & MDCR_TPM)) {
1366 return CP_ACCESS_TRAP_EL2;
1367 }
1368 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TPM)) {
1369 return CP_ACCESS_TRAP_EL3;
1370 }
1371
1372 return CP_ACCESS_OK;
1373}
1374
1375static CPAccessResult pmreg_access_xevcntr(CPUARMState *env,
1376 const ARMCPRegInfo *ri,
1377 bool isread)
1378{
1379
1380 if (arm_feature(env, ARM_FEATURE_V8)
1381 && arm_current_el(env) == 0
1382 && (env->cp15.c9_pmuserenr & (1 << 3)) != 0
1383 && isread) {
1384 return CP_ACCESS_OK;
1385 }
1386
1387 return pmreg_access(env, ri, isread);
1388}
1389
1390static CPAccessResult pmreg_access_swinc(CPUARMState *env,
1391 const ARMCPRegInfo *ri,
1392 bool isread)
1393{
1394
1395 if (arm_feature(env, ARM_FEATURE_V8)
1396 && arm_current_el(env) == 0
1397 && (env->cp15.c9_pmuserenr & (1 << 1)) != 0
1398 && !isread) {
1399 return CP_ACCESS_OK;
1400 }
1401
1402 return pmreg_access(env, ri, isread);
1403}
1404
1405static CPAccessResult pmreg_access_selr(CPUARMState *env,
1406 const ARMCPRegInfo *ri,
1407 bool isread)
1408{
1409
1410 if (arm_feature(env, ARM_FEATURE_V8)
1411 && arm_current_el(env) == 0
1412 && (env->cp15.c9_pmuserenr & (1 << 3)) != 0) {
1413 return CP_ACCESS_OK;
1414 }
1415
1416 return pmreg_access(env, ri, isread);
1417}
1418
1419static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
1420 const ARMCPRegInfo *ri,
1421 bool isread)
1422{
1423
1424 if (arm_feature(env, ARM_FEATURE_V8)
1425 && arm_current_el(env) == 0
1426 && (env->cp15.c9_pmuserenr & (1 << 2)) != 0
1427 && isread) {
1428 return CP_ACCESS_OK;
1429 }
1430
1431 return pmreg_access(env, ri, isread);
1432}
1433
1434
1435
1436
1437static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
1438{
1439 uint64_t filter;
1440 bool e, p, u, nsk, nsu, nsh, m;
1441 bool enabled, prohibited, filtered;
1442 bool secure = arm_is_secure(env);
1443 int el = arm_current_el(env);
1444 uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
1445 uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
1446
1447 if (!arm_feature(env, ARM_FEATURE_PMU)) {
1448 return false;
1449 }
1450
1451 if (!arm_feature(env, ARM_FEATURE_EL2) ||
1452 (counter < hpmn || counter == 31)) {
1453 e = env->cp15.c9_pmcr & PMCRE;
1454 } else {
1455 e = mdcr_el2 & MDCR_HPME;
1456 }
1457 enabled = e && (env->cp15.c9_pmcnten & (1 << counter));
1458
1459 if (!secure) {
1460 if (el == 2 && (counter < hpmn || counter == 31)) {
1461 prohibited = mdcr_el2 & MDCR_HPMD;
1462 } else {
1463 prohibited = false;
1464 }
1465 } else {
1466 prohibited = arm_feature(env, ARM_FEATURE_EL3) &&
1467 !(env->cp15.mdcr_el3 & MDCR_SPME);
1468 }
1469
1470 if (prohibited && counter == 31) {
1471 prohibited = env->cp15.c9_pmcr & PMCRDP;
1472 }
1473
1474 if (counter == 31) {
1475 filter = env->cp15.pmccfiltr_el0;
1476 } else {
1477 filter = env->cp15.c14_pmevtyper[counter];
1478 }
1479
1480 p = filter & PMXEVTYPER_P;
1481 u = filter & PMXEVTYPER_U;
1482 nsk = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSK);
1483 nsu = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSU);
1484 nsh = arm_feature(env, ARM_FEATURE_EL2) && (filter & PMXEVTYPER_NSH);
1485 m = arm_el_is_aa64(env, 1) &&
1486 arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_M);
1487
1488 if (el == 0) {
1489 filtered = secure ? u : u != nsu;
1490 } else if (el == 1) {
1491 filtered = secure ? p : p != nsk;
1492 } else if (el == 2) {
1493 filtered = !nsh;
1494 } else {
1495 filtered = m != p;
1496 }
1497
1498 if (counter != 31) {
1499
1500
1501
1502
1503 uint16_t event = filter & PMXEVTYPER_EVTCOUNT;
1504 if (!event_supported(event)) {
1505 return false;
1506 }
1507 }
1508
1509 return enabled && !prohibited && !filtered;
1510}
1511
1512static void pmu_update_irq(CPUARMState *env)
1513{
1514 ARMCPU *cpu = env_archcpu(env);
1515 qemu_set_irq(cpu->pmu_interrupt, (env->cp15.c9_pmcr & PMCRE) &&
1516 (env->cp15.c9_pminten & env->cp15.c9_pmovsr));
1517}
1518
1519
1520
1521
1522
1523
1524
1525static void pmccntr_op_start(CPUARMState *env)
1526{
1527 uint64_t cycles = cycles_get_count(env);
1528
1529 if (pmu_counter_enabled(env, 31)) {
1530 uint64_t eff_cycles = cycles;
1531 if (env->cp15.c9_pmcr & PMCRD) {
1532
1533 eff_cycles /= 64;
1534 }
1535
1536 uint64_t new_pmccntr = eff_cycles - env->cp15.c15_ccnt_delta;
1537
1538 uint64_t overflow_mask = env->cp15.c9_pmcr & PMCRLC ? \
1539 1ull << 63 : 1ull << 31;
1540 if (env->cp15.c15_ccnt & ~new_pmccntr & overflow_mask) {
1541 env->cp15.c9_pmovsr |= (1 << 31);
1542 pmu_update_irq(env);
1543 }
1544
1545 env->cp15.c15_ccnt = new_pmccntr;
1546 }
1547 env->cp15.c15_ccnt_delta = cycles;
1548}
1549
1550
1551
1552
1553
1554
1555static void pmccntr_op_finish(CPUARMState *env)
1556{
1557 if (pmu_counter_enabled(env, 31)) {
1558#ifndef CONFIG_USER_ONLY
1559
1560 uint64_t remaining_cycles = -env->cp15.c15_ccnt;
1561 if (!(env->cp15.c9_pmcr & PMCRLC)) {
1562 remaining_cycles = (uint32_t)remaining_cycles;
1563 }
1564 int64_t overflow_in = cycles_ns_per(remaining_cycles);
1565
1566 if (overflow_in > 0) {
1567 int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
1568 overflow_in;
1569 ARMCPU *cpu = env_archcpu(env);
1570 timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
1571 }
1572#endif
1573
1574 uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
1575 if (env->cp15.c9_pmcr & PMCRD) {
1576
1577 prev_cycles /= 64;
1578 }
1579 env->cp15.c15_ccnt_delta = prev_cycles - env->cp15.c15_ccnt;
1580 }
1581}
1582
1583static void pmevcntr_op_start(CPUARMState *env, uint8_t counter)
1584{
1585
1586 uint16_t event = env->cp15.c14_pmevtyper[counter] & PMXEVTYPER_EVTCOUNT;
1587 uint64_t count = 0;
1588 if (event_supported(event)) {
1589 uint16_t event_idx = supported_event_map[event];
1590 count = pm_events[event_idx].get_count(env);
1591 }
1592
1593 if (pmu_counter_enabled(env, counter)) {
1594 uint32_t new_pmevcntr = count - env->cp15.c14_pmevcntr_delta[counter];
1595
1596 if (env->cp15.c14_pmevcntr[counter] & ~new_pmevcntr & INT32_MIN) {
1597 env->cp15.c9_pmovsr |= (1 << counter);
1598 pmu_update_irq(env);
1599 }
1600 env->cp15.c14_pmevcntr[counter] = new_pmevcntr;
1601 }
1602 env->cp15.c14_pmevcntr_delta[counter] = count;
1603}
1604
1605static void pmevcntr_op_finish(CPUARMState *env, uint8_t counter)
1606{
1607 if (pmu_counter_enabled(env, counter)) {
1608#ifndef CONFIG_USER_ONLY
1609 uint16_t event = env->cp15.c14_pmevtyper[counter] & PMXEVTYPER_EVTCOUNT;
1610 uint16_t event_idx = supported_event_map[event];
1611 uint64_t delta = UINT32_MAX -
1612 (uint32_t)env->cp15.c14_pmevcntr[counter] + 1;
1613 int64_t overflow_in = pm_events[event_idx].ns_per_count(delta);
1614
1615 if (overflow_in > 0) {
1616 int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
1617 overflow_in;
1618 ARMCPU *cpu = env_archcpu(env);
1619 timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
1620 }
1621#endif
1622
1623 env->cp15.c14_pmevcntr_delta[counter] -=
1624 env->cp15.c14_pmevcntr[counter];
1625 }
1626}
1627
1628void pmu_op_start(CPUARMState *env)
1629{
1630 unsigned int i;
1631 pmccntr_op_start(env);
1632 for (i = 0; i < pmu_num_counters(env); i++) {
1633 pmevcntr_op_start(env, i);
1634 }
1635}
1636
1637void pmu_op_finish(CPUARMState *env)
1638{
1639 unsigned int i;
1640 pmccntr_op_finish(env);
1641 for (i = 0; i < pmu_num_counters(env); i++) {
1642 pmevcntr_op_finish(env, i);
1643 }
1644}
1645
1646void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
1647{
1648 pmu_op_start(&cpu->env);
1649}
1650
1651void pmu_post_el_change(ARMCPU *cpu, void *ignored)
1652{
1653 pmu_op_finish(&cpu->env);
1654}
1655
1656void arm_pmu_timer_cb(void *opaque)
1657{
1658 ARMCPU *cpu = opaque;
1659
1660
1661
1662
1663
1664
1665
1666 pmu_op_start(&cpu->env);
1667 pmu_op_finish(&cpu->env);
1668}
1669
1670static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1671 uint64_t value)
1672{
1673 pmu_op_start(env);
1674
1675 if (value & PMCRC) {
1676
1677 env->cp15.c15_ccnt = 0;
1678 }
1679
1680 if (value & PMCRP) {
1681 unsigned int i;
1682 for (i = 0; i < pmu_num_counters(env); i++) {
1683 env->cp15.c14_pmevcntr[i] = 0;
1684 }
1685 }
1686
1687 env->cp15.c9_pmcr &= ~PMCR_WRITEABLE_MASK;
1688 env->cp15.c9_pmcr |= (value & PMCR_WRITEABLE_MASK);
1689
1690 pmu_op_finish(env);
1691}
1692
1693static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
1694 uint64_t value)
1695{
1696 unsigned int i;
1697 for (i = 0; i < pmu_num_counters(env); i++) {
1698
1699 if ((value & (1 << i)) &&
1700
1701 pmu_counter_enabled(env, i) &&
1702
1703 (env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) {
1704 pmevcntr_op_start(env, i);
1705
1706
1707
1708
1709
1710 uint32_t new_pmswinc = env->cp15.c14_pmevcntr[i] + 1;
1711
1712 if (env->cp15.c14_pmevcntr[i] & ~new_pmswinc & INT32_MIN) {
1713 env->cp15.c9_pmovsr |= (1 << i);
1714 pmu_update_irq(env);
1715 }
1716
1717 env->cp15.c14_pmevcntr[i] = new_pmswinc;
1718
1719 pmevcntr_op_finish(env, i);
1720 }
1721 }
1722}
1723
1724static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
1725{
1726 uint64_t ret;
1727 pmccntr_op_start(env);
1728 ret = env->cp15.c15_ccnt;
1729 pmccntr_op_finish(env);
1730 return ret;
1731}
1732
1733static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1734 uint64_t value)
1735{
1736
1737
1738
1739
1740
1741 env->cp15.c9_pmselr = value & 0x1f;
1742}
1743
1744static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1745 uint64_t value)
1746{
1747 pmccntr_op_start(env);
1748 env->cp15.c15_ccnt = value;
1749 pmccntr_op_finish(env);
1750}
1751
1752static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
1753 uint64_t value)
1754{
1755 uint64_t cur_val = pmccntr_read(env, NULL);
1756
1757 pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value));
1758}
1759
1760static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1761 uint64_t value)
1762{
1763 pmccntr_op_start(env);
1764 env->cp15.pmccfiltr_el0 = value & PMCCFILTR_EL0;
1765 pmccntr_op_finish(env);
1766}
1767
1768static void pmccfiltr_write_a32(CPUARMState *env, const ARMCPRegInfo *ri,
1769 uint64_t value)
1770{
1771 pmccntr_op_start(env);
1772
1773 env->cp15.pmccfiltr_el0 = (env->cp15.pmccfiltr_el0 & PMCCFILTR_M) |
1774 (value & PMCCFILTR);
1775 pmccntr_op_finish(env);
1776}
1777
1778static uint64_t pmccfiltr_read_a32(CPUARMState *env, const ARMCPRegInfo *ri)
1779{
1780
1781 return env->cp15.pmccfiltr_el0 & PMCCFILTR;
1782}
1783
1784static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
1785 uint64_t value)
1786{
1787 value &= pmu_counter_mask(env);
1788 env->cp15.c9_pmcnten |= value;
1789}
1790
1791static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1792 uint64_t value)
1793{
1794 value &= pmu_counter_mask(env);
1795 env->cp15.c9_pmcnten &= ~value;
1796}
1797
1798static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1799 uint64_t value)
1800{
1801 value &= pmu_counter_mask(env);
1802 env->cp15.c9_pmovsr &= ~value;
1803 pmu_update_irq(env);
1804}
1805
1806static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
1807 uint64_t value)
1808{
1809 value &= pmu_counter_mask(env);
1810 env->cp15.c9_pmovsr |= value;
1811 pmu_update_irq(env);
1812}
1813
1814static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
1815 uint64_t value, const uint8_t counter)
1816{
1817 if (counter == 31) {
1818 pmccfiltr_write(env, ri, value);
1819 } else if (counter < pmu_num_counters(env)) {
1820 pmevcntr_op_start(env, counter);
1821
1822
1823
1824
1825
1826
1827
1828 uint16_t old_event = env->cp15.c14_pmevtyper[counter] &
1829 PMXEVTYPER_EVTCOUNT;
1830 uint16_t new_event = value & PMXEVTYPER_EVTCOUNT;
1831 if (old_event != new_event) {
1832 uint64_t count = 0;
1833 if (event_supported(new_event)) {
1834 uint16_t event_idx = supported_event_map[new_event];
1835 count = pm_events[event_idx].get_count(env);
1836 }
1837 env->cp15.c14_pmevcntr_delta[counter] = count;
1838 }
1839
1840 env->cp15.c14_pmevtyper[counter] = value & PMXEVTYPER_MASK;
1841 pmevcntr_op_finish(env, counter);
1842 }
1843
1844
1845
1846
1847}
1848
1849static uint64_t pmevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri,
1850 const uint8_t counter)
1851{
1852 if (counter == 31) {
1853 return env->cp15.pmccfiltr_el0;
1854 } else if (counter < pmu_num_counters(env)) {
1855 return env->cp15.c14_pmevtyper[counter];
1856 } else {
1857
1858
1859
1860
1861 return 0;
1862 }
1863}
1864
1865static void pmevtyper_writefn(CPUARMState *env, const ARMCPRegInfo *ri,
1866 uint64_t value)
1867{
1868 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1869 pmevtyper_write(env, ri, value, counter);
1870}
1871
1872static void pmevtyper_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri,
1873 uint64_t value)
1874{
1875 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1876 env->cp15.c14_pmevtyper[counter] = value;
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887 uint16_t event = value & PMXEVTYPER_EVTCOUNT;
1888 if (event_supported(event)) {
1889 uint16_t event_idx = supported_event_map[event];
1890 env->cp15.c14_pmevcntr_delta[counter] =
1891 pm_events[event_idx].get_count(env);
1892 }
1893}
1894
1895static uint64_t pmevtyper_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
1896{
1897 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1898 return pmevtyper_read(env, ri, counter);
1899}
1900
1901static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
1902 uint64_t value)
1903{
1904 pmevtyper_write(env, ri, value, env->cp15.c9_pmselr & 31);
1905}
1906
1907static uint64_t pmxevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri)
1908{
1909 return pmevtyper_read(env, ri, env->cp15.c9_pmselr & 31);
1910}
1911
1912static void pmevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1913 uint64_t value, uint8_t counter)
1914{
1915 if (counter < pmu_num_counters(env)) {
1916 pmevcntr_op_start(env, counter);
1917 env->cp15.c14_pmevcntr[counter] = value;
1918 pmevcntr_op_finish(env, counter);
1919 }
1920
1921
1922
1923
1924}
1925
1926static uint64_t pmevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri,
1927 uint8_t counter)
1928{
1929 if (counter < pmu_num_counters(env)) {
1930 uint64_t ret;
1931 pmevcntr_op_start(env, counter);
1932 ret = env->cp15.c14_pmevcntr[counter];
1933 pmevcntr_op_finish(env, counter);
1934 return ret;
1935 } else {
1936
1937
1938 return 0;
1939 }
1940}
1941
1942static void pmevcntr_writefn(CPUARMState *env, const ARMCPRegInfo *ri,
1943 uint64_t value)
1944{
1945 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1946 pmevcntr_write(env, ri, value, counter);
1947}
1948
1949static uint64_t pmevcntr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
1950{
1951 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1952 return pmevcntr_read(env, ri, counter);
1953}
1954
1955static void pmevcntr_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri,
1956 uint64_t value)
1957{
1958 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1959 assert(counter < pmu_num_counters(env));
1960 env->cp15.c14_pmevcntr[counter] = value;
1961 pmevcntr_write(env, ri, value, counter);
1962}
1963
1964static uint64_t pmevcntr_rawread(CPUARMState *env, const ARMCPRegInfo *ri)
1965{
1966 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1967 assert(counter < pmu_num_counters(env));
1968 return env->cp15.c14_pmevcntr[counter];
1969}
1970
1971static void pmxevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1972 uint64_t value)
1973{
1974 pmevcntr_write(env, ri, value, env->cp15.c9_pmselr & 31);
1975}
1976
1977static uint64_t pmxevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
1978{
1979 return pmevcntr_read(env, ri, env->cp15.c9_pmselr & 31);
1980}
1981
1982static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1983 uint64_t value)
1984{
1985 if (arm_feature(env, ARM_FEATURE_V8)) {
1986 env->cp15.c9_pmuserenr = value & 0xf;
1987 } else {
1988 env->cp15.c9_pmuserenr = value & 1;
1989 }
1990}
1991
1992static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
1993 uint64_t value)
1994{
1995
1996 value &= pmu_counter_mask(env);
1997 env->cp15.c9_pminten |= value;
1998 pmu_update_irq(env);
1999}
2000
2001static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
2002 uint64_t value)
2003{
2004 value &= pmu_counter_mask(env);
2005 env->cp15.c9_pminten &= ~value;
2006 pmu_update_irq(env);
2007}
2008
2009static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
2010 uint64_t value)
2011{
2012
2013
2014
2015
2016
2017
2018 raw_write(env, ri, value & ~0x1FULL);
2019}
2020
2021static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
2022{
2023
2024 uint32_t valid_mask = 0x3fff;
2025 ARMCPU *cpu = env_archcpu(env);
2026
2027 if (ri->state == ARM_CP_STATE_AA64) {
2028 if (arm_feature(env, ARM_FEATURE_AARCH64) &&
2029 !cpu_isar_feature(aa64_aa32_el1, cpu)) {
2030 value |= SCR_FW | SCR_AW;
2031 }
2032 valid_mask &= ~SCR_NET;
2033
2034 if (cpu_isar_feature(aa64_lor, cpu)) {
2035 valid_mask |= SCR_TLOR;
2036 }
2037 if (cpu_isar_feature(aa64_pauth, cpu)) {
2038 valid_mask |= SCR_API | SCR_APK;
2039 }
2040 if (cpu_isar_feature(aa64_sel2, cpu)) {
2041 valid_mask |= SCR_EEL2;
2042 }
2043 if (cpu_isar_feature(aa64_mte, cpu)) {
2044 valid_mask |= SCR_ATA;
2045 }
2046 } else {
2047 valid_mask &= ~(SCR_RW | SCR_ST);
2048 }
2049
2050 if (!arm_feature(env, ARM_FEATURE_EL2)) {
2051 valid_mask &= ~SCR_HCE;
2052
2053
2054
2055
2056
2057
2058
2059 if (arm_feature(env, ARM_FEATURE_V7) &&
2060 !arm_feature(env, ARM_FEATURE_V8)) {
2061 valid_mask &= ~SCR_SMD;
2062 }
2063 }
2064
2065
2066 value &= valid_mask;
2067 raw_write(env, ri, value);
2068}
2069
2070static void scr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
2071{
2072
2073
2074
2075
2076 scr_write(env, ri, 0);
2077}
2078
2079static CPAccessResult access_aa64_tid2(CPUARMState *env,
2080 const ARMCPRegInfo *ri,
2081 bool isread)
2082{
2083 if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID2)) {
2084 return CP_ACCESS_TRAP_EL2;
2085 }
2086
2087 return CP_ACCESS_OK;
2088}
2089
2090static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
2091{
2092 ARMCPU *cpu = env_archcpu(env);
2093
2094
2095
2096
2097 uint32_t index = A32_BANKED_REG_GET(env, csselr,
2098 ri->secure & ARM_CP_SECSTATE_S);
2099
2100 return cpu->ccsidr[index];
2101}
2102
2103static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
2104 uint64_t value)
2105{
2106 raw_write(env, ri, value & 0xf);
2107}
2108
2109static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
2110{
2111 CPUState *cs = env_cpu(env);
2112 bool el1 = arm_current_el(env) == 1;
2113 uint64_t hcr_el2 = el1 ? arm_hcr_el2_eff(env) : 0;
2114 uint64_t ret = 0;
2115
2116 if (hcr_el2 & HCR_IMO) {
2117 if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
2118 ret |= CPSR_I;
2119 }
2120 } else {
2121 if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
2122 ret |= CPSR_I;
2123 }
2124 }
2125
2126 if (hcr_el2 & HCR_FMO) {
2127 if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
2128 ret |= CPSR_F;
2129 }
2130 } else {
2131 if (cs->interrupt_request & CPU_INTERRUPT_FIQ) {
2132 ret |= CPSR_F;
2133 }
2134 }
2135
2136
2137 return ret;
2138}
2139
2140static CPAccessResult access_aa64_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
2141 bool isread)
2142{
2143 if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID1)) {
2144 return CP_ACCESS_TRAP_EL2;
2145 }
2146
2147 return CP_ACCESS_OK;
2148}
2149
2150static CPAccessResult access_aa32_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
2151 bool isread)
2152{
2153 if (arm_feature(env, ARM_FEATURE_V8)) {
2154 return access_aa64_tid1(env, ri, isread);
2155 }
2156
2157 return CP_ACCESS_OK;
2158}
2159
2160static const ARMCPRegInfo v7_cp_reginfo[] = {
2161
2162 { .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
2163 .access = PL1_W, .type = ARM_CP_NOP },
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175 { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
2176 .access = PL0_RW, .type = ARM_CP_ALIAS,
2177 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
2178 .writefn = pmcntenset_write,
2179 .accessfn = pmreg_access,
2180 .raw_writefn = raw_write },
2181 { .name = "PMCNTENSET_EL0", .state = ARM_CP_STATE_AA64,
2182 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 1,
2183 .access = PL0_RW, .accessfn = pmreg_access,
2184 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .resetvalue = 0,
2185 .writefn = pmcntenset_write, .raw_writefn = raw_write },
2186 { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
2187 .access = PL0_RW,
2188 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
2189 .accessfn = pmreg_access,
2190 .writefn = pmcntenclr_write,
2191 .type = ARM_CP_ALIAS },
2192 { .name = "PMCNTENCLR_EL0", .state = ARM_CP_STATE_AA64,
2193 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 2,
2194 .access = PL0_RW, .accessfn = pmreg_access,
2195 .type = ARM_CP_ALIAS,
2196 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
2197 .writefn = pmcntenclr_write },
2198 { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
2199 .access = PL0_RW, .type = ARM_CP_IO,
2200 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
2201 .accessfn = pmreg_access,
2202 .writefn = pmovsr_write,
2203 .raw_writefn = raw_write },
2204 { .name = "PMOVSCLR_EL0", .state = ARM_CP_STATE_AA64,
2205 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 3,
2206 .access = PL0_RW, .accessfn = pmreg_access,
2207 .type = ARM_CP_ALIAS | ARM_CP_IO,
2208 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
2209 .writefn = pmovsr_write,
2210 .raw_writefn = raw_write },
2211 { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
2212 .access = PL0_W, .accessfn = pmreg_access_swinc,
2213 .type = ARM_CP_NO_RAW | ARM_CP_IO,
2214 .writefn = pmswinc_write },
2215 { .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
2216 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
2217 .access = PL0_W, .accessfn = pmreg_access_swinc,
2218 .type = ARM_CP_NO_RAW | ARM_CP_IO,
2219 .writefn = pmswinc_write },
2220 { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
2221 .access = PL0_RW, .type = ARM_CP_ALIAS,
2222 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
2223 .accessfn = pmreg_access_selr, .writefn = pmselr_write,
2224 .raw_writefn = raw_write},
2225 { .name = "PMSELR_EL0", .state = ARM_CP_STATE_AA64,
2226 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 5,
2227 .access = PL0_RW, .accessfn = pmreg_access_selr,
2228 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmselr),
2229 .writefn = pmselr_write, .raw_writefn = raw_write, },
2230 { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
2231 .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_ALIAS | ARM_CP_IO,
2232 .readfn = pmccntr_read, .writefn = pmccntr_write32,
2233 .accessfn = pmreg_access_ccntr },
2234 { .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64,
2235 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0,
2236 .access = PL0_RW, .accessfn = pmreg_access_ccntr,
2237 .type = ARM_CP_IO,
2238 .fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt),
2239 .readfn = pmccntr_read, .writefn = pmccntr_write,
2240 .raw_readfn = raw_read, .raw_writefn = raw_write, },
2241 { .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7,
2242 .writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32,
2243 .access = PL0_RW, .accessfn = pmreg_access,
2244 .type = ARM_CP_ALIAS | ARM_CP_IO,
2245 .resetvalue = 0, },
2246 { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
2247 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
2248 .writefn = pmccfiltr_write, .raw_writefn = raw_write,
2249 .access = PL0_RW, .accessfn = pmreg_access,
2250 .type = ARM_CP_IO,
2251 .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
2252 .resetvalue = 0, },
2253 { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
2254 .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
2255 .accessfn = pmreg_access,
2256 .writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
2257 { .name = "PMXEVTYPER_EL0", .state = ARM_CP_STATE_AA64,
2258 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 1,
2259 .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
2260 .accessfn = pmreg_access,
2261 .writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
2262 { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2,
2263 .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
2264 .accessfn = pmreg_access_xevcntr,
2265 .writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
2266 { .name = "PMXEVCNTR_EL0", .state = ARM_CP_STATE_AA64,
2267 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 2,
2268 .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
2269 .accessfn = pmreg_access_xevcntr,
2270 .writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
2271 { .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0,
2272 .access = PL0_R | PL1_RW, .accessfn = access_tpm,
2273 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmuserenr),
2274 .resetvalue = 0,
2275 .writefn = pmuserenr_write, .raw_writefn = raw_write },
2276 { .name = "PMUSERENR_EL0", .state = ARM_CP_STATE_AA64,
2277 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 0,
2278 .access = PL0_R | PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS,
2279 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr),
2280 .resetvalue = 0,
2281 .writefn = pmuserenr_write, .raw_writefn = raw_write },
2282 { .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1,
2283 .access = PL1_RW, .accessfn = access_tpm,
2284 .type = ARM_CP_ALIAS | ARM_CP_IO,
2285 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten),
2286 .resetvalue = 0,
2287 .writefn = pmintenset_write, .raw_writefn = raw_write },
2288 { .name = "PMINTENSET_EL1", .state = ARM_CP_STATE_AA64,
2289 .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 1,
2290 .access = PL1_RW, .accessfn = access_tpm,
2291 .type = ARM_CP_IO,
2292 .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
2293 .writefn = pmintenset_write, .raw_writefn = raw_write,
2294 .resetvalue = 0x0 },
2295 { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2,
2296 .access = PL1_RW, .accessfn = access_tpm,
2297 .type = ARM_CP_ALIAS | ARM_CP_IO | ARM_CP_NO_RAW,
2298 .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
2299 .writefn = pmintenclr_write, },
2300 { .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64,
2301 .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 2,
2302 .access = PL1_RW, .accessfn = access_tpm,
2303 .type = ARM_CP_ALIAS | ARM_CP_IO | ARM_CP_NO_RAW,
2304 .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
2305 .writefn = pmintenclr_write },
2306 { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
2307 .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
2308 .access = PL1_R,
2309 .accessfn = access_aa64_tid2,
2310 .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
2311 { .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
2312 .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
2313 .access = PL1_RW,
2314 .accessfn = access_aa64_tid2,
2315 .writefn = csselr_write, .resetvalue = 0,
2316 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
2317 offsetof(CPUARMState, cp15.csselr_ns) } },
2318
2319
2320
2321 { .name = "AIDR", .state = ARM_CP_STATE_BOTH,
2322 .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7,
2323 .access = PL1_R, .type = ARM_CP_CONST,
2324 .accessfn = access_aa64_tid1,
2325 .resetvalue = 0 },
2326
2327
2328
2329 { .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH,
2330 .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0,
2331 .access = PL1_RW, .accessfn = access_tvm_trvm,
2332 .type = ARM_CP_CONST, .resetvalue = 0 },
2333 { .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH,
2334 .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
2335 .access = PL1_RW, .accessfn = access_tvm_trvm,
2336 .type = ARM_CP_CONST, .resetvalue = 0 },
2337
2338
2339
2340 { .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
2341 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
2342 .access = PL1_RW, .accessfn = access_tvm_trvm,
2343 .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
2344 .resetvalue = 0 },
2345 { .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64,
2346 .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 2, .opc2 = 0,
2347 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[3]),
2348 .resetvalue = 0 },
2349
2350
2351
2352
2353
2354
2355
2356 { .name = "MAIR0", .state = ARM_CP_STATE_AA32,
2357 .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
2358 .access = PL1_RW, .accessfn = access_tvm_trvm,
2359 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair0_s),
2360 offsetof(CPUARMState, cp15.mair0_ns) },
2361 .resetfn = arm_cp_reset_ignore },
2362 { .name = "MAIR1", .state = ARM_CP_STATE_AA32,
2363 .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1,
2364 .access = PL1_RW, .accessfn = access_tvm_trvm,
2365 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair1_s),
2366 offsetof(CPUARMState, cp15.mair1_ns) },
2367 .resetfn = arm_cp_reset_ignore },
2368 { .name = "ISR_EL1", .state = ARM_CP_STATE_BOTH,
2369 .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 0,
2370 .type = ARM_CP_NO_RAW, .access = PL1_R, .readfn = isr_read },
2371
2372 { .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0,
2373 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2374 .writefn = tlbiall_write },
2375 { .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
2376 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2377 .writefn = tlbimva_write },
2378 { .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 2,
2379 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2380 .writefn = tlbiasid_write },
2381
2382 { .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 0,
2383 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2384 .writefn = tlbiall_write },
2385 { .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
2386 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2387 .writefn = tlbimva_write },
2388 { .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 2,
2389 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2390 .writefn = tlbiasid_write },
2391
2392 { .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
2393 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2394 .writefn = tlbiall_write },
2395 { .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
2396 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2397 .writefn = tlbimva_write },
2398 { .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
2399 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2400 .writefn = tlbiasid_write },
2401 { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
2402 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2403 .writefn = tlbimvaa_write },
2404 REGINFO_SENTINEL
2405};
2406
2407static const ARMCPRegInfo v7mp_cp_reginfo[] = {
2408
2409 { .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
2410 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2411 .writefn = tlbiall_is_write },
2412 { .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
2413 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2414 .writefn = tlbimva_is_write },
2415 { .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
2416 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2417 .writefn = tlbiasid_is_write },
2418 { .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
2419 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
2420 .writefn = tlbimvaa_is_write },
2421 REGINFO_SENTINEL
2422};
2423
2424static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
2425
2426 { .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3,
2427 .access = PL0_RW, .accessfn = pmreg_access,
2428 .type = ARM_CP_ALIAS | ARM_CP_IO,
2429 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
2430 .writefn = pmovsset_write,
2431 .raw_writefn = raw_write },
2432 { .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64,
2433 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3,
2434 .access = PL0_RW, .accessfn = pmreg_access,
2435 .type = ARM_CP_ALIAS | ARM_CP_IO,
2436 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
2437 .writefn = pmovsset_write,
2438 .raw_writefn = raw_write },
2439 REGINFO_SENTINEL
2440};
2441
2442static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
2443 uint64_t value)
2444{
2445 value &= 1;
2446 env->teecr = value;
2447}
2448
2449static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri,
2450 bool isread)
2451{
2452 if (arm_current_el(env) == 0 && (env->teecr & 1)) {
2453 return CP_ACCESS_TRAP;
2454 }
2455 return CP_ACCESS_OK;
2456}
2457
2458static const ARMCPRegInfo t2ee_cp_reginfo[] = {
2459 { .name = "TEECR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 6, .opc2 = 0,
2460 .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, teecr),
2461 .resetvalue = 0,
2462 .writefn = teecr_write },
2463 { .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
2464 .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
2465 .accessfn = teehbr_access, .resetvalue = 0 },
2466 REGINFO_SENTINEL
2467};
2468
2469static const ARMCPRegInfo v6k_cp_reginfo[] = {
2470 { .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64,
2471 .opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0,
2472 .access = PL0_RW,
2473 .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]), .resetvalue = 0 },
2474 { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
2475 .access = PL0_RW,
2476 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s),
2477 offsetoflow32(CPUARMState, cp15.tpidrurw_ns) },
2478 .resetfn = arm_cp_reset_ignore },
2479 { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
2480 .opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
2481 .access = PL0_R|PL1_W,
2482 .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[0]),
2483 .resetvalue = 0},
2484 { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
2485 .access = PL0_R|PL1_W,
2486 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
2487 offsetoflow32(CPUARMState, cp15.tpidruro_ns) },
2488 .resetfn = arm_cp_reset_ignore },
2489 { .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64,
2490 .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
2491 .access = PL1_RW,
2492 .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[1]), .resetvalue = 0 },
2493 { .name = "TPIDRPRW", .opc1 = 0, .cp = 15, .crn = 13, .crm = 0, .opc2 = 4,
2494 .access = PL1_RW,
2495 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrprw_s),
2496 offsetoflow32(CPUARMState, cp15.tpidrprw_ns) },
2497 .resetvalue = 0 },
2498 REGINFO_SENTINEL
2499};
2500
2501#ifndef CONFIG_USER_ONLY
2502
2503static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri,
2504 bool isread)
2505{
2506
2507
2508
2509 int el = arm_current_el(env);
2510 uint64_t hcr;
2511 uint32_t cntkctl;
2512
2513 switch (el) {
2514 case 0:
2515 hcr = arm_hcr_el2_eff(env);
2516 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
2517 cntkctl = env->cp15.cnthctl_el2;
2518 } else {
2519 cntkctl = env->cp15.c14_cntkctl;
2520 }
2521 if (!extract32(cntkctl, 0, 2)) {
2522 return CP_ACCESS_TRAP;
2523 }
2524 break;
2525 case 1:
2526 if (!isread && ri->state == ARM_CP_STATE_AA32 &&
2527 arm_is_secure_below_el3(env)) {
2528
2529 return CP_ACCESS_TRAP_UNCATEGORIZED;
2530 }
2531 break;
2532 case 2:
2533 case 3:
2534 break;
2535 }
2536
2537 if (!isread && el < arm_highest_el(env)) {
2538 return CP_ACCESS_TRAP_UNCATEGORIZED;
2539 }
2540
2541 return CP_ACCESS_OK;
2542}
2543
2544static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
2545 bool isread)
2546{
2547 unsigned int cur_el = arm_current_el(env);
2548 bool has_el2 = arm_is_el2_enabled(env);
2549 uint64_t hcr = arm_hcr_el2_eff(env);
2550
2551 switch (cur_el) {
2552 case 0:
2553
2554 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
2555 return (extract32(env->cp15.cnthctl_el2, timeridx, 1)
2556 ? CP_ACCESS_OK : CP_ACCESS_TRAP_EL2);
2557 }
2558
2559
2560 if (!extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
2561 return CP_ACCESS_TRAP;
2562 }
2563
2564
2565 if (hcr & HCR_E2H) {
2566 if (timeridx == GTIMER_PHYS &&
2567 !extract32(env->cp15.cnthctl_el2, 10, 1)) {
2568 return CP_ACCESS_TRAP_EL2;
2569 }
2570 } else {
2571
2572 if (has_el2 && timeridx == GTIMER_PHYS &&
2573 !extract32(env->cp15.cnthctl_el2, 1, 1)) {
2574 return CP_ACCESS_TRAP_EL2;
2575 }
2576 }
2577 break;
2578
2579 case 1:
2580
2581 if (has_el2 && timeridx == GTIMER_PHYS &&
2582 (hcr & HCR_E2H
2583 ? !extract32(env->cp15.cnthctl_el2, 10, 1)
2584 : !extract32(env->cp15.cnthctl_el2, 0, 1))) {
2585 return CP_ACCESS_TRAP_EL2;
2586 }
2587 break;
2588 }
2589 return CP_ACCESS_OK;
2590}
2591
2592static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx,
2593 bool isread)
2594{
2595 unsigned int cur_el = arm_current_el(env);
2596 bool has_el2 = arm_is_el2_enabled(env);
2597 uint64_t hcr = arm_hcr_el2_eff(env);
2598
2599 switch (cur_el) {
2600 case 0:
2601 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
2602
2603 return (extract32(env->cp15.cnthctl_el2, 9 - timeridx, 1)
2604 ? CP_ACCESS_OK : CP_ACCESS_TRAP_EL2);
2605 }
2606
2607
2608
2609
2610
2611 if (!extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
2612 return CP_ACCESS_TRAP;
2613 }
2614
2615
2616 case 1:
2617 if (has_el2 && timeridx == GTIMER_PHYS) {
2618 if (hcr & HCR_E2H) {
2619
2620 if (!extract32(env->cp15.cnthctl_el2, 11, 1)) {
2621 return CP_ACCESS_TRAP_EL2;
2622 }
2623 } else {
2624
2625 if (!extract32(env->cp15.cnthctl_el2, 1, 1)) {
2626 return CP_ACCESS_TRAP_EL2;
2627 }
2628 }
2629 }
2630 break;
2631 }
2632 return CP_ACCESS_OK;
2633}
2634
2635static CPAccessResult gt_pct_access(CPUARMState *env,
2636 const ARMCPRegInfo *ri,
2637 bool isread)
2638{
2639 return gt_counter_access(env, GTIMER_PHYS, isread);
2640}
2641
2642static CPAccessResult gt_vct_access(CPUARMState *env,
2643 const ARMCPRegInfo *ri,
2644 bool isread)
2645{
2646 return gt_counter_access(env, GTIMER_VIRT, isread);
2647}
2648
2649static CPAccessResult gt_ptimer_access(CPUARMState *env, const ARMCPRegInfo *ri,
2650 bool isread)
2651{
2652 return gt_timer_access(env, GTIMER_PHYS, isread);
2653}
2654
2655static CPAccessResult gt_vtimer_access(CPUARMState *env, const ARMCPRegInfo *ri,
2656 bool isread)
2657{
2658 return gt_timer_access(env, GTIMER_VIRT, isread);
2659}
2660
2661static CPAccessResult gt_stimer_access(CPUARMState *env,
2662 const ARMCPRegInfo *ri,
2663 bool isread)
2664{
2665
2666
2667
2668
2669 switch (arm_current_el(env)) {
2670 case 1:
2671 if (!arm_is_secure(env)) {
2672 return CP_ACCESS_TRAP;
2673 }
2674 if (!(env->cp15.scr_el3 & SCR_ST)) {
2675 return CP_ACCESS_TRAP_EL3;
2676 }
2677 return CP_ACCESS_OK;
2678 case 0:
2679 case 2:
2680 return CP_ACCESS_TRAP;
2681 case 3:
2682 return CP_ACCESS_OK;
2683 default:
2684 g_assert_not_reached();
2685 }
2686}
2687
2688static uint64_t gt_get_countervalue(CPUARMState *env)
2689{
2690 ARMCPU *cpu = env_archcpu(env);
2691
2692 return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / gt_cntfrq_period_ns(cpu);
2693}
2694
2695static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
2696{
2697 ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
2698
2699 if (gt->ctl & 1) {
2700
2701
2702
2703 uint64_t offset = timeridx == GTIMER_VIRT ?
2704 cpu->env.cp15.cntvoff_el2 : 0;
2705 uint64_t count = gt_get_countervalue(&cpu->env);
2706
2707 int istatus = count - offset >= gt->cval;
2708 uint64_t nexttick;
2709 int irqstate;
2710
2711 gt->ctl = deposit32(gt->ctl, 2, 1, istatus);
2712
2713 irqstate = (istatus && !(gt->ctl & 2));
2714 qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
2715
2716 if (istatus) {
2717
2718 nexttick = UINT64_MAX;
2719 } else {
2720
2721 nexttick = gt->cval + offset;
2722 }
2723
2724
2725
2726
2727
2728 if (nexttick > INT64_MAX / gt_cntfrq_period_ns(cpu)) {
2729 timer_mod_ns(cpu->gt_timer[timeridx], INT64_MAX);
2730 } else {
2731 timer_mod(cpu->gt_timer[timeridx], nexttick);
2732 }
2733 trace_arm_gt_recalc(timeridx, irqstate, nexttick);
2734 } else {
2735
2736 gt->ctl &= ~4;
2737 qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0);
2738 timer_del(cpu->gt_timer[timeridx]);
2739 trace_arm_gt_recalc_disabled(timeridx);
2740 }
2741}
2742
2743static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
2744 int timeridx)
2745{
2746 ARMCPU *cpu = env_archcpu(env);
2747
2748 timer_del(cpu->gt_timer[timeridx]);
2749}
2750
2751static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
2752{
2753 return gt_get_countervalue(env);
2754}
2755
2756static uint64_t gt_virt_cnt_offset(CPUARMState *env)
2757{
2758 uint64_t hcr;
2759
2760 switch (arm_current_el(env)) {
2761 case 2:
2762 hcr = arm_hcr_el2_eff(env);
2763 if (hcr & HCR_E2H) {
2764 return 0;
2765 }
2766 break;
2767 case 0:
2768 hcr = arm_hcr_el2_eff(env);
2769 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
2770 return 0;
2771 }
2772 break;
2773 }
2774
2775 return env->cp15.cntvoff_el2;
2776}
2777
2778static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
2779{
2780 return gt_get_countervalue(env) - gt_virt_cnt_offset(env);
2781}
2782
2783static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2784 int timeridx,
2785 uint64_t value)
2786{
2787 trace_arm_gt_cval_write(timeridx, value);
2788 env->cp15.c14_timer[timeridx].cval = value;
2789 gt_recalc_timer(env_archcpu(env), timeridx);
2790}
2791
2792static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
2793 int timeridx)
2794{
2795 uint64_t offset = 0;
2796
2797 switch (timeridx) {
2798 case GTIMER_VIRT:
2799 case GTIMER_HYPVIRT:
2800 offset = gt_virt_cnt_offset(env);
2801 break;
2802 }
2803
2804 return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
2805 (gt_get_countervalue(env) - offset));
2806}
2807
2808static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2809 int timeridx,
2810 uint64_t value)
2811{
2812 uint64_t offset = 0;
2813
2814 switch (timeridx) {
2815 case GTIMER_VIRT:
2816 case GTIMER_HYPVIRT:
2817 offset = gt_virt_cnt_offset(env);
2818 break;
2819 }
2820
2821 trace_arm_gt_tval_write(timeridx, value);
2822 env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset +
2823 sextract64(value, 0, 32);
2824 gt_recalc_timer(env_archcpu(env), timeridx);
2825}
2826
2827static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
2828 int timeridx,
2829 uint64_t value)
2830{
2831 ARMCPU *cpu = env_archcpu(env);
2832 uint32_t oldval = env->cp15.c14_timer[timeridx].ctl;
2833
2834 trace_arm_gt_ctl_write(timeridx, value);
2835 env->cp15.c14_timer[timeridx].ctl = deposit64(oldval, 0, 2, value);
2836 if ((oldval ^ value) & 1) {
2837
2838 gt_recalc_timer(cpu, timeridx);
2839 } else if ((oldval ^ value) & 2) {
2840
2841
2842
2843 int irqstate = (oldval & 4) && !(value & 2);
2844
2845 trace_arm_gt_imask_toggle(timeridx, irqstate);
2846 qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
2847 }
2848}
2849
2850static void gt_phys_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
2851{
2852 gt_timer_reset(env, ri, GTIMER_PHYS);
2853}
2854
2855static void gt_phys_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2856 uint64_t value)
2857{
2858 gt_cval_write(env, ri, GTIMER_PHYS, value);
2859}
2860
2861static uint64_t gt_phys_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
2862{
2863 return gt_tval_read(env, ri, GTIMER_PHYS);
2864}
2865
2866static void gt_phys_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2867 uint64_t value)
2868{
2869 gt_tval_write(env, ri, GTIMER_PHYS, value);
2870}
2871
2872static void gt_phys_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
2873 uint64_t value)
2874{
2875 gt_ctl_write(env, ri, GTIMER_PHYS, value);
2876}
2877
2878static int gt_phys_redir_timeridx(CPUARMState *env)
2879{
2880 switch (arm_mmu_idx(env)) {
2881 case ARMMMUIdx_E20_0:
2882 case ARMMMUIdx_E20_2:
2883 case ARMMMUIdx_E20_2_PAN:
2884 case ARMMMUIdx_SE20_0:
2885 case ARMMMUIdx_SE20_2:
2886 case ARMMMUIdx_SE20_2_PAN:
2887 return GTIMER_HYP;
2888 default:
2889 return GTIMER_PHYS;
2890 }
2891}
2892
2893static int gt_virt_redir_timeridx(CPUARMState *env)
2894{
2895 switch (arm_mmu_idx(env)) {
2896 case ARMMMUIdx_E20_0:
2897 case ARMMMUIdx_E20_2:
2898 case ARMMMUIdx_E20_2_PAN:
2899 case ARMMMUIdx_SE20_0:
2900 case ARMMMUIdx_SE20_2:
2901 case ARMMMUIdx_SE20_2_PAN:
2902 return GTIMER_HYPVIRT;
2903 default:
2904 return GTIMER_VIRT;
2905 }
2906}
2907
2908static uint64_t gt_phys_redir_cval_read(CPUARMState *env,
2909 const ARMCPRegInfo *ri)
2910{
2911 int timeridx = gt_phys_redir_timeridx(env);
2912 return env->cp15.c14_timer[timeridx].cval;
2913}
2914
2915static void gt_phys_redir_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2916 uint64_t value)
2917{
2918 int timeridx = gt_phys_redir_timeridx(env);
2919 gt_cval_write(env, ri, timeridx, value);
2920}
2921
2922static uint64_t gt_phys_redir_tval_read(CPUARMState *env,
2923 const ARMCPRegInfo *ri)
2924{
2925 int timeridx = gt_phys_redir_timeridx(env);
2926 return gt_tval_read(env, ri, timeridx);
2927}
2928
2929static void gt_phys_redir_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2930 uint64_t value)
2931{
2932 int timeridx = gt_phys_redir_timeridx(env);
2933 gt_tval_write(env, ri, timeridx, value);
2934}
2935
2936static uint64_t gt_phys_redir_ctl_read(CPUARMState *env,
2937 const ARMCPRegInfo *ri)
2938{
2939 int timeridx = gt_phys_redir_timeridx(env);
2940 return env->cp15.c14_timer[timeridx].ctl;
2941}
2942
2943static void gt_phys_redir_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
2944 uint64_t value)
2945{
2946 int timeridx = gt_phys_redir_timeridx(env);
2947 gt_ctl_write(env, ri, timeridx, value);
2948}
2949
2950static void gt_virt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
2951{
2952 gt_timer_reset(env, ri, GTIMER_VIRT);
2953}
2954
2955static void gt_virt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2956 uint64_t value)
2957{
2958 gt_cval_write(env, ri, GTIMER_VIRT, value);
2959}
2960
2961static uint64_t gt_virt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
2962{
2963 return gt_tval_read(env, ri, GTIMER_VIRT);
2964}
2965
2966static void gt_virt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2967 uint64_t value)
2968{
2969 gt_tval_write(env, ri, GTIMER_VIRT, value);
2970}
2971
2972static void gt_virt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
2973 uint64_t value)
2974{
2975 gt_ctl_write(env, ri, GTIMER_VIRT, value);
2976}
2977
2978static void gt_cntvoff_write(CPUARMState *env, const ARMCPRegInfo *ri,
2979 uint64_t value)
2980{
2981 ARMCPU *cpu = env_archcpu(env);
2982
2983 trace_arm_gt_cntvoff_write(value);
2984 raw_write(env, ri, value);
2985 gt_recalc_timer(cpu, GTIMER_VIRT);
2986}
2987
2988static uint64_t gt_virt_redir_cval_read(CPUARMState *env,
2989 const ARMCPRegInfo *ri)
2990{
2991 int timeridx = gt_virt_redir_timeridx(env);
2992 return env->cp15.c14_timer[timeridx].cval;
2993}
2994
2995static void gt_virt_redir_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2996 uint64_t value)
2997{
2998 int timeridx = gt_virt_redir_timeridx(env);
2999 gt_cval_write(env, ri, timeridx, value);
3000}
3001
3002static uint64_t gt_virt_redir_tval_read(CPUARMState *env,
3003 const ARMCPRegInfo *ri)
3004{
3005 int timeridx = gt_virt_redir_timeridx(env);
3006 return gt_tval_read(env, ri, timeridx);
3007}
3008
3009static void gt_virt_redir_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
3010 uint64_t value)
3011{
3012 int timeridx = gt_virt_redir_timeridx(env);
3013 gt_tval_write(env, ri, timeridx, value);
3014}
3015
3016static uint64_t gt_virt_redir_ctl_read(CPUARMState *env,
3017 const ARMCPRegInfo *ri)
3018{
3019 int timeridx = gt_virt_redir_timeridx(env);
3020 return env->cp15.c14_timer[timeridx].ctl;
3021}
3022
3023static void gt_virt_redir_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
3024 uint64_t value)
3025{
3026 int timeridx = gt_virt_redir_timeridx(env);
3027 gt_ctl_write(env, ri, timeridx, value);
3028}
3029
3030static void gt_hyp_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
3031{
3032 gt_timer_reset(env, ri, GTIMER_HYP);
3033}
3034
3035static void gt_hyp_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
3036 uint64_t value)
3037{
3038 gt_cval_write(env, ri, GTIMER_HYP, value);
3039}
3040
3041static uint64_t gt_hyp_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
3042{
3043 return gt_tval_read(env, ri, GTIMER_HYP);
3044}
3045
3046static void gt_hyp_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
3047 uint64_t value)
3048{
3049 gt_tval_write(env, ri, GTIMER_HYP, value);
3050}
3051
3052static void gt_hyp_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
3053 uint64_t value)
3054{
3055 gt_ctl_write(env, ri, GTIMER_HYP, value);
3056}
3057
3058static void gt_sec_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
3059{
3060 gt_timer_reset(env, ri, GTIMER_SEC);
3061}
3062
3063static void gt_sec_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
3064 uint64_t value)
3065{
3066 gt_cval_write(env, ri, GTIMER_SEC, value);
3067}
3068
3069static uint64_t gt_sec_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
3070{
3071 return gt_tval_read(env, ri, GTIMER_SEC);
3072}
3073
3074static void gt_sec_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
3075 uint64_t value)
3076{
3077 gt_tval_write(env, ri, GTIMER_SEC, value);
3078}
3079
3080static void gt_sec_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
3081 uint64_t value)
3082{
3083 gt_ctl_write(env, ri, GTIMER_SEC, value);
3084}
3085
3086static void gt_hv_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
3087{
3088 gt_timer_reset(env, ri, GTIMER_HYPVIRT);
3089}
3090
3091static void gt_hv_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
3092 uint64_t value)
3093{
3094 gt_cval_write(env, ri, GTIMER_HYPVIRT, value);
3095}
3096
3097static uint64_t gt_hv_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
3098{
3099 return gt_tval_read(env, ri, GTIMER_HYPVIRT);
3100}
3101
3102static void gt_hv_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
3103 uint64_t value)
3104{
3105 gt_tval_write(env, ri, GTIMER_HYPVIRT, value);
3106}
3107
3108static void gt_hv_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
3109 uint64_t value)
3110{
3111 gt_ctl_write(env, ri, GTIMER_HYPVIRT, value);
3112}
3113
3114void arm_gt_ptimer_cb(void *opaque)
3115{
3116 ARMCPU *cpu = opaque;
3117
3118 gt_recalc_timer(cpu, GTIMER_PHYS);
3119}
3120
3121void arm_gt_vtimer_cb(void *opaque)
3122{
3123 ARMCPU *cpu = opaque;
3124
3125 gt_recalc_timer(cpu, GTIMER_VIRT);
3126}
3127
3128void arm_gt_htimer_cb(void *opaque)
3129{
3130 ARMCPU *cpu = opaque;
3131
3132 gt_recalc_timer(cpu, GTIMER_HYP);
3133}
3134
3135void arm_gt_stimer_cb(void *opaque)
3136{
3137 ARMCPU *cpu = opaque;
3138
3139 gt_recalc_timer(cpu, GTIMER_SEC);
3140}
3141
3142void arm_gt_hvtimer_cb(void *opaque)
3143{
3144 ARMCPU *cpu = opaque;
3145
3146 gt_recalc_timer(cpu, GTIMER_HYPVIRT);
3147}
3148
3149static void arm_gt_cntfrq_reset(CPUARMState *env, const ARMCPRegInfo *opaque)
3150{
3151 ARMCPU *cpu = env_archcpu(env);
3152
3153 cpu->env.cp15.c14_cntfrq = cpu->gt_cntfrq_hz;
3154}
3155
3156static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
3157
3158
3159
3160
3161 { .name = "CNTFRQ", .cp = 15, .crn = 14, .crm = 0, .opc1 = 0, .opc2 = 0,
3162 .type = ARM_CP_ALIAS,
3163 .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access,
3164 .fieldoffset = offsetoflow32(CPUARMState, cp15.c14_cntfrq),
3165 },
3166 { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64,
3167 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
3168 .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access,
3169 .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
3170 .resetfn = arm_gt_cntfrq_reset,
3171 },
3172
3173 { .name = "CNTKCTL", .state = ARM_CP_STATE_BOTH,
3174 .opc0 = 3, .opc1 = 0, .crn = 14, .crm = 1, .opc2 = 0,
3175 .access = PL1_RW,
3176 .fieldoffset = offsetof(CPUARMState, cp15.c14_cntkctl),
3177 .resetvalue = 0,
3178 },
3179
3180 { .name = "CNTP_CTL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1,
3181 .secure = ARM_CP_SECSTATE_NS,
3182 .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL0_RW,
3183 .accessfn = gt_ptimer_access,
3184 .fieldoffset = offsetoflow32(CPUARMState,
3185 cp15.c14_timer[GTIMER_PHYS].ctl),
3186 .readfn = gt_phys_redir_ctl_read, .raw_readfn = raw_read,
3187 .writefn = gt_phys_redir_ctl_write, .raw_writefn = raw_write,
3188 },
3189 { .name = "CNTP_CTL_S",
3190 .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1,
3191 .secure = ARM_CP_SECSTATE_S,
3192 .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL0_RW,
3193 .accessfn = gt_ptimer_access,
3194 .fieldoffset = offsetoflow32(CPUARMState,
3195 cp15.c14_timer[GTIMER_SEC].ctl),
3196 .writefn = gt_sec_ctl_write, .raw_writefn = raw_write,
3197 },
3198 { .name = "CNTP_CTL_EL0", .state = ARM_CP_STATE_AA64,
3199 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 1,
3200 .type = ARM_CP_IO, .access = PL0_RW,
3201 .accessfn = gt_ptimer_access,
3202 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
3203 .resetvalue = 0,
3204 .readfn = gt_phys_redir_ctl_read, .raw_readfn = raw_read,
3205 .writefn = gt_phys_redir_ctl_write, .raw_writefn = raw_write,
3206 },
3207 { .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1,
3208 .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL0_RW,
3209 .accessfn = gt_vtimer_access,
3210 .fieldoffset = offsetoflow32(CPUARMState,
3211 cp15.c14_timer[GTIMER_VIRT].ctl),
3212 .readfn = gt_virt_redir_ctl_read, .raw_readfn = raw_read,
3213 .writefn = gt_virt_redir_ctl_write, .raw_writefn = raw_write,
3214 },
3215 { .name = "CNTV_CTL_EL0", .state = ARM_CP_STATE_AA64,
3216 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 1,
3217 .type = ARM_CP_IO, .access = PL0_RW,
3218 .accessfn = gt_vtimer_access,
3219 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
3220 .resetvalue = 0,
3221 .readfn = gt_virt_redir_ctl_read, .raw_readfn = raw_read,
3222 .writefn = gt_virt_redir_ctl_write, .raw_writefn = raw_write,
3223 },
3224
3225 { .name = "CNTP_TVAL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0,
3226 .secure = ARM_CP_SECSTATE_NS,
3227 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL0_RW,
3228 .accessfn = gt_ptimer_access,
3229 .readfn = gt_phys_redir_tval_read, .writefn = gt_phys_redir_tval_write,
3230 },
3231 { .name = "CNTP_TVAL_S",
3232 .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0,
3233 .secure = ARM_CP_SECSTATE_S,
3234 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL0_RW,
3235 .accessfn = gt_ptimer_access,
3236 .readfn = gt_sec_tval_read, .writefn = gt_sec_tval_write,
3237 },
3238 { .name = "CNTP_TVAL_EL0", .state = ARM_CP_STATE_AA64,
3239 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 0,
3240 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL0_RW,
3241 .accessfn = gt_ptimer_access, .resetfn = gt_phys_timer_reset,
3242 .readfn = gt_phys_redir_tval_read, .writefn = gt_phys_redir_tval_write,
3243 },
3244 { .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0,
3245 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL0_RW,
3246 .accessfn = gt_vtimer_access,
3247 .readfn = gt_virt_redir_tval_read, .writefn = gt_virt_redir_tval_write,
3248 },
3249 { .name = "CNTV_TVAL_EL0", .state = ARM_CP_STATE_AA64,
3250 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 0,
3251 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL0_RW,
3252 .accessfn = gt_vtimer_access, .resetfn = gt_virt_timer_reset,
3253 .readfn = gt_virt_redir_tval_read, .writefn = gt_virt_redir_tval_write,
3254 },
3255
3256 { .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0,
3257 .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO,
3258 .accessfn = gt_pct_access,
3259 .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore,
3260 },
3261 { .name = "CNTPCT_EL0", .state = ARM_CP_STATE_AA64,
3262 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 1,
3263 .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
3264 .accessfn = gt_pct_access, .readfn = gt_cnt_read,
3265 },
3266 { .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1,
3267 .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO,
3268 .accessfn = gt_vct_access,
3269 .readfn = gt_virt_cnt_read, .resetfn = arm_cp_reset_ignore,
3270 },
3271 { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
3272 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
3273 .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
3274 .accessfn = gt_vct_access, .readfn = gt_virt_cnt_read,
3275 },
3276
3277 { .name = "CNTP_CVAL", .cp = 15, .crm = 14, .opc1 = 2,
3278 .secure = ARM_CP_SECSTATE_NS,
3279 .access = PL0_RW,
3280 .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS,
3281 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
3282 .accessfn = gt_ptimer_access,
3283 .readfn = gt_phys_redir_cval_read, .raw_readfn = raw_read,
3284 .writefn = gt_phys_redir_cval_write, .raw_writefn = raw_write,
3285 },
3286 { .name = "CNTP_CVAL_S", .cp = 15, .crm = 14, .opc1 = 2,
3287 .secure = ARM_CP_SECSTATE_S,
3288 .access = PL0_RW,
3289 .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS,
3290 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval),
3291 .accessfn = gt_ptimer_access,
3292 .writefn = gt_sec_cval_write, .raw_writefn = raw_write,
3293 },
3294 { .name = "CNTP_CVAL_EL0", .state = ARM_CP_STATE_AA64,
3295 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 2,
3296 .access = PL0_RW,
3297 .type = ARM_CP_IO,
3298 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
3299 .resetvalue = 0, .accessfn = gt_ptimer_access,
3300 .readfn = gt_phys_redir_cval_read, .raw_readfn = raw_read,
3301 .writefn = gt_phys_redir_cval_write, .raw_writefn = raw_write,
3302 },
3303 { .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3,
3304 .access = PL0_RW,
3305 .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS,
3306 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
3307 .accessfn = gt_vtimer_access,
3308 .readfn = gt_virt_redir_cval_read, .raw_readfn = raw_read,
3309 .writefn = gt_virt_redir_cval_write, .raw_writefn = raw_write,
3310 },
3311 { .name = "CNTV_CVAL_EL0", .state = ARM_CP_STATE_AA64,
3312 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 2,
3313 .access = PL0_RW,
3314 .type = ARM_CP_IO,
3315 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
3316 .resetvalue = 0, .accessfn = gt_vtimer_access,
3317 .readfn = gt_virt_redir_cval_read, .raw_readfn = raw_read,
3318 .writefn = gt_virt_redir_cval_write, .raw_writefn = raw_write,
3319 },
3320
3321
3322
3323 { .name = "CNTPS_TVAL_EL1", .state = ARM_CP_STATE_AA64,
3324 .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 0,
3325 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW,
3326 .accessfn = gt_stimer_access,
3327 .readfn = gt_sec_tval_read,
3328 .writefn = gt_sec_tval_write,
3329 .resetfn = gt_sec_timer_reset,
3330 },
3331 { .name = "CNTPS_CTL_EL1", .state = ARM_CP_STATE_AA64,
3332 .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 1,
3333 .type = ARM_CP_IO, .access = PL1_RW,
3334 .accessfn = gt_stimer_access,
3335 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].ctl),
3336 .resetvalue = 0,
3337 .writefn = gt_sec_ctl_write, .raw_writefn = raw_write,
3338 },
3339 { .name = "CNTPS_CVAL_EL1", .state = ARM_CP_STATE_AA64,
3340 .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 2,
3341 .type = ARM_CP_IO, .access = PL1_RW,
3342 .accessfn = gt_stimer_access,
3343 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval),
3344 .writefn = gt_sec_cval_write, .raw_writefn = raw_write,
3345 },
3346 REGINFO_SENTINEL
3347};
3348
3349static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
3350 bool isread)
3351{
3352 if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
3353 return CP_ACCESS_TRAP;
3354 }
3355 return CP_ACCESS_OK;
3356}
3357
3358#else
3359
3360
3361
3362
3363
3364static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
3365{
3366 ARMCPU *cpu = env_archcpu(env);
3367
3368
3369
3370
3371
3372 return cpu_get_clock() / gt_cntfrq_period_ns(cpu);
3373}
3374
3375static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
3376 { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64,
3377 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
3378 .type = ARM_CP_CONST, .access = PL0_R ,
3379 .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
3380 .resetvalue = NANOSECONDS_PER_SECOND / GTIMER_SCALE,
3381 },
3382 { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
3383 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
3384 .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
3385 .readfn = gt_virt_cnt_read,
3386 },
3387 REGINFO_SENTINEL
3388};
3389
3390#endif
3391
3392static void par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
3393{
3394 if (arm_feature(env, ARM_FEATURE_LPAE)) {
3395 raw_write(env, ri, value);
3396 } else if (arm_feature(env, ARM_FEATURE_V7)) {
3397 raw_write(env, ri, value & 0xfffff6ff);
3398 } else {
3399 raw_write(env, ri, value & 0xfffff1ff);
3400 }
3401}
3402
3403#ifndef CONFIG_USER_ONLY
3404
3405
3406static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
3407 bool isread)
3408{
3409 if (ri->opc2 & 4) {
3410
3411
3412
3413
3414
3415 if (arm_current_el(env) == 1) {
3416 if (arm_is_secure_below_el3(env)) {
3417 if (env->cp15.scr_el3 & SCR_EEL2) {
3418 return CP_ACCESS_TRAP_UNCATEGORIZED_EL2;
3419 }
3420 return CP_ACCESS_TRAP_UNCATEGORIZED_EL3;
3421 }
3422 return CP_ACCESS_TRAP_UNCATEGORIZED;
3423 }
3424 }
3425 return CP_ACCESS_OK;
3426}
3427
3428#ifdef CONFIG_TCG
3429static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
3430 MMUAccessType access_type, ARMMMUIdx mmu_idx)
3431{
3432 hwaddr phys_addr;
3433 target_ulong page_size;
3434 int prot;
3435 bool ret;
3436 uint64_t par64;
3437 bool format64 = false;
3438 MemTxAttrs attrs = {};
3439 ARMMMUFaultInfo fi = {};
3440 ARMCacheAttrs cacheattrs = {};
3441
3442 ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
3443 &prot, &page_size, &fi, &cacheattrs);
3444
3445 if (ret) {
3446
3447
3448
3449
3450 int current_el = arm_current_el(env);
3451 int target_el;
3452 uint32_t syn, fsr, fsc;
3453 bool take_exc = false;
3454
3455 if (fi.s1ptw && current_el == 1
3456 && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
3457
3458
3459
3460
3461
3462
3463
3464
3465 if (fi.type == ARMFault_SyncExternalOnWalk &&
3466 (env->cp15.scr_el3 & SCR_EA)) {
3467 target_el = 3;
3468 } else {
3469 env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4;
3470 if (arm_is_secure_below_el3(env) && fi.s1ns) {
3471 env->cp15.hpfar_el2 |= HPFAR_NS;
3472 }
3473 target_el = 2;
3474 }
3475 take_exc = true;
3476 } else if (fi.type == ARMFault_SyncExternalOnWalk) {
3477
3478
3479
3480
3481 if (fi.stage2) {
3482 if (current_el == 3) {
3483 target_el = 3;
3484 } else {
3485 target_el = 2;
3486 }
3487 } else {
3488 target_el = exception_target_el(env);
3489 }
3490 take_exc = true;
3491 }
3492
3493 if (take_exc) {
3494
3495 if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
3496 arm_s1_regime_using_lpae_format(env, mmu_idx)) {
3497 fsr = arm_fi_to_lfsc(&fi);
3498 fsc = extract32(fsr, 0, 6);
3499 } else {
3500 fsr = arm_fi_to_sfsc(&fi);
3501 fsc = 0x3f;
3502 }
3503
3504
3505
3506
3507 syn = syn_data_abort_no_iss(current_el == target_el, 0,
3508 fi.ea, 1, fi.s1ptw, 1, fsc);
3509 env->exception.vaddress = value;
3510 env->exception.fsr = fsr;
3511 raise_exception(env, EXCP_DATA_ABORT, syn, target_el);
3512 }
3513 }
3514
3515 if (is_a64(env)) {
3516 format64 = true;
3517 } else if (arm_feature(env, ARM_FEATURE_LPAE)) {
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532 format64 = arm_s1_regime_using_lpae_format(env, mmu_idx);
3533
3534 if (arm_feature(env, ARM_FEATURE_EL2)) {
3535 if (mmu_idx == ARMMMUIdx_E10_0 ||
3536 mmu_idx == ARMMMUIdx_E10_1 ||
3537 mmu_idx == ARMMMUIdx_E10_1_PAN) {
3538 format64 |= env->cp15.hcr_el2 & (HCR_VM | HCR_DC);
3539 } else {
3540 format64 |= arm_current_el(env) == 2;
3541 }
3542 }
3543 }
3544
3545 if (format64) {
3546
3547 par64 = (1 << 11);
3548 if (!ret) {
3549 par64 |= phys_addr & ~0xfffULL;
3550 if (!attrs.secure) {
3551 par64 |= (1 << 9);
3552 }
3553 par64 |= (uint64_t)cacheattrs.attrs << 56;
3554 par64 |= cacheattrs.shareability << 7;
3555 } else {
3556 uint32_t fsr = arm_fi_to_lfsc(&fi);
3557
3558 par64 |= 1;
3559 par64 |= (fsr & 0x3f) << 1;
3560 if (fi.stage2) {
3561 par64 |= (1 << 9);
3562 }
3563 if (fi.s1ptw) {
3564 par64 |= (1 << 8);
3565 }
3566 }
3567 } else {
3568
3569
3570
3571
3572 if (!ret) {
3573
3574 if (page_size == (1 << 24)
3575 && arm_feature(env, ARM_FEATURE_V7)) {
3576 par64 = (phys_addr & 0xff000000) | (1 << 1);
3577 } else {
3578 par64 = phys_addr & 0xfffff000;
3579 }
3580 if (!attrs.secure) {
3581 par64 |= (1 << 9);
3582 }
3583 } else {
3584 uint32_t fsr = arm_fi_to_sfsc(&fi);
3585
3586 par64 = ((fsr & (1 << 10)) >> 5) | ((fsr & (1 << 12)) >> 6) |
3587 ((fsr & 0xf) << 1) | 1;
3588 }
3589 }
3590 return par64;
3591}
3592#endif
3593
3594static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
3595{
3596#ifdef CONFIG_TCG
3597 MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
3598 uint64_t par64;
3599 ARMMMUIdx mmu_idx;
3600 int el = arm_current_el(env);
3601 bool secure = arm_is_secure_below_el3(env);
3602
3603 switch (ri->opc2 & 6) {
3604 case 0:
3605
3606 switch (el) {
3607 case 3:
3608 mmu_idx = ARMMMUIdx_SE3;
3609 break;
3610 case 2:
3611 g_assert(!secure);
3612
3613 case 1:
3614 if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
3615 mmu_idx = (secure ? ARMMMUIdx_Stage1_SE1_PAN
3616 : ARMMMUIdx_Stage1_E1_PAN);
3617 } else {
3618 mmu_idx = secure ? ARMMMUIdx_Stage1_SE1 : ARMMMUIdx_Stage1_E1;
3619 }
3620 break;
3621 default:
3622 g_assert_not_reached();
3623 }
3624 break;
3625 case 2:
3626
3627 switch (el) {
3628 case 3:
3629 mmu_idx = ARMMMUIdx_SE10_0;
3630 break;
3631 case 2:
3632 g_assert(!secure);
3633 mmu_idx = ARMMMUIdx_Stage1_E0;
3634 break;
3635 case 1:
3636 mmu_idx = secure ? ARMMMUIdx_Stage1_SE0 : ARMMMUIdx_Stage1_E0;
3637 break;
3638 default:
3639 g_assert_not_reached();
3640 }
3641 break;
3642 case 4:
3643
3644 mmu_idx = ARMMMUIdx_E10_1;
3645 break;
3646 case 6:
3647
3648 mmu_idx = ARMMMUIdx_E10_0;
3649 break;
3650 default:
3651 g_assert_not_reached();
3652 }
3653
3654 par64 = do_ats_write(env, value, access_type, mmu_idx);
3655
3656 A32_BANKED_CURRENT_REG_SET(env, par, par64);
3657#else
3658
3659 g_assert_not_reached();
3660#endif
3661}
3662
3663static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
3664 uint64_t value)
3665{
3666#ifdef CONFIG_TCG
3667 MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
3668 uint64_t par64;
3669
3670 par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2);
3671
3672 A32_BANKED_CURRENT_REG_SET(env, par, par64);
3673#else
3674
3675 g_assert_not_reached();
3676#endif
3677}
3678
3679static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
3680 bool isread)
3681{
3682 if (arm_current_el(env) == 3 &&
3683 !(env->cp15.scr_el3 & (SCR_NS | SCR_EEL2))) {
3684 return CP_ACCESS_TRAP;
3685 }
3686 return CP_ACCESS_OK;
3687}
3688
3689static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
3690 uint64_t value)
3691{
3692#ifdef CONFIG_TCG
3693 MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
3694 ARMMMUIdx mmu_idx;
3695 int secure = arm_is_secure_below_el3(env);
3696
3697 switch (ri->opc2 & 6) {
3698 case 0:
3699 switch (ri->opc1) {
3700 case 0:
3701 if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) {
3702 mmu_idx = (secure ? ARMMMUIdx_Stage1_SE1_PAN
3703 : ARMMMUIdx_Stage1_E1_PAN);
3704 } else {
3705 mmu_idx = secure ? ARMMMUIdx_Stage1_SE1 : ARMMMUIdx_Stage1_E1;
3706 }
3707 break;
3708 case 4:
3709 mmu_idx = secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2;
3710 break;
3711 case 6:
3712 mmu_idx = ARMMMUIdx_SE3;
3713 break;
3714 default:
3715 g_assert_not_reached();
3716 }
3717 break;
3718 case 2:
3719 mmu_idx = secure ? ARMMMUIdx_Stage1_SE0 : ARMMMUIdx_Stage1_E0;
3720 break;
3721 case 4:
3722 mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_E10_1;
3723 break;
3724 case 6:
3725 mmu_idx = secure ? ARMMMUIdx_SE10_0 : ARMMMUIdx_E10_0;
3726 break;
3727 default:
3728 g_assert_not_reached();
3729 }
3730
3731 env->cp15.par_el[1] = do_ats_write(env, value, access_type, mmu_idx);
3732#else
3733
3734 g_assert_not_reached();
3735#endif
3736}
3737#endif
3738
3739static const ARMCPRegInfo vapa_cp_reginfo[] = {
3740 { .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0,
3741 .access = PL1_RW, .resetvalue = 0,
3742 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.par_s),
3743 offsetoflow32(CPUARMState, cp15.par_ns) },
3744 .writefn = par_write },
3745#ifndef CONFIG_USER_ONLY
3746
3747 { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY,
3748 .access = PL1_W, .accessfn = ats_access,
3749 .writefn = ats_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
3750#endif
3751 REGINFO_SENTINEL
3752};
3753
3754
3755static uint32_t simple_mpu_ap_bits(uint32_t val)
3756{
3757 uint32_t ret;
3758 uint32_t mask;
3759 int i;
3760 ret = 0;
3761 mask = 3;
3762 for (i = 0; i < 16; i += 2) {
3763 ret |= (val >> i) & mask;
3764 mask <<= 2;
3765 }
3766 return ret;
3767}
3768
3769
3770static uint32_t extended_mpu_ap_bits(uint32_t val)
3771{
3772 uint32_t ret;
3773 uint32_t mask;
3774 int i;
3775 ret = 0;
3776 mask = 3;
3777 for (i = 0; i < 16; i += 2) {
3778 ret |= (val & mask) << i;
3779 mask <<= 2;
3780 }
3781 return ret;
3782}
3783
3784static void pmsav5_data_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
3785 uint64_t value)
3786{
3787 env->cp15.pmsav5_data_ap = extended_mpu_ap_bits(value);
3788}
3789
3790static uint64_t pmsav5_data_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
3791{
3792 return simple_mpu_ap_bits(env->cp15.pmsav5_data_ap);
3793}
3794
3795static void pmsav5_insn_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
3796 uint64_t value)
3797{
3798 env->cp15.pmsav5_insn_ap = extended_mpu_ap_bits(value);
3799}
3800
3801static uint64_t pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
3802{
3803 return simple_mpu_ap_bits(env->cp15.pmsav5_insn_ap);
3804}
3805
3806static uint64_t pmsav7_read(CPUARMState *env, const ARMCPRegInfo *ri)
3807{
3808 uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri);
3809
3810 if (!u32p) {
3811 return 0;
3812 }
3813
3814 u32p += env->pmsav7.rnr[M_REG_NS];
3815 return *u32p;
3816}
3817
3818static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri,
3819 uint64_t value)
3820{
3821 ARMCPU *cpu = env_archcpu(env);
3822 uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri);
3823
3824 if (!u32p) {
3825 return;
3826 }
3827
3828 u32p += env->pmsav7.rnr[M_REG_NS];
3829 tlb_flush(CPU(cpu));
3830 *u32p = value;
3831}
3832
3833static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri,
3834 uint64_t value)
3835{
3836 ARMCPU *cpu = env_archcpu(env);
3837 uint32_t nrgs = cpu->pmsav7_dregion;
3838
3839 if (value >= nrgs) {
3840 qemu_log_mask(LOG_GUEST_ERROR,
3841 "PMSAv7 RGNR write >= # supported regions, %" PRIu32
3842 " > %" PRIu32 "\n", (uint32_t)value, nrgs);
3843 return;
3844 }
3845
3846 raw_write(env, ri, value);
3847}
3848
3849static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
3850
3851
3852
3853
3854 { .name = "DRBAR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 0,
3855 .access = PL1_RW, .type = ARM_CP_NO_RAW,
3856 .fieldoffset = offsetof(CPUARMState, pmsav7.drbar),
3857 .readfn = pmsav7_read, .writefn = pmsav7_write,
3858 .resetfn = arm_cp_reset_ignore },
3859 { .name = "DRSR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 2,
3860 .access = PL1_RW, .type = ARM_CP_NO_RAW,
3861 .fieldoffset = offsetof(CPUARMState, pmsav7.drsr),
3862 .readfn = pmsav7_read, .writefn = pmsav7_write,
3863 .resetfn = arm_cp_reset_ignore },
3864 { .name = "DRACR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 4,
3865 .access = PL1_RW, .type = ARM_CP_NO_RAW,
3866 .fieldoffset = offsetof(CPUARMState, pmsav7.dracr),
3867 .readfn = pmsav7_read, .writefn = pmsav7_write,
3868 .resetfn = arm_cp_reset_ignore },
3869 { .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0,
3870 .access = PL1_RW,
3871 .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]),
3872 .writefn = pmsav7_rgnr_write,
3873 .resetfn = arm_cp_reset_ignore },
3874 REGINFO_SENTINEL
3875};
3876
3877static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
3878 { .name = "DATA_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
3879 .access = PL1_RW, .type = ARM_CP_ALIAS,
3880 .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap),
3881 .readfn = pmsav5_data_ap_read, .writefn = pmsav5_data_ap_write, },
3882 { .name = "INSN_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
3883 .access = PL1_RW, .type = ARM_CP_ALIAS,
3884 .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap),
3885 .readfn = pmsav5_insn_ap_read, .writefn = pmsav5_insn_ap_write, },
3886 { .name = "DATA_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 2,
3887 .access = PL1_RW,
3888 .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap),
3889 .resetvalue = 0, },
3890 { .name = "INSN_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 3,
3891 .access = PL1_RW,
3892 .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap),
3893 .resetvalue = 0, },
3894 { .name = "DCACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
3895 .access = PL1_RW,
3896 .fieldoffset = offsetof(CPUARMState, cp15.c2_data), .resetvalue = 0, },
3897 { .name = "ICACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
3898 .access = PL1_RW,
3899 .fieldoffset = offsetof(CPUARMState, cp15.c2_insn), .resetvalue = 0, },
3900
3901 { .name = "946_PRBS0", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0,
3902 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3903 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[0]) },
3904 { .name = "946_PRBS1", .cp = 15, .crn = 6, .crm = 1, .opc1 = 0,
3905 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3906 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[1]) },
3907 { .name = "946_PRBS2", .cp = 15, .crn = 6, .crm = 2, .opc1 = 0,
3908 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3909 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[2]) },
3910 { .name = "946_PRBS3", .cp = 15, .crn = 6, .crm = 3, .opc1 = 0,
3911 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3912 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[3]) },
3913 { .name = "946_PRBS4", .cp = 15, .crn = 6, .crm = 4, .opc1 = 0,
3914 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3915 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[4]) },
3916 { .name = "946_PRBS5", .cp = 15, .crn = 6, .crm = 5, .opc1 = 0,
3917 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3918 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[5]) },
3919 { .name = "946_PRBS6", .cp = 15, .crn = 6, .crm = 6, .opc1 = 0,
3920 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3921 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[6]) },
3922 { .name = "946_PRBS7", .cp = 15, .crn = 6, .crm = 7, .opc1 = 0,
3923 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3924 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[7]) },
3925 REGINFO_SENTINEL
3926};
3927
3928static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
3929 uint64_t value)
3930{
3931 TCR *tcr = raw_ptr(env, ri);
3932 int maskshift = extract32(value, 0, 3);
3933
3934 if (!arm_feature(env, ARM_FEATURE_V8)) {
3935 if (arm_feature(env, ARM_FEATURE_LPAE) && (value & TTBCR_EAE)) {
3936
3937
3938 value &= ~((7 << 19) | (3 << 14) | (0xf << 3));
3939 } else if (arm_feature(env, ARM_FEATURE_EL3)) {
3940
3941
3942
3943
3944 value &= TTBCR_PD1 | TTBCR_PD0 | TTBCR_N;
3945 } else {
3946 value &= TTBCR_N;
3947 }
3948 }
3949
3950
3951
3952
3953
3954
3955
3956 tcr->raw_tcr = value;
3957 tcr->mask = ~(((uint32_t)0xffffffffu) >> maskshift);
3958 tcr->base_mask = ~((uint32_t)0x3fffu >> maskshift);
3959}
3960
3961static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
3962 uint64_t value)
3963{
3964 ARMCPU *cpu = env_archcpu(env);
3965 TCR *tcr = raw_ptr(env, ri);
3966
3967 if (arm_feature(env, ARM_FEATURE_LPAE)) {
3968
3969
3970
3971 tlb_flush(CPU(cpu));
3972 }
3973
3974 value = deposit64(tcr->raw_tcr, 0, 32, value);
3975 vmsa_ttbcr_raw_write(env, ri, value);
3976}
3977
3978static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
3979{
3980 TCR *tcr = raw_ptr(env, ri);
3981
3982
3983
3984
3985 tcr->raw_tcr = 0;
3986 tcr->mask = 0;
3987 tcr->base_mask = 0xffffc000u;
3988}
3989
3990static void vmsa_tcr_el12_write(CPUARMState *env, const ARMCPRegInfo *ri,
3991 uint64_t value)
3992{
3993 ARMCPU *cpu = env_archcpu(env);
3994 TCR *tcr = raw_ptr(env, ri);
3995
3996
3997 tlb_flush(CPU(cpu));
3998 tcr->raw_tcr = value;
3999}
4000
4001static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
4002 uint64_t value)
4003{
4004
4005 if (cpreg_field_is_64bit(ri) &&
4006 extract64(raw_read(env, ri) ^ value, 48, 16) != 0) {
4007 ARMCPU *cpu = env_archcpu(env);
4008 tlb_flush(CPU(cpu));
4009 }
4010 raw_write(env, ri, value);
4011}
4012
4013static void vmsa_tcr_ttbr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
4014 uint64_t value)
4015{
4016
4017
4018
4019
4020
4021
4022 if (extract64(raw_read(env, ri) ^ value, 48, 16) &&
4023 (arm_hcr_el2_eff(env) & HCR_E2H)) {
4024 uint16_t mask = ARMMMUIdxBit_E20_2 |
4025 ARMMMUIdxBit_E20_2_PAN |
4026 ARMMMUIdxBit_E20_0;
4027
4028 if (arm_is_secure_below_el3(env)) {
4029 mask >>= ARM_MMU_IDX_A_NS;
4030 }
4031
4032 tlb_flush_by_mmuidx(env_cpu(env), mask);
4033 }
4034 raw_write(env, ri, value);
4035}
4036
4037static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
4038 uint64_t value)
4039{
4040 ARMCPU *cpu = env_archcpu(env);
4041 CPUState *cs = CPU(cpu);
4042
4043
4044
4045
4046
4047 if (raw_read(env, ri) != value) {
4048 uint16_t mask = ARMMMUIdxBit_E10_1 |
4049 ARMMMUIdxBit_E10_1_PAN |
4050 ARMMMUIdxBit_E10_0;
4051
4052 if (arm_is_secure_below_el3(env)) {
4053 mask >>= ARM_MMU_IDX_A_NS;
4054 }
4055
4056 tlb_flush_by_mmuidx(cs, mask);
4057 raw_write(env, ri, value);
4058 }
4059}
4060
4061static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
4062 { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
4063 .access = PL1_RW, .accessfn = access_tvm_trvm, .type = ARM_CP_ALIAS,
4064 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s),
4065 offsetoflow32(CPUARMState, cp15.dfsr_ns) }, },
4066 { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
4067 .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
4068 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ifsr_s),
4069 offsetoflow32(CPUARMState, cp15.ifsr_ns) } },
4070 { .name = "DFAR", .cp = 15, .opc1 = 0, .crn = 6, .crm = 0, .opc2 = 0,
4071 .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
4072 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.dfar_s),
4073 offsetof(CPUARMState, cp15.dfar_ns) } },
4074 { .name = "FAR_EL1", .state = ARM_CP_STATE_AA64,
4075 .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
4076 .access = PL1_RW, .accessfn = access_tvm_trvm,
4077 .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
4078 .resetvalue = 0, },
4079 REGINFO_SENTINEL
4080};
4081
4082static const ARMCPRegInfo vmsa_cp_reginfo[] = {
4083 { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
4084 .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
4085 .access = PL1_RW, .accessfn = access_tvm_trvm,
4086 .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
4087 { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
4088 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
4089 .access = PL1_RW, .accessfn = access_tvm_trvm,
4090 .writefn = vmsa_ttbr_write, .resetvalue = 0,
4091 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
4092 offsetof(CPUARMState, cp15.ttbr0_ns) } },
4093 { .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
4094 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
4095 .access = PL1_RW, .accessfn = access_tvm_trvm,
4096 .writefn = vmsa_ttbr_write, .resetvalue = 0,
4097 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
4098 offsetof(CPUARMState, cp15.ttbr1_ns) } },
4099 { .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
4100 .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
4101 .access = PL1_RW, .accessfn = access_tvm_trvm,
4102 .writefn = vmsa_tcr_el12_write,
4103 .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
4104 .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[1]) },
4105 { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
4106 .access = PL1_RW, .accessfn = access_tvm_trvm,
4107 .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write,
4108 .raw_writefn = vmsa_ttbcr_raw_write,
4109
4110 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.tcr_el[3]),
4111 offsetof(CPUARMState, cp15.tcr_el[1])} },
4112 REGINFO_SENTINEL
4113};
4114
4115
4116
4117
4118static const ARMCPRegInfo ttbcr2_reginfo = {
4119 .name = "TTBCR2", .cp = 15, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 3,
4120 .access = PL1_RW, .accessfn = access_tvm_trvm,
4121 .type = ARM_CP_ALIAS,
4122 .bank_fieldoffsets = {
4123 offsetofhigh32(CPUARMState, cp15.tcr_el[3].raw_tcr),
4124 offsetofhigh32(CPUARMState, cp15.tcr_el[1].raw_tcr),
4125 },
4126};
4127
4128static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
4129 uint64_t value)
4130{
4131 env->cp15.c15_ticonfig = value & 0xe7;
4132
4133 env->cp15.c0_cpuid = (value & (1 << 5)) ?
4134 ARM_CPUID_TI915T : ARM_CPUID_TI925T;
4135}
4136
4137static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
4138 uint64_t value)
4139{
4140 env->cp15.c15_threadid = value & 0xffff;
4141}
4142
4143static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
4144 uint64_t value)
4145{
4146
4147 cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HALT);
4148}
4149
4150static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
4151 uint64_t value)
4152{
4153
4154
4155
4156 env->cp15.c15_i_max = 0x000;
4157 env->cp15.c15_i_min = 0xff0;
4158}
4159
4160static const ARMCPRegInfo omap_cp_reginfo[] = {
4161 { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
4162 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE,
4163 .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
4164 .resetvalue = 0, },
4165 { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
4166 .access = PL1_RW, .type = ARM_CP_NOP },
4167 { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
4168 .access = PL1_RW,
4169 .fieldoffset = offsetof(CPUARMState, cp15.c15_ticonfig), .resetvalue = 0,
4170 .writefn = omap_ticonfig_write },
4171 { .name = "IMAX", .cp = 15, .crn = 15, .crm = 2, .opc1 = 0, .opc2 = 0,
4172 .access = PL1_RW,
4173 .fieldoffset = offsetof(CPUARMState, cp15.c15_i_max), .resetvalue = 0, },
4174 { .name = "IMIN", .cp = 15, .crn = 15, .crm = 3, .opc1 = 0, .opc2 = 0,
4175 .access = PL1_RW, .resetvalue = 0xff0,
4176 .fieldoffset = offsetof(CPUARMState, cp15.c15_i_min) },
4177 { .name = "THREADID", .cp = 15, .crn = 15, .crm = 4, .opc1 = 0, .opc2 = 0,
4178 .access = PL1_RW,
4179 .fieldoffset = offsetof(CPUARMState, cp15.c15_threadid), .resetvalue = 0,
4180 .writefn = omap_threadid_write },
4181 { .name = "TI925T_STATUS", .cp = 15, .crn = 15,
4182 .crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
4183 .type = ARM_CP_NO_RAW,
4184 .readfn = arm_cp_read_zero, .writefn = omap_wfi_write, },
4185
4186
4187
4188
4189
4190 { .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
4191 .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
4192 .type = ARM_CP_OVERRIDE | ARM_CP_NO_RAW,
4193 .writefn = omap_cachemaint_write },
4194 { .name = "C9", .cp = 15, .crn = 9,
4195 .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
4196 .type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 },
4197 REGINFO_SENTINEL
4198};
4199
4200static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
4201 uint64_t value)
4202{
4203 env->cp15.c15_cpar = value & 0x3fff;
4204}
4205
4206static const ARMCPRegInfo xscale_cp_reginfo[] = {
4207 { .name = "XSCALE_CPAR",
4208 .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
4209 .fieldoffset = offsetof(CPUARMState, cp15.c15_cpar), .resetvalue = 0,
4210 .writefn = xscale_cpar_write, },
4211 { .name = "XSCALE_AUXCR",
4212 .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW,
4213 .fieldoffset = offsetof(CPUARMState, cp15.c1_xscaleauxcr),
4214 .resetvalue = 0, },
4215
4216
4217
4218 { .name = "XSCALE_LOCK_ICACHE_LINE",
4219 .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
4220 .access = PL1_W, .type = ARM_CP_NOP },
4221 { .name = "XSCALE_UNLOCK_ICACHE",
4222 .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
4223 .access = PL1_W, .type = ARM_CP_NOP },
4224 { .name = "XSCALE_DCACHE_LOCK",
4225 .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 0,
4226 .access = PL1_RW, .type = ARM_CP_NOP },
4227 { .name = "XSCALE_UNLOCK_DCACHE",
4228 .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 1,
4229 .access = PL1_W, .type = ARM_CP_NOP },
4230 REGINFO_SENTINEL
4231};
4232
4233static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
4234
4235
4236
4237
4238
4239 { .name = "C15_IMPDEF", .cp = 15, .crn = 15,
4240 .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
4241 .access = PL1_RW,
4242 .type = ARM_CP_CONST | ARM_CP_NO_RAW | ARM_CP_OVERRIDE,
4243 .resetvalue = 0 },
4244 REGINFO_SENTINEL
4245};
4246
4247static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = {
4248
4249 { .name = "CDSR", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 6,
4250 .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
4251 .resetvalue = 0 },
4252 REGINFO_SENTINEL
4253};
4254
4255static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
4256
4257 { .name = "BXSR", .cp = 15, .crn = 7, .crm = 12, .opc1 = 0, .opc2 = 4,
4258 .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
4259 .resetvalue = 0 },
4260
4261 { .name = "IICR", .cp = 15, .crm = 5, .opc1 = 0,
4262 .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4263 { .name = "IDCR", .cp = 15, .crm = 6, .opc1 = 0,
4264 .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4265 { .name = "CDCR", .cp = 15, .crm = 12, .opc1 = 0,
4266 .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4267 { .name = "PIR", .cp = 15, .crm = 12, .opc1 = 1,
4268 .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4269 { .name = "PDR", .cp = 15, .crm = 12, .opc1 = 2,
4270 .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4271 { .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0,
4272 .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4273 REGINFO_SENTINEL
4274};
4275
4276static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
4277
4278
4279
4280 { .name = "TC_DCACHE", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 3,
4281 .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
4282 .resetvalue = (1 << 30) },
4283 { .name = "TCI_DCACHE", .cp = 15, .crn = 7, .crm = 14, .opc1 = 0, .opc2 = 3,
4284 .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
4285 .resetvalue = (1 << 30) },
4286 REGINFO_SENTINEL
4287};
4288
4289static const ARMCPRegInfo strongarm_cp_reginfo[] = {
4290
4291 { .name = "C9_READBUFFER", .cp = 15, .crn = 9,
4292 .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
4293 .access = PL1_RW, .resetvalue = 0,
4294 .type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_RAW },
4295 REGINFO_SENTINEL
4296};
4297
4298static uint64_t midr_read(CPUARMState *env, const ARMCPRegInfo *ri)
4299{
4300 unsigned int cur_el = arm_current_el(env);
4301
4302 if (arm_is_el2_enabled(env) && cur_el == 1) {
4303 return env->cp15.vpidr_el2;
4304 }
4305 return raw_read(env, ri);
4306}
4307
4308static uint64_t mpidr_read_val(CPUARMState *env)
4309{
4310 ARMCPU *cpu = env_archcpu(env);
4311 uint64_t mpidr = cpu->mp_affinity;
4312
4313 if (arm_feature(env, ARM_FEATURE_V7MP)) {
4314 mpidr |= (1U << 31);
4315
4316
4317
4318
4319 if (cpu->mp_is_up) {
4320 mpidr |= (1u << 30);
4321 }
4322 }
4323 return mpidr;
4324}
4325
4326static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
4327{
4328 unsigned int cur_el = arm_current_el(env);
4329
4330 if (arm_is_el2_enabled(env) && cur_el == 1) {
4331 return env->cp15.vmpidr_el2;
4332 }
4333 return mpidr_read_val(env);
4334}
4335
4336static const ARMCPRegInfo lpae_cp_reginfo[] = {
4337
4338 { .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
4339 .opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
4340 .access = PL1_RW, .accessfn = access_tvm_trvm,
4341 .type = ARM_CP_CONST, .resetvalue = 0 },
4342
4343 { .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
4344 .access = PL1_RW, .accessfn = access_tvm_trvm,
4345 .type = ARM_CP_CONST, .resetvalue = 0 },
4346 { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
4347 .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
4348 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s),
4349 offsetof(CPUARMState, cp15.par_ns)} },
4350 { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
4351 .access = PL1_RW, .accessfn = access_tvm_trvm,
4352 .type = ARM_CP_64BIT | ARM_CP_ALIAS,
4353 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
4354 offsetof(CPUARMState, cp15.ttbr0_ns) },
4355 .writefn = vmsa_ttbr_write, },
4356 { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
4357 .access = PL1_RW, .accessfn = access_tvm_trvm,
4358 .type = ARM_CP_64BIT | ARM_CP_ALIAS,
4359 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
4360 offsetof(CPUARMState, cp15.ttbr1_ns) },
4361 .writefn = vmsa_ttbr_write, },
4362 REGINFO_SENTINEL
4363};
4364
4365static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
4366{
4367 return vfp_get_fpcr(env);
4368}
4369
4370static void aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
4371 uint64_t value)
4372{
4373 vfp_set_fpcr(env, value);
4374}
4375
4376static uint64_t aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri)
4377{
4378 return vfp_get_fpsr(env);
4379}
4380
4381static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
4382 uint64_t value)
4383{
4384 vfp_set_fpsr(env, value);
4385}
4386
4387static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri,
4388 bool isread)
4389{
4390 if (arm_current_el(env) == 0 && !(arm_sctlr(env, 0) & SCTLR_UMA)) {
4391 return CP_ACCESS_TRAP;
4392 }
4393 return CP_ACCESS_OK;
4394}
4395
4396static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri,
4397 uint64_t value)
4398{
4399 env->daif = value & PSTATE_DAIF;
4400}
4401
4402static uint64_t aa64_pan_read(CPUARMState *env, const ARMCPRegInfo *ri)
4403{
4404 return env->pstate & PSTATE_PAN;
4405}
4406
4407static void aa64_pan_write(CPUARMState *env, const ARMCPRegInfo *ri,
4408 uint64_t value)
4409{
4410 env->pstate = (env->pstate & ~PSTATE_PAN) | (value & PSTATE_PAN);
4411}
4412
4413static const ARMCPRegInfo pan_reginfo = {
4414 .name = "PAN", .state = ARM_CP_STATE_AA64,
4415 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 3,
4416 .type = ARM_CP_NO_RAW, .access = PL1_RW,
4417 .readfn = aa64_pan_read, .writefn = aa64_pan_write
4418};
4419
4420static uint64_t aa64_uao_read(CPUARMState *env, const ARMCPRegInfo *ri)
4421{
4422 return env->pstate & PSTATE_UAO;
4423}
4424
4425static void aa64_uao_write(CPUARMState *env, const ARMCPRegInfo *ri,
4426 uint64_t value)
4427{
4428 env->pstate = (env->pstate & ~PSTATE_UAO) | (value & PSTATE_UAO);
4429}
4430
4431static const ARMCPRegInfo uao_reginfo = {
4432 .name = "UAO", .state = ARM_CP_STATE_AA64,
4433 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 4,
4434 .type = ARM_CP_NO_RAW, .access = PL1_RW,
4435 .readfn = aa64_uao_read, .writefn = aa64_uao_write
4436};
4437
4438static uint64_t aa64_dit_read(CPUARMState *env, const ARMCPRegInfo *ri)
4439{
4440 return env->pstate & PSTATE_DIT;
4441}
4442
4443static void aa64_dit_write(CPUARMState *env, const ARMCPRegInfo *ri,
4444 uint64_t value)
4445{
4446 env->pstate = (env->pstate & ~PSTATE_DIT) | (value & PSTATE_DIT);
4447}
4448
4449static const ARMCPRegInfo dit_reginfo = {
4450 .name = "DIT", .state = ARM_CP_STATE_AA64,
4451 .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 5,
4452 .type = ARM_CP_NO_RAW, .access = PL0_RW,
4453 .readfn = aa64_dit_read, .writefn = aa64_dit_write
4454};
4455
4456static uint64_t aa64_ssbs_read(CPUARMState *env, const ARMCPRegInfo *ri)
4457{
4458 return env->pstate & PSTATE_SSBS;
4459}
4460
4461static void aa64_ssbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
4462 uint64_t value)
4463{
4464 env->pstate = (env->pstate & ~PSTATE_SSBS) | (value & PSTATE_SSBS);
4465}
4466
4467static const ARMCPRegInfo ssbs_reginfo = {
4468 .name = "SSBS", .state = ARM_CP_STATE_AA64,
4469 .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 6,
4470 .type = ARM_CP_NO_RAW, .access = PL0_RW,
4471 .readfn = aa64_ssbs_read, .writefn = aa64_ssbs_write
4472};
4473
4474static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
4475 const ARMCPRegInfo *ri,
4476 bool isread)
4477{
4478
4479 switch (arm_current_el(env)) {
4480 case 0:
4481
4482 if (!(arm_sctlr(env, 0) & SCTLR_UCI)) {
4483 return CP_ACCESS_TRAP;
4484 }
4485
4486 case 1:
4487
4488 if (arm_hcr_el2_eff(env) & HCR_TPCP) {
4489 return CP_ACCESS_TRAP_EL2;
4490 }
4491 break;
4492 }
4493 return CP_ACCESS_OK;
4494}
4495
4496static CPAccessResult aa64_cacheop_pou_access(CPUARMState *env,
4497 const ARMCPRegInfo *ri,
4498 bool isread)
4499{
4500
4501 switch (arm_current_el(env)) {
4502 case 0:
4503
4504 if (!(arm_sctlr(env, 0) & SCTLR_UCI)) {
4505 return CP_ACCESS_TRAP;
4506 }
4507
4508 case 1:
4509
4510 if (arm_hcr_el2_eff(env) & HCR_TPU) {
4511 return CP_ACCESS_TRAP_EL2;
4512 }
4513 break;
4514 }
4515 return CP_ACCESS_OK;
4516}
4517
4518
4519
4520
4521
4522static int vae1_tlbmask(CPUARMState *env)
4523{
4524 uint64_t hcr = arm_hcr_el2_eff(env);
4525 uint16_t mask;
4526
4527 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
4528 mask = ARMMMUIdxBit_E20_2 |
4529 ARMMMUIdxBit_E20_2_PAN |
4530 ARMMMUIdxBit_E20_0;
4531 } else {
4532 mask = ARMMMUIdxBit_E10_1 |
4533 ARMMMUIdxBit_E10_1_PAN |
4534 ARMMMUIdxBit_E10_0;
4535 }
4536
4537 if (arm_is_secure_below_el3(env)) {
4538 mask >>= ARM_MMU_IDX_A_NS;
4539 }
4540
4541 return mask;
4542}
4543
4544
4545static int tlbbits_for_regime(CPUARMState *env, ARMMMUIdx mmu_idx,
4546 uint64_t addr)
4547{
4548 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
4549 int tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
4550 int select = extract64(addr, 55, 1);
4551
4552 return (tbi >> select) & 1 ? 56 : 64;
4553}
4554
4555static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
4556{
4557 uint64_t hcr = arm_hcr_el2_eff(env);
4558 ARMMMUIdx mmu_idx;
4559
4560
4561 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
4562 mmu_idx = ARMMMUIdx_E20_0;
4563 } else {
4564 mmu_idx = ARMMMUIdx_E10_0;
4565 }
4566
4567 if (arm_is_secure_below_el3(env)) {
4568 mmu_idx &= ~ARM_MMU_IDX_A_NS;
4569 }
4570
4571 return tlbbits_for_regime(env, mmu_idx, addr);
4572}
4573
4574static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4575 uint64_t value)
4576{
4577 CPUState *cs = env_cpu(env);
4578 int mask = vae1_tlbmask(env);
4579
4580 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask);
4581}
4582
4583static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
4584 uint64_t value)
4585{
4586 CPUState *cs = env_cpu(env);
4587 int mask = vae1_tlbmask(env);
4588
4589 if (tlb_force_broadcast(env)) {
4590 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask);
4591 } else {
4592 tlb_flush_by_mmuidx(cs, mask);
4593 }
4594}
4595
4596static int alle1_tlbmask(CPUARMState *env)
4597{
4598
4599
4600
4601
4602
4603 if (arm_is_secure_below_el3(env)) {
4604 return ARMMMUIdxBit_SE10_1 |
4605 ARMMMUIdxBit_SE10_1_PAN |
4606 ARMMMUIdxBit_SE10_0;
4607 } else {
4608 return ARMMMUIdxBit_E10_1 |
4609 ARMMMUIdxBit_E10_1_PAN |
4610 ARMMMUIdxBit_E10_0;
4611 }
4612}
4613
4614static int e2_tlbmask(CPUARMState *env)
4615{
4616 if (arm_is_secure_below_el3(env)) {
4617 return ARMMMUIdxBit_SE20_0 |
4618 ARMMMUIdxBit_SE20_2 |
4619 ARMMMUIdxBit_SE20_2_PAN |
4620 ARMMMUIdxBit_SE2;
4621 } else {
4622 return ARMMMUIdxBit_E20_0 |
4623 ARMMMUIdxBit_E20_2 |
4624 ARMMMUIdxBit_E20_2_PAN |
4625 ARMMMUIdxBit_E2;
4626 }
4627}
4628
4629static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
4630 uint64_t value)
4631{
4632 CPUState *cs = env_cpu(env);
4633 int mask = alle1_tlbmask(env);
4634
4635 tlb_flush_by_mmuidx(cs, mask);
4636}
4637
4638static void tlbi_aa64_alle2_write(CPUARMState *env, const ARMCPRegInfo *ri,
4639 uint64_t value)
4640{
4641 CPUState *cs = env_cpu(env);
4642 int mask = e2_tlbmask(env);
4643
4644 tlb_flush_by_mmuidx(cs, mask);
4645}
4646
4647static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri,
4648 uint64_t value)
4649{
4650 ARMCPU *cpu = env_archcpu(env);
4651 CPUState *cs = CPU(cpu);
4652
4653 tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_SE3);
4654}
4655
4656static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4657 uint64_t value)
4658{
4659 CPUState *cs = env_cpu(env);
4660 int mask = alle1_tlbmask(env);
4661
4662 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask);
4663}
4664
4665static void tlbi_aa64_alle2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4666 uint64_t value)
4667{
4668 CPUState *cs = env_cpu(env);
4669 int mask = e2_tlbmask(env);
4670
4671 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask);
4672}
4673
4674static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4675 uint64_t value)
4676{
4677 CPUState *cs = env_cpu(env);
4678
4679 tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_SE3);
4680}
4681
4682static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
4683 uint64_t value)
4684{
4685
4686
4687
4688
4689 CPUState *cs = env_cpu(env);
4690 int mask = e2_tlbmask(env);
4691 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4692
4693 tlb_flush_page_by_mmuidx(cs, pageaddr, mask);
4694}
4695
4696static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
4697 uint64_t value)
4698{
4699
4700
4701
4702
4703 ARMCPU *cpu = env_archcpu(env);
4704 CPUState *cs = CPU(cpu);
4705 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4706
4707 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_SE3);
4708}
4709
4710static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4711 uint64_t value)
4712{
4713 CPUState *cs = env_cpu(env);
4714 int mask = vae1_tlbmask(env);
4715 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4716 int bits = vae1_tlbbits(env, pageaddr);
4717
4718 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
4719}
4720
4721static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
4722 uint64_t value)
4723{
4724
4725
4726
4727
4728
4729 CPUState *cs = env_cpu(env);
4730 int mask = vae1_tlbmask(env);
4731 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4732 int bits = vae1_tlbbits(env, pageaddr);
4733
4734 if (tlb_force_broadcast(env)) {
4735 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
4736 } else {
4737 tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits);
4738 }
4739}
4740
4741static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4742 uint64_t value)
4743{
4744 CPUState *cs = env_cpu(env);
4745 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4746 bool secure = arm_is_secure_below_el3(env);
4747 int mask = secure ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2;
4748 int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2,
4749 pageaddr);
4750
4751 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
4752}
4753
4754static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4755 uint64_t value)
4756{
4757 CPUState *cs = env_cpu(env);
4758 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4759 int bits = tlbbits_for_regime(env, ARMMMUIdx_SE3, pageaddr);
4760
4761 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
4762 ARMMMUIdxBit_SE3, bits);
4763}
4764
4765#ifdef TARGET_AARCH64
4766static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
4767 uint64_t value)
4768{
4769 unsigned int page_shift;
4770 unsigned int page_size_granule;
4771 uint64_t num;
4772 uint64_t scale;
4773 uint64_t exponent;
4774 uint64_t length;
4775
4776 num = extract64(value, 39, 4);
4777 scale = extract64(value, 44, 2);
4778 page_size_granule = extract64(value, 46, 2);
4779
4780 page_shift = page_size_granule * 2 + 12;
4781
4782 if (page_size_granule == 0) {
4783 qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
4784 page_size_granule);
4785 return 0;
4786 }
4787
4788 exponent = (5 * scale) + 1;
4789 length = (num + 1) << (exponent + page_shift);
4790
4791 return length;
4792}
4793
4794static uint64_t tlbi_aa64_range_get_base(CPUARMState *env, uint64_t value,
4795 bool two_ranges)
4796{
4797
4798 uint64_t pageaddr;
4799
4800 if (two_ranges) {
4801 pageaddr = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
4802 } else {
4803 pageaddr = extract64(value, 0, 37) << TARGET_PAGE_BITS;
4804 }
4805
4806 return pageaddr;
4807}
4808
4809static void do_rvae_write(CPUARMState *env, uint64_t value,
4810 int idxmap, bool synced)
4811{
4812 ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
4813 bool two_ranges = regime_has_2_ranges(one_idx);
4814 uint64_t baseaddr, length;
4815 int bits;
4816
4817 baseaddr = tlbi_aa64_range_get_base(env, value, two_ranges);
4818 length = tlbi_aa64_range_get_length(env, value);
4819 bits = tlbbits_for_regime(env, one_idx, baseaddr);
4820
4821 if (synced) {
4822 tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env),
4823 baseaddr,
4824 length,
4825 idxmap,
4826 bits);
4827 } else {
4828 tlb_flush_range_by_mmuidx(env_cpu(env), baseaddr,
4829 length, idxmap, bits);
4830 }
4831}
4832
4833static void tlbi_aa64_rvae1_write(CPUARMState *env,
4834 const ARMCPRegInfo *ri,
4835 uint64_t value)
4836{
4837
4838
4839
4840
4841
4842
4843
4844 do_rvae_write(env, value, vae1_tlbmask(env),
4845 tlb_force_broadcast(env));
4846}
4847
4848static void tlbi_aa64_rvae1is_write(CPUARMState *env,
4849 const ARMCPRegInfo *ri,
4850 uint64_t value)
4851{
4852
4853
4854
4855
4856
4857
4858
4859
4860 do_rvae_write(env, value, vae1_tlbmask(env), true);
4861}
4862
4863static int vae2_tlbmask(CPUARMState *env)
4864{
4865 return (arm_is_secure_below_el3(env)
4866 ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2);
4867}
4868
4869static void tlbi_aa64_rvae2_write(CPUARMState *env,
4870 const ARMCPRegInfo *ri,
4871 uint64_t value)
4872{
4873
4874
4875
4876
4877
4878
4879
4880 do_rvae_write(env, value, vae2_tlbmask(env),
4881 tlb_force_broadcast(env));
4882
4883
4884}
4885
4886static void tlbi_aa64_rvae2is_write(CPUARMState *env,
4887 const ARMCPRegInfo *ri,
4888 uint64_t value)
4889{
4890
4891
4892
4893
4894
4895
4896
4897 do_rvae_write(env, value, vae2_tlbmask(env), true);
4898
4899}
4900
4901static void tlbi_aa64_rvae3_write(CPUARMState *env,
4902 const ARMCPRegInfo *ri,
4903 uint64_t value)
4904{
4905
4906
4907
4908
4909
4910
4911
4912 do_rvae_write(env, value, ARMMMUIdxBit_SE3,
4913 tlb_force_broadcast(env));
4914}
4915
4916static void tlbi_aa64_rvae3is_write(CPUARMState *env,
4917 const ARMCPRegInfo *ri,
4918 uint64_t value)
4919{
4920
4921
4922
4923
4924
4925
4926
4927 do_rvae_write(env, value, ARMMMUIdxBit_SE3, true);
4928}
4929#endif
4930
4931static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
4932 bool isread)
4933{
4934 int cur_el = arm_current_el(env);
4935
4936 if (cur_el < 2) {
4937 uint64_t hcr = arm_hcr_el2_eff(env);
4938
4939 if (cur_el == 0) {
4940 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
4941 if (!(env->cp15.sctlr_el[2] & SCTLR_DZE)) {
4942 return CP_ACCESS_TRAP_EL2;
4943 }
4944 } else {
4945 if (!(env->cp15.sctlr_el[1] & SCTLR_DZE)) {
4946 return CP_ACCESS_TRAP;
4947 }
4948 if (hcr & HCR_TDZ) {
4949 return CP_ACCESS_TRAP_EL2;
4950 }
4951 }
4952 } else if (hcr & HCR_TDZ) {
4953 return CP_ACCESS_TRAP_EL2;
4954 }
4955 }
4956 return CP_ACCESS_OK;
4957}
4958
4959static uint64_t aa64_dczid_read(CPUARMState *env, const ARMCPRegInfo *ri)
4960{
4961 ARMCPU *cpu = env_archcpu(env);
4962 int dzp_bit = 1 << 4;
4963
4964
4965 if (aa64_zva_access(env, NULL, false) == CP_ACCESS_OK) {
4966 dzp_bit = 0;
4967 }
4968 return cpu->dcz_blocksize | dzp_bit;
4969}
4970
4971static CPAccessResult sp_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
4972 bool isread)
4973{
4974 if (!(env->pstate & PSTATE_SP)) {
4975
4976
4977
4978 return CP_ACCESS_TRAP_UNCATEGORIZED;
4979 }
4980 return CP_ACCESS_OK;
4981}
4982
4983static uint64_t spsel_read(CPUARMState *env, const ARMCPRegInfo *ri)
4984{
4985 return env->pstate & PSTATE_SP;
4986}
4987
4988static void spsel_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
4989{
4990 update_spsel(env, val);
4991}
4992
4993static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
4994 uint64_t value)
4995{
4996 ARMCPU *cpu = env_archcpu(env);
4997
4998 if (arm_feature(env, ARM_FEATURE_PMSA) && !cpu->has_mpu) {
4999
5000 value &= ~SCTLR_M;
5001 }
5002
5003
5004
5005 if (ri->state == ARM_CP_STATE_AA64 && !cpu_isar_feature(aa64_mte, cpu)) {
5006 if (ri->opc1 == 6) {
5007 value &= ~(SCTLR_ITFSB | SCTLR_TCF | SCTLR_ATA);
5008 } else {
5009 value &= ~(SCTLR_ITFSB | SCTLR_TCF0 | SCTLR_TCF |
5010 SCTLR_ATA0 | SCTLR_ATA);
5011 }
5012 }
5013
5014 if (raw_read(env, ri) == value) {
5015
5016
5017
5018 return;
5019 }
5020
5021 raw_write(env, ri, value);
5022
5023
5024 tlb_flush(CPU(cpu));
5025
5026 if (ri->type & ARM_CP_SUPPRESS_TB_END) {
5027
5028
5029
5030
5031
5032
5033 arm_rebuild_hflags(env);
5034 }
5035}
5036
5037static CPAccessResult fpexc32_access(CPUARMState *env, const ARMCPRegInfo *ri,
5038 bool isread)
5039{
5040 if ((env->cp15.cptr_el[2] & CPTR_TFP) && arm_current_el(env) == 2) {
5041 return CP_ACCESS_TRAP_FP_EL2;
5042 }
5043 if (env->cp15.cptr_el[3] & CPTR_TFP) {
5044 return CP_ACCESS_TRAP_FP_EL3;
5045 }
5046 return CP_ACCESS_OK;
5047}
5048
5049static void sdcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
5050 uint64_t value)
5051{
5052 env->cp15.mdcr_el3 = value & SDCR_VALID_MASK;
5053}
5054
5055static const ARMCPRegInfo v8_cp_reginfo[] = {
5056
5057
5058
5059 { .name = "NZCV", .state = ARM_CP_STATE_AA64,
5060 .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 2,
5061 .access = PL0_RW, .type = ARM_CP_NZCV },
5062 { .name = "DAIF", .state = ARM_CP_STATE_AA64,
5063 .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 2,
5064 .type = ARM_CP_NO_RAW,
5065 .access = PL0_RW, .accessfn = aa64_daif_access,
5066 .fieldoffset = offsetof(CPUARMState, daif),
5067 .writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore },
5068 { .name = "FPCR", .state = ARM_CP_STATE_AA64,
5069 .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
5070 .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
5071 .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
5072 { .name = "FPSR", .state = ARM_CP_STATE_AA64,
5073 .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
5074 .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
5075 .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
5076 { .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64,
5077 .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
5078 .access = PL0_R, .type = ARM_CP_NO_RAW,
5079 .readfn = aa64_dczid_read },
5080 { .name = "DC_ZVA", .state = ARM_CP_STATE_AA64,
5081 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 1,
5082 .access = PL0_W, .type = ARM_CP_DC_ZVA,
5083#ifndef CONFIG_USER_ONLY
5084
5085 .accessfn = aa64_zva_access,
5086#endif
5087 },
5088 { .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
5089 .opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2,
5090 .access = PL1_R, .type = ARM_CP_CURRENTEL },
5091
5092 { .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
5093 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
5094 .access = PL1_W, .type = ARM_CP_NOP,
5095 .accessfn = aa64_cacheop_pou_access },
5096 { .name = "IC_IALLU", .state = ARM_CP_STATE_AA64,
5097 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
5098 .access = PL1_W, .type = ARM_CP_NOP,
5099 .accessfn = aa64_cacheop_pou_access },
5100 { .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
5101 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
5102 .access = PL0_W, .type = ARM_CP_NOP,
5103 .accessfn = aa64_cacheop_pou_access },
5104 { .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
5105 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
5106 .access = PL1_W, .accessfn = aa64_cacheop_poc_access,
5107 .type = ARM_CP_NOP },
5108 { .name = "DC_ISW", .state = ARM_CP_STATE_AA64,
5109 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
5110 .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
5111 { .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
5112 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
5113 .access = PL0_W, .type = ARM_CP_NOP,
5114 .accessfn = aa64_cacheop_poc_access },
5115 { .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
5116 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
5117 .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
5118 { .name = "DC_CVAU", .state = ARM_CP_STATE_AA64,
5119 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1,
5120 .access = PL0_W, .type = ARM_CP_NOP,
5121 .accessfn = aa64_cacheop_pou_access },
5122 { .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64,
5123 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1,
5124 .access = PL0_W, .type = ARM_CP_NOP,
5125 .accessfn = aa64_cacheop_poc_access },
5126 { .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
5127 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
5128 .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
5129
5130 { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
5131 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
5132 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5133 .writefn = tlbi_aa64_vmalle1is_write },
5134 { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64,
5135 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
5136 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5137 .writefn = tlbi_aa64_vae1is_write },
5138 { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64,
5139 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
5140 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5141 .writefn = tlbi_aa64_vmalle1is_write },
5142 { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64,
5143 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
5144 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5145 .writefn = tlbi_aa64_vae1is_write },
5146 { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64,
5147 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
5148 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5149 .writefn = tlbi_aa64_vae1is_write },
5150 { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64,
5151 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
5152 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5153 .writefn = tlbi_aa64_vae1is_write },
5154 { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64,
5155 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
5156 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5157 .writefn = tlbi_aa64_vmalle1_write },
5158 { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64,
5159 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
5160 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5161 .writefn = tlbi_aa64_vae1_write },
5162 { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64,
5163 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
5164 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5165 .writefn = tlbi_aa64_vmalle1_write },
5166 { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64,
5167 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
5168 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5169 .writefn = tlbi_aa64_vae1_write },
5170 { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64,
5171 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
5172 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5173 .writefn = tlbi_aa64_vae1_write },
5174 { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64,
5175 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
5176 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5177 .writefn = tlbi_aa64_vae1_write },
5178 { .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
5179 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
5180 .access = PL2_W, .type = ARM_CP_NOP },
5181 { .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
5182 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
5183 .access = PL2_W, .type = ARM_CP_NOP },
5184 { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
5185 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
5186 .access = PL2_W, .type = ARM_CP_NO_RAW,
5187 .writefn = tlbi_aa64_alle1is_write },
5188 { .name = "TLBI_VMALLS12E1IS", .state = ARM_CP_STATE_AA64,
5189 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 6,
5190 .access = PL2_W, .type = ARM_CP_NO_RAW,
5191 .writefn = tlbi_aa64_alle1is_write },
5192 { .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
5193 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
5194 .access = PL2_W, .type = ARM_CP_NOP },
5195 { .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
5196 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
5197 .access = PL2_W, .type = ARM_CP_NOP },
5198 { .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
5199 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
5200 .access = PL2_W, .type = ARM_CP_NO_RAW,
5201 .writefn = tlbi_aa64_alle1_write },
5202 { .name = "TLBI_VMALLS12E1", .state = ARM_CP_STATE_AA64,
5203 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 6,
5204 .access = PL2_W, .type = ARM_CP_NO_RAW,
5205 .writefn = tlbi_aa64_alle1is_write },
5206#ifndef CONFIG_USER_ONLY
5207
5208 { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64,
5209 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0,
5210 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5211 .writefn = ats_write64 },
5212 { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
5213 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1,
5214 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5215 .writefn = ats_write64 },
5216 { .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64,
5217 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2,
5218 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5219 .writefn = ats_write64 },
5220 { .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64,
5221 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3,
5222 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5223 .writefn = ats_write64 },
5224 { .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64,
5225 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4,
5226 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5227 .writefn = ats_write64 },
5228 { .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64,
5229 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5,
5230 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5231 .writefn = ats_write64 },
5232 { .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64,
5233 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6,
5234 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5235 .writefn = ats_write64 },
5236 { .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64,
5237 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7,
5238 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5239 .writefn = ats_write64 },
5240
5241 { .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64,
5242 .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0,
5243 .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5244 .writefn = ats_write64 },
5245 { .name = "AT_S1E3W", .state = ARM_CP_STATE_AA64,
5246 .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 1,
5247 .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5248 .writefn = ats_write64 },
5249 { .name = "PAR_EL1", .state = ARM_CP_STATE_AA64,
5250 .type = ARM_CP_ALIAS,
5251 .opc0 = 3, .opc1 = 0, .crn = 7, .crm = 4, .opc2 = 0,
5252 .access = PL1_RW, .resetvalue = 0,
5253 .fieldoffset = offsetof(CPUARMState, cp15.par_el[1]),
5254 .writefn = par_write },
5255#endif
5256
5257 { .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
5258 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
5259 .writefn = tlbimva_is_write },
5260 { .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
5261 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
5262 .writefn = tlbimvaa_is_write },
5263 { .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
5264 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
5265 .writefn = tlbimva_write },
5266 { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
5267 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
5268 .writefn = tlbimvaa_write },
5269 { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
5270 .type = ARM_CP_NO_RAW, .access = PL2_W,
5271 .writefn = tlbimva_hyp_write },
5272 { .name = "TLBIMVALHIS",
5273 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
5274 .type = ARM_CP_NO_RAW, .access = PL2_W,
5275 .writefn = tlbimva_hyp_is_write },
5276 { .name = "TLBIIPAS2",
5277 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
5278 .type = ARM_CP_NOP, .access = PL2_W },
5279 { .name = "TLBIIPAS2IS",
5280 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
5281 .type = ARM_CP_NOP, .access = PL2_W },
5282 { .name = "TLBIIPAS2L",
5283 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
5284 .type = ARM_CP_NOP, .access = PL2_W },
5285 { .name = "TLBIIPAS2LIS",
5286 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
5287 .type = ARM_CP_NOP, .access = PL2_W },
5288
5289 { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
5290 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
5291 { .name = "BPIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 6,
5292 .type = ARM_CP_NOP, .access = PL1_W },
5293 { .name = "ICIALLU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
5294 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
5295 { .name = "ICIMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 1,
5296 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
5297 { .name = "BPIALL", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 6,
5298 .type = ARM_CP_NOP, .access = PL1_W },
5299 { .name = "BPIMVA", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 7,
5300 .type = ARM_CP_NOP, .access = PL1_W },
5301 { .name = "DCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
5302 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
5303 { .name = "DCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
5304 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
5305 { .name = "DCCMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 1,
5306 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
5307 { .name = "DCCSW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
5308 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
5309 { .name = "DCCMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 11, .opc2 = 1,
5310 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
5311 { .name = "DCCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 1,
5312 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
5313 { .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
5314 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
5315
5316 { .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0,
5317 .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
5318 .writefn = dacr_write, .raw_writefn = raw_write,
5319 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
5320 offsetoflow32(CPUARMState, cp15.dacr_ns) } },
5321 { .name = "ELR_EL1", .state = ARM_CP_STATE_AA64,
5322 .type = ARM_CP_ALIAS,
5323 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1,
5324 .access = PL1_RW,
5325 .fieldoffset = offsetof(CPUARMState, elr_el[1]) },
5326 { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
5327 .type = ARM_CP_ALIAS,
5328 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
5329 .access = PL1_RW,
5330 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
5331
5332
5333
5334
5335 { .name = "SP_EL0", .state = ARM_CP_STATE_AA64,
5336 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 1, .opc2 = 0,
5337 .access = PL1_RW, .accessfn = sp_el0_access,
5338 .type = ARM_CP_ALIAS,
5339 .fieldoffset = offsetof(CPUARMState, sp_el[0]) },
5340 { .name = "SP_EL1", .state = ARM_CP_STATE_AA64,
5341 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 1, .opc2 = 0,
5342 .access = PL2_RW, .type = ARM_CP_ALIAS,
5343 .fieldoffset = offsetof(CPUARMState, sp_el[1]) },
5344 { .name = "SPSel", .state = ARM_CP_STATE_AA64,
5345 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 0,
5346 .type = ARM_CP_NO_RAW,
5347 .access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
5348 { .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64,
5349 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0,
5350 .type = ARM_CP_ALIAS,
5351 .fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]),
5352 .access = PL2_RW, .accessfn = fpexc32_access },
5353 { .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
5354 .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
5355 .access = PL2_RW, .resetvalue = 0,
5356 .writefn = dacr_write, .raw_writefn = raw_write,
5357 .fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
5358 { .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
5359 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
5360 .access = PL2_RW, .resetvalue = 0,
5361 .fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
5362 { .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
5363 .type = ARM_CP_ALIAS,
5364 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0,
5365 .access = PL2_RW,
5366 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_IRQ]) },
5367 { .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64,
5368 .type = ARM_CP_ALIAS,
5369 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1,
5370 .access = PL2_RW,
5371 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_ABT]) },
5372 { .name = "SPSR_UND", .state = ARM_CP_STATE_AA64,
5373 .type = ARM_CP_ALIAS,
5374 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2,
5375 .access = PL2_RW,
5376 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_UND]) },
5377 { .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64,
5378 .type = ARM_CP_ALIAS,
5379 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3,
5380 .access = PL2_RW,
5381 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) },
5382 { .name = "MDCR_EL3", .state = ARM_CP_STATE_AA64,
5383 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 3, .opc2 = 1,
5384 .resetvalue = 0,
5385 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el3) },
5386 { .name = "SDCR", .type = ARM_CP_ALIAS,
5387 .cp = 15, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 1,
5388 .access = PL1_RW, .accessfn = access_trap_aa32s_el1,
5389 .writefn = sdcr_write,
5390 .fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) },
5391 REGINFO_SENTINEL
5392};
5393
5394
5395static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
5396 { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
5397 .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
5398 .access = PL2_RW,
5399 .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
5400 { .name = "HCR_EL2", .state = ARM_CP_STATE_BOTH,
5401 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
5402 .access = PL2_RW,
5403 .type = ARM_CP_CONST, .resetvalue = 0 },
5404 { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
5405 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
5406 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5407 { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
5408 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
5409 .access = PL2_RW,
5410 .type = ARM_CP_CONST, .resetvalue = 0 },
5411 { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
5412 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
5413 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5414 { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH,
5415 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0,
5416 .access = PL2_RW, .type = ARM_CP_CONST,
5417 .resetvalue = 0 },
5418 { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
5419 .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
5420 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5421 { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
5422 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
5423 .access = PL2_RW, .type = ARM_CP_CONST,
5424 .resetvalue = 0 },
5425 { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
5426 .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
5427 .access = PL2_RW, .type = ARM_CP_CONST,
5428 .resetvalue = 0 },
5429 { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
5430 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0,
5431 .access = PL2_RW, .type = ARM_CP_CONST,
5432 .resetvalue = 0 },
5433 { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH,
5434 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1,
5435 .access = PL2_RW, .type = ARM_CP_CONST,
5436 .resetvalue = 0 },
5437 { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
5438 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
5439 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5440 { .name = "VTCR_EL2", .state = ARM_CP_STATE_BOTH,
5441 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
5442 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5443 .type = ARM_CP_CONST, .resetvalue = 0 },
5444 { .name = "VTTBR", .state = ARM_CP_STATE_AA32,
5445 .cp = 15, .opc1 = 6, .crm = 2,
5446 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5447 .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
5448 { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
5449 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
5450 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5451 { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
5452 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
5453 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5454 { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
5455 .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
5456 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5457 { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
5458 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
5459 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5460 { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
5461 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
5462 .resetvalue = 0 },
5463 { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
5464 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
5465 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5466 { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64,
5467 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
5468 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5469 { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14,
5470 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
5471 .resetvalue = 0 },
5472 { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64,
5473 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2,
5474 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5475 { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14,
5476 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
5477 .resetvalue = 0 },
5478 { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH,
5479 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0,
5480 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5481 { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH,
5482 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1,
5483 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5484 { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
5485 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
5486 .access = PL2_RW, .accessfn = access_tda,
5487 .type = ARM_CP_CONST, .resetvalue = 0 },
5488 { .name = "HPFAR_EL2", .state = ARM_CP_STATE_BOTH,
5489 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
5490 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5491 .type = ARM_CP_CONST, .resetvalue = 0 },
5492 { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
5493 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
5494 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5495 { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
5496 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
5497 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5498 { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
5499 .type = ARM_CP_CONST,
5500 .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
5501 .access = PL2_RW, .resetvalue = 0 },
5502 REGINFO_SENTINEL
5503};
5504
5505
5506static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
5507 { .name = "HCR2", .state = ARM_CP_STATE_AA32,
5508 .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
5509 .access = PL2_RW,
5510 .type = ARM_CP_CONST, .resetvalue = 0 },
5511 REGINFO_SENTINEL
5512};
5513
5514static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
5515{
5516 ARMCPU *cpu = env_archcpu(env);
5517
5518 if (arm_feature(env, ARM_FEATURE_V8)) {
5519 valid_mask |= MAKE_64BIT_MASK(0, 34);
5520 } else {
5521 valid_mask |= MAKE_64BIT_MASK(0, 28);
5522 }
5523
5524 if (arm_feature(env, ARM_FEATURE_EL3)) {
5525 valid_mask &= ~HCR_HCD;
5526 } else if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
5527
5528
5529
5530
5531
5532
5533
5534 valid_mask &= ~HCR_TSC;
5535 }
5536
5537 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
5538 if (cpu_isar_feature(aa64_vh, cpu)) {
5539 valid_mask |= HCR_E2H;
5540 }
5541 if (cpu_isar_feature(aa64_lor, cpu)) {
5542 valid_mask |= HCR_TLOR;
5543 }
5544 if (cpu_isar_feature(aa64_pauth, cpu)) {
5545 valid_mask |= HCR_API | HCR_APK;
5546 }
5547 if (cpu_isar_feature(aa64_mte, cpu)) {
5548 valid_mask |= HCR_ATA | HCR_DCT | HCR_TID5;
5549 }
5550 }
5551
5552
5553 value &= valid_mask;
5554
5555
5556
5557
5558
5559
5560
5561
5562 if ((env->cp15.hcr_el2 ^ value) & (HCR_VM | HCR_PTW | HCR_DC | HCR_DCT)) {
5563 tlb_flush(CPU(cpu));
5564 }
5565 env->cp15.hcr_el2 = value;
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578 g_assert(qemu_mutex_iothread_locked());
5579 arm_cpu_update_virq(cpu);
5580 arm_cpu_update_vfiq(cpu);
5581}
5582
5583static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
5584{
5585 do_hcr_write(env, value, 0);
5586}
5587
5588static void hcr_writehigh(CPUARMState *env, const ARMCPRegInfo *ri,
5589 uint64_t value)
5590{
5591
5592 value = deposit64(env->cp15.hcr_el2, 32, 32, value);
5593 do_hcr_write(env, value, MAKE_64BIT_MASK(0, 32));
5594}
5595
5596static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
5597 uint64_t value)
5598{
5599
5600 value = deposit64(env->cp15.hcr_el2, 0, 32, value);
5601 do_hcr_write(env, value, MAKE_64BIT_MASK(32, 32));
5602}
5603
5604
5605
5606
5607
5608
5609uint64_t arm_hcr_el2_eff(CPUARMState *env)
5610{
5611 uint64_t ret = env->cp15.hcr_el2;
5612
5613 if (!arm_is_el2_enabled(env)) {
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629 return 0;
5630 }
5631
5632
5633
5634
5635
5636
5637 if (!arm_el_is_aa64(env, 2)) {
5638 uint64_t aa32_valid;
5639
5640
5641
5642
5643
5644
5645 aa32_valid = MAKE_64BIT_MASK(0, 32) & ~(HCR_RW | HCR_TDZ);
5646 aa32_valid |= (HCR_CD | HCR_ID | HCR_TERR | HCR_TEA | HCR_MIOCNCE |
5647 HCR_TID4 | HCR_TICAB | HCR_TOCU | HCR_TTLBIS);
5648 ret &= aa32_valid;
5649 }
5650
5651 if (ret & HCR_TGE) {
5652
5653 if (ret & HCR_E2H) {
5654 ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO |
5655 HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE |
5656 HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU |
5657 HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE |
5658 HCR_TID4 | HCR_TICAB | HCR_TOCU | HCR_ENSCXT |
5659 HCR_TTLBIS | HCR_TTLBOS | HCR_TID5);
5660 } else {
5661 ret |= HCR_FMO | HCR_IMO | HCR_AMO;
5662 }
5663 ret &= ~(HCR_SWIO | HCR_PTW | HCR_VF | HCR_VI | HCR_VSE |
5664 HCR_FB | HCR_TID1 | HCR_TID3 | HCR_TSC | HCR_TACR |
5665 HCR_TSW | HCR_TTLB | HCR_TVM | HCR_HCD | HCR_TRVM |
5666 HCR_TLOR);
5667 }
5668
5669 return ret;
5670}
5671
5672static void cptr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
5673 uint64_t value)
5674{
5675
5676
5677
5678
5679 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
5680 !arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
5681 value &= ~(0x3 << 10);
5682 value |= env->cp15.cptr_el[2] & (0x3 << 10);
5683 }
5684 env->cp15.cptr_el[2] = value;
5685}
5686
5687static uint64_t cptr_el2_read(CPUARMState *env, const ARMCPRegInfo *ri)
5688{
5689
5690
5691
5692
5693 uint64_t value = env->cp15.cptr_el[2];
5694
5695 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
5696 !arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
5697 value |= 0x3 << 10;
5698 }
5699 return value;
5700}
5701
5702static const ARMCPRegInfo el2_cp_reginfo[] = {
5703 { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
5704 .type = ARM_CP_IO,
5705 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
5706 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
5707 .writefn = hcr_write },
5708 { .name = "HCR", .state = ARM_CP_STATE_AA32,
5709 .type = ARM_CP_ALIAS | ARM_CP_IO,
5710 .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
5711 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
5712 .writefn = hcr_writelow },
5713 { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
5714 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
5715 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5716 { .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
5717 .type = ARM_CP_ALIAS,
5718 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
5719 .access = PL2_RW,
5720 .fieldoffset = offsetof(CPUARMState, elr_el[2]) },
5721 { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
5722 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
5723 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
5724 { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
5725 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
5726 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) },
5727 { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
5728 .type = ARM_CP_ALIAS,
5729 .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
5730 .access = PL2_RW,
5731 .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[2]) },
5732 { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
5733 .type = ARM_CP_ALIAS,
5734 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
5735 .access = PL2_RW,
5736 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
5737 { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
5738 .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
5739 .access = PL2_RW, .writefn = vbar_write,
5740 .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]),
5741 .resetvalue = 0 },
5742 { .name = "SP_EL2", .state = ARM_CP_STATE_AA64,
5743 .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 1, .opc2 = 0,
5744 .access = PL3_RW, .type = ARM_CP_ALIAS,
5745 .fieldoffset = offsetof(CPUARMState, sp_el[2]) },
5746 { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
5747 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
5748 .access = PL2_RW, .accessfn = cptr_access, .resetvalue = 0,
5749 .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[2]),
5750 .readfn = cptr_el2_read, .writefn = cptr_el2_write },
5751 { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH,
5752 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0,
5753 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[2]),
5754 .resetvalue = 0 },
5755 { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
5756 .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
5757 .access = PL2_RW, .type = ARM_CP_ALIAS,
5758 .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el[2]) },
5759 { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
5760 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
5761 .access = PL2_RW, .type = ARM_CP_CONST,
5762 .resetvalue = 0 },
5763
5764 { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
5765 .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
5766 .access = PL2_RW, .type = ARM_CP_CONST,
5767 .resetvalue = 0 },
5768 { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
5769 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0,
5770 .access = PL2_RW, .type = ARM_CP_CONST,
5771 .resetvalue = 0 },
5772 { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH,
5773 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1,
5774 .access = PL2_RW, .type = ARM_CP_CONST,
5775 .resetvalue = 0 },
5776 { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
5777 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
5778 .access = PL2_RW, .writefn = vmsa_tcr_el12_write,
5779
5780 .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) },
5781 { .name = "VTCR", .state = ARM_CP_STATE_AA32,
5782 .cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
5783 .type = ARM_CP_ALIAS,
5784 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5785 .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) },
5786 { .name = "VTCR_EL2", .state = ARM_CP_STATE_AA64,
5787 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
5788 .access = PL2_RW,
5789
5790
5791
5792 .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) },
5793 { .name = "VTTBR", .state = ARM_CP_STATE_AA32,
5794 .cp = 15, .opc1 = 6, .crm = 2,
5795 .type = ARM_CP_64BIT | ARM_CP_ALIAS,
5796 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5797 .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2),
5798 .writefn = vttbr_write },
5799 { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
5800 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
5801 .access = PL2_RW, .writefn = vttbr_write,
5802 .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) },
5803 { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
5804 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
5805 .access = PL2_RW, .raw_writefn = raw_write, .writefn = sctlr_write,
5806 .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[2]) },
5807 { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
5808 .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
5809 .access = PL2_RW, .resetvalue = 0,
5810 .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) },
5811 { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
5812 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
5813 .access = PL2_RW, .resetvalue = 0, .writefn = vmsa_tcr_ttbr_el2_write,
5814 .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
5815 { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
5816 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
5817 .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
5818 { .name = "TLBIALLNSNH",
5819 .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
5820 .type = ARM_CP_NO_RAW, .access = PL2_W,
5821 .writefn = tlbiall_nsnh_write },
5822 { .name = "TLBIALLNSNHIS",
5823 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
5824 .type = ARM_CP_NO_RAW, .access = PL2_W,
5825 .writefn = tlbiall_nsnh_is_write },
5826 { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
5827 .type = ARM_CP_NO_RAW, .access = PL2_W,
5828 .writefn = tlbiall_hyp_write },
5829 { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0,
5830 .type = ARM_CP_NO_RAW, .access = PL2_W,
5831 .writefn = tlbiall_hyp_is_write },
5832 { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
5833 .type = ARM_CP_NO_RAW, .access = PL2_W,
5834 .writefn = tlbimva_hyp_write },
5835 { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
5836 .type = ARM_CP_NO_RAW, .access = PL2_W,
5837 .writefn = tlbimva_hyp_is_write },
5838 { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
5839 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
5840 .type = ARM_CP_NO_RAW, .access = PL2_W,
5841 .writefn = tlbi_aa64_alle2_write },
5842 { .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64,
5843 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
5844 .type = ARM_CP_NO_RAW, .access = PL2_W,
5845 .writefn = tlbi_aa64_vae2_write },
5846 { .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64,
5847 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
5848 .access = PL2_W, .type = ARM_CP_NO_RAW,
5849 .writefn = tlbi_aa64_vae2_write },
5850 { .name = "TLBI_ALLE2IS", .state = ARM_CP_STATE_AA64,
5851 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0,
5852 .access = PL2_W, .type = ARM_CP_NO_RAW,
5853 .writefn = tlbi_aa64_alle2is_write },
5854 { .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64,
5855 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
5856 .type = ARM_CP_NO_RAW, .access = PL2_W,
5857 .writefn = tlbi_aa64_vae2is_write },
5858 { .name = "TLBI_VALE2IS", .state = ARM_CP_STATE_AA64,
5859 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
5860 .access = PL2_W, .type = ARM_CP_NO_RAW,
5861 .writefn = tlbi_aa64_vae2is_write },
5862#ifndef CONFIG_USER_ONLY
5863
5864
5865
5866
5867 { .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64,
5868 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
5869 .access = PL2_W, .accessfn = at_s1e2_access,
5870 .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
5871 { .name = "AT_S1E2W", .state = ARM_CP_STATE_AA64,
5872 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
5873 .access = PL2_W, .accessfn = at_s1e2_access,
5874 .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
5875
5876
5877
5878
5879
5880 { .name = "ATS1HR", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
5881 .access = PL2_W,
5882 .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
5883 { .name = "ATS1HW", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
5884 .access = PL2_W,
5885 .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
5886 { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
5887 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
5888
5889
5890
5891
5892 .access = PL2_RW, .resetvalue = 3,
5893 .fieldoffset = offsetof(CPUARMState, cp15.cnthctl_el2) },
5894 { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64,
5895 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
5896 .access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 0,
5897 .writefn = gt_cntvoff_write,
5898 .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) },
5899 { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14,
5900 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS | ARM_CP_IO,
5901 .writefn = gt_cntvoff_write,
5902 .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) },
5903 { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64,
5904 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2,
5905 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval),
5906 .type = ARM_CP_IO, .access = PL2_RW,
5907 .writefn = gt_hyp_cval_write, .raw_writefn = raw_write },
5908 { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14,
5909 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval),
5910 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_IO,
5911 .writefn = gt_hyp_cval_write, .raw_writefn = raw_write },
5912 { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH,
5913 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0,
5914 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW,
5915 .resetfn = gt_hyp_timer_reset,
5916 .readfn = gt_hyp_tval_read, .writefn = gt_hyp_tval_write },
5917 { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH,
5918 .type = ARM_CP_IO,
5919 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1,
5920 .access = PL2_RW,
5921 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].ctl),
5922 .resetvalue = 0,
5923 .writefn = gt_hyp_ctl_write, .raw_writefn = raw_write },
5924#endif
5925
5926
5927
5928 { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
5929 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
5930 .access = PL2_RW, .resetvalue = PMCR_NUM_COUNTERS,
5931 .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), },
5932 { .name = "HPFAR", .state = ARM_CP_STATE_AA32,
5933 .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
5934 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5935 .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) },
5936 { .name = "HPFAR_EL2", .state = ARM_CP_STATE_AA64,
5937 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
5938 .access = PL2_RW,
5939 .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) },
5940 { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
5941 .cp = 15, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
5942 .access = PL2_RW,
5943 .fieldoffset = offsetof(CPUARMState, cp15.hstr_el2) },
5944 REGINFO_SENTINEL
5945};
5946
5947static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
5948 { .name = "HCR2", .state = ARM_CP_STATE_AA32,
5949 .type = ARM_CP_ALIAS | ARM_CP_IO,
5950 .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
5951 .access = PL2_RW,
5952 .fieldoffset = offsetofhigh32(CPUARMState, cp15.hcr_el2),
5953 .writefn = hcr_writehigh },
5954 REGINFO_SENTINEL
5955};
5956
5957static CPAccessResult sel2_access(CPUARMState *env, const ARMCPRegInfo *ri,
5958 bool isread)
5959{
5960 if (arm_current_el(env) == 3 || arm_is_secure_below_el3(env)) {
5961 return CP_ACCESS_OK;
5962 }
5963 return CP_ACCESS_TRAP_UNCATEGORIZED;
5964}
5965
5966static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
5967 { .name = "VSTTBR_EL2", .state = ARM_CP_STATE_AA64,
5968 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 0,
5969 .access = PL2_RW, .accessfn = sel2_access,
5970 .fieldoffset = offsetof(CPUARMState, cp15.vsttbr_el2) },
5971 { .name = "VSTCR_EL2", .state = ARM_CP_STATE_AA64,
5972 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 2,
5973 .access = PL2_RW, .accessfn = sel2_access,
5974 .fieldoffset = offsetof(CPUARMState, cp15.vstcr_el2) },
5975 REGINFO_SENTINEL
5976};
5977
5978static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
5979 bool isread)
5980{
5981
5982
5983
5984 if (arm_current_el(env) == 3) {
5985 return CP_ACCESS_OK;
5986 }
5987 if (arm_is_secure_below_el3(env)) {
5988 if (env->cp15.scr_el3 & SCR_EEL2) {
5989 return CP_ACCESS_TRAP_EL2;
5990 }
5991 return CP_ACCESS_TRAP_EL3;
5992 }
5993
5994 if (isread) {
5995 return CP_ACCESS_OK;
5996 }
5997 return CP_ACCESS_TRAP_UNCATEGORIZED;
5998}
5999
6000static const ARMCPRegInfo el3_cp_reginfo[] = {
6001 { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
6002 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
6003 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
6004 .resetfn = scr_reset, .writefn = scr_write },
6005 { .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
6006 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
6007 .access = PL1_RW, .accessfn = access_trap_aa32s_el1,
6008 .fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
6009 .writefn = scr_write },
6010 { .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64,
6011 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1,
6012 .access = PL3_RW, .resetvalue = 0,
6013 .fieldoffset = offsetof(CPUARMState, cp15.sder) },
6014 { .name = "SDER",
6015 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 1,
6016 .access = PL3_RW, .resetvalue = 0,
6017 .fieldoffset = offsetoflow32(CPUARMState, cp15.sder) },
6018 { .name = "MVBAR", .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
6019 .access = PL1_RW, .accessfn = access_trap_aa32s_el1,
6020 .writefn = vbar_write, .resetvalue = 0,
6021 .fieldoffset = offsetof(CPUARMState, cp15.mvbar) },
6022 { .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64,
6023 .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 0,
6024 .access = PL3_RW, .resetvalue = 0,
6025 .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[3]) },
6026 { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
6027 .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 2,
6028 .access = PL3_RW,
6029
6030
6031
6032
6033
6034 .resetfn = vmsa_ttbcr_reset, .raw_writefn = vmsa_ttbcr_raw_write,
6035 .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[3]) },
6036 { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
6037 .type = ARM_CP_ALIAS,
6038 .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
6039 .access = PL3_RW,
6040 .fieldoffset = offsetof(CPUARMState, elr_el[3]) },
6041 { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64,
6042 .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0,
6043 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[3]) },
6044 { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64,
6045 .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0,
6046 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[3]) },
6047 { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64,
6048 .type = ARM_CP_ALIAS,
6049 .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0,
6050 .access = PL3_RW,
6051 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_MON]) },
6052 { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
6053 .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
6054 .access = PL3_RW, .writefn = vbar_write,
6055 .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[3]),
6056 .resetvalue = 0 },
6057 { .name = "CPTR_EL3", .state = ARM_CP_STATE_AA64,
6058 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 2,
6059 .access = PL3_RW, .accessfn = cptr_access, .resetvalue = 0,
6060 .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[3]) },
6061 { .name = "TPIDR_EL3", .state = ARM_CP_STATE_AA64,
6062 .opc0 = 3, .opc1 = 6, .crn = 13, .crm = 0, .opc2 = 2,
6063 .access = PL3_RW, .resetvalue = 0,
6064 .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[3]) },
6065 { .name = "AMAIR_EL3", .state = ARM_CP_STATE_AA64,
6066 .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 3, .opc2 = 0,
6067 .access = PL3_RW, .type = ARM_CP_CONST,
6068 .resetvalue = 0 },
6069 { .name = "AFSR0_EL3", .state = ARM_CP_STATE_BOTH,
6070 .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 0,
6071 .access = PL3_RW, .type = ARM_CP_CONST,
6072 .resetvalue = 0 },
6073 { .name = "AFSR1_EL3", .state = ARM_CP_STATE_BOTH,
6074 .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 1,
6075 .access = PL3_RW, .type = ARM_CP_CONST,
6076 .resetvalue = 0 },
6077 { .name = "TLBI_ALLE3IS", .state = ARM_CP_STATE_AA64,
6078 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 0,
6079 .access = PL3_W, .type = ARM_CP_NO_RAW,
6080 .writefn = tlbi_aa64_alle3is_write },
6081 { .name = "TLBI_VAE3IS", .state = ARM_CP_STATE_AA64,
6082 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 1,
6083 .access = PL3_W, .type = ARM_CP_NO_RAW,
6084 .writefn = tlbi_aa64_vae3is_write },
6085 { .name = "TLBI_VALE3IS", .state = ARM_CP_STATE_AA64,
6086 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 5,
6087 .access = PL3_W, .type = ARM_CP_NO_RAW,
6088 .writefn = tlbi_aa64_vae3is_write },
6089 { .name = "TLBI_ALLE3", .state = ARM_CP_STATE_AA64,
6090 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 0,
6091 .access = PL3_W, .type = ARM_CP_NO_RAW,
6092 .writefn = tlbi_aa64_alle3_write },
6093 { .name = "TLBI_VAE3", .state = ARM_CP_STATE_AA64,
6094 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 1,
6095 .access = PL3_W, .type = ARM_CP_NO_RAW,
6096 .writefn = tlbi_aa64_vae3_write },
6097 { .name = "TLBI_VALE3", .state = ARM_CP_STATE_AA64,
6098 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 5,
6099 .access = PL3_W, .type = ARM_CP_NO_RAW,
6100 .writefn = tlbi_aa64_vae3_write },
6101 REGINFO_SENTINEL
6102};
6103
6104#ifndef CONFIG_USER_ONLY
6105
6106static bool redirect_for_e2h(CPUARMState *env)
6107{
6108 return arm_current_el(env) == 2 && (arm_hcr_el2_eff(env) & HCR_E2H);
6109}
6110
6111static uint64_t el2_e2h_read(CPUARMState *env, const ARMCPRegInfo *ri)
6112{
6113 CPReadFn *readfn;
6114
6115 if (redirect_for_e2h(env)) {
6116
6117 ri = ri->opaque;
6118 readfn = ri->readfn;
6119 } else {
6120 readfn = ri->orig_readfn;
6121 }
6122 if (readfn == NULL) {
6123 readfn = raw_read;
6124 }
6125 return readfn(env, ri);
6126}
6127
6128static void el2_e2h_write(CPUARMState *env, const ARMCPRegInfo *ri,
6129 uint64_t value)
6130{
6131 CPWriteFn *writefn;
6132
6133 if (redirect_for_e2h(env)) {
6134
6135 ri = ri->opaque;
6136 writefn = ri->writefn;
6137 } else {
6138 writefn = ri->orig_writefn;
6139 }
6140 if (writefn == NULL) {
6141 writefn = raw_write;
6142 }
6143 writefn(env, ri, value);
6144}
6145
6146static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
6147{
6148 struct E2HAlias {
6149 uint32_t src_key, dst_key, new_key;
6150 const char *src_name, *dst_name, *new_name;
6151 bool (*feature)(const ARMISARegisters *id);
6152 };
6153
6154#define K(op0, op1, crn, crm, op2) \
6155 ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, crn, crm, op0, op1, op2)
6156
6157 static const struct E2HAlias aliases[] = {
6158 { K(3, 0, 1, 0, 0), K(3, 4, 1, 0, 0), K(3, 5, 1, 0, 0),
6159 "SCTLR", "SCTLR_EL2", "SCTLR_EL12" },
6160 { K(3, 0, 1, 0, 2), K(3, 4, 1, 1, 2), K(3, 5, 1, 0, 2),
6161 "CPACR", "CPTR_EL2", "CPACR_EL12" },
6162 { K(3, 0, 2, 0, 0), K(3, 4, 2, 0, 0), K(3, 5, 2, 0, 0),
6163 "TTBR0_EL1", "TTBR0_EL2", "TTBR0_EL12" },
6164 { K(3, 0, 2, 0, 1), K(3, 4, 2, 0, 1), K(3, 5, 2, 0, 1),
6165 "TTBR1_EL1", "TTBR1_EL2", "TTBR1_EL12" },
6166 { K(3, 0, 2, 0, 2), K(3, 4, 2, 0, 2), K(3, 5, 2, 0, 2),
6167 "TCR_EL1", "TCR_EL2", "TCR_EL12" },
6168 { K(3, 0, 4, 0, 0), K(3, 4, 4, 0, 0), K(3, 5, 4, 0, 0),
6169 "SPSR_EL1", "SPSR_EL2", "SPSR_EL12" },
6170 { K(3, 0, 4, 0, 1), K(3, 4, 4, 0, 1), K(3, 5, 4, 0, 1),
6171 "ELR_EL1", "ELR_EL2", "ELR_EL12" },
6172 { K(3, 0, 5, 1, 0), K(3, 4, 5, 1, 0), K(3, 5, 5, 1, 0),
6173 "AFSR0_EL1", "AFSR0_EL2", "AFSR0_EL12" },
6174 { K(3, 0, 5, 1, 1), K(3, 4, 5, 1, 1), K(3, 5, 5, 1, 1),
6175 "AFSR1_EL1", "AFSR1_EL2", "AFSR1_EL12" },
6176 { K(3, 0, 5, 2, 0), K(3, 4, 5, 2, 0), K(3, 5, 5, 2, 0),
6177 "ESR_EL1", "ESR_EL2", "ESR_EL12" },
6178 { K(3, 0, 6, 0, 0), K(3, 4, 6, 0, 0), K(3, 5, 6, 0, 0),
6179 "FAR_EL1", "FAR_EL2", "FAR_EL12" },
6180 { K(3, 0, 10, 2, 0), K(3, 4, 10, 2, 0), K(3, 5, 10, 2, 0),
6181 "MAIR_EL1", "MAIR_EL2", "MAIR_EL12" },
6182 { K(3, 0, 10, 3, 0), K(3, 4, 10, 3, 0), K(3, 5, 10, 3, 0),
6183 "AMAIR0", "AMAIR_EL2", "AMAIR_EL12" },
6184 { K(3, 0, 12, 0, 0), K(3, 4, 12, 0, 0), K(3, 5, 12, 0, 0),
6185 "VBAR", "VBAR_EL2", "VBAR_EL12" },
6186 { K(3, 0, 13, 0, 1), K(3, 4, 13, 0, 1), K(3, 5, 13, 0, 1),
6187 "CONTEXTIDR_EL1", "CONTEXTIDR_EL2", "CONTEXTIDR_EL12" },
6188 { K(3, 0, 14, 1, 0), K(3, 4, 14, 1, 0), K(3, 5, 14, 1, 0),
6189 "CNTKCTL", "CNTHCTL_EL2", "CNTKCTL_EL12" },
6190
6191
6192
6193
6194
6195
6196 { K(3, 0, 1, 2, 0), K(3, 4, 1, 2, 0), K(3, 5, 1, 2, 0),
6197 "ZCR_EL1", "ZCR_EL2", "ZCR_EL12", isar_feature_aa64_sve },
6198
6199 { K(3, 0, 5, 6, 0), K(3, 4, 5, 6, 0), K(3, 5, 5, 6, 0),
6200 "TFSR_EL1", "TFSR_EL2", "TFSR_EL12", isar_feature_aa64_mte },
6201
6202
6203
6204 };
6205#undef K
6206
6207 size_t i;
6208
6209 for (i = 0; i < ARRAY_SIZE(aliases); i++) {
6210 const struct E2HAlias *a = &aliases[i];
6211 ARMCPRegInfo *src_reg, *dst_reg;
6212
6213 if (a->feature && !a->feature(&cpu->isar)) {
6214 continue;
6215 }
6216
6217 src_reg = g_hash_table_lookup(cpu->cp_regs, &a->src_key);
6218 dst_reg = g_hash_table_lookup(cpu->cp_regs, &a->dst_key);
6219 g_assert(src_reg != NULL);
6220 g_assert(dst_reg != NULL);
6221
6222
6223 g_assert(strcmp(src_reg->name, a->src_name) == 0);
6224 g_assert(strcmp(dst_reg->name, a->dst_name) == 0);
6225
6226
6227 g_assert(src_reg->opaque == NULL);
6228
6229
6230 if (a->new_key) {
6231 ARMCPRegInfo *new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
6232 uint32_t *new_key = g_memdup(&a->new_key, sizeof(uint32_t));
6233 bool ok;
6234
6235 new_reg->name = a->new_name;
6236 new_reg->type |= ARM_CP_ALIAS;
6237
6238 new_reg->access &= PL2_RW | PL3_RW;
6239
6240 ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg);
6241 g_assert(ok);
6242 }
6243
6244 src_reg->opaque = dst_reg;
6245 src_reg->orig_readfn = src_reg->readfn ?: raw_read;
6246 src_reg->orig_writefn = src_reg->writefn ?: raw_write;
6247 if (!src_reg->raw_readfn) {
6248 src_reg->raw_readfn = raw_read;
6249 }
6250 if (!src_reg->raw_writefn) {
6251 src_reg->raw_writefn = raw_write;
6252 }
6253 src_reg->readfn = el2_e2h_read;
6254 src_reg->writefn = el2_e2h_write;
6255 }
6256}
6257#endif
6258
6259static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
6260 bool isread)
6261{
6262 int cur_el = arm_current_el(env);
6263
6264 if (cur_el < 2) {
6265 uint64_t hcr = arm_hcr_el2_eff(env);
6266
6267 if (cur_el == 0) {
6268 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
6269 if (!(env->cp15.sctlr_el[2] & SCTLR_UCT)) {
6270 return CP_ACCESS_TRAP_EL2;
6271 }
6272 } else {
6273 if (!(env->cp15.sctlr_el[1] & SCTLR_UCT)) {
6274 return CP_ACCESS_TRAP;
6275 }
6276 if (hcr & HCR_TID2) {
6277 return CP_ACCESS_TRAP_EL2;
6278 }
6279 }
6280 } else if (hcr & HCR_TID2) {
6281 return CP_ACCESS_TRAP_EL2;
6282 }
6283 }
6284
6285 if (arm_current_el(env) < 2 && arm_hcr_el2_eff(env) & HCR_TID2) {
6286 return CP_ACCESS_TRAP_EL2;
6287 }
6288
6289 return CP_ACCESS_OK;
6290}
6291
6292static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
6293 uint64_t value)
6294{
6295
6296
6297
6298 int oslock;
6299
6300 if (ri->state == ARM_CP_STATE_AA32) {
6301 oslock = (value == 0xC5ACCE55);
6302 } else {
6303 oslock = value & 1;
6304 }
6305
6306 env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock);
6307}
6308
6309static const ARMCPRegInfo debug_cp_reginfo[] = {
6310
6311
6312
6313
6314
6315
6316 { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
6317 .access = PL0_R, .accessfn = access_tdra,
6318 .type = ARM_CP_CONST, .resetvalue = 0 },
6319 { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64,
6320 .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
6321 .access = PL1_R, .accessfn = access_tdra,
6322 .type = ARM_CP_CONST, .resetvalue = 0 },
6323 { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
6324 .access = PL0_R, .accessfn = access_tdra,
6325 .type = ARM_CP_CONST, .resetvalue = 0 },
6326
6327 { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH,
6328 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
6329 .access = PL1_RW, .accessfn = access_tda,
6330 .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
6331 .resetvalue = 0 },
6332
6333
6334
6335
6336 { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64,
6337 .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,
6338 .access = PL0_R, .accessfn = access_tda,
6339 .type = ARM_CP_CONST, .resetvalue = 0 },
6340
6341
6342
6343
6344
6345 { .name = "DBGDSCRint", .state = ARM_CP_STATE_AA32,
6346 .cp = 14, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
6347 .type = ARM_CP_ALIAS,
6348 .access = PL1_R, .accessfn = access_tda,
6349 .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), },
6350 { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH,
6351 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,
6352 .access = PL1_W, .type = ARM_CP_NO_RAW,
6353 .accessfn = access_tdosa,
6354 .writefn = oslar_write },
6355 { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH,
6356 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4,
6357 .access = PL1_R, .resetvalue = 10,
6358 .accessfn = access_tdosa,
6359 .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) },
6360
6361 { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH,
6362 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,
6363 .access = PL1_RW, .accessfn = access_tdosa,
6364 .type = ARM_CP_NOP },
6365
6366
6367
6368 { .name = "DBGVCR",
6369 .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
6370 .access = PL1_RW, .accessfn = access_tda,
6371 .type = ARM_CP_NOP },
6372
6373
6374
6375 { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
6376 .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
6377 .access = PL2_RW, .accessfn = access_tda,
6378 .type = ARM_CP_NOP },
6379
6380
6381
6382
6383 { .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
6384 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
6385 .access = PL1_RW, .accessfn = access_tda,
6386 .type = ARM_CP_NOP },
6387 REGINFO_SENTINEL
6388};
6389
6390static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
6391
6392 { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0,
6393 .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
6394 { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
6395 .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
6396 REGINFO_SENTINEL
6397};
6398
6399
6400
6401
6402
6403
6404
6405int sve_exception_el(CPUARMState *env, int el)
6406{
6407#ifndef CONFIG_USER_ONLY
6408 uint64_t hcr_el2 = arm_hcr_el2_eff(env);
6409
6410 if (el <= 1 && (hcr_el2 & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
6411 bool disabled = false;
6412
6413
6414
6415
6416
6417
6418 if (!extract32(env->cp15.cpacr_el1, 16, 1)) {
6419 disabled = true;
6420 } else if (!extract32(env->cp15.cpacr_el1, 17, 1)) {
6421 disabled = el == 0;
6422 }
6423 if (disabled) {
6424
6425 return hcr_el2 & HCR_TGE ? 2 : 1;
6426 }
6427
6428
6429 if (!extract32(env->cp15.cpacr_el1, 20, 1)) {
6430 disabled = true;
6431 } else if (!extract32(env->cp15.cpacr_el1, 21, 1)) {
6432 disabled = el == 0;
6433 }
6434 if (disabled) {
6435 return 0;
6436 }
6437 }
6438
6439
6440
6441
6442 if (el <= 2 && arm_is_el2_enabled(env)) {
6443 if (env->cp15.cptr_el[2] & CPTR_TZ) {
6444 return 2;
6445 }
6446 if (env->cp15.cptr_el[2] & CPTR_TFP) {
6447 return 0;
6448 }
6449 }
6450
6451
6452 if (arm_feature(env, ARM_FEATURE_EL3)
6453 && !(env->cp15.cptr_el[3] & CPTR_EZ)) {
6454 return 3;
6455 }
6456#endif
6457 return 0;
6458}
6459
6460uint32_t aarch64_sve_zcr_get_valid_len(ARMCPU *cpu, uint32_t start_len)
6461{
6462 uint32_t end_len;
6463
6464 start_len = MIN(start_len, ARM_MAX_VQ - 1);
6465 end_len = start_len;
6466
6467 if (!test_bit(start_len, cpu->sve_vq_map)) {
6468 end_len = find_last_bit(cpu->sve_vq_map, start_len);
6469 assert(end_len < start_len);
6470 }
6471 return end_len;
6472}
6473
6474
6475
6476
6477uint32_t sve_zcr_len_for_el(CPUARMState *env, int el)
6478{
6479 ARMCPU *cpu = env_archcpu(env);
6480 uint32_t zcr_len = cpu->sve_max_vq - 1;
6481
6482 if (el <= 1) {
6483 zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
6484 }
6485 if (el <= 2 && arm_feature(env, ARM_FEATURE_EL2)) {
6486 zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
6487 }
6488 if (arm_feature(env, ARM_FEATURE_EL3)) {
6489 zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
6490 }
6491
6492 return aarch64_sve_zcr_get_valid_len(cpu, zcr_len);
6493}
6494
6495static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
6496 uint64_t value)
6497{
6498 int cur_el = arm_current_el(env);
6499 int old_len = sve_zcr_len_for_el(env, cur_el);
6500 int new_len;
6501
6502
6503 QEMU_BUILD_BUG_ON(ARM_MAX_VQ > 16);
6504 raw_write(env, ri, value & 0xf);
6505
6506
6507
6508
6509
6510 new_len = sve_zcr_len_for_el(env, cur_el);
6511 if (new_len < old_len) {
6512 aarch64_sve_narrow_vq(env, new_len + 1);
6513 }
6514}
6515
6516static const ARMCPRegInfo zcr_el1_reginfo = {
6517 .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
6518 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
6519 .access = PL1_RW, .type = ARM_CP_SVE,
6520 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
6521 .writefn = zcr_write, .raw_writefn = raw_write
6522};
6523
6524static const ARMCPRegInfo zcr_el2_reginfo = {
6525 .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
6526 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
6527 .access = PL2_RW, .type = ARM_CP_SVE,
6528 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
6529 .writefn = zcr_write, .raw_writefn = raw_write
6530};
6531
6532static const ARMCPRegInfo zcr_no_el2_reginfo = {
6533 .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
6534 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
6535 .access = PL2_RW, .type = ARM_CP_SVE,
6536 .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
6537};
6538
6539static const ARMCPRegInfo zcr_el3_reginfo = {
6540 .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
6541 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
6542 .access = PL3_RW, .type = ARM_CP_SVE,
6543 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
6544 .writefn = zcr_write, .raw_writefn = raw_write
6545};
6546
6547void hw_watchpoint_update(ARMCPU *cpu, int n)
6548{
6549 CPUARMState *env = &cpu->env;
6550 vaddr len = 0;
6551 vaddr wvr = env->cp15.dbgwvr[n];
6552 uint64_t wcr = env->cp15.dbgwcr[n];
6553 int mask;
6554 int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
6555
6556 if (env->cpu_watchpoint[n]) {
6557 cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
6558 env->cpu_watchpoint[n] = NULL;
6559 }
6560
6561 if (!extract64(wcr, 0, 1)) {
6562
6563 return;
6564 }
6565
6566 switch (extract64(wcr, 3, 2)) {
6567 case 0:
6568
6569 return;
6570 case 1:
6571 flags |= BP_MEM_READ;
6572 break;
6573 case 2:
6574 flags |= BP_MEM_WRITE;
6575 break;
6576 case 3:
6577 flags |= BP_MEM_ACCESS;
6578 break;
6579 }
6580
6581
6582
6583
6584
6585 mask = extract64(wcr, 24, 4);
6586 if (mask == 1 || mask == 2) {
6587
6588
6589
6590
6591 return;
6592 } else if (mask) {
6593
6594 len = 1ULL << mask;
6595
6596
6597
6598
6599 wvr &= ~(len - 1);
6600 } else {
6601
6602 int bas = extract64(wcr, 5, 8);
6603 int basstart;
6604
6605 if (extract64(wvr, 2, 1)) {
6606
6607
6608
6609 bas &= 0xf;
6610 }
6611
6612 if (bas == 0) {
6613
6614 return;
6615 }
6616
6617
6618
6619
6620
6621
6622 basstart = ctz32(bas);
6623 len = cto32(bas >> basstart);
6624 wvr += basstart;
6625 }
6626
6627 cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
6628 &env->cpu_watchpoint[n]);
6629}
6630
6631void hw_watchpoint_update_all(ARMCPU *cpu)
6632{
6633 int i;
6634 CPUARMState *env = &cpu->env;
6635
6636
6637
6638
6639 cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
6640 memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
6641
6642 for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
6643 hw_watchpoint_update(cpu, i);
6644 }
6645}
6646
6647static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
6648 uint64_t value)
6649{
6650 ARMCPU *cpu = env_archcpu(env);
6651 int i = ri->crm;
6652
6653
6654
6655
6656
6657 value = sextract64(value, 0, 49) & ~3ULL;
6658
6659 raw_write(env, ri, value);
6660 hw_watchpoint_update(cpu, i);
6661}
6662
6663static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
6664 uint64_t value)
6665{
6666 ARMCPU *cpu = env_archcpu(env);
6667 int i = ri->crm;
6668
6669 raw_write(env, ri, value);
6670 hw_watchpoint_update(cpu, i);
6671}
6672
6673void hw_breakpoint_update(ARMCPU *cpu, int n)
6674{
6675 CPUARMState *env = &cpu->env;
6676 uint64_t bvr = env->cp15.dbgbvr[n];
6677 uint64_t bcr = env->cp15.dbgbcr[n];
6678 vaddr addr;
6679 int bt;
6680 int flags = BP_CPU;
6681
6682 if (env->cpu_breakpoint[n]) {
6683 cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
6684 env->cpu_breakpoint[n] = NULL;
6685 }
6686
6687 if (!extract64(bcr, 0, 1)) {
6688
6689 return;
6690 }
6691
6692 bt = extract64(bcr, 20, 4);
6693
6694 switch (bt) {
6695 case 4:
6696 case 5:
6697 qemu_log_mask(LOG_UNIMP,
6698 "arm: address mismatch breakpoint types not implemented\n");
6699 return;
6700 case 0:
6701 case 1:
6702 {
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718 int bas = extract64(bcr, 5, 4);
6719 addr = sextract64(bvr, 0, 49) & ~3ULL;
6720 if (bas == 0) {
6721 return;
6722 }
6723 if (bas == 0xc) {
6724 addr += 2;
6725 }
6726 break;
6727 }
6728 case 2:
6729 case 8:
6730 case 10:
6731 qemu_log_mask(LOG_UNIMP,
6732 "arm: unlinked context breakpoint types not implemented\n");
6733 return;
6734 case 9:
6735 case 11:
6736 case 3:
6737 default:
6738
6739
6740
6741
6742
6743 return;
6744 }
6745
6746 cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
6747}
6748
6749void hw_breakpoint_update_all(ARMCPU *cpu)
6750{
6751 int i;
6752 CPUARMState *env = &cpu->env;
6753
6754
6755
6756
6757 cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
6758 memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
6759
6760 for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
6761 hw_breakpoint_update(cpu, i);
6762 }
6763}
6764
6765static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
6766 uint64_t value)
6767{
6768 ARMCPU *cpu = env_archcpu(env);
6769 int i = ri->crm;
6770
6771 raw_write(env, ri, value);
6772 hw_breakpoint_update(cpu, i);
6773}
6774
6775static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
6776 uint64_t value)
6777{
6778 ARMCPU *cpu = env_archcpu(env);
6779 int i = ri->crm;
6780
6781
6782
6783
6784 value = deposit64(value, 6, 1, extract64(value, 5, 1));
6785 value = deposit64(value, 8, 1, extract64(value, 7, 1));
6786
6787 raw_write(env, ri, value);
6788 hw_breakpoint_update(cpu, i);
6789}
6790
6791static void define_debug_regs(ARMCPU *cpu)
6792{
6793
6794
6795
6796 int i;
6797 int wrps, brps, ctx_cmps;
6798
6799
6800
6801
6802
6803
6804 if (cpu->isar.dbgdidr != 0) {
6805 ARMCPRegInfo dbgdidr = {
6806 .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0,
6807 .opc1 = 0, .opc2 = 0,
6808 .access = PL0_R, .accessfn = access_tda,
6809 .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
6810 };
6811 define_one_arm_cp_reg(cpu, &dbgdidr);
6812 }
6813
6814
6815 brps = arm_num_brps(cpu);
6816 wrps = arm_num_wrps(cpu);
6817 ctx_cmps = arm_num_ctx_cmps(cpu);
6818
6819 assert(ctx_cmps <= brps);
6820
6821 define_arm_cp_regs(cpu, debug_cp_reginfo);
6822
6823 if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
6824 define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
6825 }
6826
6827 for (i = 0; i < brps; i++) {
6828 ARMCPRegInfo dbgregs[] = {
6829 { .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,
6830 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
6831 .access = PL1_RW, .accessfn = access_tda,
6832 .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
6833 .writefn = dbgbvr_write, .raw_writefn = raw_write
6834 },
6835 { .name = "DBGBCR", .state = ARM_CP_STATE_BOTH,
6836 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
6837 .access = PL1_RW, .accessfn = access_tda,
6838 .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
6839 .writefn = dbgbcr_write, .raw_writefn = raw_write
6840 },
6841 REGINFO_SENTINEL
6842 };
6843 define_arm_cp_regs(cpu, dbgregs);
6844 }
6845
6846 for (i = 0; i < wrps; i++) {
6847 ARMCPRegInfo dbgregs[] = {
6848 { .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,
6849 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
6850 .access = PL1_RW, .accessfn = access_tda,
6851 .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
6852 .writefn = dbgwvr_write, .raw_writefn = raw_write
6853 },
6854 { .name = "DBGWCR", .state = ARM_CP_STATE_BOTH,
6855 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
6856 .access = PL1_RW, .accessfn = access_tda,
6857 .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
6858 .writefn = dbgwcr_write, .raw_writefn = raw_write
6859 },
6860 REGINFO_SENTINEL
6861 };
6862 define_arm_cp_regs(cpu, dbgregs);
6863 }
6864}
6865
6866static void define_pmu_regs(ARMCPU *cpu)
6867{
6868
6869
6870
6871
6872
6873 unsigned int i, pmcrn = PMCR_NUM_COUNTERS;
6874 ARMCPRegInfo pmcr = {
6875 .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
6876 .access = PL0_RW,
6877 .type = ARM_CP_IO | ARM_CP_ALIAS,
6878 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
6879 .accessfn = pmreg_access, .writefn = pmcr_write,
6880 .raw_writefn = raw_write,
6881 };
6882 ARMCPRegInfo pmcr64 = {
6883 .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
6884 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
6885 .access = PL0_RW, .accessfn = pmreg_access,
6886 .type = ARM_CP_IO,
6887 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
6888 .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) |
6889 PMCRLC,
6890 .writefn = pmcr_write, .raw_writefn = raw_write,
6891 };
6892 define_one_arm_cp_reg(cpu, &pmcr);
6893 define_one_arm_cp_reg(cpu, &pmcr64);
6894 for (i = 0; i < pmcrn; i++) {
6895 char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
6896 char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
6897 char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
6898 char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
6899 ARMCPRegInfo pmev_regs[] = {
6900 { .name = pmevcntr_name, .cp = 15, .crn = 14,
6901 .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
6902 .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
6903 .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
6904 .accessfn = pmreg_access },
6905 { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
6906 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
6907 .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
6908 .type = ARM_CP_IO,
6909 .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
6910 .raw_readfn = pmevcntr_rawread,
6911 .raw_writefn = pmevcntr_rawwrite },
6912 { .name = pmevtyper_name, .cp = 15, .crn = 14,
6913 .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
6914 .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
6915 .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
6916 .accessfn = pmreg_access },
6917 { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
6918 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
6919 .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
6920 .type = ARM_CP_IO,
6921 .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
6922 .raw_writefn = pmevtyper_rawwrite },
6923 REGINFO_SENTINEL
6924 };
6925 define_arm_cp_regs(cpu, pmev_regs);
6926 g_free(pmevcntr_name);
6927 g_free(pmevcntr_el0_name);
6928 g_free(pmevtyper_name);
6929 g_free(pmevtyper_el0_name);
6930 }
6931 if (cpu_isar_feature(aa32_pmu_8_1, cpu)) {
6932 ARMCPRegInfo v81_pmu_regs[] = {
6933 { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
6934 .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
6935 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6936 .resetvalue = extract64(cpu->pmceid0, 32, 32) },
6937 { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
6938 .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
6939 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6940 .resetvalue = extract64(cpu->pmceid1, 32, 32) },
6941 REGINFO_SENTINEL
6942 };
6943 define_arm_cp_regs(cpu, v81_pmu_regs);
6944 }
6945 if (cpu_isar_feature(any_pmu_8_4, cpu)) {
6946 static const ARMCPRegInfo v84_pmmir = {
6947 .name = "PMMIR_EL1", .state = ARM_CP_STATE_BOTH,
6948 .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 6,
6949 .access = PL1_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6950 .resetvalue = 0
6951 };
6952 define_one_arm_cp_reg(cpu, &v84_pmmir);
6953 }
6954}
6955
6956
6957
6958
6959
6960
6961static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
6962{
6963 ARMCPU *cpu = env_archcpu(env);
6964 uint64_t pfr1 = cpu->isar.id_pfr1;
6965
6966 if (env->gicv3state) {
6967 pfr1 |= 1 << 28;
6968 }
6969 return pfr1;
6970}
6971
6972#ifndef CONFIG_USER_ONLY
6973static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
6974{
6975 ARMCPU *cpu = env_archcpu(env);
6976 uint64_t pfr0 = cpu->isar.id_aa64pfr0;
6977
6978 if (env->gicv3state) {
6979 pfr0 |= 1 << 24;
6980 }
6981 return pfr0;
6982}
6983#endif
6984
6985
6986
6987
6988static CPAccessResult access_lor_ns(CPUARMState *env,
6989 const ARMCPRegInfo *ri, bool isread)
6990{
6991 int el = arm_current_el(env);
6992
6993 if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TLOR)) {
6994 return CP_ACCESS_TRAP_EL2;
6995 }
6996 if (el < 3 && (env->cp15.scr_el3 & SCR_TLOR)) {
6997 return CP_ACCESS_TRAP_EL3;
6998 }
6999 return CP_ACCESS_OK;
7000}
7001
7002static CPAccessResult access_lor_other(CPUARMState *env,
7003 const ARMCPRegInfo *ri, bool isread)
7004{
7005 if (arm_is_secure_below_el3(env)) {
7006
7007 return CP_ACCESS_TRAP;
7008 }
7009 return access_lor_ns(env, ri, isread);
7010}
7011
7012
7013
7014
7015
7016
7017static const ARMCPRegInfo lor_reginfo[] = {
7018 { .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64,
7019 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0,
7020 .access = PL1_RW, .accessfn = access_lor_other,
7021 .type = ARM_CP_CONST, .resetvalue = 0 },
7022 { .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64,
7023 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1,
7024 .access = PL1_RW, .accessfn = access_lor_other,
7025 .type = ARM_CP_CONST, .resetvalue = 0 },
7026 { .name = "LORN_EL1", .state = ARM_CP_STATE_AA64,
7027 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2,
7028 .access = PL1_RW, .accessfn = access_lor_other,
7029 .type = ARM_CP_CONST, .resetvalue = 0 },
7030 { .name = "LORC_EL1", .state = ARM_CP_STATE_AA64,
7031 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3,
7032 .access = PL1_RW, .accessfn = access_lor_other,
7033 .type = ARM_CP_CONST, .resetvalue = 0 },
7034 { .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
7035 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
7036 .access = PL1_R, .accessfn = access_lor_ns,
7037 .type = ARM_CP_CONST, .resetvalue = 0 },
7038 REGINFO_SENTINEL
7039};
7040
7041#ifdef TARGET_AARCH64
7042static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri,
7043 bool isread)
7044{
7045 int el = arm_current_el(env);
7046
7047 if (el < 2 &&
7048 arm_feature(env, ARM_FEATURE_EL2) &&
7049 !(arm_hcr_el2_eff(env) & HCR_APK)) {
7050 return CP_ACCESS_TRAP_EL2;
7051 }
7052 if (el < 3 &&
7053 arm_feature(env, ARM_FEATURE_EL3) &&
7054 !(env->cp15.scr_el3 & SCR_APK)) {
7055 return CP_ACCESS_TRAP_EL3;
7056 }
7057 return CP_ACCESS_OK;
7058}
7059
7060static const ARMCPRegInfo pauth_reginfo[] = {
7061 { .name = "APDAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
7062 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
7063 .access = PL1_RW, .accessfn = access_pauth,
7064 .fieldoffset = offsetof(CPUARMState, keys.apda.lo) },
7065 { .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
7066 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
7067 .access = PL1_RW, .accessfn = access_pauth,
7068 .fieldoffset = offsetof(CPUARMState, keys.apda.hi) },
7069 { .name = "APDBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
7070 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
7071 .access = PL1_RW, .accessfn = access_pauth,
7072 .fieldoffset = offsetof(CPUARMState, keys.apdb.lo) },
7073 { .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
7074 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
7075 .access = PL1_RW, .accessfn = access_pauth,
7076 .fieldoffset = offsetof(CPUARMState, keys.apdb.hi) },
7077 { .name = "APGAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
7078 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 0,
7079 .access = PL1_RW, .accessfn = access_pauth,
7080 .fieldoffset = offsetof(CPUARMState, keys.apga.lo) },
7081 { .name = "APGAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
7082 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 1,
7083 .access = PL1_RW, .accessfn = access_pauth,
7084 .fieldoffset = offsetof(CPUARMState, keys.apga.hi) },
7085 { .name = "APIAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
7086 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 0,
7087 .access = PL1_RW, .accessfn = access_pauth,
7088 .fieldoffset = offsetof(CPUARMState, keys.apia.lo) },
7089 { .name = "APIAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
7090 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 1,
7091 .access = PL1_RW, .accessfn = access_pauth,
7092 .fieldoffset = offsetof(CPUARMState, keys.apia.hi) },
7093 { .name = "APIBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
7094 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 2,
7095 .access = PL1_RW, .accessfn = access_pauth,
7096 .fieldoffset = offsetof(CPUARMState, keys.apib.lo) },
7097 { .name = "APIBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
7098 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
7099 .access = PL1_RW, .accessfn = access_pauth,
7100 .fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
7101 REGINFO_SENTINEL
7102};
7103
7104static const ARMCPRegInfo tlbirange_reginfo[] = {
7105 { .name = "TLBI_RVAE1IS", .state = ARM_CP_STATE_AA64,
7106 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 1,
7107 .access = PL1_W, .type = ARM_CP_NO_RAW,
7108 .writefn = tlbi_aa64_rvae1is_write },
7109 { .name = "TLBI_RVAAE1IS", .state = ARM_CP_STATE_AA64,
7110 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 3,
7111 .access = PL1_W, .type = ARM_CP_NO_RAW,
7112 .writefn = tlbi_aa64_rvae1is_write },
7113 { .name = "TLBI_RVALE1IS", .state = ARM_CP_STATE_AA64,
7114 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 5,
7115 .access = PL1_W, .type = ARM_CP_NO_RAW,
7116 .writefn = tlbi_aa64_rvae1is_write },
7117 { .name = "TLBI_RVAALE1IS", .state = ARM_CP_STATE_AA64,
7118 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 7,
7119 .access = PL1_W, .type = ARM_CP_NO_RAW,
7120 .writefn = tlbi_aa64_rvae1is_write },
7121 { .name = "TLBI_RVAE1OS", .state = ARM_CP_STATE_AA64,
7122 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
7123 .access = PL1_W, .type = ARM_CP_NO_RAW,
7124 .writefn = tlbi_aa64_rvae1is_write },
7125 { .name = "TLBI_RVAAE1OS", .state = ARM_CP_STATE_AA64,
7126 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 3,
7127 .access = PL1_W, .type = ARM_CP_NO_RAW,
7128 .writefn = tlbi_aa64_rvae1is_write },
7129 { .name = "TLBI_RVALE1OS", .state = ARM_CP_STATE_AA64,
7130 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 5,
7131 .access = PL1_W, .type = ARM_CP_NO_RAW,
7132 .writefn = tlbi_aa64_rvae1is_write },
7133 { .name = "TLBI_RVAALE1OS", .state = ARM_CP_STATE_AA64,
7134 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 7,
7135 .access = PL1_W, .type = ARM_CP_NO_RAW,
7136 .writefn = tlbi_aa64_rvae1is_write },
7137 { .name = "TLBI_RVAE1", .state = ARM_CP_STATE_AA64,
7138 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
7139 .access = PL1_W, .type = ARM_CP_NO_RAW,
7140 .writefn = tlbi_aa64_rvae1_write },
7141 { .name = "TLBI_RVAAE1", .state = ARM_CP_STATE_AA64,
7142 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 3,
7143 .access = PL1_W, .type = ARM_CP_NO_RAW,
7144 .writefn = tlbi_aa64_rvae1_write },
7145 { .name = "TLBI_RVALE1", .state = ARM_CP_STATE_AA64,
7146 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 5,
7147 .access = PL1_W, .type = ARM_CP_NO_RAW,
7148 .writefn = tlbi_aa64_rvae1_write },
7149 { .name = "TLBI_RVAALE1", .state = ARM_CP_STATE_AA64,
7150 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 7,
7151 .access = PL1_W, .type = ARM_CP_NO_RAW,
7152 .writefn = tlbi_aa64_rvae1_write },
7153 { .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64,
7154 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2,
7155 .access = PL2_W, .type = ARM_CP_NOP },
7156 { .name = "TLBI_RIPAS2LE1IS", .state = ARM_CP_STATE_AA64,
7157 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 6,
7158 .access = PL2_W, .type = ARM_CP_NOP },
7159 { .name = "TLBI_RVAE2IS", .state = ARM_CP_STATE_AA64,
7160 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 1,
7161 .access = PL2_W, .type = ARM_CP_NO_RAW,
7162 .writefn = tlbi_aa64_rvae2is_write },
7163 { .name = "TLBI_RVALE2IS", .state = ARM_CP_STATE_AA64,
7164 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 5,
7165 .access = PL2_W, .type = ARM_CP_NO_RAW,
7166 .writefn = tlbi_aa64_rvae2is_write },
7167 { .name = "TLBI_RIPAS2E1", .state = ARM_CP_STATE_AA64,
7168 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 2,
7169 .access = PL2_W, .type = ARM_CP_NOP },
7170 { .name = "TLBI_RIPAS2LE1", .state = ARM_CP_STATE_AA64,
7171 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 6,
7172 .access = PL2_W, .type = ARM_CP_NOP },
7173 { .name = "TLBI_RVAE2OS", .state = ARM_CP_STATE_AA64,
7174 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 1,
7175 .access = PL2_W, .type = ARM_CP_NO_RAW,
7176 .writefn = tlbi_aa64_rvae2is_write },
7177 { .name = "TLBI_RVALE2OS", .state = ARM_CP_STATE_AA64,
7178 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 5,
7179 .access = PL2_W, .type = ARM_CP_NO_RAW,
7180 .writefn = tlbi_aa64_rvae2is_write },
7181 { .name = "TLBI_RVAE2", .state = ARM_CP_STATE_AA64,
7182 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 1,
7183 .access = PL2_W, .type = ARM_CP_NO_RAW,
7184 .writefn = tlbi_aa64_rvae2_write },
7185 { .name = "TLBI_RVALE2", .state = ARM_CP_STATE_AA64,
7186 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 5,
7187 .access = PL2_W, .type = ARM_CP_NO_RAW,
7188 .writefn = tlbi_aa64_rvae2_write },
7189 { .name = "TLBI_RVAE3IS", .state = ARM_CP_STATE_AA64,
7190 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 1,
7191 .access = PL3_W, .type = ARM_CP_NO_RAW,
7192 .writefn = tlbi_aa64_rvae3is_write },
7193 { .name = "TLBI_RVALE3IS", .state = ARM_CP_STATE_AA64,
7194 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 5,
7195 .access = PL3_W, .type = ARM_CP_NO_RAW,
7196 .writefn = tlbi_aa64_rvae3is_write },
7197 { .name = "TLBI_RVAE3OS", .state = ARM_CP_STATE_AA64,
7198 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 1,
7199 .access = PL3_W, .type = ARM_CP_NO_RAW,
7200 .writefn = tlbi_aa64_rvae3is_write },
7201 { .name = "TLBI_RVALE3OS", .state = ARM_CP_STATE_AA64,
7202 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 5,
7203 .access = PL3_W, .type = ARM_CP_NO_RAW,
7204 .writefn = tlbi_aa64_rvae3is_write },
7205 { .name = "TLBI_RVAE3", .state = ARM_CP_STATE_AA64,
7206 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 1,
7207 .access = PL3_W, .type = ARM_CP_NO_RAW,
7208 .writefn = tlbi_aa64_rvae3_write },
7209 { .name = "TLBI_RVALE3", .state = ARM_CP_STATE_AA64,
7210 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 5,
7211 .access = PL3_W, .type = ARM_CP_NO_RAW,
7212 .writefn = tlbi_aa64_rvae3_write },
7213 REGINFO_SENTINEL
7214};
7215
7216static const ARMCPRegInfo tlbios_reginfo[] = {
7217 { .name = "TLBI_VMALLE1OS", .state = ARM_CP_STATE_AA64,
7218 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0,
7219 .access = PL1_W, .type = ARM_CP_NO_RAW,
7220 .writefn = tlbi_aa64_vmalle1is_write },
7221 { .name = "TLBI_ASIDE1OS", .state = ARM_CP_STATE_AA64,
7222 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 2,
7223 .access = PL1_W, .type = ARM_CP_NO_RAW,
7224 .writefn = tlbi_aa64_vmalle1is_write },
7225 { .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64,
7226 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0,
7227 .access = PL2_W, .type = ARM_CP_NO_RAW,
7228 .writefn = tlbi_aa64_alle2is_write },
7229 { .name = "TLBI_ALLE1OS", .state = ARM_CP_STATE_AA64,
7230 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 4,
7231 .access = PL2_W, .type = ARM_CP_NO_RAW,
7232 .writefn = tlbi_aa64_alle1is_write },
7233 { .name = "TLBI_VMALLS12E1OS", .state = ARM_CP_STATE_AA64,
7234 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 6,
7235 .access = PL2_W, .type = ARM_CP_NO_RAW,
7236 .writefn = tlbi_aa64_alle1is_write },
7237 { .name = "TLBI_IPAS2E1OS", .state = ARM_CP_STATE_AA64,
7238 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 0,
7239 .access = PL2_W, .type = ARM_CP_NOP },
7240 { .name = "TLBI_RIPAS2E1OS", .state = ARM_CP_STATE_AA64,
7241 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 3,
7242 .access = PL2_W, .type = ARM_CP_NOP },
7243 { .name = "TLBI_IPAS2LE1OS", .state = ARM_CP_STATE_AA64,
7244 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 4,
7245 .access = PL2_W, .type = ARM_CP_NOP },
7246 { .name = "TLBI_RIPAS2LE1OS", .state = ARM_CP_STATE_AA64,
7247 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 7,
7248 .access = PL2_W, .type = ARM_CP_NOP },
7249 { .name = "TLBI_ALLE3OS", .state = ARM_CP_STATE_AA64,
7250 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 0,
7251 .access = PL3_W, .type = ARM_CP_NO_RAW,
7252 .writefn = tlbi_aa64_alle3is_write },
7253 REGINFO_SENTINEL
7254};
7255
7256static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
7257{
7258 Error *err = NULL;
7259 uint64_t ret;
7260
7261
7262 env->NF = env->CF = env->VF = 0, env->ZF = 1;
7263
7264 if (qemu_guest_getrandom(&ret, sizeof(ret), &err) < 0) {
7265
7266
7267
7268
7269
7270
7271
7272 qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
7273 ri->name, error_get_pretty(err));
7274 error_free(err);
7275
7276 env->ZF = 0;
7277 return 0;
7278 }
7279 return ret;
7280}
7281
7282
7283static const ARMCPRegInfo rndr_reginfo[] = {
7284 { .name = "RNDR", .state = ARM_CP_STATE_AA64,
7285 .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
7286 .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 0,
7287 .access = PL0_R, .readfn = rndr_readfn },
7288 { .name = "RNDRRS", .state = ARM_CP_STATE_AA64,
7289 .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
7290 .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
7291 .access = PL0_R, .readfn = rndr_readfn },
7292 REGINFO_SENTINEL
7293};
7294
7295#ifndef CONFIG_USER_ONLY
7296static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
7297 uint64_t value)
7298{
7299 ARMCPU *cpu = env_archcpu(env);
7300
7301 uint64_t dline_size = 4 << ((cpu->ctr >> 16) & 0xF);
7302 uint64_t vaddr_in = (uint64_t) value;
7303 uint64_t vaddr = vaddr_in & ~(dline_size - 1);
7304 void *haddr;
7305 int mem_idx = cpu_mmu_index(env, false);
7306
7307
7308 haddr = probe_read(env, vaddr, dline_size, mem_idx, GETPC());
7309 if (haddr) {
7310
7311 ram_addr_t offset;
7312 MemoryRegion *mr;
7313
7314
7315 mr = memory_region_from_host(haddr, &offset);
7316
7317 if (mr) {
7318 memory_region_writeback(mr, offset, dline_size);
7319 }
7320 }
7321}
7322
7323static const ARMCPRegInfo dcpop_reg[] = {
7324 { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
7325 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
7326 .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
7327 .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
7328 REGINFO_SENTINEL
7329};
7330
7331static const ARMCPRegInfo dcpodp_reg[] = {
7332 { .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
7333 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
7334 .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
7335 .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
7336 REGINFO_SENTINEL
7337};
7338#endif
7339
7340static CPAccessResult access_aa64_tid5(CPUARMState *env, const ARMCPRegInfo *ri,
7341 bool isread)
7342{
7343 if ((arm_current_el(env) < 2) && (arm_hcr_el2_eff(env) & HCR_TID5)) {
7344 return CP_ACCESS_TRAP_EL2;
7345 }
7346
7347 return CP_ACCESS_OK;
7348}
7349
7350static CPAccessResult access_mte(CPUARMState *env, const ARMCPRegInfo *ri,
7351 bool isread)
7352{
7353 int el = arm_current_el(env);
7354
7355 if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
7356 uint64_t hcr = arm_hcr_el2_eff(env);
7357 if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
7358 return CP_ACCESS_TRAP_EL2;
7359 }
7360 }
7361 if (el < 3 &&
7362 arm_feature(env, ARM_FEATURE_EL3) &&
7363 !(env->cp15.scr_el3 & SCR_ATA)) {
7364 return CP_ACCESS_TRAP_EL3;
7365 }
7366 return CP_ACCESS_OK;
7367}
7368
7369static uint64_t tco_read(CPUARMState *env, const ARMCPRegInfo *ri)
7370{
7371 return env->pstate & PSTATE_TCO;
7372}
7373
7374static void tco_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
7375{
7376 env->pstate = (env->pstate & ~PSTATE_TCO) | (val & PSTATE_TCO);
7377}
7378
7379static const ARMCPRegInfo mte_reginfo[] = {
7380 { .name = "TFSRE0_EL1", .state = ARM_CP_STATE_AA64,
7381 .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 1,
7382 .access = PL1_RW, .accessfn = access_mte,
7383 .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[0]) },
7384 { .name = "TFSR_EL1", .state = ARM_CP_STATE_AA64,
7385 .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 0,
7386 .access = PL1_RW, .accessfn = access_mte,
7387 .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
7388 { .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
7389 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 6, .opc2 = 0,
7390 .access = PL2_RW, .accessfn = access_mte,
7391 .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[2]) },
7392 { .name = "TFSR_EL3", .state = ARM_CP_STATE_AA64,
7393 .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 6, .opc2 = 0,
7394 .access = PL3_RW,
7395 .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[3]) },
7396 { .name = "RGSR_EL1", .state = ARM_CP_STATE_AA64,
7397 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 5,
7398 .access = PL1_RW, .accessfn = access_mte,
7399 .fieldoffset = offsetof(CPUARMState, cp15.rgsr_el1) },
7400 { .name = "GCR_EL1", .state = ARM_CP_STATE_AA64,
7401 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 6,
7402 .access = PL1_RW, .accessfn = access_mte,
7403 .fieldoffset = offsetof(CPUARMState, cp15.gcr_el1) },
7404 { .name = "GMID_EL1", .state = ARM_CP_STATE_AA64,
7405 .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 4,
7406 .access = PL1_R, .accessfn = access_aa64_tid5,
7407 .type = ARM_CP_CONST, .resetvalue = GMID_EL1_BS },
7408 { .name = "TCO", .state = ARM_CP_STATE_AA64,
7409 .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
7410 .type = ARM_CP_NO_RAW,
7411 .access = PL0_RW, .readfn = tco_read, .writefn = tco_write },
7412 { .name = "DC_IGVAC", .state = ARM_CP_STATE_AA64,
7413 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 3,
7414 .type = ARM_CP_NOP, .access = PL1_W,
7415 .accessfn = aa64_cacheop_poc_access },
7416 { .name = "DC_IGSW", .state = ARM_CP_STATE_AA64,
7417 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 4,
7418 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7419 { .name = "DC_IGDVAC", .state = ARM_CP_STATE_AA64,
7420 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 5,
7421 .type = ARM_CP_NOP, .access = PL1_W,
7422 .accessfn = aa64_cacheop_poc_access },
7423 { .name = "DC_IGDSW", .state = ARM_CP_STATE_AA64,
7424 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 6,
7425 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7426 { .name = "DC_CGSW", .state = ARM_CP_STATE_AA64,
7427 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 4,
7428 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7429 { .name = "DC_CGDSW", .state = ARM_CP_STATE_AA64,
7430 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 6,
7431 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7432 { .name = "DC_CIGSW", .state = ARM_CP_STATE_AA64,
7433 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 4,
7434 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7435 { .name = "DC_CIGDSW", .state = ARM_CP_STATE_AA64,
7436 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 6,
7437 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7438 REGINFO_SENTINEL
7439};
7440
7441static const ARMCPRegInfo mte_tco_ro_reginfo[] = {
7442 { .name = "TCO", .state = ARM_CP_STATE_AA64,
7443 .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
7444 .type = ARM_CP_CONST, .access = PL0_RW, },
7445 REGINFO_SENTINEL
7446};
7447
7448static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
7449 { .name = "DC_CGVAC", .state = ARM_CP_STATE_AA64,
7450 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 3,
7451 .type = ARM_CP_NOP, .access = PL0_W,
7452 .accessfn = aa64_cacheop_poc_access },
7453 { .name = "DC_CGDVAC", .state = ARM_CP_STATE_AA64,
7454 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 5,
7455 .type = ARM_CP_NOP, .access = PL0_W,
7456 .accessfn = aa64_cacheop_poc_access },
7457 { .name = "DC_CGVAP", .state = ARM_CP_STATE_AA64,
7458 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 3,
7459 .type = ARM_CP_NOP, .access = PL0_W,
7460 .accessfn = aa64_cacheop_poc_access },
7461 { .name = "DC_CGDVAP", .state = ARM_CP_STATE_AA64,
7462 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 5,
7463 .type = ARM_CP_NOP, .access = PL0_W,
7464 .accessfn = aa64_cacheop_poc_access },
7465 { .name = "DC_CGVADP", .state = ARM_CP_STATE_AA64,
7466 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 3,
7467 .type = ARM_CP_NOP, .access = PL0_W,
7468 .accessfn = aa64_cacheop_poc_access },
7469 { .name = "DC_CGDVADP", .state = ARM_CP_STATE_AA64,
7470 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 5,
7471 .type = ARM_CP_NOP, .access = PL0_W,
7472 .accessfn = aa64_cacheop_poc_access },
7473 { .name = "DC_CIGVAC", .state = ARM_CP_STATE_AA64,
7474 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 3,
7475 .type = ARM_CP_NOP, .access = PL0_W,
7476 .accessfn = aa64_cacheop_poc_access },
7477 { .name = "DC_CIGDVAC", .state = ARM_CP_STATE_AA64,
7478 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 5,
7479 .type = ARM_CP_NOP, .access = PL0_W,
7480 .accessfn = aa64_cacheop_poc_access },
7481 { .name = "DC_GVA", .state = ARM_CP_STATE_AA64,
7482 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 3,
7483 .access = PL0_W, .type = ARM_CP_DC_GVA,
7484#ifndef CONFIG_USER_ONLY
7485
7486 .accessfn = aa64_zva_access,
7487#endif
7488 },
7489 { .name = "DC_GZVA", .state = ARM_CP_STATE_AA64,
7490 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 4,
7491 .access = PL0_W, .type = ARM_CP_DC_GZVA,
7492#ifndef CONFIG_USER_ONLY
7493
7494 .accessfn = aa64_zva_access,
7495#endif
7496 },
7497 REGINFO_SENTINEL
7498};
7499
7500#endif
7501
7502static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
7503 bool isread)
7504{
7505 int el = arm_current_el(env);
7506
7507 if (el == 0) {
7508 uint64_t sctlr = arm_sctlr(env, el);
7509 if (!(sctlr & SCTLR_EnRCTX)) {
7510 return CP_ACCESS_TRAP;
7511 }
7512 } else if (el == 1) {
7513 uint64_t hcr = arm_hcr_el2_eff(env);
7514 if (hcr & HCR_NV) {
7515 return CP_ACCESS_TRAP_EL2;
7516 }
7517 }
7518 return CP_ACCESS_OK;
7519}
7520
7521static const ARMCPRegInfo predinv_reginfo[] = {
7522 { .name = "CFP_RCTX", .state = ARM_CP_STATE_AA64,
7523 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 4,
7524 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7525 { .name = "DVP_RCTX", .state = ARM_CP_STATE_AA64,
7526 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 5,
7527 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7528 { .name = "CPP_RCTX", .state = ARM_CP_STATE_AA64,
7529 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 7,
7530 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7531
7532
7533
7534 { .name = "CFPRCTX", .state = ARM_CP_STATE_AA32,
7535 .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 4,
7536 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7537 { .name = "DVPRCTX", .state = ARM_CP_STATE_AA32,
7538 .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 5,
7539 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7540 { .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
7541 .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
7542 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7543 REGINFO_SENTINEL
7544};
7545
7546static uint64_t ccsidr2_read(CPUARMState *env, const ARMCPRegInfo *ri)
7547{
7548
7549 return extract64(ccsidr_read(env, ri), 32, 32);
7550}
7551
7552static const ARMCPRegInfo ccsidr2_reginfo[] = {
7553 { .name = "CCSIDR2", .state = ARM_CP_STATE_BOTH,
7554 .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 2,
7555 .access = PL1_R,
7556 .accessfn = access_aa64_tid2,
7557 .readfn = ccsidr2_read, .type = ARM_CP_NO_RAW },
7558 REGINFO_SENTINEL
7559};
7560
7561static CPAccessResult access_aa64_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
7562 bool isread)
7563{
7564 if ((arm_current_el(env) < 2) && (arm_hcr_el2_eff(env) & HCR_TID3)) {
7565 return CP_ACCESS_TRAP_EL2;
7566 }
7567
7568 return CP_ACCESS_OK;
7569}
7570
7571static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
7572 bool isread)
7573{
7574 if (arm_feature(env, ARM_FEATURE_V8)) {
7575 return access_aa64_tid3(env, ri, isread);
7576 }
7577
7578 return CP_ACCESS_OK;
7579}
7580
7581static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
7582 bool isread)
7583{
7584 if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID0)) {
7585 return CP_ACCESS_TRAP_EL2;
7586 }
7587
7588 return CP_ACCESS_OK;
7589}
7590
7591static const ARMCPRegInfo jazelle_regs[] = {
7592 { .name = "JIDR",
7593 .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
7594 .access = PL1_R, .accessfn = access_jazelle,
7595 .type = ARM_CP_CONST, .resetvalue = 0 },
7596 { .name = "JOSCR",
7597 .cp = 14, .crn = 1, .crm = 0, .opc1 = 7, .opc2 = 0,
7598 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
7599 { .name = "JMCR",
7600 .cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
7601 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
7602 REGINFO_SENTINEL
7603};
7604
7605static const ARMCPRegInfo vhe_reginfo[] = {
7606 { .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
7607 .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
7608 .access = PL2_RW,
7609 .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2]) },
7610 { .name = "TTBR1_EL2", .state = ARM_CP_STATE_AA64,
7611 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 1,
7612 .access = PL2_RW, .writefn = vmsa_tcr_ttbr_el2_write,
7613 .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el[2]) },
7614#ifndef CONFIG_USER_ONLY
7615 { .name = "CNTHV_CVAL_EL2", .state = ARM_CP_STATE_AA64,
7616 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 3, .opc2 = 2,
7617 .fieldoffset =
7618 offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYPVIRT].cval),
7619 .type = ARM_CP_IO, .access = PL2_RW,
7620 .writefn = gt_hv_cval_write, .raw_writefn = raw_write },
7621 { .name = "CNTHV_TVAL_EL2", .state = ARM_CP_STATE_BOTH,
7622 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 3, .opc2 = 0,
7623 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW,
7624 .resetfn = gt_hv_timer_reset,
7625 .readfn = gt_hv_tval_read, .writefn = gt_hv_tval_write },
7626 { .name = "CNTHV_CTL_EL2", .state = ARM_CP_STATE_BOTH,
7627 .type = ARM_CP_IO,
7628 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 3, .opc2 = 1,
7629 .access = PL2_RW,
7630 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYPVIRT].ctl),
7631 .writefn = gt_hv_ctl_write, .raw_writefn = raw_write },
7632 { .name = "CNTP_CTL_EL02", .state = ARM_CP_STATE_AA64,
7633 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 1,
7634 .type = ARM_CP_IO | ARM_CP_ALIAS,
7635 .access = PL2_RW, .accessfn = e2h_access,
7636 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
7637 .writefn = gt_phys_ctl_write, .raw_writefn = raw_write },
7638 { .name = "CNTV_CTL_EL02", .state = ARM_CP_STATE_AA64,
7639 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 1,
7640 .type = ARM_CP_IO | ARM_CP_ALIAS,
7641 .access = PL2_RW, .accessfn = e2h_access,
7642 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
7643 .writefn = gt_virt_ctl_write, .raw_writefn = raw_write },
7644 { .name = "CNTP_TVAL_EL02", .state = ARM_CP_STATE_AA64,
7645 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 0,
7646 .type = ARM_CP_NO_RAW | ARM_CP_IO | ARM_CP_ALIAS,
7647 .access = PL2_RW, .accessfn = e2h_access,
7648 .readfn = gt_phys_tval_read, .writefn = gt_phys_tval_write },
7649 { .name = "CNTV_TVAL_EL02", .state = ARM_CP_STATE_AA64,
7650 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 0,
7651 .type = ARM_CP_NO_RAW | ARM_CP_IO | ARM_CP_ALIAS,
7652 .access = PL2_RW, .accessfn = e2h_access,
7653 .readfn = gt_virt_tval_read, .writefn = gt_virt_tval_write },
7654 { .name = "CNTP_CVAL_EL02", .state = ARM_CP_STATE_AA64,
7655 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 2,
7656 .type = ARM_CP_IO | ARM_CP_ALIAS,
7657 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
7658 .access = PL2_RW, .accessfn = e2h_access,
7659 .writefn = gt_phys_cval_write, .raw_writefn = raw_write },
7660 { .name = "CNTV_CVAL_EL02", .state = ARM_CP_STATE_AA64,
7661 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 2,
7662 .type = ARM_CP_IO | ARM_CP_ALIAS,
7663 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
7664 .access = PL2_RW, .accessfn = e2h_access,
7665 .writefn = gt_virt_cval_write, .raw_writefn = raw_write },
7666#endif
7667 REGINFO_SENTINEL
7668};
7669
7670#ifndef CONFIG_USER_ONLY
7671static const ARMCPRegInfo ats1e1_reginfo[] = {
7672 { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64,
7673 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
7674 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
7675 .writefn = ats_write64 },
7676 { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
7677 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
7678 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
7679 .writefn = ats_write64 },
7680 REGINFO_SENTINEL
7681};
7682
7683static const ARMCPRegInfo ats1cp_reginfo[] = {
7684 { .name = "ATS1CPRP",
7685 .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
7686 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
7687 .writefn = ats_write },
7688 { .name = "ATS1CPWP",
7689 .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
7690 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
7691 .writefn = ats_write },
7692 REGINFO_SENTINEL
7693};
7694#endif
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
7706 { .name = "ACTLR2", .state = ARM_CP_STATE_AA32,
7707 .cp = 15, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 3,
7708 .access = PL1_RW, .accessfn = access_tacr,
7709 .type = ARM_CP_CONST, .resetvalue = 0 },
7710 { .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
7711 .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
7712 .access = PL2_RW, .type = ARM_CP_CONST,
7713 .resetvalue = 0 },
7714 REGINFO_SENTINEL
7715};
7716
7717void register_cp_regs_for_features(ARMCPU *cpu)
7718{
7719
7720 CPUARMState *env = &cpu->env;
7721 if (arm_feature(env, ARM_FEATURE_M)) {
7722
7723 return;
7724 }
7725
7726 define_arm_cp_regs(cpu, cp_reginfo);
7727 if (!arm_feature(env, ARM_FEATURE_V8)) {
7728
7729
7730
7731 define_arm_cp_regs(cpu, not_v8_cp_reginfo);
7732 }
7733
7734 if (arm_feature(env, ARM_FEATURE_V6)) {
7735
7736 ARMCPRegInfo v6_idregs[] = {
7737 { .name = "ID_PFR0", .state = ARM_CP_STATE_BOTH,
7738 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
7739 .access = PL1_R, .type = ARM_CP_CONST,
7740 .accessfn = access_aa32_tid3,
7741 .resetvalue = cpu->isar.id_pfr0 },
7742
7743
7744
7745 { .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH,
7746 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1,
7747 .access = PL1_R, .type = ARM_CP_NO_RAW,
7748 .accessfn = access_aa32_tid3,
7749 .readfn = id_pfr1_read,
7750 .writefn = arm_cp_write_ignore },
7751 { .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH,
7752 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
7753 .access = PL1_R, .type = ARM_CP_CONST,
7754 .accessfn = access_aa32_tid3,
7755 .resetvalue = cpu->isar.id_dfr0 },
7756 { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
7757 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
7758 .access = PL1_R, .type = ARM_CP_CONST,
7759 .accessfn = access_aa32_tid3,
7760 .resetvalue = cpu->id_afr0 },
7761 { .name = "ID_MMFR0", .state = ARM_CP_STATE_BOTH,
7762 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4,
7763 .access = PL1_R, .type = ARM_CP_CONST,
7764 .accessfn = access_aa32_tid3,
7765 .resetvalue = cpu->isar.id_mmfr0 },
7766 { .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,
7767 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,
7768 .access = PL1_R, .type = ARM_CP_CONST,
7769 .accessfn = access_aa32_tid3,
7770 .resetvalue = cpu->isar.id_mmfr1 },
7771 { .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,
7772 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,
7773 .access = PL1_R, .type = ARM_CP_CONST,
7774 .accessfn = access_aa32_tid3,
7775 .resetvalue = cpu->isar.id_mmfr2 },
7776 { .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,
7777 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,
7778 .access = PL1_R, .type = ARM_CP_CONST,
7779 .accessfn = access_aa32_tid3,
7780 .resetvalue = cpu->isar.id_mmfr3 },
7781 { .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
7782 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
7783 .access = PL1_R, .type = ARM_CP_CONST,
7784 .accessfn = access_aa32_tid3,
7785 .resetvalue = cpu->isar.id_isar0 },
7786 { .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH,
7787 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1,
7788 .access = PL1_R, .type = ARM_CP_CONST,
7789 .accessfn = access_aa32_tid3,
7790 .resetvalue = cpu->isar.id_isar1 },
7791 { .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH,
7792 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
7793 .access = PL1_R, .type = ARM_CP_CONST,
7794 .accessfn = access_aa32_tid3,
7795 .resetvalue = cpu->isar.id_isar2 },
7796 { .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH,
7797 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3,
7798 .access = PL1_R, .type = ARM_CP_CONST,
7799 .accessfn = access_aa32_tid3,
7800 .resetvalue = cpu->isar.id_isar3 },
7801 { .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH,
7802 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4,
7803 .access = PL1_R, .type = ARM_CP_CONST,
7804 .accessfn = access_aa32_tid3,
7805 .resetvalue = cpu->isar.id_isar4 },
7806 { .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH,
7807 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,
7808 .access = PL1_R, .type = ARM_CP_CONST,
7809 .accessfn = access_aa32_tid3,
7810 .resetvalue = cpu->isar.id_isar5 },
7811 { .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
7812 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
7813 .access = PL1_R, .type = ARM_CP_CONST,
7814 .accessfn = access_aa32_tid3,
7815 .resetvalue = cpu->isar.id_mmfr4 },
7816 { .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
7817 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
7818 .access = PL1_R, .type = ARM_CP_CONST,
7819 .accessfn = access_aa32_tid3,
7820 .resetvalue = cpu->isar.id_isar6 },
7821 REGINFO_SENTINEL
7822 };
7823 define_arm_cp_regs(cpu, v6_idregs);
7824 define_arm_cp_regs(cpu, v6_cp_reginfo);
7825 } else {
7826 define_arm_cp_regs(cpu, not_v6_cp_reginfo);
7827 }
7828 if (arm_feature(env, ARM_FEATURE_V6K)) {
7829 define_arm_cp_regs(cpu, v6k_cp_reginfo);
7830 }
7831 if (arm_feature(env, ARM_FEATURE_V7MP) &&
7832 !arm_feature(env, ARM_FEATURE_PMSA)) {
7833 define_arm_cp_regs(cpu, v7mp_cp_reginfo);
7834 }
7835 if (arm_feature(env, ARM_FEATURE_V7VE)) {
7836 define_arm_cp_regs(cpu, pmovsset_cp_reginfo);
7837 }
7838 if (arm_feature(env, ARM_FEATURE_V7)) {
7839 ARMCPRegInfo clidr = {
7840 .name = "CLIDR", .state = ARM_CP_STATE_BOTH,
7841 .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
7842 .access = PL1_R, .type = ARM_CP_CONST,
7843 .accessfn = access_aa64_tid2,
7844 .resetvalue = cpu->clidr
7845 };
7846 define_one_arm_cp_reg(cpu, &clidr);
7847 define_arm_cp_regs(cpu, v7_cp_reginfo);
7848 define_debug_regs(cpu);
7849 define_pmu_regs(cpu);
7850 } else {
7851 define_arm_cp_regs(cpu, not_v7_cp_reginfo);
7852 }
7853 if (arm_feature(env, ARM_FEATURE_V8)) {
7854
7855
7856
7857
7858
7859 ARMCPRegInfo v8_idregs[] = {
7860
7861
7862
7863
7864
7865 { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64,
7866 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0,
7867 .access = PL1_R,
7868#ifdef CONFIG_USER_ONLY
7869 .type = ARM_CP_CONST,
7870 .resetvalue = cpu->isar.id_aa64pfr0
7871#else
7872 .type = ARM_CP_NO_RAW,
7873 .accessfn = access_aa64_tid3,
7874 .readfn = id_aa64pfr0_read,
7875 .writefn = arm_cp_write_ignore
7876#endif
7877 },
7878 { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64,
7879 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
7880 .access = PL1_R, .type = ARM_CP_CONST,
7881 .accessfn = access_aa64_tid3,
7882 .resetvalue = cpu->isar.id_aa64pfr1},
7883 { .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7884 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,
7885 .access = PL1_R, .type = ARM_CP_CONST,
7886 .accessfn = access_aa64_tid3,
7887 .resetvalue = 0 },
7888 { .name = "ID_AA64PFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7889 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 3,
7890 .access = PL1_R, .type = ARM_CP_CONST,
7891 .accessfn = access_aa64_tid3,
7892 .resetvalue = 0 },
7893 { .name = "ID_AA64ZFR0_EL1", .state = ARM_CP_STATE_AA64,
7894 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4,
7895 .access = PL1_R, .type = ARM_CP_CONST,
7896 .accessfn = access_aa64_tid3,
7897 .resetvalue = cpu->isar.id_aa64zfr0 },
7898 { .name = "ID_AA64PFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7899 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,
7900 .access = PL1_R, .type = ARM_CP_CONST,
7901 .accessfn = access_aa64_tid3,
7902 .resetvalue = 0 },
7903 { .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7904 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6,
7905 .access = PL1_R, .type = ARM_CP_CONST,
7906 .accessfn = access_aa64_tid3,
7907 .resetvalue = 0 },
7908 { .name = "ID_AA64PFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7909 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 7,
7910 .access = PL1_R, .type = ARM_CP_CONST,
7911 .accessfn = access_aa64_tid3,
7912 .resetvalue = 0 },
7913 { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64,
7914 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
7915 .access = PL1_R, .type = ARM_CP_CONST,
7916 .accessfn = access_aa64_tid3,
7917 .resetvalue = cpu->isar.id_aa64dfr0 },
7918 { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
7919 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
7920 .access = PL1_R, .type = ARM_CP_CONST,
7921 .accessfn = access_aa64_tid3,
7922 .resetvalue = cpu->isar.id_aa64dfr1 },
7923 { .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7924 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
7925 .access = PL1_R, .type = ARM_CP_CONST,
7926 .accessfn = access_aa64_tid3,
7927 .resetvalue = 0 },
7928 { .name = "ID_AA64DFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7929 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 3,
7930 .access = PL1_R, .type = ARM_CP_CONST,
7931 .accessfn = access_aa64_tid3,
7932 .resetvalue = 0 },
7933 { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64,
7934 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4,
7935 .access = PL1_R, .type = ARM_CP_CONST,
7936 .accessfn = access_aa64_tid3,
7937 .resetvalue = cpu->id_aa64afr0 },
7938 { .name = "ID_AA64AFR1_EL1", .state = ARM_CP_STATE_AA64,
7939 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5,
7940 .access = PL1_R, .type = ARM_CP_CONST,
7941 .accessfn = access_aa64_tid3,
7942 .resetvalue = cpu->id_aa64afr1 },
7943 { .name = "ID_AA64AFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7944 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 6,
7945 .access = PL1_R, .type = ARM_CP_CONST,
7946 .accessfn = access_aa64_tid3,
7947 .resetvalue = 0 },
7948 { .name = "ID_AA64AFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7949 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 7,
7950 .access = PL1_R, .type = ARM_CP_CONST,
7951 .accessfn = access_aa64_tid3,
7952 .resetvalue = 0 },
7953 { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,
7954 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
7955 .access = PL1_R, .type = ARM_CP_CONST,
7956 .accessfn = access_aa64_tid3,
7957 .resetvalue = cpu->isar.id_aa64isar0 },
7958 { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
7959 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
7960 .access = PL1_R, .type = ARM_CP_CONST,
7961 .accessfn = access_aa64_tid3,
7962 .resetvalue = cpu->isar.id_aa64isar1 },
7963 { .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7964 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
7965 .access = PL1_R, .type = ARM_CP_CONST,
7966 .accessfn = access_aa64_tid3,
7967 .resetvalue = 0 },
7968 { .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7969 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3,
7970 .access = PL1_R, .type = ARM_CP_CONST,
7971 .accessfn = access_aa64_tid3,
7972 .resetvalue = 0 },
7973 { .name = "ID_AA64ISAR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7974 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 4,
7975 .access = PL1_R, .type = ARM_CP_CONST,
7976 .accessfn = access_aa64_tid3,
7977 .resetvalue = 0 },
7978 { .name = "ID_AA64ISAR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7979 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 5,
7980 .access = PL1_R, .type = ARM_CP_CONST,
7981 .accessfn = access_aa64_tid3,
7982 .resetvalue = 0 },
7983 { .name = "ID_AA64ISAR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7984 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 6,
7985 .access = PL1_R, .type = ARM_CP_CONST,
7986 .accessfn = access_aa64_tid3,
7987 .resetvalue = 0 },
7988 { .name = "ID_AA64ISAR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7989 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 7,
7990 .access = PL1_R, .type = ARM_CP_CONST,
7991 .accessfn = access_aa64_tid3,
7992 .resetvalue = 0 },
7993 { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,
7994 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
7995 .access = PL1_R, .type = ARM_CP_CONST,
7996 .accessfn = access_aa64_tid3,
7997 .resetvalue = cpu->isar.id_aa64mmfr0 },
7998 { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
7999 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
8000 .access = PL1_R, .type = ARM_CP_CONST,
8001 .accessfn = access_aa64_tid3,
8002 .resetvalue = cpu->isar.id_aa64mmfr1 },
8003 { .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64,
8004 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
8005 .access = PL1_R, .type = ARM_CP_CONST,
8006 .accessfn = access_aa64_tid3,
8007 .resetvalue = cpu->isar.id_aa64mmfr2 },
8008 { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
8009 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
8010 .access = PL1_R, .type = ARM_CP_CONST,
8011 .accessfn = access_aa64_tid3,
8012 .resetvalue = 0 },
8013 { .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
8014 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
8015 .access = PL1_R, .type = ARM_CP_CONST,
8016 .accessfn = access_aa64_tid3,
8017 .resetvalue = 0 },
8018 { .name = "ID_AA64MMFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
8019 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 5,
8020 .access = PL1_R, .type = ARM_CP_CONST,
8021 .accessfn = access_aa64_tid3,
8022 .resetvalue = 0 },
8023 { .name = "ID_AA64MMFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
8024 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 6,
8025 .access = PL1_R, .type = ARM_CP_CONST,
8026 .accessfn = access_aa64_tid3,
8027 .resetvalue = 0 },
8028 { .name = "ID_AA64MMFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
8029 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 7,
8030 .access = PL1_R, .type = ARM_CP_CONST,
8031 .accessfn = access_aa64_tid3,
8032 .resetvalue = 0 },
8033 { .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64,
8034 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0,
8035 .access = PL1_R, .type = ARM_CP_CONST,
8036 .accessfn = access_aa64_tid3,
8037 .resetvalue = cpu->isar.mvfr0 },
8038 { .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64,
8039 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1,
8040 .access = PL1_R, .type = ARM_CP_CONST,
8041 .accessfn = access_aa64_tid3,
8042 .resetvalue = cpu->isar.mvfr1 },
8043 { .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64,
8044 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
8045 .access = PL1_R, .type = ARM_CP_CONST,
8046 .accessfn = access_aa64_tid3,
8047 .resetvalue = cpu->isar.mvfr2 },
8048 { .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
8049 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3,
8050 .access = PL1_R, .type = ARM_CP_CONST,
8051 .accessfn = access_aa64_tid3,
8052 .resetvalue = 0 },
8053 { .name = "ID_PFR2", .state = ARM_CP_STATE_BOTH,
8054 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
8055 .access = PL1_R, .type = ARM_CP_CONST,
8056 .accessfn = access_aa64_tid3,
8057 .resetvalue = cpu->isar.id_pfr2 },
8058 { .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
8059 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
8060 .access = PL1_R, .type = ARM_CP_CONST,
8061 .accessfn = access_aa64_tid3,
8062 .resetvalue = 0 },
8063 { .name = "MVFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
8064 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
8065 .access = PL1_R, .type = ARM_CP_CONST,
8066 .accessfn = access_aa64_tid3,
8067 .resetvalue = 0 },
8068 { .name = "MVFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
8069 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,
8070 .access = PL1_R, .type = ARM_CP_CONST,
8071 .accessfn = access_aa64_tid3,
8072 .resetvalue = 0 },
8073 { .name = "PMCEID0", .state = ARM_CP_STATE_AA32,
8074 .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6,
8075 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
8076 .resetvalue = extract64(cpu->pmceid0, 0, 32) },
8077 { .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64,
8078 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6,
8079 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
8080 .resetvalue = cpu->pmceid0 },
8081 { .name = "PMCEID1", .state = ARM_CP_STATE_AA32,
8082 .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 7,
8083 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
8084 .resetvalue = extract64(cpu->pmceid1, 0, 32) },
8085 { .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64,
8086 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,
8087 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
8088 .resetvalue = cpu->pmceid1 },
8089 REGINFO_SENTINEL
8090 };
8091#ifdef CONFIG_USER_ONLY
8092 ARMCPRegUserSpaceInfo v8_user_idregs[] = {
8093 { .name = "ID_AA64PFR0_EL1",
8094 .exported_bits = 0x000f000f00ff0000,
8095 .fixed_bits = 0x0000000000000011 },
8096 { .name = "ID_AA64PFR1_EL1",
8097 .exported_bits = 0x00000000000000f0 },
8098 { .name = "ID_AA64PFR*_EL1_RESERVED",
8099 .is_glob = true },
8100 { .name = "ID_AA64ZFR0_EL1" },
8101 { .name = "ID_AA64MMFR0_EL1",
8102 .fixed_bits = 0x00000000ff000000 },
8103 { .name = "ID_AA64MMFR1_EL1" },
8104 { .name = "ID_AA64MMFR*_EL1_RESERVED",
8105 .is_glob = true },
8106 { .name = "ID_AA64DFR0_EL1",
8107 .fixed_bits = 0x0000000000000006 },
8108 { .name = "ID_AA64DFR1_EL1" },
8109 { .name = "ID_AA64DFR*_EL1_RESERVED",
8110 .is_glob = true },
8111 { .name = "ID_AA64AFR*",
8112 .is_glob = true },
8113 { .name = "ID_AA64ISAR0_EL1",
8114 .exported_bits = 0x00fffffff0fffff0 },
8115 { .name = "ID_AA64ISAR1_EL1",
8116 .exported_bits = 0x000000f0ffffffff },
8117 { .name = "ID_AA64ISAR*_EL1_RESERVED",
8118 .is_glob = true },
8119 REGUSERINFO_SENTINEL
8120 };
8121 modify_arm_cp_regs(v8_idregs, v8_user_idregs);
8122#endif
8123
8124 if (!arm_feature(env, ARM_FEATURE_EL3) &&
8125 !arm_feature(env, ARM_FEATURE_EL2)) {
8126 ARMCPRegInfo rvbar = {
8127 .name = "RVBAR_EL1", .state = ARM_CP_STATE_AA64,
8128 .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
8129 .type = ARM_CP_CONST, .access = PL1_R, .resetvalue = cpu->rvbar
8130 };
8131 define_one_arm_cp_reg(cpu, &rvbar);
8132 }
8133 define_arm_cp_regs(cpu, v8_idregs);
8134 define_arm_cp_regs(cpu, v8_cp_reginfo);
8135 }
8136 if (arm_feature(env, ARM_FEATURE_EL2)) {
8137 uint64_t vmpidr_def = mpidr_read_val(env);
8138 ARMCPRegInfo vpidr_regs[] = {
8139 { .name = "VPIDR", .state = ARM_CP_STATE_AA32,
8140 .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
8141 .access = PL2_RW, .accessfn = access_el3_aa32ns,
8142 .resetvalue = cpu->midr, .type = ARM_CP_ALIAS,
8143 .fieldoffset = offsetoflow32(CPUARMState, cp15.vpidr_el2) },
8144 { .name = "VPIDR_EL2", .state = ARM_CP_STATE_AA64,
8145 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
8146 .access = PL2_RW, .resetvalue = cpu->midr,
8147 .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
8148 { .name = "VMPIDR", .state = ARM_CP_STATE_AA32,
8149 .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
8150 .access = PL2_RW, .accessfn = access_el3_aa32ns,
8151 .resetvalue = vmpidr_def, .type = ARM_CP_ALIAS,
8152 .fieldoffset = offsetoflow32(CPUARMState, cp15.vmpidr_el2) },
8153 { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_AA64,
8154 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
8155 .access = PL2_RW,
8156 .resetvalue = vmpidr_def,
8157 .fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
8158 REGINFO_SENTINEL
8159 };
8160 define_arm_cp_regs(cpu, vpidr_regs);
8161 define_arm_cp_regs(cpu, el2_cp_reginfo);
8162 if (arm_feature(env, ARM_FEATURE_V8)) {
8163 define_arm_cp_regs(cpu, el2_v8_cp_reginfo);
8164 }
8165 if (cpu_isar_feature(aa64_sel2, cpu)) {
8166 define_arm_cp_regs(cpu, el2_sec_cp_reginfo);
8167 }
8168
8169 if (!arm_feature(env, ARM_FEATURE_EL3)) {
8170 ARMCPRegInfo rvbar = {
8171 .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
8172 .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
8173 .type = ARM_CP_CONST, .access = PL2_R, .resetvalue = cpu->rvbar
8174 };
8175 define_one_arm_cp_reg(cpu, &rvbar);
8176 }
8177 } else {
8178
8179
8180
8181 if (arm_feature(env, ARM_FEATURE_EL3)) {
8182
8183
8184
8185 ARMCPRegInfo vpidr_regs[] = {
8186 { .name = "VPIDR_EL2", .state = ARM_CP_STATE_BOTH,
8187 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
8188 .access = PL2_RW, .accessfn = access_el3_aa32ns,
8189 .type = ARM_CP_CONST, .resetvalue = cpu->midr,
8190 .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
8191 { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_BOTH,
8192 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
8193 .access = PL2_RW, .accessfn = access_el3_aa32ns,
8194 .type = ARM_CP_NO_RAW,
8195 .writefn = arm_cp_write_ignore, .readfn = mpidr_read },
8196 REGINFO_SENTINEL
8197 };
8198 define_arm_cp_regs(cpu, vpidr_regs);
8199 define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);
8200 if (arm_feature(env, ARM_FEATURE_V8)) {
8201 define_arm_cp_regs(cpu, el3_no_el2_v8_cp_reginfo);
8202 }
8203 }
8204 }
8205 if (arm_feature(env, ARM_FEATURE_EL3)) {
8206 define_arm_cp_regs(cpu, el3_cp_reginfo);
8207 ARMCPRegInfo el3_regs[] = {
8208 { .name = "RVBAR_EL3", .state = ARM_CP_STATE_AA64,
8209 .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 1,
8210 .type = ARM_CP_CONST, .access = PL3_R, .resetvalue = cpu->rvbar },
8211 { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64,
8212 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 0,
8213 .access = PL3_RW,
8214 .raw_writefn = raw_write, .writefn = sctlr_write,
8215 .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]),
8216 .resetvalue = cpu->reset_sctlr },
8217 REGINFO_SENTINEL
8218 };
8219
8220 define_arm_cp_regs(cpu, el3_regs);
8221 }
8222
8223
8224
8225
8226
8227
8228
8229
8230 if (arm_feature(env, ARM_FEATURE_EL3)) {
8231 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
8232 ARMCPRegInfo nsacr = {
8233 .name = "NSACR", .type = ARM_CP_CONST,
8234 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
8235 .access = PL1_RW, .accessfn = nsacr_access,
8236 .resetvalue = 0xc00
8237 };
8238 define_one_arm_cp_reg(cpu, &nsacr);
8239 } else {
8240 ARMCPRegInfo nsacr = {
8241 .name = "NSACR",
8242 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
8243 .access = PL3_RW | PL1_R,
8244 .resetvalue = 0,
8245 .fieldoffset = offsetof(CPUARMState, cp15.nsacr)
8246 };
8247 define_one_arm_cp_reg(cpu, &nsacr);
8248 }
8249 } else {
8250 if (arm_feature(env, ARM_FEATURE_V8)) {
8251 ARMCPRegInfo nsacr = {
8252 .name = "NSACR", .type = ARM_CP_CONST,
8253 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
8254 .access = PL1_R,
8255 .resetvalue = 0xc00
8256 };
8257 define_one_arm_cp_reg(cpu, &nsacr);
8258 }
8259 }
8260
8261 if (arm_feature(env, ARM_FEATURE_PMSA)) {
8262 if (arm_feature(env, ARM_FEATURE_V6)) {
8263
8264 assert(arm_feature(env, ARM_FEATURE_V7));
8265 define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
8266 define_arm_cp_regs(cpu, pmsav7_cp_reginfo);
8267 } else {
8268 define_arm_cp_regs(cpu, pmsav5_cp_reginfo);
8269 }
8270 } else {
8271 define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
8272 define_arm_cp_regs(cpu, vmsa_cp_reginfo);
8273
8274 if (cpu_isar_feature(aa32_hpd, cpu)) {
8275 define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
8276 }
8277 }
8278 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
8279 define_arm_cp_regs(cpu, t2ee_cp_reginfo);
8280 }
8281 if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
8282 define_arm_cp_regs(cpu, generic_timer_cp_reginfo);
8283 }
8284 if (arm_feature(env, ARM_FEATURE_VAPA)) {
8285 define_arm_cp_regs(cpu, vapa_cp_reginfo);
8286 }
8287 if (arm_feature(env, ARM_FEATURE_CACHE_TEST_CLEAN)) {
8288 define_arm_cp_regs(cpu, cache_test_clean_cp_reginfo);
8289 }
8290 if (arm_feature(env, ARM_FEATURE_CACHE_DIRTY_REG)) {
8291 define_arm_cp_regs(cpu, cache_dirty_status_cp_reginfo);
8292 }
8293 if (arm_feature(env, ARM_FEATURE_CACHE_BLOCK_OPS)) {
8294 define_arm_cp_regs(cpu, cache_block_ops_cp_reginfo);
8295 }
8296 if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
8297 define_arm_cp_regs(cpu, omap_cp_reginfo);
8298 }
8299 if (arm_feature(env, ARM_FEATURE_STRONGARM)) {
8300 define_arm_cp_regs(cpu, strongarm_cp_reginfo);
8301 }
8302 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
8303 define_arm_cp_regs(cpu, xscale_cp_reginfo);
8304 }
8305 if (arm_feature(env, ARM_FEATURE_DUMMY_C15_REGS)) {
8306 define_arm_cp_regs(cpu, dummy_c15_cp_reginfo);
8307 }
8308 if (arm_feature(env, ARM_FEATURE_LPAE)) {
8309 define_arm_cp_regs(cpu, lpae_cp_reginfo);
8310 }
8311 if (cpu_isar_feature(aa32_jazelle, cpu)) {
8312 define_arm_cp_regs(cpu, jazelle_regs);
8313 }
8314
8315
8316
8317
8318 {
8319 ARMCPRegInfo id_pre_v8_midr_cp_reginfo[] = {
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329 { .name = "MIDR",
8330 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = CP_ANY,
8331 .access = PL1_R, .resetvalue = cpu->midr,
8332 .writefn = arm_cp_write_ignore, .raw_writefn = raw_write,
8333 .readfn = midr_read,
8334 .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
8335 .type = ARM_CP_OVERRIDE },
8336
8337 { .name = "DUMMY",
8338 .cp = 15, .crn = 0, .crm = 3, .opc1 = 0, .opc2 = CP_ANY,
8339 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
8340 { .name = "DUMMY",
8341 .cp = 15, .crn = 0, .crm = 4, .opc1 = 0, .opc2 = CP_ANY,
8342 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
8343 { .name = "DUMMY",
8344 .cp = 15, .crn = 0, .crm = 5, .opc1 = 0, .opc2 = CP_ANY,
8345 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
8346 { .name = "DUMMY",
8347 .cp = 15, .crn = 0, .crm = 6, .opc1 = 0, .opc2 = CP_ANY,
8348 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
8349 { .name = "DUMMY",
8350 .cp = 15, .crn = 0, .crm = 7, .opc1 = 0, .opc2 = CP_ANY,
8351 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
8352 REGINFO_SENTINEL
8353 };
8354 ARMCPRegInfo id_v8_midr_cp_reginfo[] = {
8355 { .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH,
8356 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 0,
8357 .access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr,
8358 .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
8359 .readfn = midr_read },
8360
8361 { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
8362 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
8363 .access = PL1_R, .resetvalue = cpu->midr },
8364 { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
8365 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7,
8366 .access = PL1_R, .resetvalue = cpu->midr },
8367 { .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,
8368 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
8369 .access = PL1_R,
8370 .accessfn = access_aa64_tid1,
8371 .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
8372 REGINFO_SENTINEL
8373 };
8374 ARMCPRegInfo id_cp_reginfo[] = {
8375
8376 { .name = "CTR",
8377 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
8378 .access = PL1_R, .accessfn = ctr_el0_access,
8379 .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
8380 { .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
8381 .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
8382 .access = PL0_R, .accessfn = ctr_el0_access,
8383 .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
8384
8385 { .name = "TCMTR",
8386 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2,
8387 .access = PL1_R,
8388 .accessfn = access_aa32_tid1,
8389 .type = ARM_CP_CONST, .resetvalue = 0 },
8390 REGINFO_SENTINEL
8391 };
8392
8393 ARMCPRegInfo id_tlbtr_reginfo = {
8394 .name = "TLBTR",
8395 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3,
8396 .access = PL1_R,
8397 .accessfn = access_aa32_tid1,
8398 .type = ARM_CP_CONST, .resetvalue = 0,
8399 };
8400
8401 ARMCPRegInfo id_mpuir_reginfo = {
8402 .name = "MPUIR",
8403 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
8404 .access = PL1_R, .type = ARM_CP_CONST,
8405 .resetvalue = cpu->pmsav7_dregion << 8
8406 };
8407 ARMCPRegInfo crn0_wi_reginfo = {
8408 .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
8409 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
8410 .type = ARM_CP_NOP | ARM_CP_OVERRIDE
8411 };
8412#ifdef CONFIG_USER_ONLY
8413 ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
8414 { .name = "MIDR_EL1",
8415 .exported_bits = 0x00000000ffffffff },
8416 { .name = "REVIDR_EL1" },
8417 REGUSERINFO_SENTINEL
8418 };
8419 modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo);
8420#endif
8421 if (arm_feature(env, ARM_FEATURE_OMAPCP) ||
8422 arm_feature(env, ARM_FEATURE_STRONGARM)) {
8423 ARMCPRegInfo *r;
8424
8425
8426
8427
8428
8429 define_one_arm_cp_reg(cpu, &crn0_wi_reginfo);
8430 for (r = id_pre_v8_midr_cp_reginfo;
8431 r->type != ARM_CP_SENTINEL; r++) {
8432 r->access = PL1_RW;
8433 }
8434 for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) {
8435 r->access = PL1_RW;
8436 }
8437 id_mpuir_reginfo.access = PL1_RW;
8438 id_tlbtr_reginfo.access = PL1_RW;
8439 }
8440 if (arm_feature(env, ARM_FEATURE_V8)) {
8441 define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo);
8442 } else {
8443 define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo);
8444 }
8445 define_arm_cp_regs(cpu, id_cp_reginfo);
8446 if (!arm_feature(env, ARM_FEATURE_PMSA)) {
8447 define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);
8448 } else if (arm_feature(env, ARM_FEATURE_V7)) {
8449 define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
8450 }
8451 }
8452
8453 if (arm_feature(env, ARM_FEATURE_MPIDR)) {
8454 ARMCPRegInfo mpidr_cp_reginfo[] = {
8455 { .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH,
8456 .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
8457 .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
8458 REGINFO_SENTINEL
8459 };
8460#ifdef CONFIG_USER_ONLY
8461 ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
8462 { .name = "MPIDR_EL1",
8463 .fixed_bits = 0x0000000080000000 },
8464 REGUSERINFO_SENTINEL
8465 };
8466 modify_arm_cp_regs(mpidr_cp_reginfo, mpidr_user_cp_reginfo);
8467#endif
8468 define_arm_cp_regs(cpu, mpidr_cp_reginfo);
8469 }
8470
8471 if (arm_feature(env, ARM_FEATURE_AUXCR)) {
8472 ARMCPRegInfo auxcr_reginfo[] = {
8473 { .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH,
8474 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1,
8475 .access = PL1_RW, .accessfn = access_tacr,
8476 .type = ARM_CP_CONST, .resetvalue = cpu->reset_auxcr },
8477 { .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH,
8478 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1,
8479 .access = PL2_RW, .type = ARM_CP_CONST,
8480 .resetvalue = 0 },
8481 { .name = "ACTLR_EL3", .state = ARM_CP_STATE_AA64,
8482 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 1,
8483 .access = PL3_RW, .type = ARM_CP_CONST,
8484 .resetvalue = 0 },
8485 REGINFO_SENTINEL
8486 };
8487 define_arm_cp_regs(cpu, auxcr_reginfo);
8488 if (cpu_isar_feature(aa32_ac2, cpu)) {
8489 define_arm_cp_regs(cpu, actlr2_hactlr2_reginfo);
8490 }
8491 }
8492
8493 if (arm_feature(env, ARM_FEATURE_CBAR)) {
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
8508
8509 uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
8510 | extract64(cpu->reset_cbar, 32, 12);
8511 ARMCPRegInfo cbar_reginfo[] = {
8512 { .name = "CBAR",
8513 .type = ARM_CP_CONST,
8514 .cp = 15, .crn = 15, .crm = 3, .opc1 = 1, .opc2 = 0,
8515 .access = PL1_R, .resetvalue = cbar32 },
8516 { .name = "CBAR_EL1", .state = ARM_CP_STATE_AA64,
8517 .type = ARM_CP_CONST,
8518 .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 0,
8519 .access = PL1_R, .resetvalue = cpu->reset_cbar },
8520 REGINFO_SENTINEL
8521 };
8522
8523 assert(arm_feature(env, ARM_FEATURE_CBAR_RO));
8524 define_arm_cp_regs(cpu, cbar_reginfo);
8525 } else {
8526 ARMCPRegInfo cbar = {
8527 .name = "CBAR",
8528 .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0,
8529 .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar,
8530 .fieldoffset = offsetof(CPUARMState,
8531 cp15.c15_config_base_address)
8532 };
8533 if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
8534 cbar.access = PL1_R;
8535 cbar.fieldoffset = 0;
8536 cbar.type = ARM_CP_CONST;
8537 }
8538 define_one_arm_cp_reg(cpu, &cbar);
8539 }
8540 }
8541
8542 if (arm_feature(env, ARM_FEATURE_VBAR)) {
8543 ARMCPRegInfo vbar_cp_reginfo[] = {
8544 { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
8545 .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
8546 .access = PL1_RW, .writefn = vbar_write,
8547 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
8548 offsetof(CPUARMState, cp15.vbar_ns) },
8549 .resetvalue = 0 },
8550 REGINFO_SENTINEL
8551 };
8552 define_arm_cp_regs(cpu, vbar_cp_reginfo);
8553 }
8554
8555
8556 {
8557 ARMCPRegInfo sctlr = {
8558 .name = "SCTLR", .state = ARM_CP_STATE_BOTH,
8559 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
8560 .access = PL1_RW, .accessfn = access_tvm_trvm,
8561 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
8562 offsetof(CPUARMState, cp15.sctlr_ns) },
8563 .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
8564 .raw_writefn = raw_write,
8565 };
8566 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
8567
8568
8569
8570
8571 sctlr.type |= ARM_CP_SUPPRESS_TB_END;
8572 }
8573 define_one_arm_cp_reg(cpu, &sctlr);
8574 }
8575
8576 if (cpu_isar_feature(aa64_lor, cpu)) {
8577 define_arm_cp_regs(cpu, lor_reginfo);
8578 }
8579 if (cpu_isar_feature(aa64_pan, cpu)) {
8580 define_one_arm_cp_reg(cpu, &pan_reginfo);
8581 }
8582#ifndef CONFIG_USER_ONLY
8583 if (cpu_isar_feature(aa64_ats1e1, cpu)) {
8584 define_arm_cp_regs(cpu, ats1e1_reginfo);
8585 }
8586 if (cpu_isar_feature(aa32_ats1e1, cpu)) {
8587 define_arm_cp_regs(cpu, ats1cp_reginfo);
8588 }
8589#endif
8590 if (cpu_isar_feature(aa64_uao, cpu)) {
8591 define_one_arm_cp_reg(cpu, &uao_reginfo);
8592 }
8593
8594 if (cpu_isar_feature(aa64_dit, cpu)) {
8595 define_one_arm_cp_reg(cpu, &dit_reginfo);
8596 }
8597 if (cpu_isar_feature(aa64_ssbs, cpu)) {
8598 define_one_arm_cp_reg(cpu, &ssbs_reginfo);
8599 }
8600
8601 if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
8602 define_arm_cp_regs(cpu, vhe_reginfo);
8603 }
8604
8605 if (cpu_isar_feature(aa64_sve, cpu)) {
8606 define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
8607 if (arm_feature(env, ARM_FEATURE_EL2)) {
8608 define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
8609 } else {
8610 define_one_arm_cp_reg(cpu, &zcr_no_el2_reginfo);
8611 }
8612 if (arm_feature(env, ARM_FEATURE_EL3)) {
8613 define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
8614 }
8615 }
8616
8617#ifdef TARGET_AARCH64
8618 if (cpu_isar_feature(aa64_pauth, cpu)) {
8619 define_arm_cp_regs(cpu, pauth_reginfo);
8620 }
8621 if (cpu_isar_feature(aa64_rndr, cpu)) {
8622 define_arm_cp_regs(cpu, rndr_reginfo);
8623 }
8624 if (cpu_isar_feature(aa64_tlbirange, cpu)) {
8625 define_arm_cp_regs(cpu, tlbirange_reginfo);
8626 }
8627 if (cpu_isar_feature(aa64_tlbios, cpu)) {
8628 define_arm_cp_regs(cpu, tlbios_reginfo);
8629 }
8630#ifndef CONFIG_USER_ONLY
8631
8632 if (cpu_isar_feature(aa64_dcpop, cpu)) {
8633 define_one_arm_cp_reg(cpu, dcpop_reg);
8634
8635 if (cpu_isar_feature(aa64_dcpodp, cpu)) {
8636 define_one_arm_cp_reg(cpu, dcpodp_reg);
8637 }
8638 }
8639#endif
8640
8641
8642
8643
8644
8645
8646 if (cpu_isar_feature(aa64_mte, cpu)) {
8647 define_arm_cp_regs(cpu, mte_reginfo);
8648 define_arm_cp_regs(cpu, mte_el0_cacheop_reginfo);
8649 } else if (cpu_isar_feature(aa64_mte_insn_reg, cpu)) {
8650 define_arm_cp_regs(cpu, mte_tco_ro_reginfo);
8651 define_arm_cp_regs(cpu, mte_el0_cacheop_reginfo);
8652 }
8653#endif
8654
8655 if (cpu_isar_feature(any_predinv, cpu)) {
8656 define_arm_cp_regs(cpu, predinv_reginfo);
8657 }
8658
8659 if (cpu_isar_feature(any_ccidx, cpu)) {
8660 define_arm_cp_regs(cpu, ccsidr2_reginfo);
8661 }
8662
8663#ifndef CONFIG_USER_ONLY
8664
8665
8666
8667
8668 if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
8669 define_arm_vh_e2h_redirects_aliases(cpu);
8670 }
8671#endif
8672}
8673
8674void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
8675{
8676 CPUState *cs = CPU(cpu);
8677 CPUARMState *env = &cpu->env;
8678
8679 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
8680
8681
8682
8683
8684#ifdef TARGET_AARCH64
8685 if (isar_feature_aa64_sve(&cpu->isar)) {
8686 gdb_register_coprocessor(cs, arm_gdb_get_svereg, arm_gdb_set_svereg,
8687 arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs),
8688 "sve-registers.xml", 0);
8689 } else
8690#endif
8691 {
8692 gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg,
8693 aarch64_fpu_gdb_set_reg,
8694 34, "aarch64-fpu.xml", 0);
8695 }
8696 } else if (arm_feature(env, ARM_FEATURE_NEON)) {
8697 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
8698 51, "arm-neon.xml", 0);
8699 } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
8700 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
8701 35, "arm-vfp3.xml", 0);
8702 } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
8703 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
8704 19, "arm-vfp.xml", 0);
8705 }
8706 gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
8707 arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
8708 "system-registers.xml", 0);
8709
8710}
8711
8712
8713static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b)
8714{
8715 ObjectClass *class_a = (ObjectClass *)a;
8716 ObjectClass *class_b = (ObjectClass *)b;
8717 const char *name_a, *name_b;
8718
8719 name_a = object_class_get_name(class_a);
8720 name_b = object_class_get_name(class_b);
8721 if (strcmp(name_a, "any-" TYPE_ARM_CPU) == 0) {
8722 return 1;
8723 } else if (strcmp(name_b, "any-" TYPE_ARM_CPU) == 0) {
8724 return -1;
8725 } else {
8726 return strcmp(name_a, name_b);
8727 }
8728}
8729
8730static void arm_cpu_list_entry(gpointer data, gpointer user_data)
8731{
8732 ObjectClass *oc = data;
8733 const char *typename;
8734 char *name;
8735
8736 typename = object_class_get_name(oc);
8737 name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_ARM_CPU));
8738 qemu_printf(" %s\n", name);
8739 g_free(name);
8740}
8741
8742void arm_cpu_list(void)
8743{
8744 GSList *list;
8745
8746 list = object_class_get_list(TYPE_ARM_CPU, false);
8747 list = g_slist_sort(list, arm_cpu_list_compare);
8748 qemu_printf("Available CPUs:\n");
8749 g_slist_foreach(list, arm_cpu_list_entry, NULL);
8750 g_slist_free(list);
8751}
8752
8753static void arm_cpu_add_definition(gpointer data, gpointer user_data)
8754{
8755 ObjectClass *oc = data;
8756 CpuDefinitionInfoList **cpu_list = user_data;
8757 CpuDefinitionInfo *info;
8758 const char *typename;
8759
8760 typename = object_class_get_name(oc);
8761 info = g_malloc0(sizeof(*info));
8762 info->name = g_strndup(typename,
8763 strlen(typename) - strlen("-" TYPE_ARM_CPU));
8764 info->q_typename = g_strdup(typename);
8765
8766 QAPI_LIST_PREPEND(*cpu_list, info);
8767}
8768
8769CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
8770{
8771 CpuDefinitionInfoList *cpu_list = NULL;
8772 GSList *list;
8773
8774 list = object_class_get_list(TYPE_ARM_CPU, false);
8775 g_slist_foreach(list, arm_cpu_add_definition, &cpu_list);
8776 g_slist_free(list);
8777
8778 return cpu_list;
8779}
8780
8781static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
8782 void *opaque, int state, int secstate,
8783 int crm, int opc1, int opc2,
8784 const char *name)
8785{
8786
8787
8788
8789 uint32_t *key = g_new(uint32_t, 1);
8790 ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
8791 int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
8792 int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
8793
8794 r2->name = g_strdup(name);
8795
8796
8797
8798 r2->secure = secstate;
8799
8800 if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
8801
8802
8803
8804
8805 r2->fieldoffset = r->bank_fieldoffsets[ns];
8806 }
8807
8808 if (state == ARM_CP_STATE_AA32) {
8809 if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820 if ((r->state == ARM_CP_STATE_BOTH && ns) ||
8821 (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
8822 r2->type |= ARM_CP_ALIAS;
8823 }
8824 } else if ((secstate != r->secure) && !ns) {
8825
8826
8827
8828 r2->type |= ARM_CP_ALIAS;
8829 }
8830
8831 if (r->state == ARM_CP_STATE_BOTH) {
8832
8833
8834 if (r2->cp == 0) {
8835 r2->cp = 15;
8836 }
8837
8838#ifdef HOST_WORDS_BIGENDIAN
8839 if (r2->fieldoffset) {
8840 r2->fieldoffset += sizeof(uint32_t);
8841 }
8842#endif
8843 }
8844 }
8845 if (state == ARM_CP_STATE_AA64) {
8846
8847
8848
8849
8850
8851
8852
8853 if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
8854 r2->cp = CP_REG_ARM64_SYSREG_CP;
8855 }
8856 *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
8857 r2->opc0, opc1, opc2);
8858 } else {
8859 *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
8860 }
8861 if (opaque) {
8862 r2->opaque = opaque;
8863 }
8864
8865
8866
8867 r2->state = state;
8868
8869
8870
8871 r2->crm = crm;
8872 r2->opc1 = opc1;
8873 r2->opc2 = opc2;
8874
8875
8876
8877
8878
8879
8880 if ((r->type & ARM_CP_SPECIAL)) {
8881 r2->type |= ARM_CP_NO_RAW;
8882 }
8883 if (((r->crm == CP_ANY) && crm != 0) ||
8884 ((r->opc1 == CP_ANY) && opc1 != 0) ||
8885 ((r->opc2 == CP_ANY) && opc2 != 0)) {
8886 r2->type |= ARM_CP_ALIAS | ARM_CP_NO_GDB;
8887 }
8888
8889
8890
8891
8892
8893 if (!(r2->type & ARM_CP_NO_RAW)) {
8894 assert(!raw_accessors_invalid(r2));
8895 }
8896
8897
8898
8899
8900 if (!(r->type & ARM_CP_OVERRIDE)) {
8901 ARMCPRegInfo *oldreg;
8902 oldreg = g_hash_table_lookup(cpu->cp_regs, key);
8903 if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
8904 fprintf(stderr, "Register redefined: cp=%d %d bit "
8905 "crn=%d crm=%d opc1=%d opc2=%d, "
8906 "was %s, now %s\n", r2->cp, 32 + 32 * is64,
8907 r2->crn, r2->crm, r2->opc1, r2->opc2,
8908 oldreg->name, r2->name);
8909 g_assert_not_reached();
8910 }
8911 }
8912 g_hash_table_insert(cpu->cp_regs, key, r2);
8913}
8914
8915
8916void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
8917 const ARMCPRegInfo *r, void *opaque)
8918{
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942 int crm, opc1, opc2, state;
8943 int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
8944 int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
8945 int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
8946 int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
8947 int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
8948 int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
8949
8950 assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
8951
8952 assert((r->state != ARM_CP_STATE_AA32) || (r->opc0 == 0));
8953
8954 assert((r->state != ARM_CP_STATE_AA64) || !(r->type & ARM_CP_64BIT));
8955
8956
8957
8958
8959
8960
8961
8962
8963 switch (r->state) {
8964 case ARM_CP_STATE_BOTH:
8965
8966 if (r->cp == 0) {
8967 break;
8968 }
8969
8970 case ARM_CP_STATE_AA32:
8971 if (arm_feature(&cpu->env, ARM_FEATURE_V8) &&
8972 !arm_feature(&cpu->env, ARM_FEATURE_M)) {
8973 assert(r->cp >= 14 && r->cp <= 15);
8974 } else {
8975 assert(r->cp < 8 || (r->cp >= 14 && r->cp <= 15));
8976 }
8977 break;
8978 case ARM_CP_STATE_AA64:
8979 assert(r->cp == 0 || r->cp == CP_REG_ARM64_SYSREG_CP);
8980 break;
8981 default:
8982 g_assert_not_reached();
8983 }
8984
8985
8986
8987
8988
8989
8990 if (r->state != ARM_CP_STATE_AA32) {
8991 int mask = 0;
8992 switch (r->opc1) {
8993 case 0:
8994
8995 mask = PL0U_R | PL1_RW;
8996 break;
8997 case 1: case 2:
8998
8999 mask = PL1_RW;
9000 break;
9001 case 3:
9002
9003 mask = PL0_RW;
9004 break;
9005 case 4:
9006 case 5:
9007
9008 mask = PL2_RW;
9009 break;
9010 case 6:
9011
9012 mask = PL3_RW;
9013 break;
9014 case 7:
9015
9016 mask = PL1_RW;
9017 break;
9018 default:
9019
9020 assert(false);
9021 break;
9022 }
9023
9024 assert((r->access & ~mask) == 0);
9025 }
9026
9027
9028
9029
9030 if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
9031 if (r->access & PL3_R) {
9032 assert((r->fieldoffset ||
9033 (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
9034 r->readfn);
9035 }
9036 if (r->access & PL3_W) {
9037 assert((r->fieldoffset ||
9038 (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
9039 r->writefn);
9040 }
9041 }
9042
9043 assert(cptype_valid(r->type));
9044 for (crm = crmmin; crm <= crmmax; crm++) {
9045 for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
9046 for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
9047 for (state = ARM_CP_STATE_AA32;
9048 state <= ARM_CP_STATE_AA64; state++) {
9049 if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
9050 continue;
9051 }
9052 if (state == ARM_CP_STATE_AA32) {
9053
9054
9055
9056 char *name;
9057
9058 switch (r->secure) {
9059 case ARM_CP_SECSTATE_S:
9060 case ARM_CP_SECSTATE_NS:
9061 add_cpreg_to_hashtable(cpu, r, opaque, state,
9062 r->secure, crm, opc1, opc2,
9063 r->name);
9064 break;
9065 default:
9066 name = g_strdup_printf("%s_S", r->name);
9067 add_cpreg_to_hashtable(cpu, r, opaque, state,
9068 ARM_CP_SECSTATE_S,
9069 crm, opc1, opc2, name);
9070 g_free(name);
9071 add_cpreg_to_hashtable(cpu, r, opaque, state,
9072 ARM_CP_SECSTATE_NS,
9073 crm, opc1, opc2, r->name);
9074 break;
9075 }
9076 } else {
9077
9078
9079 add_cpreg_to_hashtable(cpu, r, opaque, state,
9080 ARM_CP_SECSTATE_NS,
9081 crm, opc1, opc2, r->name);
9082 }
9083 }
9084 }
9085 }
9086 }
9087}
9088
9089void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
9090 const ARMCPRegInfo *regs, void *opaque)
9091{
9092
9093 const ARMCPRegInfo *r;
9094 for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
9095 define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
9096 }
9097}
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
9108{
9109 const ARMCPRegUserSpaceInfo *m;
9110 ARMCPRegInfo *r;
9111
9112 for (m = mods; m->name; m++) {
9113 GPatternSpec *pat = NULL;
9114 if (m->is_glob) {
9115 pat = g_pattern_spec_new(m->name);
9116 }
9117 for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
9118 if (pat && g_pattern_match_string(pat, r->name)) {
9119 r->type = ARM_CP_CONST;
9120 r->access = PL0U_R;
9121 r->resetvalue = 0;
9122
9123 } else if (strcmp(r->name, m->name) == 0) {
9124 r->type = ARM_CP_CONST;
9125 r->access = PL0U_R;
9126 r->resetvalue &= m->exported_bits;
9127 r->resetvalue |= m->fixed_bits;
9128 break;
9129 }
9130 }
9131 if (pat) {
9132 g_pattern_spec_free(pat);
9133 }
9134 }
9135}
9136
9137const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
9138{
9139 return g_hash_table_lookup(cpregs, &encoded_cp);
9140}
9141
9142void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
9143 uint64_t value)
9144{
9145
9146}
9147
9148uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
9149{
9150
9151 return 0;
9152}
9153
9154void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
9155{
9156
9157}
9158
9159static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
9160{
9161
9162
9163
9164
9165
9166
9167 if (write_type == CPSRWriteByInstr &&
9168 ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_HYP ||
9169 mode == ARM_CPU_MODE_HYP)) {
9170 return 1;
9171 }
9172
9173 switch (mode) {
9174 case ARM_CPU_MODE_USR:
9175 return 0;
9176 case ARM_CPU_MODE_SYS:
9177 case ARM_CPU_MODE_SVC:
9178 case ARM_CPU_MODE_ABT:
9179 case ARM_CPU_MODE_UND:
9180 case ARM_CPU_MODE_IRQ:
9181 case ARM_CPU_MODE_FIQ:
9182
9183
9184
9185
9186
9187
9188 if (write_type == CPSRWriteByInstr &&
9189 (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON &&
9190 (arm_hcr_el2_eff(env) & HCR_TGE)) {
9191 return 1;
9192 }
9193 return 0;
9194 case ARM_CPU_MODE_HYP:
9195 return !arm_is_el2_enabled(env) || arm_current_el(env) < 2;
9196 case ARM_CPU_MODE_MON:
9197 return arm_current_el(env) < 3;
9198 default:
9199 return 1;
9200 }
9201}
9202
9203uint32_t cpsr_read(CPUARMState *env)
9204{
9205 int ZF;
9206 ZF = (env->ZF == 0);
9207 return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) |
9208 (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
9209 | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
9210 | ((env->condexec_bits & 0xfc) << 8)
9211 | (env->GE << 16) | (env->daif & CPSR_AIF);
9212}
9213
9214void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
9215 CPSRWriteType write_type)
9216{
9217 uint32_t changed_daif;
9218
9219 if (mask & CPSR_NZCV) {
9220 env->ZF = (~val) & CPSR_Z;
9221 env->NF = val;
9222 env->CF = (val >> 29) & 1;
9223 env->VF = (val << 3) & 0x80000000;
9224 }
9225 if (mask & CPSR_Q)
9226 env->QF = ((val & CPSR_Q) != 0);
9227 if (mask & CPSR_T)
9228 env->thumb = ((val & CPSR_T) != 0);
9229 if (mask & CPSR_IT_0_1) {
9230 env->condexec_bits &= ~3;
9231 env->condexec_bits |= (val >> 25) & 3;
9232 }
9233 if (mask & CPSR_IT_2_7) {
9234 env->condexec_bits &= 3;
9235 env->condexec_bits |= (val >> 8) & 0xfc;
9236 }
9237 if (mask & CPSR_GE) {
9238 env->GE = (val >> 16) & 0xf;
9239 }
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249 if (write_type != CPSRWriteRaw && !arm_feature(env, ARM_FEATURE_V8) &&
9250 arm_feature(env, ARM_FEATURE_EL3) &&
9251 !arm_feature(env, ARM_FEATURE_EL2) &&
9252 !arm_is_secure(env)) {
9253
9254 changed_daif = (env->daif ^ val) & mask;
9255
9256 if (changed_daif & CPSR_A) {
9257
9258
9259
9260 if (!(env->cp15.scr_el3 & SCR_AW)) {
9261 qemu_log_mask(LOG_GUEST_ERROR,
9262 "Ignoring attempt to switch CPSR_A flag from "
9263 "non-secure world with SCR.AW bit clear\n");
9264 mask &= ~CPSR_A;
9265 }
9266 }
9267
9268 if (changed_daif & CPSR_F) {
9269
9270
9271
9272 if (!(env->cp15.scr_el3 & SCR_FW)) {
9273 qemu_log_mask(LOG_GUEST_ERROR,
9274 "Ignoring attempt to switch CPSR_F flag from "
9275 "non-secure world with SCR.FW bit clear\n");
9276 mask &= ~CPSR_F;
9277 }
9278
9279
9280
9281
9282
9283 if ((A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_NMFI) &&
9284 (val & CPSR_F)) {
9285 qemu_log_mask(LOG_GUEST_ERROR,
9286 "Ignoring attempt to enable CPSR_F flag "
9287 "(non-maskable FIQ [NMFI] support enabled)\n");
9288 mask &= ~CPSR_F;
9289 }
9290 }
9291 }
9292
9293 env->daif &= ~(CPSR_AIF & mask);
9294 env->daif |= val & CPSR_AIF & mask;
9295
9296 if (write_type != CPSRWriteRaw &&
9297 ((env->uncached_cpsr ^ val) & mask & CPSR_M)) {
9298 if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) {
9299
9300
9301
9302
9303
9304
9305 mask &= ~CPSR_M;
9306 } else if (bad_mode_switch(env, val & CPSR_M, write_type)) {
9307
9308
9309
9310
9311
9312
9313
9314
9315 mask &= ~CPSR_M;
9316 if (write_type != CPSRWriteByGDBStub &&
9317 arm_feature(env, ARM_FEATURE_V8)) {
9318 mask |= CPSR_IL;
9319 val |= CPSR_IL;
9320 }
9321 qemu_log_mask(LOG_GUEST_ERROR,
9322 "Illegal AArch32 mode switch attempt from %s to %s\n",
9323 aarch32_mode_name(env->uncached_cpsr),
9324 aarch32_mode_name(val));
9325 } else {
9326 qemu_log_mask(CPU_LOG_INT, "%s %s to %s PC 0x%" PRIx32 "\n",
9327 write_type == CPSRWriteExceptionReturn ?
9328 "Exception return from AArch32" :
9329 "AArch32 mode switch from",
9330 aarch32_mode_name(env->uncached_cpsr),
9331 aarch32_mode_name(val), env->regs[15]);
9332 switch_mode(env, val & CPSR_M);
9333 }
9334 }
9335 mask &= ~CACHED_CPSR_BITS;
9336 env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
9337}
9338
9339
9340uint32_t HELPER(sxtb16)(uint32_t x)
9341{
9342 uint32_t res;
9343 res = (uint16_t)(int8_t)x;
9344 res |= (uint32_t)(int8_t)(x >> 16) << 16;
9345 return res;
9346}
9347
9348uint32_t HELPER(uxtb16)(uint32_t x)
9349{
9350 uint32_t res;
9351 res = (uint16_t)(uint8_t)x;
9352 res |= (uint32_t)(uint8_t)(x >> 16) << 16;
9353 return res;
9354}
9355
9356int32_t HELPER(sdiv)(int32_t num, int32_t den)
9357{
9358 if (den == 0)
9359 return 0;
9360 if (num == INT_MIN && den == -1)
9361 return INT_MIN;
9362 return num / den;
9363}
9364
9365uint32_t HELPER(udiv)(uint32_t num, uint32_t den)
9366{
9367 if (den == 0)
9368 return 0;
9369 return num / den;
9370}
9371
9372uint32_t HELPER(rbit)(uint32_t x)
9373{
9374 return revbit32(x);
9375}
9376
9377#ifdef CONFIG_USER_ONLY
9378
9379static void switch_mode(CPUARMState *env, int mode)
9380{
9381 ARMCPU *cpu = env_archcpu(env);
9382
9383 if (mode != ARM_CPU_MODE_USR) {
9384 cpu_abort(CPU(cpu), "Tried to switch out of user mode\n");
9385 }
9386}
9387
9388uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
9389 uint32_t cur_el, bool secure)
9390{
9391 return 1;
9392}
9393
9394void aarch64_sync_64_to_32(CPUARMState *env)
9395{
9396 g_assert_not_reached();
9397}
9398
9399#else
9400
9401static void switch_mode(CPUARMState *env, int mode)
9402{
9403 int old_mode;
9404 int i;
9405
9406 old_mode = env->uncached_cpsr & CPSR_M;
9407 if (mode == old_mode)
9408 return;
9409
9410 if (old_mode == ARM_CPU_MODE_FIQ) {
9411 memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
9412 memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
9413 } else if (mode == ARM_CPU_MODE_FIQ) {
9414 memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
9415 memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
9416 }
9417
9418 i = bank_number(old_mode);
9419 env->banked_r13[i] = env->regs[13];
9420 env->banked_spsr[i] = env->spsr;
9421
9422 i = bank_number(mode);
9423 env->regs[13] = env->banked_r13[i];
9424 env->spsr = env->banked_spsr[i];
9425
9426 env->banked_r14[r14_bank_number(old_mode)] = env->regs[14];
9427 env->regs[14] = env->banked_r14[r14_bank_number(mode)];
9428}
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
9445
9446
9447
9448
9449
9450
9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467static const int8_t target_el_table[2][2][2][2][2][4] = {
9468 {{{{{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },},
9469 {{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},},
9470 {{{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },},
9471 {{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},},},
9472 {{{{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},
9473 {{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},},
9474 {{{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},
9475 {{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},},},},
9476 {{{{{ 1, 1, 2, -1 },{ 1, 1, -1, 1 },},
9477 {{ 2, 2, 2, -1 },{ 2, 2, -1, 1 },},},
9478 {{{ 1, 1, 1, -1 },{ 1, 1, 1, 1 },},
9479 {{ 2, 2, 2, -1 },{ 2, 2, 2, 1 },},},},
9480 {{{{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},
9481 {{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},},
9482 {{{ 3, 3, 3, -1 },{ 3, 3, 3, 3 },},
9483 {{ 3, 3, 3, -1 },{ 3, 3, 3, 3 },},},},},
9484};
9485
9486
9487
9488
9489uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
9490 uint32_t cur_el, bool secure)
9491{
9492 CPUARMState *env = cs->env_ptr;
9493 bool rw;
9494 bool scr;
9495 bool hcr;
9496 int target_el;
9497
9498 bool is64 = arm_feature(env, ARM_FEATURE_AARCH64);
9499 uint64_t hcr_el2;
9500
9501 if (arm_feature(env, ARM_FEATURE_EL3)) {
9502 rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
9503 } else {
9504
9505
9506
9507
9508 rw = is64;
9509 }
9510
9511 hcr_el2 = arm_hcr_el2_eff(env);
9512 switch (excp_idx) {
9513 case EXCP_IRQ:
9514 scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
9515 hcr = hcr_el2 & HCR_IMO;
9516 break;
9517 case EXCP_FIQ:
9518 scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
9519 hcr = hcr_el2 & HCR_FMO;
9520 break;
9521 default:
9522 scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA);
9523 hcr = hcr_el2 & HCR_AMO;
9524 break;
9525 };
9526
9527
9528
9529
9530
9531 hcr |= (hcr_el2 & HCR_TGE) != 0;
9532
9533
9534 target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el];
9535
9536 assert(target_el > 0);
9537
9538 return target_el;
9539}
9540
9541void arm_log_exception(int idx)
9542{
9543 if (qemu_loglevel_mask(CPU_LOG_INT)) {
9544 const char *exc = NULL;
9545 static const char * const excnames[] = {
9546 [EXCP_UDEF] = "Undefined Instruction",
9547 [EXCP_SWI] = "SVC",
9548 [EXCP_PREFETCH_ABORT] = "Prefetch Abort",
9549 [EXCP_DATA_ABORT] = "Data Abort",
9550 [EXCP_IRQ] = "IRQ",
9551 [EXCP_FIQ] = "FIQ",
9552 [EXCP_BKPT] = "Breakpoint",
9553 [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
9554 [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
9555 [EXCP_HVC] = "Hypervisor Call",
9556 [EXCP_HYP_TRAP] = "Hypervisor Trap",
9557 [EXCP_SMC] = "Secure Monitor Call",
9558 [EXCP_VIRQ] = "Virtual IRQ",
9559 [EXCP_VFIQ] = "Virtual FIQ",
9560 [EXCP_SEMIHOST] = "Semihosting call",
9561 [EXCP_NOCP] = "v7M NOCP UsageFault",
9562 [EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
9563 [EXCP_STKOF] = "v8M STKOF UsageFault",
9564 [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
9565 [EXCP_LSERR] = "v8M LSERR UsageFault",
9566 [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
9567 };
9568
9569 if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
9570 exc = excnames[idx];
9571 }
9572 if (!exc) {
9573 exc = "unknown";
9574 }
9575 qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
9576 }
9577}
9578
9579
9580
9581
9582
9583
9584void aarch64_sync_32_to_64(CPUARMState *env)
9585{
9586 int i;
9587 uint32_t mode = env->uncached_cpsr & CPSR_M;
9588
9589
9590 for (i = 0; i < 8; i++) {
9591 env->xregs[i] = env->regs[i];
9592 }
9593
9594
9595
9596
9597
9598 if (mode == ARM_CPU_MODE_FIQ) {
9599 for (i = 8; i < 13; i++) {
9600 env->xregs[i] = env->usr_regs[i - 8];
9601 }
9602 } else {
9603 for (i = 8; i < 13; i++) {
9604 env->xregs[i] = env->regs[i];
9605 }
9606 }
9607
9608
9609
9610
9611
9612
9613 if (mode == ARM_CPU_MODE_USR || mode == ARM_CPU_MODE_SYS) {
9614 env->xregs[13] = env->regs[13];
9615 env->xregs[14] = env->regs[14];
9616 } else {
9617 env->xregs[13] = env->banked_r13[bank_number(ARM_CPU_MODE_USR)];
9618
9619 if (mode == ARM_CPU_MODE_HYP) {
9620 env->xregs[14] = env->regs[14];
9621 } else {
9622 env->xregs[14] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_USR)];
9623 }
9624 }
9625
9626 if (mode == ARM_CPU_MODE_HYP) {
9627 env->xregs[15] = env->regs[13];
9628 } else {
9629 env->xregs[15] = env->banked_r13[bank_number(ARM_CPU_MODE_HYP)];
9630 }
9631
9632 if (mode == ARM_CPU_MODE_IRQ) {
9633 env->xregs[16] = env->regs[14];
9634 env->xregs[17] = env->regs[13];
9635 } else {
9636 env->xregs[16] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_IRQ)];
9637 env->xregs[17] = env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)];
9638 }
9639
9640 if (mode == ARM_CPU_MODE_SVC) {
9641 env->xregs[18] = env->regs[14];
9642 env->xregs[19] = env->regs[13];
9643 } else {
9644 env->xregs[18] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_SVC)];
9645 env->xregs[19] = env->banked_r13[bank_number(ARM_CPU_MODE_SVC)];
9646 }
9647
9648 if (mode == ARM_CPU_MODE_ABT) {
9649 env->xregs[20] = env->regs[14];
9650 env->xregs[21] = env->regs[13];
9651 } else {
9652 env->xregs[20] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_ABT)];
9653 env->xregs[21] = env->banked_r13[bank_number(ARM_CPU_MODE_ABT)];
9654 }
9655
9656 if (mode == ARM_CPU_MODE_UND) {
9657 env->xregs[22] = env->regs[14];
9658 env->xregs[23] = env->regs[13];
9659 } else {
9660 env->xregs[22] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_UND)];
9661 env->xregs[23] = env->banked_r13[bank_number(ARM_CPU_MODE_UND)];
9662 }
9663
9664
9665
9666
9667
9668
9669 if (mode == ARM_CPU_MODE_FIQ) {
9670 for (i = 24; i < 31; i++) {
9671 env->xregs[i] = env->regs[i - 16];
9672 }
9673 } else {
9674 for (i = 24; i < 29; i++) {
9675 env->xregs[i] = env->fiq_regs[i - 24];
9676 }
9677 env->xregs[29] = env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)];
9678 env->xregs[30] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_FIQ)];
9679 }
9680
9681 env->pc = env->regs[15];
9682}
9683
9684
9685
9686
9687
9688
9689void aarch64_sync_64_to_32(CPUARMState *env)
9690{
9691 int i;
9692 uint32_t mode = env->uncached_cpsr & CPSR_M;
9693
9694
9695 for (i = 0; i < 8; i++) {
9696 env->regs[i] = env->xregs[i];
9697 }
9698
9699
9700
9701
9702
9703 if (mode == ARM_CPU_MODE_FIQ) {
9704 for (i = 8; i < 13; i++) {
9705 env->usr_regs[i - 8] = env->xregs[i];
9706 }
9707 } else {
9708 for (i = 8; i < 13; i++) {
9709 env->regs[i] = env->xregs[i];
9710 }
9711 }
9712
9713
9714
9715
9716
9717
9718
9719 if (mode == ARM_CPU_MODE_USR || mode == ARM_CPU_MODE_SYS) {
9720 env->regs[13] = env->xregs[13];
9721 env->regs[14] = env->xregs[14];
9722 } else {
9723 env->banked_r13[bank_number(ARM_CPU_MODE_USR)] = env->xregs[13];
9724
9725
9726
9727
9728
9729 if (mode == ARM_CPU_MODE_HYP) {
9730 env->regs[14] = env->xregs[14];
9731 } else {
9732 env->banked_r14[r14_bank_number(ARM_CPU_MODE_USR)] = env->xregs[14];
9733 }
9734 }
9735
9736 if (mode == ARM_CPU_MODE_HYP) {
9737 env->regs[13] = env->xregs[15];
9738 } else {
9739 env->banked_r13[bank_number(ARM_CPU_MODE_HYP)] = env->xregs[15];
9740 }
9741
9742 if (mode == ARM_CPU_MODE_IRQ) {
9743 env->regs[14] = env->xregs[16];
9744 env->regs[13] = env->xregs[17];
9745 } else {
9746 env->banked_r14[r14_bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[16];
9747 env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[17];
9748 }
9749
9750 if (mode == ARM_CPU_MODE_SVC) {
9751 env->regs[14] = env->xregs[18];
9752 env->regs[13] = env->xregs[19];
9753 } else {
9754 env->banked_r14[r14_bank_number(ARM_CPU_MODE_SVC)] = env->xregs[18];
9755 env->banked_r13[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[19];
9756 }
9757
9758 if (mode == ARM_CPU_MODE_ABT) {
9759 env->regs[14] = env->xregs[20];
9760 env->regs[13] = env->xregs[21];
9761 } else {
9762 env->banked_r14[r14_bank_number(ARM_CPU_MODE_ABT)] = env->xregs[20];
9763 env->banked_r13[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[21];
9764 }
9765
9766 if (mode == ARM_CPU_MODE_UND) {
9767 env->regs[14] = env->xregs[22];
9768 env->regs[13] = env->xregs[23];
9769 } else {
9770 env->banked_r14[r14_bank_number(ARM_CPU_MODE_UND)] = env->xregs[22];
9771 env->banked_r13[bank_number(ARM_CPU_MODE_UND)] = env->xregs[23];
9772 }
9773
9774
9775
9776
9777
9778 if (mode == ARM_CPU_MODE_FIQ) {
9779 for (i = 24; i < 31; i++) {
9780 env->regs[i - 16] = env->xregs[i];
9781 }
9782 } else {
9783 for (i = 24; i < 29; i++) {
9784 env->fiq_regs[i - 24] = env->xregs[i];
9785 }
9786 env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[29];
9787 env->banked_r14[r14_bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[30];
9788 }
9789
9790 env->regs[15] = env->pc;
9791}
9792
9793static void take_aarch32_exception(CPUARMState *env, int new_mode,
9794 uint32_t mask, uint32_t offset,
9795 uint32_t newpc)
9796{
9797 int new_el;
9798
9799
9800 switch_mode(env, new_mode);
9801
9802
9803
9804
9805
9806 env->pstate &= ~PSTATE_SS;
9807 env->spsr = cpsr_read(env);
9808
9809 env->condexec_bits = 0;
9810
9811 env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
9812
9813
9814 new_el = arm_current_el(env);
9815
9816
9817 env->uncached_cpsr &= ~CPSR_E;
9818 if (env->cp15.sctlr_el[new_el] & SCTLR_EE) {
9819 env->uncached_cpsr |= CPSR_E;
9820 }
9821
9822 env->uncached_cpsr &= ~(CPSR_IL | CPSR_J);
9823 env->daif |= mask;
9824
9825 if (cpu_isar_feature(aa32_ssbs, env_archcpu(env))) {
9826 if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_32) {
9827 env->uncached_cpsr |= CPSR_SSBS;
9828 } else {
9829 env->uncached_cpsr &= ~CPSR_SSBS;
9830 }
9831 }
9832
9833 if (new_mode == ARM_CPU_MODE_HYP) {
9834 env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
9835 env->elr_el[2] = env->regs[15];
9836 } else {
9837
9838 if (cpu_isar_feature(aa32_pan, env_archcpu(env))) {
9839 switch (new_el) {
9840 case 3:
9841 if (!arm_is_secure_below_el3(env)) {
9842
9843 env->uncached_cpsr &= ~CPSR_PAN;
9844 break;
9845 }
9846
9847
9848 case 1:
9849
9850 if (!(env->cp15.sctlr_el[new_el] & SCTLR_SPAN)) {
9851 env->uncached_cpsr |= CPSR_PAN;
9852 }
9853 break;
9854 }
9855 }
9856
9857
9858
9859
9860 if (arm_feature(env, ARM_FEATURE_V4T)) {
9861 env->thumb =
9862 (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) != 0;
9863 }
9864 env->regs[14] = env->regs[15] + offset;
9865 }
9866 env->regs[15] = newpc;
9867 arm_rebuild_hflags(env);
9868}
9869
9870static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
9871{
9872
9873
9874
9875
9876
9877
9878
9879
9880
9881
9882
9883 uint32_t addr, mask;
9884 ARMCPU *cpu = ARM_CPU(cs);
9885 CPUARMState *env = &cpu->env;
9886
9887 switch (cs->exception_index) {
9888 case EXCP_UDEF:
9889 addr = 0x04;
9890 break;
9891 case EXCP_SWI:
9892 addr = 0x14;
9893 break;
9894 case EXCP_BKPT:
9895
9896 case EXCP_PREFETCH_ABORT:
9897 env->cp15.ifar_s = env->exception.vaddress;
9898 qemu_log_mask(CPU_LOG_INT, "...with HIFAR 0x%x\n",
9899 (uint32_t)env->exception.vaddress);
9900 addr = 0x0c;
9901 break;
9902 case EXCP_DATA_ABORT:
9903 env->cp15.dfar_s = env->exception.vaddress;
9904 qemu_log_mask(CPU_LOG_INT, "...with HDFAR 0x%x\n",
9905 (uint32_t)env->exception.vaddress);
9906 addr = 0x10;
9907 break;
9908 case EXCP_IRQ:
9909 addr = 0x18;
9910 break;
9911 case EXCP_FIQ:
9912 addr = 0x1c;
9913 break;
9914 case EXCP_HVC:
9915 addr = 0x08;
9916 break;
9917 case EXCP_HYP_TRAP:
9918 addr = 0x14;
9919 break;
9920 default:
9921 cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
9922 }
9923
9924 if (cs->exception_index != EXCP_IRQ && cs->exception_index != EXCP_FIQ) {
9925 if (!arm_feature(env, ARM_FEATURE_V8)) {
9926
9927
9928
9929
9930
9931 if (cs->exception_index == EXCP_PREFETCH_ABORT ||
9932 (cs->exception_index == EXCP_DATA_ABORT &&
9933 !(env->exception.syndrome & ARM_EL_ISV)) ||
9934 syn_get_ec(env->exception.syndrome) == EC_UNCATEGORIZED) {
9935 env->exception.syndrome &= ~ARM_EL_IL;
9936 }
9937 }
9938 env->cp15.esr_el[2] = env->exception.syndrome;
9939 }
9940
9941 if (arm_current_el(env) != 2 && addr < 0x14) {
9942 addr = 0x14;
9943 }
9944
9945 mask = 0;
9946 if (!(env->cp15.scr_el3 & SCR_EA)) {
9947 mask |= CPSR_A;
9948 }
9949 if (!(env->cp15.scr_el3 & SCR_IRQ)) {
9950 mask |= CPSR_I;
9951 }
9952 if (!(env->cp15.scr_el3 & SCR_FIQ)) {
9953 mask |= CPSR_F;
9954 }
9955
9956 addr += env->cp15.hvbar;
9957
9958 take_aarch32_exception(env, ARM_CPU_MODE_HYP, mask, 0, addr);
9959}
9960
9961static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
9962{
9963 ARMCPU *cpu = ARM_CPU(cs);
9964 CPUARMState *env = &cpu->env;
9965 uint32_t addr;
9966 uint32_t mask;
9967 int new_mode;
9968 uint32_t offset;
9969 uint32_t moe;
9970
9971
9972 switch (syn_get_ec(env->exception.syndrome)) {
9973 case EC_BREAKPOINT:
9974 case EC_BREAKPOINT_SAME_EL:
9975 moe = 1;
9976 break;
9977 case EC_WATCHPOINT:
9978 case EC_WATCHPOINT_SAME_EL:
9979 moe = 10;
9980 break;
9981 case EC_AA32_BKPT:
9982 moe = 3;
9983 break;
9984 case EC_VECTORCATCH:
9985 moe = 5;
9986 break;
9987 default:
9988 moe = 0;
9989 break;
9990 }
9991
9992 if (moe) {
9993 env->cp15.mdscr_el1 = deposit64(env->cp15.mdscr_el1, 2, 4, moe);
9994 }
9995
9996 if (env->exception.target_el == 2) {
9997 arm_cpu_do_interrupt_aarch32_hyp(cs);
9998 return;
9999 }
10000
10001 switch (cs->exception_index) {
10002 case EXCP_UDEF:
10003 new_mode = ARM_CPU_MODE_UND;
10004 addr = 0x04;
10005 mask = CPSR_I;
10006 if (env->thumb)
10007 offset = 2;
10008 else
10009 offset = 4;
10010 break;
10011 case EXCP_SWI:
10012 new_mode = ARM_CPU_MODE_SVC;
10013 addr = 0x08;
10014 mask = CPSR_I;
10015
10016 offset = 0;
10017 break;
10018 case EXCP_BKPT:
10019
10020 case EXCP_PREFETCH_ABORT:
10021 A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr);
10022 A32_BANKED_CURRENT_REG_SET(env, ifar, env->exception.vaddress);
10023 qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",
10024 env->exception.fsr, (uint32_t)env->exception.vaddress);
10025 new_mode = ARM_CPU_MODE_ABT;
10026 addr = 0x0c;
10027 mask = CPSR_A | CPSR_I;
10028 offset = 4;
10029 break;
10030 case EXCP_DATA_ABORT:
10031 A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr);
10032 A32_BANKED_CURRENT_REG_SET(env, dfar, env->exception.vaddress);
10033 qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",
10034 env->exception.fsr,
10035 (uint32_t)env->exception.vaddress);
10036 new_mode = ARM_CPU_MODE_ABT;
10037 addr = 0x10;
10038 mask = CPSR_A | CPSR_I;
10039 offset = 8;
10040 break;
10041 case EXCP_IRQ:
10042 new_mode = ARM_CPU_MODE_IRQ;
10043 addr = 0x18;
10044
10045 mask = CPSR_A | CPSR_I;
10046 offset = 4;
10047 if (env->cp15.scr_el3 & SCR_IRQ) {
10048
10049 new_mode = ARM_CPU_MODE_MON;
10050 mask |= CPSR_F;
10051 }
10052 break;
10053 case EXCP_FIQ:
10054 new_mode = ARM_CPU_MODE_FIQ;
10055 addr = 0x1c;
10056
10057 mask = CPSR_A | CPSR_I | CPSR_F;
10058 if (env->cp15.scr_el3 & SCR_FIQ) {
10059
10060 new_mode = ARM_CPU_MODE_MON;
10061 }
10062 offset = 4;
10063 break;
10064 case EXCP_VIRQ:
10065 new_mode = ARM_CPU_MODE_IRQ;
10066 addr = 0x18;
10067
10068 mask = CPSR_A | CPSR_I;
10069 offset = 4;
10070 break;
10071 case EXCP_VFIQ:
10072 new_mode = ARM_CPU_MODE_FIQ;
10073 addr = 0x1c;
10074
10075 mask = CPSR_A | CPSR_I | CPSR_F;
10076 offset = 4;
10077 break;
10078 case EXCP_SMC:
10079 new_mode = ARM_CPU_MODE_MON;
10080 addr = 0x08;
10081 mask = CPSR_A | CPSR_I | CPSR_F;
10082 offset = 0;
10083 break;
10084 default:
10085 cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
10086 return;
10087 }
10088
10089 if (new_mode == ARM_CPU_MODE_MON) {
10090 addr += env->cp15.mvbar;
10091 } else if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
10092
10093 addr += 0xffff0000;
10094 } else {
10095
10096
10097
10098
10099
10100 addr += A32_BANKED_CURRENT_REG_GET(env, vbar);
10101 }
10102
10103 if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
10104 env->cp15.scr_el3 &= ~SCR_NS;
10105 }
10106
10107 take_aarch32_exception(env, new_mode, mask, offset, addr);
10108}
10109
10110static int aarch64_regnum(CPUARMState *env, int aarch32_reg)
10111{
10112
10113
10114
10115
10116
10117 int mode = env->uncached_cpsr & CPSR_M;
10118
10119 switch (aarch32_reg) {
10120 case 0 ... 7:
10121 return aarch32_reg;
10122 case 8 ... 12:
10123 return mode == ARM_CPU_MODE_FIQ ? aarch32_reg + 16 : aarch32_reg;
10124 case 13:
10125 switch (mode) {
10126 case ARM_CPU_MODE_USR:
10127 case ARM_CPU_MODE_SYS:
10128 return 13;
10129 case ARM_CPU_MODE_HYP:
10130 return 15;
10131 case ARM_CPU_MODE_IRQ:
10132 return 17;
10133 case ARM_CPU_MODE_SVC:
10134 return 19;
10135 case ARM_CPU_MODE_ABT:
10136 return 21;
10137 case ARM_CPU_MODE_UND:
10138 return 23;
10139 case ARM_CPU_MODE_FIQ:
10140 return 29;
10141 default:
10142 g_assert_not_reached();
10143 }
10144 case 14:
10145 switch (mode) {
10146 case ARM_CPU_MODE_USR:
10147 case ARM_CPU_MODE_SYS:
10148 case ARM_CPU_MODE_HYP:
10149 return 14;
10150 case ARM_CPU_MODE_IRQ:
10151 return 16;
10152 case ARM_CPU_MODE_SVC:
10153 return 18;
10154 case ARM_CPU_MODE_ABT:
10155 return 20;
10156 case ARM_CPU_MODE_UND:
10157 return 22;
10158 case ARM_CPU_MODE_FIQ:
10159 return 30;
10160 default:
10161 g_assert_not_reached();
10162 }
10163 case 15:
10164 return 31;
10165 default:
10166 g_assert_not_reached();
10167 }
10168}
10169
10170static uint32_t cpsr_read_for_spsr_elx(CPUARMState *env)
10171{
10172 uint32_t ret = cpsr_read(env);
10173
10174
10175 if (ret & CPSR_DIT) {
10176 ret &= ~CPSR_DIT;
10177 ret |= PSTATE_DIT;
10178 }
10179
10180 ret |= env->pstate & PSTATE_SS;
10181
10182 return ret;
10183}
10184
10185
10186static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
10187{
10188 ARMCPU *cpu = ARM_CPU(cs);
10189 CPUARMState *env = &cpu->env;
10190 unsigned int new_el = env->exception.target_el;
10191 target_ulong addr = env->cp15.vbar_el[new_el];
10192 unsigned int new_mode = aarch64_pstate_mode(new_el, true);
10193 unsigned int old_mode;
10194 unsigned int cur_el = arm_current_el(env);
10195 int rt;
10196
10197
10198
10199
10200
10201 aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
10202
10203 if (cur_el < new_el) {
10204
10205
10206
10207 bool is_aa64;
10208 uint64_t hcr;
10209
10210 switch (new_el) {
10211 case 3:
10212 is_aa64 = (env->cp15.scr_el3 & SCR_RW) != 0;
10213 break;
10214 case 2:
10215 hcr = arm_hcr_el2_eff(env);
10216 if ((hcr & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
10217 is_aa64 = (hcr & HCR_RW) != 0;
10218 break;
10219 }
10220
10221 case 1:
10222 is_aa64 = is_a64(env);
10223 break;
10224 default:
10225 g_assert_not_reached();
10226 }
10227
10228 if (is_aa64) {
10229 addr += 0x400;
10230 } else {
10231 addr += 0x600;
10232 }
10233 } else if (pstate_read(env) & PSTATE_SP) {
10234 addr += 0x200;
10235 }
10236
10237 switch (cs->exception_index) {
10238 case EXCP_PREFETCH_ABORT:
10239 case EXCP_DATA_ABORT:
10240 env->cp15.far_el[new_el] = env->exception.vaddress;
10241 qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n",
10242 env->cp15.far_el[new_el]);
10243
10244 case EXCP_BKPT:
10245 case EXCP_UDEF:
10246 case EXCP_SWI:
10247 case EXCP_HVC:
10248 case EXCP_HYP_TRAP:
10249 case EXCP_SMC:
10250 switch (syn_get_ec(env->exception.syndrome)) {
10251 case EC_ADVSIMDFPACCESSTRAP:
10252
10253
10254
10255
10256
10257
10258 env->exception.syndrome &= ~MAKE_64BIT_MASK(0, 20);
10259 break;
10260 case EC_CP14RTTRAP:
10261 case EC_CP15RTTRAP:
10262 case EC_CP14DTTRAP:
10263
10264
10265
10266
10267
10268
10269
10270 rt = extract32(env->exception.syndrome, 5, 4);
10271 rt = aarch64_regnum(env, rt);
10272 env->exception.syndrome = deposit32(env->exception.syndrome,
10273 5, 5, rt);
10274 break;
10275 case EC_CP15RRTTRAP:
10276 case EC_CP14RRTTRAP:
10277
10278 rt = extract32(env->exception.syndrome, 5, 4);
10279 rt = aarch64_regnum(env, rt);
10280 env->exception.syndrome = deposit32(env->exception.syndrome,
10281 5, 5, rt);
10282 rt = extract32(env->exception.syndrome, 10, 4);
10283 rt = aarch64_regnum(env, rt);
10284 env->exception.syndrome = deposit32(env->exception.syndrome,
10285 10, 5, rt);
10286 break;
10287 }
10288 env->cp15.esr_el[new_el] = env->exception.syndrome;
10289 break;
10290 case EXCP_IRQ:
10291 case EXCP_VIRQ:
10292 addr += 0x80;
10293 break;
10294 case EXCP_FIQ:
10295 case EXCP_VFIQ:
10296 addr += 0x100;
10297 break;
10298 default:
10299 cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
10300 }
10301
10302 if (is_a64(env)) {
10303 old_mode = pstate_read(env);
10304 aarch64_save_sp(env, arm_current_el(env));
10305 env->elr_el[new_el] = env->pc;
10306 } else {
10307 old_mode = cpsr_read_for_spsr_elx(env);
10308 env->elr_el[new_el] = env->regs[15];
10309
10310 aarch64_sync_32_to_64(env);
10311
10312 env->condexec_bits = 0;
10313 }
10314 env->banked_spsr[aarch64_banked_spsr_index(new_el)] = old_mode;
10315
10316 qemu_log_mask(CPU_LOG_INT, "...with ELR 0x%" PRIx64 "\n",
10317 env->elr_el[new_el]);
10318
10319 if (cpu_isar_feature(aa64_pan, cpu)) {
10320
10321 new_mode |= old_mode & PSTATE_PAN;
10322 switch (new_el) {
10323 case 2:
10324
10325 if ((arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE))
10326 != (HCR_E2H | HCR_TGE)) {
10327 break;
10328 }
10329
10330 case 1:
10331
10332
10333 if ((env->cp15.sctlr_el[new_el] & SCTLR_SPAN) == 0) {
10334 new_mode |= PSTATE_PAN;
10335 }
10336 break;
10337 }
10338 }
10339 if (cpu_isar_feature(aa64_mte, cpu)) {
10340 new_mode |= PSTATE_TCO;
10341 }
10342
10343 if (cpu_isar_feature(aa64_ssbs, cpu)) {
10344 if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_64) {
10345 new_mode |= PSTATE_SSBS;
10346 } else {
10347 new_mode &= ~PSTATE_SSBS;
10348 }
10349 }
10350
10351 pstate_write(env, PSTATE_DAIF | new_mode);
10352 env->aarch64 = 1;
10353 aarch64_restore_sp(env, new_el);
10354 helper_rebuild_hflags_a64(env, new_el);
10355
10356 env->pc = addr;
10357
10358 qemu_log_mask(CPU_LOG_INT, "...to EL%d PC 0x%" PRIx64 " PSTATE 0x%x\n",
10359 new_el, env->pc, pstate_read(env));
10360}
10361
10362
10363
10364
10365
10366
10367
10368
10369#ifdef CONFIG_TCG
10370static void handle_semihosting(CPUState *cs)
10371{
10372 ARMCPU *cpu = ARM_CPU(cs);
10373 CPUARMState *env = &cpu->env;
10374
10375 if (is_a64(env)) {
10376 qemu_log_mask(CPU_LOG_INT,
10377 "...handling as semihosting call 0x%" PRIx64 "\n",
10378 env->xregs[0]);
10379 env->xregs[0] = do_common_semihosting(cs);
10380 env->pc += 4;
10381 } else {
10382 qemu_log_mask(CPU_LOG_INT,
10383 "...handling as semihosting call 0x%x\n",
10384 env->regs[0]);
10385 env->regs[0] = do_common_semihosting(cs);
10386 env->regs[15] += env->thumb ? 2 : 4;
10387 }
10388}
10389#endif
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400void arm_cpu_do_interrupt(CPUState *cs)
10401{
10402 ARMCPU *cpu = ARM_CPU(cs);
10403 CPUARMState *env = &cpu->env;
10404 unsigned int new_el = env->exception.target_el;
10405
10406 assert(!arm_feature(env, ARM_FEATURE_M));
10407
10408 arm_log_exception(cs->exception_index);
10409 qemu_log_mask(CPU_LOG_INT, "...from EL%d to EL%d\n", arm_current_el(env),
10410 new_el);
10411 if (qemu_loglevel_mask(CPU_LOG_INT)
10412 && !excp_is_internal(cs->exception_index)) {
10413 qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%x/0x%" PRIx32 "\n",
10414 syn_get_ec(env->exception.syndrome),
10415 env->exception.syndrome);
10416 }
10417
10418 if (arm_is_psci_call(cpu, cs->exception_index)) {
10419 arm_handle_psci_call(cpu);
10420 qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
10421 return;
10422 }
10423
10424
10425
10426
10427
10428
10429#ifdef CONFIG_TCG
10430 if (cs->exception_index == EXCP_SEMIHOST) {
10431 handle_semihosting(cs);
10432 return;
10433 }
10434#endif
10435
10436
10437
10438
10439
10440 g_assert(qemu_mutex_iothread_locked());
10441
10442 arm_call_pre_el_change_hook(cpu);
10443
10444 assert(!excp_is_internal(cs->exception_index));
10445 if (arm_el_is_aa64(env, new_el)) {
10446 arm_cpu_do_interrupt_aarch64(cs);
10447 } else {
10448 arm_cpu_do_interrupt_aarch32(cs);
10449 }
10450
10451 arm_call_el_change_hook(cpu);
10452
10453 if (!kvm_enabled()) {
10454 cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
10455 }
10456}
10457#endif
10458
10459uint64_t arm_sctlr(CPUARMState *env, int el)
10460{
10461
10462 if (el == 0) {
10463 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, 0);
10464 el = (mmu_idx == ARMMMUIdx_E20_0 || mmu_idx == ARMMMUIdx_SE20_0)
10465 ? 2 : 1;
10466 }
10467 return env->cp15.sctlr_el[el];
10468}
10469
10470
10471static inline uint64_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
10472{
10473 return env->cp15.sctlr_el[regime_el(env, mmu_idx)];
10474}
10475
10476#ifndef CONFIG_USER_ONLY
10477
10478
10479static inline bool regime_translation_disabled(CPUARMState *env,
10480 ARMMMUIdx mmu_idx)
10481{
10482 uint64_t hcr_el2;
10483
10484 if (arm_feature(env, ARM_FEATURE_M)) {
10485 switch (env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] &
10486 (R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
10487 case R_V7M_MPU_CTRL_ENABLE_MASK:
10488
10489 return mmu_idx & ARM_MMU_IDX_M_NEGPRI;
10490 case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK:
10491
10492 return false;
10493 case 0:
10494 default:
10495
10496
10497
10498 return true;
10499 }
10500 }
10501
10502 hcr_el2 = arm_hcr_el2_eff(env);
10503
10504 if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
10505
10506 return (hcr_el2 & (HCR_DC | HCR_VM)) == 0;
10507 }
10508
10509 if (hcr_el2 & HCR_TGE) {
10510
10511 if (!regime_is_secure(env, mmu_idx) && regime_el(env, mmu_idx) == 1) {
10512 return true;
10513 }
10514 }
10515
10516 if ((hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
10517
10518 return true;
10519 }
10520
10521 return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
10522}
10523
10524static inline bool regime_translation_big_endian(CPUARMState *env,
10525 ARMMMUIdx mmu_idx)
10526{
10527 return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0;
10528}
10529
10530
10531static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
10532 int ttbrn)
10533{
10534 if (mmu_idx == ARMMMUIdx_Stage2) {
10535 return env->cp15.vttbr_el2;
10536 }
10537 if (mmu_idx == ARMMMUIdx_Stage2_S) {
10538 return env->cp15.vsttbr_el2;
10539 }
10540 if (ttbrn == 0) {
10541 return env->cp15.ttbr0_el[regime_el(env, mmu_idx)];
10542 } else {
10543 return env->cp15.ttbr1_el[regime_el(env, mmu_idx)];
10544 }
10545}
10546
10547#endif
10548
10549
10550
10551
10552static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
10553{
10554 switch (mmu_idx) {
10555 case ARMMMUIdx_SE10_0:
10556 return ARMMMUIdx_Stage1_SE0;
10557 case ARMMMUIdx_SE10_1:
10558 return ARMMMUIdx_Stage1_SE1;
10559 case ARMMMUIdx_SE10_1_PAN:
10560 return ARMMMUIdx_Stage1_SE1_PAN;
10561 case ARMMMUIdx_E10_0:
10562 return ARMMMUIdx_Stage1_E0;
10563 case ARMMMUIdx_E10_1:
10564 return ARMMMUIdx_Stage1_E1;
10565 case ARMMMUIdx_E10_1_PAN:
10566 return ARMMMUIdx_Stage1_E1_PAN;
10567 default:
10568 return mmu_idx;
10569 }
10570}
10571
10572
10573static inline bool regime_using_lpae_format(CPUARMState *env,
10574 ARMMMUIdx mmu_idx)
10575{
10576 int el = regime_el(env, mmu_idx);
10577 if (el == 2 || arm_el_is_aa64(env, el)) {
10578 return true;
10579 }
10580 if (arm_feature(env, ARM_FEATURE_LPAE)
10581 && (regime_tcr(env, mmu_idx)->raw_tcr & TTBCR_EAE)) {
10582 return true;
10583 }
10584 return false;
10585}
10586
10587
10588
10589
10590bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
10591{
10592 mmu_idx = stage_1_mmu_idx(mmu_idx);
10593
10594 return regime_using_lpae_format(env, mmu_idx);
10595}
10596
10597#ifndef CONFIG_USER_ONLY
10598static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
10599{
10600 switch (mmu_idx) {
10601 case ARMMMUIdx_SE10_0:
10602 case ARMMMUIdx_E20_0:
10603 case ARMMMUIdx_SE20_0:
10604 case ARMMMUIdx_Stage1_E0:
10605 case ARMMMUIdx_Stage1_SE0:
10606 case ARMMMUIdx_MUser:
10607 case ARMMMUIdx_MSUser:
10608 case ARMMMUIdx_MUserNegPri:
10609 case ARMMMUIdx_MSUserNegPri:
10610 return true;
10611 default:
10612 return false;
10613 case ARMMMUIdx_E10_0:
10614 case ARMMMUIdx_E10_1:
10615 case ARMMMUIdx_E10_1_PAN:
10616 g_assert_not_reached();
10617 }
10618}
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628static inline int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx,
10629 int ap, int domain_prot)
10630{
10631 bool is_user = regime_is_user(env, mmu_idx);
10632
10633 if (domain_prot == 3) {
10634 return PAGE_READ | PAGE_WRITE;
10635 }
10636
10637 switch (ap) {
10638 case 0:
10639 if (arm_feature(env, ARM_FEATURE_V7)) {
10640 return 0;
10641 }
10642 switch (regime_sctlr(env, mmu_idx) & (SCTLR_S | SCTLR_R)) {
10643 case SCTLR_S:
10644 return is_user ? 0 : PAGE_READ;
10645 case SCTLR_R:
10646 return PAGE_READ;
10647 default:
10648 return 0;
10649 }
10650 case 1:
10651 return is_user ? 0 : PAGE_READ | PAGE_WRITE;
10652 case 2:
10653 if (is_user) {
10654 return PAGE_READ;
10655 } else {
10656 return PAGE_READ | PAGE_WRITE;
10657 }
10658 case 3:
10659 return PAGE_READ | PAGE_WRITE;
10660 case 4:
10661 return 0;
10662 case 5:
10663 return is_user ? 0 : PAGE_READ;
10664 case 6:
10665 return PAGE_READ;
10666 case 7:
10667 if (!arm_feature(env, ARM_FEATURE_V6K)) {
10668 return 0;
10669 }
10670 return PAGE_READ;
10671 default:
10672 g_assert_not_reached();
10673 }
10674}
10675
10676
10677
10678
10679
10680
10681
10682static inline int simple_ap_to_rw_prot_is_user(int ap, bool is_user)
10683{
10684 switch (ap) {
10685 case 0:
10686 return is_user ? 0 : PAGE_READ | PAGE_WRITE;
10687 case 1:
10688 return PAGE_READ | PAGE_WRITE;
10689 case 2:
10690 return is_user ? 0 : PAGE_READ;
10691 case 3:
10692 return PAGE_READ;
10693 default:
10694 g_assert_not_reached();
10695 }
10696}
10697
10698static inline int
10699simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
10700{
10701 return simple_ap_to_rw_prot_is_user(ap, regime_is_user(env, mmu_idx));
10702}
10703
10704
10705
10706
10707
10708
10709
10710
10711static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
10712{
10713 int prot = 0;
10714
10715 if (s2ap & 1) {
10716 prot |= PAGE_READ;
10717 }
10718 if (s2ap & 2) {
10719 prot |= PAGE_WRITE;
10720 }
10721
10722 if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
10723 switch (xn) {
10724 case 0:
10725 prot |= PAGE_EXEC;
10726 break;
10727 case 1:
10728 if (s1_is_el0) {
10729 prot |= PAGE_EXEC;
10730 }
10731 break;
10732 case 2:
10733 break;
10734 case 3:
10735 if (!s1_is_el0) {
10736 prot |= PAGE_EXEC;
10737 }
10738 break;
10739 default:
10740 g_assert_not_reached();
10741 }
10742 } else {
10743 if (!extract32(xn, 1, 1)) {
10744 if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
10745 prot |= PAGE_EXEC;
10746 }
10747 }
10748 }
10749 return prot;
10750}
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
10763 int ap, int ns, int xn, int pxn)
10764{
10765 bool is_user = regime_is_user(env, mmu_idx);
10766 int prot_rw, user_rw;
10767 bool have_wxn;
10768 int wxn = 0;
10769
10770 assert(mmu_idx != ARMMMUIdx_Stage2);
10771 assert(mmu_idx != ARMMMUIdx_Stage2_S);
10772
10773 user_rw = simple_ap_to_rw_prot_is_user(ap, true);
10774 if (is_user) {
10775 prot_rw = user_rw;
10776 } else {
10777 if (user_rw && regime_is_pan(env, mmu_idx)) {
10778
10779 prot_rw = 0;
10780 } else {
10781 prot_rw = simple_ap_to_rw_prot_is_user(ap, false);
10782 }
10783 }
10784
10785 if (ns && arm_is_secure(env) && (env->cp15.scr_el3 & SCR_SIF)) {
10786 return prot_rw;
10787 }
10788
10789
10790
10791
10792
10793
10794 have_wxn = arm_feature(env, ARM_FEATURE_LPAE);
10795
10796 if (have_wxn) {
10797 wxn = regime_sctlr(env, mmu_idx) & SCTLR_WXN;
10798 }
10799
10800 if (is_aa64) {
10801 if (regime_has_2_ranges(mmu_idx) && !is_user) {
10802 xn = pxn || (user_rw & PAGE_WRITE);
10803 }
10804 } else if (arm_feature(env, ARM_FEATURE_V7)) {
10805 switch (regime_el(env, mmu_idx)) {
10806 case 1:
10807 case 3:
10808 if (is_user) {
10809 xn = xn || !(user_rw & PAGE_READ);
10810 } else {
10811 int uwxn = 0;
10812 if (have_wxn) {
10813 uwxn = regime_sctlr(env, mmu_idx) & SCTLR_UWXN;
10814 }
10815 xn = xn || !(prot_rw & PAGE_READ) || pxn ||
10816 (uwxn && (user_rw & PAGE_WRITE));
10817 }
10818 break;
10819 case 2:
10820 break;
10821 }
10822 } else {
10823 xn = wxn = 0;
10824 }
10825
10826 if (xn || (wxn && (prot_rw & PAGE_WRITE))) {
10827 return prot_rw;
10828 }
10829 return prot_rw | PAGE_EXEC;
10830}
10831
10832static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
10833 uint32_t *table, uint32_t address)
10834{
10835
10836 TCR *tcr = regime_tcr(env, mmu_idx);
10837
10838 if (address & tcr->mask) {
10839 if (tcr->raw_tcr & TTBCR_PD1) {
10840
10841 return false;
10842 }
10843 *table = regime_ttbr(env, mmu_idx, 1) & 0xffffc000;
10844 } else {
10845 if (tcr->raw_tcr & TTBCR_PD0) {
10846
10847 return false;
10848 }
10849 *table = regime_ttbr(env, mmu_idx, 0) & tcr->base_mask;
10850 }
10851 *table |= (address >> 18) & 0x3ffc;
10852 return true;
10853}
10854
10855
10856static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
10857 hwaddr addr, bool *is_secure,
10858 ARMMMUFaultInfo *fi)
10859{
10860 if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
10861 !regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
10862 target_ulong s2size;
10863 hwaddr s2pa;
10864 int s2prot;
10865 int ret;
10866 ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S
10867 : ARMMMUIdx_Stage2;
10868 ARMCacheAttrs cacheattrs = {};
10869 MemTxAttrs txattrs = {};
10870
10871 ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx, false,
10872 &s2pa, &txattrs, &s2prot, &s2size, fi,
10873 &cacheattrs);
10874 if (ret) {
10875 assert(fi->type != ARMFault_None);
10876 fi->s2addr = addr;
10877 fi->stage2 = true;
10878 fi->s1ptw = true;
10879 fi->s1ns = !*is_secure;
10880 return ~0;
10881 }
10882 if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
10883 (cacheattrs.attrs & 0xf0) == 0) {
10884
10885
10886
10887
10888 fi->type = ARMFault_Permission;
10889 fi->s2addr = addr;
10890 fi->stage2 = true;
10891 fi->s1ptw = true;
10892 fi->s1ns = !*is_secure;
10893 return ~0;
10894 }
10895
10896 if (arm_is_secure_below_el3(env)) {
10897
10898 if (*is_secure) {
10899 *is_secure = !(env->cp15.vstcr_el2.raw_tcr & VSTCR_SW);
10900 } else {
10901 *is_secure = !(env->cp15.vtcr_el2.raw_tcr & VTCR_NSW);
10902 }
10903 } else {
10904 assert(!*is_secure);
10905 }
10906
10907 addr = s2pa;
10908 }
10909 return addr;
10910}
10911
10912
10913static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
10914 ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
10915{
10916 ARMCPU *cpu = ARM_CPU(cs);
10917 CPUARMState *env = &cpu->env;
10918 MemTxAttrs attrs = {};
10919 MemTxResult result = MEMTX_OK;
10920 AddressSpace *as;
10921 uint32_t data;
10922
10923 addr = S1_ptw_translate(env, mmu_idx, addr, &is_secure, fi);
10924 attrs.secure = is_secure;
10925 as = arm_addressspace(cs, attrs);
10926 if (fi->s1ptw) {
10927 return 0;
10928 }
10929 if (regime_translation_big_endian(env, mmu_idx)) {
10930 data = address_space_ldl_be(as, addr, attrs, &result);
10931 } else {
10932 data = address_space_ldl_le(as, addr, attrs, &result);
10933 }
10934 if (result == MEMTX_OK) {
10935 return data;
10936 }
10937 fi->type = ARMFault_SyncExternalOnWalk;
10938 fi->ea = arm_extabort_type(result);
10939 return 0;
10940}
10941
10942static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
10943 ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
10944{
10945 ARMCPU *cpu = ARM_CPU(cs);
10946 CPUARMState *env = &cpu->env;
10947 MemTxAttrs attrs = {};
10948 MemTxResult result = MEMTX_OK;
10949 AddressSpace *as;
10950 uint64_t data;
10951
10952 addr = S1_ptw_translate(env, mmu_idx, addr, &is_secure, fi);
10953 attrs.secure = is_secure;
10954 as = arm_addressspace(cs, attrs);
10955 if (fi->s1ptw) {
10956 return 0;
10957 }
10958 if (regime_translation_big_endian(env, mmu_idx)) {
10959 data = address_space_ldq_be(as, addr, attrs, &result);
10960 } else {
10961 data = address_space_ldq_le(as, addr, attrs, &result);
10962 }
10963 if (result == MEMTX_OK) {
10964 return data;
10965 }
10966 fi->type = ARMFault_SyncExternalOnWalk;
10967 fi->ea = arm_extabort_type(result);
10968 return 0;
10969}
10970
10971static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
10972 MMUAccessType access_type, ARMMMUIdx mmu_idx,
10973 hwaddr *phys_ptr, int *prot,
10974 target_ulong *page_size,
10975 ARMMMUFaultInfo *fi)
10976{
10977 CPUState *cs = env_cpu(env);
10978 int level = 1;
10979 uint32_t table;
10980 uint32_t desc;
10981 int type;
10982 int ap;
10983 int domain = 0;
10984 int domain_prot;
10985 hwaddr phys_addr;
10986 uint32_t dacr;
10987
10988
10989
10990 if (!get_level1_table_address(env, mmu_idx, &table, address)) {
10991
10992 fi->type = ARMFault_Translation;
10993 goto do_fault;
10994 }
10995 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
10996 mmu_idx, fi);
10997 if (fi->type != ARMFault_None) {
10998 goto do_fault;
10999 }
11000 type = (desc & 3);
11001 domain = (desc >> 5) & 0x0f;
11002 if (regime_el(env, mmu_idx) == 1) {
11003 dacr = env->cp15.dacr_ns;
11004 } else {
11005 dacr = env->cp15.dacr_s;
11006 }
11007 domain_prot = (dacr >> (domain * 2)) & 3;
11008 if (type == 0) {
11009
11010 fi->type = ARMFault_Translation;
11011 goto do_fault;
11012 }
11013 if (type != 2) {
11014 level = 2;
11015 }
11016 if (domain_prot == 0 || domain_prot == 2) {
11017 fi->type = ARMFault_Domain;
11018 goto do_fault;
11019 }
11020 if (type == 2) {
11021
11022 phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
11023 ap = (desc >> 10) & 3;
11024 *page_size = 1024 * 1024;
11025 } else {
11026
11027 if (type == 1) {
11028
11029 table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
11030 } else {
11031
11032 table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
11033 }
11034 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
11035 mmu_idx, fi);
11036 if (fi->type != ARMFault_None) {
11037 goto do_fault;
11038 }
11039 switch (desc & 3) {
11040 case 0:
11041 fi->type = ARMFault_Translation;
11042 goto do_fault;
11043 case 1:
11044 phys_addr = (desc & 0xffff0000) | (address & 0xffff);
11045 ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
11046 *page_size = 0x10000;
11047 break;
11048 case 2:
11049 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
11050 ap = (desc >> (4 + ((address >> 9) & 6))) & 3;
11051 *page_size = 0x1000;
11052 break;
11053 case 3:
11054 if (type == 1) {
11055
11056 if (arm_feature(env, ARM_FEATURE_XSCALE)
11057 || arm_feature(env, ARM_FEATURE_V6)) {
11058 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
11059 *page_size = 0x1000;
11060 } else {
11061
11062
11063
11064 fi->type = ARMFault_Translation;
11065 goto do_fault;
11066 }
11067 } else {
11068 phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
11069 *page_size = 0x400;
11070 }
11071 ap = (desc >> 4) & 3;
11072 break;
11073 default:
11074
11075 abort();
11076 }
11077 }
11078 *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
11079 *prot |= *prot ? PAGE_EXEC : 0;
11080 if (!(*prot & (1 << access_type))) {
11081
11082 fi->type = ARMFault_Permission;
11083 goto do_fault;
11084 }
11085 *phys_ptr = phys_addr;
11086 return false;
11087do_fault:
11088 fi->domain = domain;
11089 fi->level = level;
11090 return true;
11091}
11092
11093static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
11094 MMUAccessType access_type, ARMMMUIdx mmu_idx,
11095 hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
11096 target_ulong *page_size, ARMMMUFaultInfo *fi)
11097{
11098 CPUState *cs = env_cpu(env);
11099 ARMCPU *cpu = env_archcpu(env);
11100 int level = 1;
11101 uint32_t table;
11102 uint32_t desc;
11103 uint32_t xn;
11104 uint32_t pxn = 0;
11105 int type;
11106 int ap;
11107 int domain = 0;
11108 int domain_prot;
11109 hwaddr phys_addr;
11110 uint32_t dacr;
11111 bool ns;
11112
11113
11114
11115 if (!get_level1_table_address(env, mmu_idx, &table, address)) {
11116
11117 fi->type = ARMFault_Translation;
11118 goto do_fault;
11119 }
11120 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
11121 mmu_idx, fi);
11122 if (fi->type != ARMFault_None) {
11123 goto do_fault;
11124 }
11125 type = (desc & 3);
11126 if (type == 0 || (type == 3 && !cpu_isar_feature(aa32_pxn, cpu))) {
11127
11128
11129
11130 fi->type = ARMFault_Translation;
11131 goto do_fault;
11132 }
11133 if ((type == 1) || !(desc & (1 << 18))) {
11134
11135 domain = (desc >> 5) & 0x0f;
11136 }
11137 if (regime_el(env, mmu_idx) == 1) {
11138 dacr = env->cp15.dacr_ns;
11139 } else {
11140 dacr = env->cp15.dacr_s;
11141 }
11142 if (type == 1) {
11143 level = 2;
11144 }
11145 domain_prot = (dacr >> (domain * 2)) & 3;
11146 if (domain_prot == 0 || domain_prot == 2) {
11147
11148 fi->type = ARMFault_Domain;
11149 goto do_fault;
11150 }
11151 if (type != 1) {
11152 if (desc & (1 << 18)) {
11153
11154 phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
11155 phys_addr |= (uint64_t)extract32(desc, 20, 4) << 32;
11156 phys_addr |= (uint64_t)extract32(desc, 5, 4) << 36;
11157 *page_size = 0x1000000;
11158 } else {
11159
11160 phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
11161 *page_size = 0x100000;
11162 }
11163 ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
11164 xn = desc & (1 << 4);
11165 pxn = desc & 1;
11166 ns = extract32(desc, 19, 1);
11167 } else {
11168 if (cpu_isar_feature(aa32_pxn, cpu)) {
11169 pxn = (desc >> 2) & 1;
11170 }
11171 ns = extract32(desc, 3, 1);
11172
11173 table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
11174 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
11175 mmu_idx, fi);
11176 if (fi->type != ARMFault_None) {
11177 goto do_fault;
11178 }
11179 ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
11180 switch (desc & 3) {
11181 case 0:
11182 fi->type = ARMFault_Translation;
11183 goto do_fault;
11184 case 1:
11185 phys_addr = (desc & 0xffff0000) | (address & 0xffff);
11186 xn = desc & (1 << 15);
11187 *page_size = 0x10000;
11188 break;
11189 case 2: case 3:
11190 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
11191 xn = desc & 1;
11192 *page_size = 0x1000;
11193 break;
11194 default:
11195
11196 abort();
11197 }
11198 }
11199 if (domain_prot == 3) {
11200 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
11201 } else {
11202 if (pxn && !regime_is_user(env, mmu_idx)) {
11203 xn = 1;
11204 }
11205 if (xn && access_type == MMU_INST_FETCH) {
11206 fi->type = ARMFault_Permission;
11207 goto do_fault;
11208 }
11209
11210 if (arm_feature(env, ARM_FEATURE_V6K) &&
11211 (regime_sctlr(env, mmu_idx) & SCTLR_AFE)) {
11212
11213 if ((ap & 1) == 0) {
11214
11215 fi->type = ARMFault_AccessFlag;
11216 goto do_fault;
11217 }
11218 *prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
11219 } else {
11220 *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
11221 }
11222 if (*prot && !xn) {
11223 *prot |= PAGE_EXEC;
11224 }
11225 if (!(*prot & (1 << access_type))) {
11226
11227 fi->type = ARMFault_Permission;
11228 goto do_fault;
11229 }
11230 }
11231 if (ns) {
11232
11233
11234
11235
11236 attrs->secure = false;
11237 }
11238 *phys_ptr = phys_addr;
11239 return false;
11240do_fault:
11241 fi->domain = domain;
11242 fi->level = level;
11243 return true;
11244}
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
11258 int inputsize, int stride)
11259{
11260 const int grainsize = stride + 3;
11261 int startsizecheck;
11262
11263
11264 if (level < 0) {
11265 return false;
11266 }
11267
11268 startsizecheck = inputsize - ((3 - level) * stride + grainsize);
11269 if (startsizecheck < 1 || startsizecheck > stride + 4) {
11270 return false;
11271 }
11272
11273 if (is_aa64) {
11274 CPUARMState *env = &cpu->env;
11275 unsigned int pamax = arm_pamax(cpu);
11276
11277 switch (stride) {
11278 case 13:
11279 if (level == 0 || (level == 1 && pamax <= 42)) {
11280 return false;
11281 }
11282 break;
11283 case 11:
11284 if (level == 0 || (level == 1 && pamax <= 40)) {
11285 return false;
11286 }
11287 break;
11288 case 9:
11289 if (level == 0 && pamax <= 42) {
11290 return false;
11291 }
11292 break;
11293 default:
11294 g_assert_not_reached();
11295 }
11296
11297
11298 if (inputsize > pamax &&
11299 (arm_el_is_aa64(env, 1) || inputsize > 40)) {
11300
11301 return false;
11302 }
11303 } else {
11304
11305 assert(stride == 9);
11306
11307 if (level == 0) {
11308 return false;
11309 }
11310 }
11311 return true;
11312}
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
11323{
11324 uint8_t hiattr = extract32(s2attrs, 2, 2);
11325 uint8_t loattr = extract32(s2attrs, 0, 2);
11326 uint8_t hihint = 0, lohint = 0;
11327
11328 if (hiattr != 0) {
11329 if (arm_hcr_el2_eff(env) & HCR_CD) {
11330 hiattr = loattr = 1;
11331 } else {
11332 if (hiattr != 1) {
11333 hihint = 3;
11334 }
11335 if (loattr != 1) {
11336 lohint = 3;
11337 }
11338 }
11339 }
11340
11341 return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
11342}
11343#endif
11344
11345static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
11346{
11347 if (regime_has_2_ranges(mmu_idx)) {
11348 return extract64(tcr, 37, 2);
11349 } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11350 return 0;
11351 } else {
11352
11353 return extract32(tcr, 20, 1) * 3;
11354 }
11355}
11356
11357static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
11358{
11359 if (regime_has_2_ranges(mmu_idx)) {
11360 return extract64(tcr, 51, 2);
11361 } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11362 return 0;
11363 } else {
11364
11365 return extract32(tcr, 29, 1) * 3;
11366 }
11367}
11368
11369static int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx)
11370{
11371 if (regime_has_2_ranges(mmu_idx)) {
11372 return extract64(tcr, 57, 2);
11373 } else {
11374
11375 return extract32(tcr, 30, 1) * 3;
11376 }
11377}
11378
11379ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
11380 ARMMMUIdx mmu_idx, bool data)
11381{
11382 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
11383 bool epd, hpd, using16k, using64k;
11384 int select, tsz, tbi, max_tsz;
11385
11386 if (!regime_has_2_ranges(mmu_idx)) {
11387 select = 0;
11388 tsz = extract32(tcr, 0, 6);
11389 using64k = extract32(tcr, 14, 1);
11390 using16k = extract32(tcr, 15, 1);
11391 if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11392
11393 hpd = false;
11394 } else {
11395 hpd = extract32(tcr, 24, 1);
11396 }
11397 epd = false;
11398 } else {
11399
11400
11401
11402
11403 select = extract64(va, 55, 1);
11404 if (!select) {
11405 tsz = extract32(tcr, 0, 6);
11406 epd = extract32(tcr, 7, 1);
11407 using64k = extract32(tcr, 14, 1);
11408 using16k = extract32(tcr, 15, 1);
11409 hpd = extract64(tcr, 41, 1);
11410 } else {
11411 int tg = extract32(tcr, 30, 2);
11412 using16k = tg == 1;
11413 using64k = tg == 3;
11414 tsz = extract32(tcr, 16, 6);
11415 epd = extract32(tcr, 23, 1);
11416 hpd = extract64(tcr, 42, 1);
11417 }
11418 }
11419
11420 if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
11421 max_tsz = 48 - using64k;
11422 } else {
11423 max_tsz = 39;
11424 }
11425
11426 tsz = MIN(tsz, max_tsz);
11427 tsz = MAX(tsz, 16);
11428
11429
11430 tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
11431 if (!data) {
11432 tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
11433 }
11434 tbi = (tbi >> select) & 1;
11435
11436 return (ARMVAParameters) {
11437 .tsz = tsz,
11438 .select = select,
11439 .tbi = tbi,
11440 .epd = epd,
11441 .hpd = hpd,
11442 .using16k = using16k,
11443 .using64k = using64k,
11444 };
11445}
11446
11447#ifndef CONFIG_USER_ONLY
11448static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
11449 ARMMMUIdx mmu_idx)
11450{
11451 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
11452 uint32_t el = regime_el(env, mmu_idx);
11453 int select, tsz;
11454 bool epd, hpd;
11455
11456 assert(mmu_idx != ARMMMUIdx_Stage2_S);
11457
11458 if (mmu_idx == ARMMMUIdx_Stage2) {
11459
11460 bool sext = extract32(tcr, 4, 1);
11461 bool sign = extract32(tcr, 3, 1);
11462
11463
11464
11465
11466
11467 if (sign != sext) {
11468 qemu_log_mask(LOG_GUEST_ERROR,
11469 "AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
11470 }
11471 tsz = sextract32(tcr, 0, 4) + 8;
11472 select = 0;
11473 hpd = false;
11474 epd = false;
11475 } else if (el == 2) {
11476
11477 tsz = extract32(tcr, 0, 3);
11478 select = 0;
11479 hpd = extract64(tcr, 24, 1);
11480 epd = false;
11481 } else {
11482 int t0sz = extract32(tcr, 0, 3);
11483 int t1sz = extract32(tcr, 16, 3);
11484
11485 if (t1sz == 0) {
11486 select = va > (0xffffffffu >> t0sz);
11487 } else {
11488
11489 select = va >= ~(0xffffffffu >> t1sz);
11490 }
11491 if (!select) {
11492 tsz = t0sz;
11493 epd = extract32(tcr, 7, 1);
11494 hpd = extract64(tcr, 41, 1);
11495 } else {
11496 tsz = t1sz;
11497 epd = extract32(tcr, 23, 1);
11498 hpd = extract64(tcr, 42, 1);
11499 }
11500
11501 hpd &= extract32(tcr, 6, 1);
11502 }
11503
11504 return (ARMVAParameters) {
11505 .tsz = tsz,
11506 .select = select,
11507 .epd = epd,
11508 .hpd = hpd,
11509 };
11510}
11511
11512
11513
11514
11515
11516
11517
11518
11519
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529
11530
11531
11532
11533
11534
11535static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
11536 MMUAccessType access_type, ARMMMUIdx mmu_idx,
11537 bool s1_is_el0,
11538 hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
11539 target_ulong *page_size_ptr,
11540 ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
11541{
11542 ARMCPU *cpu = env_archcpu(env);
11543 CPUState *cs = CPU(cpu);
11544
11545 ARMFaultType fault_type = ARMFault_Translation;
11546 uint32_t level;
11547 ARMVAParameters param;
11548 uint64_t ttbr;
11549 hwaddr descaddr, indexmask, indexmask_grainsize;
11550 uint32_t tableattrs;
11551 target_ulong page_size;
11552 uint32_t attrs;
11553 int32_t stride;
11554 int addrsize, inputsize;
11555 TCR *tcr = regime_tcr(env, mmu_idx);
11556 int ap, ns, xn, pxn;
11557 uint32_t el = regime_el(env, mmu_idx);
11558 uint64_t descaddrmask;
11559 bool aarch64 = arm_el_is_aa64(env, el);
11560 bool guarded = false;
11561
11562
11563 if (aarch64) {
11564 param = aa64_va_parameters(env, address, mmu_idx,
11565 access_type != MMU_INST_FETCH);
11566 level = 0;
11567 addrsize = 64 - 8 * param.tbi;
11568 inputsize = 64 - param.tsz;
11569 } else {
11570 param = aa32_va_parameters(env, address, mmu_idx);
11571 level = 1;
11572 addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
11573 inputsize = addrsize - param.tsz;
11574 }
11575
11576
11577
11578
11579
11580
11581
11582
11583
11584
11585 if (inputsize < addrsize) {
11586 target_ulong top_bits = sextract64(address, inputsize,
11587 addrsize - inputsize);
11588 if (-top_bits != param.select) {
11589
11590 fault_type = ARMFault_Translation;
11591 goto do_fault;
11592 }
11593 }
11594
11595 if (param.using64k) {
11596 stride = 13;
11597 } else if (param.using16k) {
11598 stride = 11;
11599 } else {
11600 stride = 9;
11601 }
11602
11603
11604
11605
11606
11607
11608
11609
11610 ttbr = regime_ttbr(env, mmu_idx, param.select);
11611
11612
11613
11614
11615
11616 if (param.epd) {
11617
11618
11619
11620 goto do_fault;
11621 }
11622
11623 if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635 level = 4 - (inputsize - 4) / stride;
11636 } else {
11637
11638
11639
11640 uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2);
11641 uint32_t startlevel;
11642 bool ok;
11643
11644 if (!aarch64 || stride == 9) {
11645
11646 startlevel = 2 - sl0;
11647
11648 if (cpu_isar_feature(aa64_st, cpu)) {
11649 startlevel &= 3;
11650 }
11651 } else {
11652
11653 startlevel = 3 - sl0;
11654 }
11655
11656
11657 ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
11658 inputsize, stride);
11659 if (!ok) {
11660 fault_type = ARMFault_Translation;
11661 goto do_fault;
11662 }
11663 level = startlevel;
11664 }
11665
11666 indexmask_grainsize = (1ULL << (stride + 3)) - 1;
11667 indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
11668
11669
11670 descaddr = extract64(ttbr, 0, 48);
11671
11672
11673
11674
11675 descaddr &= ~indexmask;
11676
11677
11678
11679
11680
11681
11682 descaddrmask = ((1ull << (aarch64 ? 48 : 40)) - 1) &
11683 ~indexmask_grainsize;
11684
11685
11686
11687
11688
11689
11690 tableattrs = regime_is_secure(env, mmu_idx) ? 0 : (1 << 4);
11691 for (;;) {
11692 uint64_t descriptor;
11693 bool nstable;
11694
11695 descaddr |= (address >> (stride * (4 - level))) & indexmask;
11696 descaddr &= ~7ULL;
11697 nstable = extract32(tableattrs, 4, 1);
11698 descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fi);
11699 if (fi->type != ARMFault_None) {
11700 goto do_fault;
11701 }
11702
11703 if (!(descriptor & 1) ||
11704 (!(descriptor & 2) && (level == 3))) {
11705
11706 goto do_fault;
11707 }
11708 descaddr = descriptor & descaddrmask;
11709
11710 if ((descriptor & 2) && (level < 3)) {
11711
11712
11713
11714
11715
11716 tableattrs |= extract64(descriptor, 59, 5);
11717 level++;
11718 indexmask = indexmask_grainsize;
11719 continue;
11720 }
11721
11722
11723
11724
11725 page_size = (1ULL << ((stride * (4 - level)) + 3));
11726 descaddr |= (address & (page_size - 1));
11727
11728 attrs = extract64(descriptor, 2, 10)
11729 | (extract64(descriptor, 52, 12) << 10);
11730
11731 if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11732
11733 break;
11734 }
11735
11736 attrs |= nstable << 3;
11737 guarded = extract64(descriptor, 50, 1);
11738 if (param.hpd) {
11739
11740 break;
11741 }
11742 attrs |= extract32(tableattrs, 0, 2) << 11;
11743
11744
11745
11746 attrs &= ~(extract32(tableattrs, 2, 1) << 4);
11747 attrs |= extract32(tableattrs, 3, 1) << 5;
11748 break;
11749 }
11750
11751
11752
11753 fault_type = ARMFault_AccessFlag;
11754 if ((attrs & (1 << 8)) == 0) {
11755
11756 goto do_fault;
11757 }
11758
11759 ap = extract32(attrs, 4, 2);
11760
11761 if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11762 ns = mmu_idx == ARMMMUIdx_Stage2;
11763 xn = extract32(attrs, 11, 2);
11764 *prot = get_S2prot(env, ap, xn, s1_is_el0);
11765 } else {
11766 ns = extract32(attrs, 3, 1);
11767 xn = extract32(attrs, 12, 1);
11768 pxn = extract32(attrs, 11, 1);
11769 *prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
11770 }
11771
11772 fault_type = ARMFault_Permission;
11773 if (!(*prot & (1 << access_type))) {
11774 goto do_fault;
11775 }
11776
11777 if (ns) {
11778
11779
11780
11781
11782 txattrs->secure = false;
11783 }
11784
11785 if (aarch64 && guarded && cpu_isar_feature(aa64_bti, cpu)) {
11786 arm_tlb_bti_gp(txattrs) = true;
11787 }
11788
11789 if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11790 cacheattrs->attrs = convert_stage2_attrs(env, extract32(attrs, 0, 4));
11791 } else {
11792
11793 uint8_t attrindx = extract32(attrs, 0, 3);
11794 uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
11795 assert(attrindx <= 7);
11796 cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
11797 }
11798 cacheattrs->shareability = extract32(attrs, 6, 2);
11799
11800 *phys_ptr = descaddr;
11801 *page_size_ptr = page_size;
11802 return false;
11803
11804do_fault:
11805 fi->type = fault_type;
11806 fi->level = level;
11807
11808 fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_Stage2 ||
11809 mmu_idx == ARMMMUIdx_Stage2_S);
11810 fi->s1ns = mmu_idx == ARMMMUIdx_Stage2;
11811 return true;
11812}
11813
11814static inline void get_phys_addr_pmsav7_default(CPUARMState *env,
11815 ARMMMUIdx mmu_idx,
11816 int32_t address, int *prot)
11817{
11818 if (!arm_feature(env, ARM_FEATURE_M)) {
11819 *prot = PAGE_READ | PAGE_WRITE;
11820 switch (address) {
11821 case 0xF0000000 ... 0xFFFFFFFF:
11822 if (regime_sctlr(env, mmu_idx) & SCTLR_V) {
11823
11824 *prot |= PAGE_EXEC;
11825 }
11826 break;
11827 case 0x00000000 ... 0x7FFFFFFF:
11828 *prot |= PAGE_EXEC;
11829 break;
11830 }
11831 } else {
11832
11833
11834
11835
11836 switch (address) {
11837 case 0x00000000 ... 0x1fffffff:
11838 case 0x20000000 ... 0x3fffffff:
11839 case 0x60000000 ... 0x7fffffff:
11840 case 0x80000000 ... 0x9fffffff:
11841 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
11842 break;
11843 case 0x40000000 ... 0x5fffffff:
11844 case 0xa0000000 ... 0xbfffffff:
11845 case 0xc0000000 ... 0xdfffffff:
11846 case 0xe0000000 ... 0xffffffff:
11847 *prot = PAGE_READ | PAGE_WRITE;
11848 break;
11849 default:
11850 g_assert_not_reached();
11851 }
11852 }
11853}
11854
11855static bool pmsav7_use_background_region(ARMCPU *cpu,
11856 ARMMMUIdx mmu_idx, bool is_user)
11857{
11858
11859
11860
11861 CPUARMState *env = &cpu->env;
11862
11863 if (is_user) {
11864 return false;
11865 }
11866
11867 if (arm_feature(env, ARM_FEATURE_M)) {
11868 return env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)]
11869 & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
11870 } else {
11871 return regime_sctlr(env, mmu_idx) & SCTLR_BR;
11872 }
11873}
11874
11875static inline bool m_is_ppb_region(CPUARMState *env, uint32_t address)
11876{
11877
11878 return arm_feature(env, ARM_FEATURE_M) &&
11879 extract32(address, 20, 12) == 0xe00;
11880}
11881
11882static inline bool m_is_system_region(CPUARMState *env, uint32_t address)
11883{
11884
11885
11886
11887 return arm_feature(env, ARM_FEATURE_M) && extract32(address, 29, 3) == 0x7;
11888}
11889
11890static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
11891 MMUAccessType access_type, ARMMMUIdx mmu_idx,
11892 hwaddr *phys_ptr, int *prot,
11893 target_ulong *page_size,
11894 ARMMMUFaultInfo *fi)
11895{
11896 ARMCPU *cpu = env_archcpu(env);
11897 int n;
11898 bool is_user = regime_is_user(env, mmu_idx);
11899
11900 *phys_ptr = address;
11901 *page_size = TARGET_PAGE_SIZE;
11902 *prot = 0;
11903
11904 if (regime_translation_disabled(env, mmu_idx) ||
11905 m_is_ppb_region(env, address)) {
11906
11907
11908
11909
11910
11911
11912
11913 get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
11914 } else {
11915 for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
11916
11917 uint32_t base = env->pmsav7.drbar[n];
11918 uint32_t rsize = extract32(env->pmsav7.drsr[n], 1, 5);
11919 uint32_t rmask;
11920 bool srdis = false;
11921
11922 if (!(env->pmsav7.drsr[n] & 0x1)) {
11923 continue;
11924 }
11925
11926 if (!rsize) {
11927 qemu_log_mask(LOG_GUEST_ERROR,
11928 "DRSR[%d]: Rsize field cannot be 0\n", n);
11929 continue;
11930 }
11931 rsize++;
11932 rmask = (1ull << rsize) - 1;
11933
11934 if (base & rmask) {
11935 qemu_log_mask(LOG_GUEST_ERROR,
11936 "DRBAR[%d]: 0x%" PRIx32 " misaligned "
11937 "to DRSR region size, mask = 0x%" PRIx32 "\n",
11938 n, base, rmask);
11939 continue;
11940 }
11941
11942 if (address < base || address > base + rmask) {
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952 if (ranges_overlap(base, rmask,
11953 address & TARGET_PAGE_MASK,
11954 TARGET_PAGE_SIZE)) {
11955 *page_size = 1;
11956 }
11957 continue;
11958 }
11959
11960
11961
11962 if (rsize >= 8) {
11963 int i, snd;
11964 uint32_t srdis_mask;
11965
11966 rsize -= 3;
11967 snd = ((address - base) >> rsize) & 0x7;
11968 srdis = extract32(env->pmsav7.drsr[n], snd + 8, 1);
11969
11970 srdis_mask = srdis ? 0x3 : 0x0;
11971 for (i = 2; i <= 8 && rsize < TARGET_PAGE_BITS; i *= 2) {
11972
11973
11974
11975
11976
11977
11978 int snd_rounded = snd & ~(i - 1);
11979 uint32_t srdis_multi = extract32(env->pmsav7.drsr[n],
11980 snd_rounded + 8, i);
11981 if (srdis_mask ^ srdis_multi) {
11982 break;
11983 }
11984 srdis_mask = (srdis_mask << i) | srdis_mask;
11985 rsize++;
11986 }
11987 }
11988 if (srdis) {
11989 continue;
11990 }
11991 if (rsize < TARGET_PAGE_BITS) {
11992 *page_size = 1 << rsize;
11993 }
11994 break;
11995 }
11996
11997 if (n == -1) {
11998 if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
11999
12000 fi->type = ARMFault_Background;
12001 return true;
12002 }
12003 get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
12004 } else {
12005 uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3);
12006 uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1);
12007
12008 if (m_is_system_region(env, address)) {
12009
12010 xn = 1;
12011 }
12012
12013 if (is_user) {
12014 switch (ap) {
12015 case 0:
12016 case 1:
12017 case 5:
12018 break;
12019 case 3:
12020 *prot |= PAGE_WRITE;
12021
12022 case 2:
12023 case 6:
12024 *prot |= PAGE_READ | PAGE_EXEC;
12025 break;
12026 case 7:
12027
12028 if (arm_feature(env, ARM_FEATURE_M)) {
12029 *prot |= PAGE_READ | PAGE_EXEC;
12030 break;
12031 }
12032
12033 default:
12034 qemu_log_mask(LOG_GUEST_ERROR,
12035 "DRACR[%d]: Bad value for AP bits: 0x%"
12036 PRIx32 "\n", n, ap);
12037 }
12038 } else {
12039 switch (ap) {
12040 case 0:
12041 break;
12042 case 1:
12043 case 2:
12044 case 3:
12045 *prot |= PAGE_WRITE;
12046
12047 case 5:
12048 case 6:
12049 *prot |= PAGE_READ | PAGE_EXEC;
12050 break;
12051 case 7:
12052
12053 if (arm_feature(env, ARM_FEATURE_M)) {
12054 *prot |= PAGE_READ | PAGE_EXEC;
12055 break;
12056 }
12057
12058 default:
12059 qemu_log_mask(LOG_GUEST_ERROR,
12060 "DRACR[%d]: Bad value for AP bits: 0x%"
12061 PRIx32 "\n", n, ap);
12062 }
12063 }
12064
12065
12066 if (xn) {
12067 *prot &= ~PAGE_EXEC;
12068 }
12069 }
12070 }
12071
12072 fi->type = ARMFault_Permission;
12073 fi->level = 1;
12074 return !(*prot & (1 << access_type));
12075}
12076
12077static bool v8m_is_sau_exempt(CPUARMState *env,
12078 uint32_t address, MMUAccessType access_type)
12079{
12080
12081
12082
12083 return
12084 (access_type == MMU_INST_FETCH && m_is_system_region(env, address)) ||
12085 (address >= 0xe0000000 && address <= 0xe0002fff) ||
12086 (address >= 0xe000e000 && address <= 0xe000efff) ||
12087 (address >= 0xe002e000 && address <= 0xe002efff) ||
12088 (address >= 0xe0040000 && address <= 0xe0041fff) ||
12089 (address >= 0xe00ff000 && address <= 0xe00fffff);
12090}
12091
12092void v8m_security_lookup(CPUARMState *env, uint32_t address,
12093 MMUAccessType access_type, ARMMMUIdx mmu_idx,
12094 V8M_SAttributes *sattrs)
12095{
12096
12097
12098
12099
12100 ARMCPU *cpu = env_archcpu(env);
12101 int r;
12102 bool idau_exempt = false, idau_ns = true, idau_nsc = true;
12103 int idau_region = IREGION_NOTVALID;
12104 uint32_t addr_page_base = address & TARGET_PAGE_MASK;
12105 uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
12106
12107 if (cpu->idau) {
12108 IDAUInterfaceClass *iic = IDAU_INTERFACE_GET_CLASS(cpu->idau);
12109 IDAUInterface *ii = IDAU_INTERFACE(cpu->idau);
12110
12111 iic->check(ii, address, &idau_region, &idau_exempt, &idau_ns,
12112 &idau_nsc);
12113 }
12114
12115 if (access_type == MMU_INST_FETCH && extract32(address, 28, 4) == 0xf) {
12116
12117 return;
12118 }
12119
12120 if (idau_exempt || v8m_is_sau_exempt(env, address, access_type)) {
12121 sattrs->ns = !regime_is_secure(env, mmu_idx);
12122 return;
12123 }
12124
12125 if (idau_region != IREGION_NOTVALID) {
12126 sattrs->irvalid = true;
12127 sattrs->iregion = idau_region;
12128 }
12129
12130 switch (env->sau.ctrl & 3) {
12131 case 0:
12132 break;
12133 case 2:
12134 sattrs->ns = true;
12135 break;
12136 default:
12137 for (r = 0; r < cpu->sau_sregion; r++) {
12138 if (env->sau.rlar[r] & 1) {
12139 uint32_t base = env->sau.rbar[r] & ~0x1f;
12140 uint32_t limit = env->sau.rlar[r] | 0x1f;
12141
12142 if (base <= address && limit >= address) {
12143 if (base > addr_page_base || limit < addr_page_limit) {
12144 sattrs->subpage = true;
12145 }
12146 if (sattrs->srvalid) {
12147
12148
12149
12150
12151 sattrs->ns = false;
12152 sattrs->nsc = false;
12153 sattrs->sregion = 0;
12154 sattrs->srvalid = false;
12155 break;
12156 } else {
12157 if (env->sau.rlar[r] & 2) {
12158 sattrs->nsc = true;
12159 } else {
12160 sattrs->ns = true;
12161 }
12162 sattrs->srvalid = true;
12163 sattrs->sregion = r;
12164 }
12165 } else {
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175 if (limit >= base &&
12176 ranges_overlap(base, limit - base + 1,
12177 addr_page_base,
12178 TARGET_PAGE_SIZE)) {
12179 sattrs->subpage = true;
12180 }
12181 }
12182 }
12183 }
12184 break;
12185 }
12186
12187
12188
12189
12190
12191 if (!idau_ns) {
12192 if (sattrs->ns || (!idau_nsc && sattrs->nsc)) {
12193 sattrs->ns = false;
12194 sattrs->nsc = idau_nsc;
12195 }
12196 }
12197}
12198
12199bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
12200 MMUAccessType access_type, ARMMMUIdx mmu_idx,
12201 hwaddr *phys_ptr, MemTxAttrs *txattrs,
12202 int *prot, bool *is_subpage,
12203 ARMMMUFaultInfo *fi, uint32_t *mregion)
12204{
12205
12206
12207
12208
12209
12210
12211
12212
12213 ARMCPU *cpu = env_archcpu(env);
12214 bool is_user = regime_is_user(env, mmu_idx);
12215 uint32_t secure = regime_is_secure(env, mmu_idx);
12216 int n;
12217 int matchregion = -1;
12218 bool hit = false;
12219 uint32_t addr_page_base = address & TARGET_PAGE_MASK;
12220 uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
12221
12222 *is_subpage = false;
12223 *phys_ptr = address;
12224 *prot = 0;
12225 if (mregion) {
12226 *mregion = -1;
12227 }
12228
12229
12230
12231
12232
12233
12234
12235 if (regime_translation_disabled(env, mmu_idx)) {
12236 hit = true;
12237 } else if (m_is_ppb_region(env, address)) {
12238 hit = true;
12239 } else {
12240 if (pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
12241 hit = true;
12242 }
12243
12244 for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
12245
12246
12247
12248
12249
12250 uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
12251 uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
12252
12253 if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
12254
12255 continue;
12256 }
12257
12258 if (address < base || address > limit) {
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268 if (limit >= base &&
12269 ranges_overlap(base, limit - base + 1,
12270 addr_page_base,
12271 TARGET_PAGE_SIZE)) {
12272 *is_subpage = true;
12273 }
12274 continue;
12275 }
12276
12277 if (base > addr_page_base || limit < addr_page_limit) {
12278 *is_subpage = true;
12279 }
12280
12281 if (matchregion != -1) {
12282
12283
12284
12285 fi->type = ARMFault_Permission;
12286 fi->level = 1;
12287 return true;
12288 }
12289
12290 matchregion = n;
12291 hit = true;
12292 }
12293 }
12294
12295 if (!hit) {
12296
12297 fi->type = ARMFault_Background;
12298 return true;
12299 }
12300
12301 if (matchregion == -1) {
12302
12303 get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
12304 } else {
12305 uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
12306 uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
12307 bool pxn = false;
12308
12309 if (arm_feature(env, ARM_FEATURE_V8_1M)) {
12310 pxn = extract32(env->pmsav8.rlar[secure][matchregion], 4, 1);
12311 }
12312
12313 if (m_is_system_region(env, address)) {
12314
12315 xn = 1;
12316 }
12317
12318 *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
12319 if (*prot && !xn && !(pxn && !is_user)) {
12320 *prot |= PAGE_EXEC;
12321 }
12322
12323
12324
12325 if (mregion) {
12326 *mregion = matchregion;
12327 }
12328 }
12329
12330 fi->type = ARMFault_Permission;
12331 fi->level = 1;
12332 return !(*prot & (1 << access_type));
12333}
12334
12335
12336static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
12337 MMUAccessType access_type, ARMMMUIdx mmu_idx,
12338 hwaddr *phys_ptr, MemTxAttrs *txattrs,
12339 int *prot, target_ulong *page_size,
12340 ARMMMUFaultInfo *fi)
12341{
12342 uint32_t secure = regime_is_secure(env, mmu_idx);
12343 V8M_SAttributes sattrs = {};
12344 bool ret;
12345 bool mpu_is_subpage;
12346
12347 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
12348 v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
12349 if (access_type == MMU_INST_FETCH) {
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367 if (sattrs.ns != !secure) {
12368 if (sattrs.nsc) {
12369 fi->type = ARMFault_QEMU_NSCExec;
12370 } else {
12371 fi->type = ARMFault_QEMU_SFault;
12372 }
12373 *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
12374 *phys_ptr = address;
12375 *prot = 0;
12376 return true;
12377 }
12378 } else {
12379
12380
12381
12382
12383 if (sattrs.ns) {
12384 txattrs->secure = false;
12385 } else if (!secure) {
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395 fi->type = ARMFault_QEMU_SFault;
12396 *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
12397 *phys_ptr = address;
12398 *prot = 0;
12399 return true;
12400 }
12401 }
12402 }
12403
12404 ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
12405 txattrs, prot, &mpu_is_subpage, fi, NULL);
12406 *page_size = sattrs.subpage || mpu_is_subpage ? 1 : TARGET_PAGE_SIZE;
12407 return ret;
12408}
12409
12410static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
12411 MMUAccessType access_type, ARMMMUIdx mmu_idx,
12412 hwaddr *phys_ptr, int *prot,
12413 ARMMMUFaultInfo *fi)
12414{
12415 int n;
12416 uint32_t mask;
12417 uint32_t base;
12418 bool is_user = regime_is_user(env, mmu_idx);
12419
12420 if (regime_translation_disabled(env, mmu_idx)) {
12421
12422 *phys_ptr = address;
12423 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
12424 return false;
12425 }
12426
12427 *phys_ptr = address;
12428 for (n = 7; n >= 0; n--) {
12429 base = env->cp15.c6_region[n];
12430 if ((base & 1) == 0) {
12431 continue;
12432 }
12433 mask = 1 << ((base >> 1) & 0x1f);
12434
12435
12436 mask = (mask << 1) - 1;
12437 if (((base ^ address) & ~mask) == 0) {
12438 break;
12439 }
12440 }
12441 if (n < 0) {
12442 fi->type = ARMFault_Background;
12443 return true;
12444 }
12445
12446 if (access_type == MMU_INST_FETCH) {
12447 mask = env->cp15.pmsav5_insn_ap;
12448 } else {
12449 mask = env->cp15.pmsav5_data_ap;
12450 }
12451 mask = (mask >> (n * 4)) & 0xf;
12452 switch (mask) {
12453 case 0:
12454 fi->type = ARMFault_Permission;
12455 fi->level = 1;
12456 return true;
12457 case 1:
12458 if (is_user) {
12459 fi->type = ARMFault_Permission;
12460 fi->level = 1;
12461 return true;
12462 }
12463 *prot = PAGE_READ | PAGE_WRITE;
12464 break;
12465 case 2:
12466 *prot = PAGE_READ;
12467 if (!is_user) {
12468 *prot |= PAGE_WRITE;
12469 }
12470 break;
12471 case 3:
12472 *prot = PAGE_READ | PAGE_WRITE;
12473 break;
12474 case 5:
12475 if (is_user) {
12476 fi->type = ARMFault_Permission;
12477 fi->level = 1;
12478 return true;
12479 }
12480 *prot = PAGE_READ;
12481 break;
12482 case 6:
12483 *prot = PAGE_READ;
12484 break;
12485 default:
12486
12487 fi->type = ARMFault_Permission;
12488 fi->level = 1;
12489 return true;
12490 }
12491 *prot |= PAGE_EXEC;
12492 return false;
12493}
12494
12495
12496
12497
12498
12499
12500
12501
12502static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2)
12503{
12504 if (s1 == 4 || s2 == 4) {
12505
12506 return 4;
12507 } else if (extract32(s1, 2, 2) == 0 || extract32(s1, 2, 2) == 2) {
12508
12509 return s1;
12510 } else if (extract32(s2, 2, 2) == 2) {
12511
12512
12513
12514 return (2 << 2) | extract32(s1, 0, 2);
12515 } else {
12516 return s1;
12517 }
12518}
12519
12520
12521
12522
12523
12524
12525
12526static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2)
12527{
12528 uint8_t s1lo, s2lo, s1hi, s2hi;
12529 ARMCacheAttrs ret;
12530 bool tagged = false;
12531
12532 if (s1.attrs == 0xf0) {
12533 tagged = true;
12534 s1.attrs = 0xff;
12535 }
12536
12537 s1lo = extract32(s1.attrs, 0, 4);
12538 s2lo = extract32(s2.attrs, 0, 4);
12539 s1hi = extract32(s1.attrs, 4, 4);
12540 s2hi = extract32(s2.attrs, 4, 4);
12541
12542
12543 if (s1.shareability == 2 || s2.shareability == 2) {
12544
12545 ret.shareability = 2;
12546 } else if (s1.shareability == 3 || s2.shareability == 3) {
12547
12548 ret.shareability = 3;
12549 } else {
12550
12551 ret.shareability = 0;
12552 }
12553
12554
12555 if (s1hi == 0 || s2hi == 0) {
12556
12557 if (s1lo == 0 || s2lo == 0) {
12558
12559 ret.attrs = 0;
12560 } else if (s1lo == 4 || s2lo == 4) {
12561
12562 ret.attrs = 4;
12563 } else if (s1lo == 8 || s2lo == 8) {
12564
12565 ret.attrs = 8;
12566 } else {
12567 ret.attrs = 0xc;
12568 }
12569
12570
12571
12572
12573 ret.shareability = 2;
12574 } else {
12575
12576 ret.attrs = combine_cacheattr_nibble(s1hi, s2hi) << 4
12577 | combine_cacheattr_nibble(s1lo, s2lo);
12578
12579 if (ret.attrs == 0x44) {
12580
12581
12582
12583
12584 ret.shareability = 2;
12585 }
12586 }
12587
12588
12589 if (tagged && ret.attrs == 0xff) {
12590 ret.attrs = 0xf0;
12591 }
12592
12593 return ret;
12594}
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
12622
12623bool get_phys_addr(CPUARMState *env, target_ulong address,
12624 MMUAccessType access_type, ARMMMUIdx mmu_idx,
12625 hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
12626 target_ulong *page_size,
12627 ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
12628{
12629 ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
12630
12631 if (mmu_idx != s1_mmu_idx) {
12632
12633
12634
12635 if (arm_feature(env, ARM_FEATURE_EL2)) {
12636 hwaddr ipa;
12637 int s2_prot;
12638 int ret;
12639 ARMCacheAttrs cacheattrs2 = {};
12640 ARMMMUIdx s2_mmu_idx;
12641 bool is_el0;
12642
12643 ret = get_phys_addr(env, address, access_type, s1_mmu_idx, &ipa,
12644 attrs, prot, page_size, fi, cacheattrs);
12645
12646
12647 if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
12648 *phys_ptr = ipa;
12649 return ret;
12650 }
12651
12652 s2_mmu_idx = attrs->secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
12653 is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
12654
12655
12656 ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx, is_el0,
12657 phys_ptr, attrs, &s2_prot,
12658 page_size, fi, &cacheattrs2);
12659 fi->s2addr = ipa;
12660
12661 *prot &= s2_prot;
12662
12663
12664 if (ret) {
12665 return ret;
12666 }
12667
12668
12669 if (arm_hcr_el2_eff(env) & HCR_DC) {
12670
12671
12672
12673
12674
12675
12676
12677 if (cacheattrs->attrs != 0xf0) {
12678 cacheattrs->attrs = 0xff;
12679 }
12680 cacheattrs->shareability = 0;
12681 }
12682 *cacheattrs = combine_cacheattrs(*cacheattrs, cacheattrs2);
12683
12684
12685 if (arm_is_secure_below_el3(env)) {
12686 if (attrs->secure) {
12687 attrs->secure =
12688 !(env->cp15.vstcr_el2.raw_tcr & (VSTCR_SA | VSTCR_SW));
12689 } else {
12690 attrs->secure =
12691 !((env->cp15.vtcr_el2.raw_tcr & (VTCR_NSA | VTCR_NSW))
12692 || (env->cp15.vstcr_el2.raw_tcr & VSTCR_SA));
12693 }
12694 }
12695 return 0;
12696 } else {
12697
12698
12699
12700 mmu_idx = stage_1_mmu_idx(mmu_idx);
12701 }
12702 }
12703
12704
12705
12706
12707
12708 attrs->secure = regime_is_secure(env, mmu_idx);
12709 attrs->user = regime_is_user(env, mmu_idx);
12710
12711
12712
12713
12714 if (address < 0x02000000 && mmu_idx != ARMMMUIdx_Stage2
12715 && !arm_feature(env, ARM_FEATURE_V8)) {
12716 if (regime_el(env, mmu_idx) == 3) {
12717 address += env->cp15.fcseidr_s;
12718 } else {
12719 address += env->cp15.fcseidr_ns;
12720 }
12721 }
12722
12723 if (arm_feature(env, ARM_FEATURE_PMSA)) {
12724 bool ret;
12725 *page_size = TARGET_PAGE_SIZE;
12726
12727 if (arm_feature(env, ARM_FEATURE_V8)) {
12728
12729 ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
12730 phys_ptr, attrs, prot, page_size, fi);
12731 } else if (arm_feature(env, ARM_FEATURE_V7)) {
12732
12733 ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
12734 phys_ptr, prot, page_size, fi);
12735 } else {
12736
12737 ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
12738 phys_ptr, prot, fi);
12739 }
12740 qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
12741 " mmu_idx %u -> %s (prot %c%c%c)\n",
12742 access_type == MMU_DATA_LOAD ? "reading" :
12743 (access_type == MMU_DATA_STORE ? "writing" : "execute"),
12744 (uint32_t)address, mmu_idx,
12745 ret ? "Miss" : "Hit",
12746 *prot & PAGE_READ ? 'r' : '-',
12747 *prot & PAGE_WRITE ? 'w' : '-',
12748 *prot & PAGE_EXEC ? 'x' : '-');
12749
12750 return ret;
12751 }
12752
12753
12754
12755 if (regime_translation_disabled(env, mmu_idx)) {
12756 uint64_t hcr;
12757 uint8_t memattr;
12758
12759
12760
12761
12762
12763 if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
12764 int r_el = regime_el(env, mmu_idx);
12765 if (arm_el_is_aa64(env, r_el)) {
12766 int pamax = arm_pamax(env_archcpu(env));
12767 uint64_t tcr = env->cp15.tcr_el[r_el].raw_tcr;
12768 int addrtop, tbi;
12769
12770 tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
12771 if (access_type == MMU_INST_FETCH) {
12772 tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
12773 }
12774 tbi = (tbi >> extract64(address, 55, 1)) & 1;
12775 addrtop = (tbi ? 55 : 63);
12776
12777 if (extract64(address, pamax, addrtop - pamax + 1) != 0) {
12778 fi->type = ARMFault_AddressSize;
12779 fi->level = 0;
12780 fi->stage2 = false;
12781 return 1;
12782 }
12783
12784
12785
12786
12787
12788
12789
12790 address = extract64(address, 0, 52);
12791 }
12792 }
12793 *phys_ptr = address;
12794 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
12795 *page_size = TARGET_PAGE_SIZE;
12796
12797
12798 hcr = arm_hcr_el2_eff(env);
12799 cacheattrs->shareability = 0;
12800 if (hcr & HCR_DC) {
12801 if (hcr & HCR_DCT) {
12802 memattr = 0xf0;
12803 } else {
12804 memattr = 0xff;
12805 }
12806 } else if (access_type == MMU_INST_FETCH) {
12807 if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
12808 memattr = 0xee;
12809 } else {
12810 memattr = 0x44;
12811 }
12812 cacheattrs->shareability = 2;
12813 } else {
12814 memattr = 0x00;
12815 }
12816 cacheattrs->attrs = memattr;
12817 return 0;
12818 }
12819
12820 if (regime_using_lpae_format(env, mmu_idx)) {
12821 return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
12822 phys_ptr, attrs, prot, page_size,
12823 fi, cacheattrs);
12824 } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
12825 return get_phys_addr_v6(env, address, access_type, mmu_idx,
12826 phys_ptr, attrs, prot, page_size, fi);
12827 } else {
12828 return get_phys_addr_v5(env, address, access_type, mmu_idx,
12829 phys_ptr, prot, page_size, fi);
12830 }
12831}
12832
12833hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
12834 MemTxAttrs *attrs)
12835{
12836 ARMCPU *cpu = ARM_CPU(cs);
12837 CPUARMState *env = &cpu->env;
12838 hwaddr phys_addr;
12839 target_ulong page_size;
12840 int prot;
12841 bool ret;
12842 ARMMMUFaultInfo fi = {};
12843 ARMMMUIdx mmu_idx = arm_mmu_idx(env);
12844 ARMCacheAttrs cacheattrs = {};
12845
12846 *attrs = (MemTxAttrs) {};
12847
12848 ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &phys_addr,
12849 attrs, &prot, &page_size, &fi, &cacheattrs);
12850
12851 if (ret) {
12852 return -1;
12853 }
12854 return phys_addr;
12855}
12856
12857#endif
12858
12859
12860
12861
12862
12863
12864
12865
12866static inline uint16_t add16_sat(uint16_t a, uint16_t b)
12867{
12868 uint16_t res;
12869
12870 res = a + b;
12871 if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
12872 if (a & 0x8000)
12873 res = 0x8000;
12874 else
12875 res = 0x7fff;
12876 }
12877 return res;
12878}
12879
12880
12881static inline uint8_t add8_sat(uint8_t a, uint8_t b)
12882{
12883 uint8_t res;
12884
12885 res = a + b;
12886 if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
12887 if (a & 0x80)
12888 res = 0x80;
12889 else
12890 res = 0x7f;
12891 }
12892 return res;
12893}
12894
12895
12896static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
12897{
12898 uint16_t res;
12899
12900 res = a - b;
12901 if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
12902 if (a & 0x8000)
12903 res = 0x8000;
12904 else
12905 res = 0x7fff;
12906 }
12907 return res;
12908}
12909
12910
12911static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
12912{
12913 uint8_t res;
12914
12915 res = a - b;
12916 if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
12917 if (a & 0x80)
12918 res = 0x80;
12919 else
12920 res = 0x7f;
12921 }
12922 return res;
12923}
12924
12925#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
12926#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
12927#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
12928#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
12929#define PFX q
12930
12931#include "op_addsub.h"
12932
12933
12934static inline uint16_t add16_usat(uint16_t a, uint16_t b)
12935{
12936 uint16_t res;
12937 res = a + b;
12938 if (res < a)
12939 res = 0xffff;
12940 return res;
12941}
12942
12943static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
12944{
12945 if (a > b)
12946 return a - b;
12947 else
12948 return 0;
12949}
12950
12951static inline uint8_t add8_usat(uint8_t a, uint8_t b)
12952{
12953 uint8_t res;
12954 res = a + b;
12955 if (res < a)
12956 res = 0xff;
12957 return res;
12958}
12959
12960static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
12961{
12962 if (a > b)
12963 return a - b;
12964 else
12965 return 0;
12966}
12967
12968#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
12969#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
12970#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
12971#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
12972#define PFX uq
12973
12974#include "op_addsub.h"
12975
12976
12977#define SARITH16(a, b, n, op) do { \
12978 int32_t sum; \
12979 sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \
12980 RESULT(sum, n, 16); \
12981 if (sum >= 0) \
12982 ge |= 3 << (n * 2); \
12983 } while(0)
12984
12985#define SARITH8(a, b, n, op) do { \
12986 int32_t sum; \
12987 sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \
12988 RESULT(sum, n, 8); \
12989 if (sum >= 0) \
12990 ge |= 1 << n; \
12991 } while(0)
12992
12993
12994#define ADD16(a, b, n) SARITH16(a, b, n, +)
12995#define SUB16(a, b, n) SARITH16(a, b, n, -)
12996#define ADD8(a, b, n) SARITH8(a, b, n, +)
12997#define SUB8(a, b, n) SARITH8(a, b, n, -)
12998#define PFX s
12999#define ARITH_GE
13000
13001#include "op_addsub.h"
13002
13003
13004#define ADD16(a, b, n) do { \
13005 uint32_t sum; \
13006 sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
13007 RESULT(sum, n, 16); \
13008 if ((sum >> 16) == 1) \
13009 ge |= 3 << (n * 2); \
13010 } while(0)
13011
13012#define ADD8(a, b, n) do { \
13013 uint32_t sum; \
13014 sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
13015 RESULT(sum, n, 8); \
13016 if ((sum >> 8) == 1) \
13017 ge |= 1 << n; \
13018 } while(0)
13019
13020#define SUB16(a, b, n) do { \
13021 uint32_t sum; \
13022 sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
13023 RESULT(sum, n, 16); \
13024 if ((sum >> 16) == 0) \
13025 ge |= 3 << (n * 2); \
13026 } while(0)
13027
13028#define SUB8(a, b, n) do { \
13029 uint32_t sum; \
13030 sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
13031 RESULT(sum, n, 8); \
13032 if ((sum >> 8) == 0) \
13033 ge |= 1 << n; \
13034 } while(0)
13035
13036#define PFX u
13037#define ARITH_GE
13038
13039#include "op_addsub.h"
13040
13041
13042#define ADD16(a, b, n) \
13043 RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
13044#define SUB16(a, b, n) \
13045 RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
13046#define ADD8(a, b, n) \
13047 RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
13048#define SUB8(a, b, n) \
13049 RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
13050#define PFX sh
13051
13052#include "op_addsub.h"
13053
13054
13055#define ADD16(a, b, n) \
13056 RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
13057#define SUB16(a, b, n) \
13058 RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
13059#define ADD8(a, b, n) \
13060 RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
13061#define SUB8(a, b, n) \
13062 RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
13063#define PFX uh
13064
13065#include "op_addsub.h"
13066
13067static inline uint8_t do_usad(uint8_t a, uint8_t b)
13068{
13069 if (a > b)
13070 return a - b;
13071 else
13072 return b - a;
13073}
13074
13075
13076uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
13077{
13078 uint32_t sum;
13079 sum = do_usad(a, b);
13080 sum += do_usad(a >> 8, b >> 8);
13081 sum += do_usad(a >> 16, b >> 16);
13082 sum += do_usad(a >> 24, b >> 24);
13083 return sum;
13084}
13085
13086
13087uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
13088{
13089 uint32_t mask;
13090
13091 mask = 0;
13092 if (flags & 1)
13093 mask |= 0xff;
13094 if (flags & 2)
13095 mask |= 0xff00;
13096 if (flags & 4)
13097 mask |= 0xff0000;
13098 if (flags & 8)
13099 mask |= 0xff000000;
13100 return (a & mask) | (b & ~mask);
13101}
13102
13103
13104
13105
13106
13107uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes)
13108{
13109 uint8_t buf[4];
13110
13111 stl_le_p(buf, val);
13112
13113
13114 return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
13115}
13116
13117uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
13118{
13119 uint8_t buf[4];
13120
13121 stl_le_p(buf, val);
13122
13123
13124 return crc32c(acc, buf, bytes) ^ 0xffffffff;
13125}
13126
13127
13128
13129
13130int fp_exception_el(CPUARMState *env, int cur_el)
13131{
13132#ifndef CONFIG_USER_ONLY
13133
13134
13135
13136 if (!arm_feature(env, ARM_FEATURE_V6)) {
13137 return 0;
13138 }
13139
13140 if (arm_feature(env, ARM_FEATURE_M)) {
13141
13142 if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
13143 return 1;
13144 }
13145
13146 if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
13147 if (!extract32(env->v7m.nsacr, 10, 1)) {
13148
13149 return 3;
13150 }
13151 }
13152
13153 return 0;
13154 }
13155
13156
13157
13158
13159
13160
13161
13162 if ((arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
13163 int fpen = extract32(env->cp15.cpacr_el1, 20, 2);
13164
13165 switch (fpen) {
13166 case 0:
13167 case 2:
13168 if (cur_el == 0 || cur_el == 1) {
13169
13170 if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
13171 return 3;
13172 }
13173 return 1;
13174 }
13175 if (cur_el == 3 && !is_a64(env)) {
13176
13177 return 3;
13178 }
13179 break;
13180 case 1:
13181 if (cur_el == 0) {
13182 return 1;
13183 }
13184 break;
13185 case 3:
13186 break;
13187 }
13188 }
13189
13190
13191
13192
13193
13194
13195 if ((arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
13196 cur_el <= 2 && !arm_is_secure_below_el3(env))) {
13197 if (!extract32(env->cp15.nsacr, 10, 1)) {
13198
13199 return cur_el == 2 ? 2 : 1;
13200 }
13201 }
13202
13203
13204
13205
13206
13207
13208 if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1)
13209 && arm_is_el2_enabled(env)) {
13210
13211 return 2;
13212 }
13213
13214
13215 if (extract32(env->cp15.cptr_el[3], 10, 1)) {
13216
13217 return 3;
13218 }
13219#endif
13220 return 0;
13221}
13222
13223
13224int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
13225{
13226 if (mmu_idx & ARM_MMU_IDX_M) {
13227 return mmu_idx & ARM_MMU_IDX_M_PRIV;
13228 }
13229
13230 switch (mmu_idx) {
13231 case ARMMMUIdx_E10_0:
13232 case ARMMMUIdx_E20_0:
13233 case ARMMMUIdx_SE10_0:
13234 case ARMMMUIdx_SE20_0:
13235 return 0;
13236 case ARMMMUIdx_E10_1:
13237 case ARMMMUIdx_E10_1_PAN:
13238 case ARMMMUIdx_SE10_1:
13239 case ARMMMUIdx_SE10_1_PAN:
13240 return 1;
13241 case ARMMMUIdx_E2:
13242 case ARMMMUIdx_E20_2:
13243 case ARMMMUIdx_E20_2_PAN:
13244 case ARMMMUIdx_SE2:
13245 case ARMMMUIdx_SE20_2:
13246 case ARMMMUIdx_SE20_2_PAN:
13247 return 2;
13248 case ARMMMUIdx_SE3:
13249 return 3;
13250 default:
13251 g_assert_not_reached();
13252 }
13253}
13254
13255#ifndef CONFIG_TCG
13256ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
13257{
13258 g_assert_not_reached();
13259}
13260#endif
13261
13262ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
13263{
13264 ARMMMUIdx idx;
13265 uint64_t hcr;
13266
13267 if (arm_feature(env, ARM_FEATURE_M)) {
13268 return arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
13269 }
13270
13271
13272 switch (el) {
13273 case 0:
13274 hcr = arm_hcr_el2_eff(env);
13275 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
13276 idx = ARMMMUIdx_E20_0;
13277 } else {
13278 idx = ARMMMUIdx_E10_0;
13279 }
13280 break;
13281 case 1:
13282 if (env->pstate & PSTATE_PAN) {
13283 idx = ARMMMUIdx_E10_1_PAN;
13284 } else {
13285 idx = ARMMMUIdx_E10_1;
13286 }
13287 break;
13288 case 2:
13289
13290 if (arm_hcr_el2_eff(env) & HCR_E2H) {
13291 if (env->pstate & PSTATE_PAN) {
13292 idx = ARMMMUIdx_E20_2_PAN;
13293 } else {
13294 idx = ARMMMUIdx_E20_2;
13295 }
13296 } else {
13297 idx = ARMMMUIdx_E2;
13298 }
13299 break;
13300 case 3:
13301 return ARMMMUIdx_SE3;
13302 default:
13303 g_assert_not_reached();
13304 }
13305
13306 if (arm_is_secure_below_el3(env)) {
13307 idx &= ~ARM_MMU_IDX_A_NS;
13308 }
13309
13310 return idx;
13311}
13312
13313ARMMMUIdx arm_mmu_idx(CPUARMState *env)
13314{
13315 return arm_mmu_idx_el(env, arm_current_el(env));
13316}
13317
13318#ifndef CONFIG_USER_ONLY
13319ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
13320{
13321 return stage_1_mmu_idx(arm_mmu_idx(env));
13322}
13323#endif
13324
13325static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
13326 ARMMMUIdx mmu_idx,
13327 CPUARMTBFlags flags)
13328{
13329 DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el);
13330 DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
13331
13332 if (arm_singlestep_active(env)) {
13333 DP_TBFLAG_ANY(flags, SS_ACTIVE, 1);
13334 }
13335 return flags;
13336}
13337
13338static CPUARMTBFlags rebuild_hflags_common_32(CPUARMState *env, int fp_el,
13339 ARMMMUIdx mmu_idx,
13340 CPUARMTBFlags flags)
13341{
13342 bool sctlr_b = arm_sctlr_b(env);
13343
13344 if (sctlr_b) {
13345 DP_TBFLAG_A32(flags, SCTLR__B, 1);
13346 }
13347 if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
13348 DP_TBFLAG_ANY(flags, BE_DATA, 1);
13349 }
13350 DP_TBFLAG_A32(flags, NS, !access_secure_reg(env));
13351
13352 return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
13353}
13354
13355static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
13356 ARMMMUIdx mmu_idx)
13357{
13358 CPUARMTBFlags flags = {};
13359 uint32_t ccr = env->v7m.ccr[env->v7m.secure];
13360
13361
13362 if (ccr & R_V7M_CCR_UNALIGN_TRP_MASK) {
13363 DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
13364 }
13365
13366 if (arm_v7m_is_handler_mode(env)) {
13367 DP_TBFLAG_M32(flags, HANDLER, 1);
13368 }
13369
13370
13371
13372
13373
13374
13375 if (arm_feature(env, ARM_FEATURE_V8) &&
13376 !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
13377 (ccr & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
13378 DP_TBFLAG_M32(flags, STACKCHECK, 1);
13379 }
13380
13381 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
13382}
13383
13384static CPUARMTBFlags rebuild_hflags_aprofile(CPUARMState *env)
13385{
13386 CPUARMTBFlags flags = {};
13387
13388 DP_TBFLAG_ANY(flags, DEBUG_TARGET_EL, arm_debug_target_el(env));
13389 return flags;
13390}
13391
13392static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
13393 ARMMMUIdx mmu_idx)
13394{
13395 CPUARMTBFlags flags = rebuild_hflags_aprofile(env);
13396 int el = arm_current_el(env);
13397
13398 if (arm_sctlr(env, el) & SCTLR_A) {
13399 DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
13400 }
13401
13402 if (arm_el_is_aa64(env, 1)) {
13403 DP_TBFLAG_A32(flags, VFPEN, 1);
13404 }
13405
13406 if (el < 2 && env->cp15.hstr_el2 &&
13407 (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
13408 DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
13409 }
13410
13411 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
13412}
13413
13414static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
13415 ARMMMUIdx mmu_idx)
13416{
13417 CPUARMTBFlags flags = rebuild_hflags_aprofile(env);
13418 ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
13419 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
13420 uint64_t sctlr;
13421 int tbii, tbid;
13422
13423 DP_TBFLAG_ANY(flags, AARCH64_STATE, 1);
13424
13425
13426 tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
13427 tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
13428
13429 DP_TBFLAG_A64(flags, TBII, tbii);
13430 DP_TBFLAG_A64(flags, TBID, tbid);
13431
13432 if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
13433 int sve_el = sve_exception_el(env, el);
13434 uint32_t zcr_len;
13435
13436
13437
13438
13439
13440 if (sve_el != 0 && fp_el == 0) {
13441 zcr_len = 0;
13442 } else {
13443 zcr_len = sve_zcr_len_for_el(env, el);
13444 }
13445 DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
13446 DP_TBFLAG_A64(flags, ZCR_LEN, zcr_len);
13447 }
13448
13449 sctlr = regime_sctlr(env, stage1);
13450
13451 if (sctlr & SCTLR_A) {
13452 DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
13453 }
13454
13455 if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
13456 DP_TBFLAG_ANY(flags, BE_DATA, 1);
13457 }
13458
13459 if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
13460
13461
13462
13463
13464
13465
13466 if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
13467 DP_TBFLAG_A64(flags, PAUTH_ACTIVE, 1);
13468 }
13469 }
13470
13471 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
13472
13473 if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
13474 DP_TBFLAG_A64(flags, BT, 1);
13475 }
13476 }
13477
13478
13479 if (!(env->pstate & PSTATE_UAO)) {
13480 switch (mmu_idx) {
13481 case ARMMMUIdx_E10_1:
13482 case ARMMMUIdx_E10_1_PAN:
13483 case ARMMMUIdx_SE10_1:
13484 case ARMMMUIdx_SE10_1_PAN:
13485
13486 DP_TBFLAG_A64(flags, UNPRIV, 1);
13487 break;
13488 case ARMMMUIdx_E20_2:
13489 case ARMMMUIdx_E20_2_PAN:
13490 case ARMMMUIdx_SE20_2:
13491 case ARMMMUIdx_SE20_2_PAN:
13492
13493
13494
13495
13496 if (env->cp15.hcr_el2 & HCR_TGE) {
13497 DP_TBFLAG_A64(flags, UNPRIV, 1);
13498 }
13499 break;
13500 default:
13501 break;
13502 }
13503 }
13504
13505 if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
13506
13507
13508
13509
13510
13511
13512
13513
13514 if (allocation_tag_access_enabled(env, el, sctlr)) {
13515 DP_TBFLAG_A64(flags, ATA, 1);
13516 if (tbid
13517 && !(env->pstate & PSTATE_TCO)
13518 && (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) {
13519 DP_TBFLAG_A64(flags, MTE_ACTIVE, 1);
13520 }
13521 }
13522
13523 if (EX_TBFLAG_A64(flags, UNPRIV)
13524 && tbid
13525 && !(env->pstate & PSTATE_TCO)
13526 && (sctlr & SCTLR_TCF0)
13527 && allocation_tag_access_enabled(env, 0, sctlr)) {
13528 DP_TBFLAG_A64(flags, MTE0_ACTIVE, 1);
13529 }
13530
13531 DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx));
13532 }
13533
13534 return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
13535}
13536
13537static CPUARMTBFlags rebuild_hflags_internal(CPUARMState *env)
13538{
13539 int el = arm_current_el(env);
13540 int fp_el = fp_exception_el(env, el);
13541 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13542
13543 if (is_a64(env)) {
13544 return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
13545 } else if (arm_feature(env, ARM_FEATURE_M)) {
13546 return rebuild_hflags_m32(env, fp_el, mmu_idx);
13547 } else {
13548 return rebuild_hflags_a32(env, fp_el, mmu_idx);
13549 }
13550}
13551
13552void arm_rebuild_hflags(CPUARMState *env)
13553{
13554 env->hflags = rebuild_hflags_internal(env);
13555}
13556
13557
13558
13559
13560
13561void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env)
13562{
13563 int el = arm_current_el(env);
13564 int fp_el = fp_exception_el(env, el);
13565 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13566
13567 env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
13568}
13569
13570void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
13571{
13572 int fp_el = fp_exception_el(env, el);
13573 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13574
13575 env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
13576}
13577
13578
13579
13580
13581
13582void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
13583{
13584 int el = arm_current_el(env);
13585 int fp_el = fp_exception_el(env, el);
13586 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13587 env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
13588}
13589
13590void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
13591{
13592 int fp_el = fp_exception_el(env, el);
13593 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13594
13595 env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
13596}
13597
13598void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
13599{
13600 int fp_el = fp_exception_el(env, el);
13601 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13602
13603 env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx);
13604}
13605
13606static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
13607{
13608#ifdef CONFIG_DEBUG_TCG
13609 CPUARMTBFlags c = env->hflags;
13610 CPUARMTBFlags r = rebuild_hflags_internal(env);
13611
13612 if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) {
13613 fprintf(stderr, "TCG hflags mismatch "
13614 "(current:(0x%08x,0x" TARGET_FMT_lx ")"
13615 " rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n",
13616 c.flags, c.flags2, r.flags, r.flags2);
13617 abort();
13618 }
13619#endif
13620}
13621
13622void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
13623 target_ulong *cs_base, uint32_t *pflags)
13624{
13625 CPUARMTBFlags flags;
13626
13627 assert_hflags_rebuild_correctly(env);
13628 flags = env->hflags;
13629
13630 if (EX_TBFLAG_ANY(flags, AARCH64_STATE)) {
13631 *pc = env->pc;
13632 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
13633 DP_TBFLAG_A64(flags, BTYPE, env->btype);
13634 }
13635 } else {
13636 *pc = env->regs[15];
13637
13638 if (arm_feature(env, ARM_FEATURE_M)) {
13639 if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
13640 FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S)
13641 != env->v7m.secure) {
13642 DP_TBFLAG_M32(flags, FPCCR_S_WRONG, 1);
13643 }
13644
13645 if ((env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
13646 (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
13647 (env->v7m.secure &&
13648 !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
13649
13650
13651
13652
13653
13654 DP_TBFLAG_M32(flags, NEW_FP_CTXT_NEEDED, 1);
13655 }
13656
13657 bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
13658 if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
13659 DP_TBFLAG_M32(flags, LSPACT, 1);
13660 }
13661 } else {
13662
13663
13664
13665
13666 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
13667 DP_TBFLAG_A32(flags, XSCALE_CPAR, env->cp15.c15_cpar);
13668 } else {
13669 DP_TBFLAG_A32(flags, VECLEN, env->vfp.vec_len);
13670 DP_TBFLAG_A32(flags, VECSTRIDE, env->vfp.vec_stride);
13671 }
13672 if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
13673 DP_TBFLAG_A32(flags, VFPEN, 1);
13674 }
13675 }
13676
13677 DP_TBFLAG_AM32(flags, THUMB, env->thumb);
13678 DP_TBFLAG_AM32(flags, CONDEXEC, env->condexec_bits);
13679 }
13680
13681
13682
13683
13684
13685
13686
13687
13688
13689
13690 if (EX_TBFLAG_ANY(flags, SS_ACTIVE) && (env->pstate & PSTATE_SS)) {
13691 DP_TBFLAG_ANY(flags, PSTATE__SS, 1);
13692 }
13693
13694 *pflags = flags.flags;
13695 *cs_base = flags.flags2;
13696}
13697
13698#ifdef TARGET_AARCH64
13699
13700
13701
13702
13703
13704
13705
13706
13707
13708
13709
13710
13711
13712
13713void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
13714{
13715 int i, j;
13716 uint64_t pmask;
13717
13718 assert(vq >= 1 && vq <= ARM_MAX_VQ);
13719 assert(vq <= env_archcpu(env)->sve_max_vq);
13720
13721
13722 for (i = 0; i < 32; i++) {
13723 memset(&env->vfp.zregs[i].d[2 * vq], 0, 16 * (ARM_MAX_VQ - vq));
13724 }
13725
13726
13727 pmask = 0;
13728 if (vq & 3) {
13729 pmask = ~(-1ULL << (16 * (vq & 3)));
13730 }
13731 for (j = vq / 4; j < ARM_MAX_VQ / 4; j++) {
13732 for (i = 0; i < 17; ++i) {
13733 env->vfp.pregs[i].p[j] &= pmask;
13734 }
13735 pmask = 0;
13736 }
13737}
13738
13739
13740
13741
13742void aarch64_sve_change_el(CPUARMState *env, int old_el,
13743 int new_el, bool el0_a64)
13744{
13745 ARMCPU *cpu = env_archcpu(env);
13746 int old_len, new_len;
13747 bool old_a64, new_a64;
13748
13749
13750 if (!cpu_isar_feature(aa64_sve, cpu)) {
13751 return;
13752 }
13753
13754
13755 if (fp_exception_el(env, old_el) || fp_exception_el(env, new_el)) {
13756 return;
13757 }
13758
13759
13760
13761
13762
13763
13764
13765
13766
13767
13768
13769
13770
13771 old_a64 = old_el ? arm_el_is_aa64(env, old_el) : el0_a64;
13772 old_len = (old_a64 && !sve_exception_el(env, old_el)
13773 ? sve_zcr_len_for_el(env, old_el) : 0);
13774 new_a64 = new_el ? arm_el_is_aa64(env, new_el) : el0_a64;
13775 new_len = (new_a64 && !sve_exception_el(env, new_el)
13776 ? sve_zcr_len_for_el(env, new_el) : 0);
13777
13778
13779 if (new_len < old_len) {
13780 aarch64_sve_narrow_vq(env, new_len + 1);
13781 }
13782}
13783#endif
13784