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 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tcr_el[3]),
4110 offsetoflow32(CPUARMState, cp15.tcr_el[1])} },
4111 REGINFO_SENTINEL
4112};
4113
4114
4115
4116
4117static const ARMCPRegInfo ttbcr2_reginfo = {
4118 .name = "TTBCR2", .cp = 15, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 3,
4119 .access = PL1_RW, .accessfn = access_tvm_trvm,
4120 .type = ARM_CP_ALIAS,
4121 .bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]),
4122 offsetofhigh32(CPUARMState, cp15.tcr_el[1]) },
4123};
4124
4125static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
4126 uint64_t value)
4127{
4128 env->cp15.c15_ticonfig = value & 0xe7;
4129
4130 env->cp15.c0_cpuid = (value & (1 << 5)) ?
4131 ARM_CPUID_TI915T : ARM_CPUID_TI925T;
4132}
4133
4134static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
4135 uint64_t value)
4136{
4137 env->cp15.c15_threadid = value & 0xffff;
4138}
4139
4140static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
4141 uint64_t value)
4142{
4143
4144 cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HALT);
4145}
4146
4147static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
4148 uint64_t value)
4149{
4150
4151
4152
4153 env->cp15.c15_i_max = 0x000;
4154 env->cp15.c15_i_min = 0xff0;
4155}
4156
4157static const ARMCPRegInfo omap_cp_reginfo[] = {
4158 { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
4159 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE,
4160 .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
4161 .resetvalue = 0, },
4162 { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
4163 .access = PL1_RW, .type = ARM_CP_NOP },
4164 { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
4165 .access = PL1_RW,
4166 .fieldoffset = offsetof(CPUARMState, cp15.c15_ticonfig), .resetvalue = 0,
4167 .writefn = omap_ticonfig_write },
4168 { .name = "IMAX", .cp = 15, .crn = 15, .crm = 2, .opc1 = 0, .opc2 = 0,
4169 .access = PL1_RW,
4170 .fieldoffset = offsetof(CPUARMState, cp15.c15_i_max), .resetvalue = 0, },
4171 { .name = "IMIN", .cp = 15, .crn = 15, .crm = 3, .opc1 = 0, .opc2 = 0,
4172 .access = PL1_RW, .resetvalue = 0xff0,
4173 .fieldoffset = offsetof(CPUARMState, cp15.c15_i_min) },
4174 { .name = "THREADID", .cp = 15, .crn = 15, .crm = 4, .opc1 = 0, .opc2 = 0,
4175 .access = PL1_RW,
4176 .fieldoffset = offsetof(CPUARMState, cp15.c15_threadid), .resetvalue = 0,
4177 .writefn = omap_threadid_write },
4178 { .name = "TI925T_STATUS", .cp = 15, .crn = 15,
4179 .crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
4180 .type = ARM_CP_NO_RAW,
4181 .readfn = arm_cp_read_zero, .writefn = omap_wfi_write, },
4182
4183
4184
4185
4186
4187 { .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
4188 .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
4189 .type = ARM_CP_OVERRIDE | ARM_CP_NO_RAW,
4190 .writefn = omap_cachemaint_write },
4191 { .name = "C9", .cp = 15, .crn = 9,
4192 .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
4193 .type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 },
4194 REGINFO_SENTINEL
4195};
4196
4197static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
4198 uint64_t value)
4199{
4200 env->cp15.c15_cpar = value & 0x3fff;
4201}
4202
4203static const ARMCPRegInfo xscale_cp_reginfo[] = {
4204 { .name = "XSCALE_CPAR",
4205 .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
4206 .fieldoffset = offsetof(CPUARMState, cp15.c15_cpar), .resetvalue = 0,
4207 .writefn = xscale_cpar_write, },
4208 { .name = "XSCALE_AUXCR",
4209 .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW,
4210 .fieldoffset = offsetof(CPUARMState, cp15.c1_xscaleauxcr),
4211 .resetvalue = 0, },
4212
4213
4214
4215 { .name = "XSCALE_LOCK_ICACHE_LINE",
4216 .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
4217 .access = PL1_W, .type = ARM_CP_NOP },
4218 { .name = "XSCALE_UNLOCK_ICACHE",
4219 .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
4220 .access = PL1_W, .type = ARM_CP_NOP },
4221 { .name = "XSCALE_DCACHE_LOCK",
4222 .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 0,
4223 .access = PL1_RW, .type = ARM_CP_NOP },
4224 { .name = "XSCALE_UNLOCK_DCACHE",
4225 .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 1,
4226 .access = PL1_W, .type = ARM_CP_NOP },
4227 REGINFO_SENTINEL
4228};
4229
4230static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
4231
4232
4233
4234
4235
4236 { .name = "C15_IMPDEF", .cp = 15, .crn = 15,
4237 .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
4238 .access = PL1_RW,
4239 .type = ARM_CP_CONST | ARM_CP_NO_RAW | ARM_CP_OVERRIDE,
4240 .resetvalue = 0 },
4241 REGINFO_SENTINEL
4242};
4243
4244static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = {
4245
4246 { .name = "CDSR", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 6,
4247 .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
4248 .resetvalue = 0 },
4249 REGINFO_SENTINEL
4250};
4251
4252static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
4253
4254 { .name = "BXSR", .cp = 15, .crn = 7, .crm = 12, .opc1 = 0, .opc2 = 4,
4255 .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
4256 .resetvalue = 0 },
4257
4258 { .name = "IICR", .cp = 15, .crm = 5, .opc1 = 0,
4259 .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4260 { .name = "IDCR", .cp = 15, .crm = 6, .opc1 = 0,
4261 .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4262 { .name = "CDCR", .cp = 15, .crm = 12, .opc1 = 0,
4263 .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4264 { .name = "PIR", .cp = 15, .crm = 12, .opc1 = 1,
4265 .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4266 { .name = "PDR", .cp = 15, .crm = 12, .opc1 = 2,
4267 .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4268 { .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0,
4269 .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
4270 REGINFO_SENTINEL
4271};
4272
4273static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
4274
4275
4276
4277 { .name = "TC_DCACHE", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 3,
4278 .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
4279 .resetvalue = (1 << 30) },
4280 { .name = "TCI_DCACHE", .cp = 15, .crn = 7, .crm = 14, .opc1 = 0, .opc2 = 3,
4281 .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
4282 .resetvalue = (1 << 30) },
4283 REGINFO_SENTINEL
4284};
4285
4286static const ARMCPRegInfo strongarm_cp_reginfo[] = {
4287
4288 { .name = "C9_READBUFFER", .cp = 15, .crn = 9,
4289 .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
4290 .access = PL1_RW, .resetvalue = 0,
4291 .type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_RAW },
4292 REGINFO_SENTINEL
4293};
4294
4295static uint64_t midr_read(CPUARMState *env, const ARMCPRegInfo *ri)
4296{
4297 unsigned int cur_el = arm_current_el(env);
4298
4299 if (arm_is_el2_enabled(env) && cur_el == 1) {
4300 return env->cp15.vpidr_el2;
4301 }
4302 return raw_read(env, ri);
4303}
4304
4305static uint64_t mpidr_read_val(CPUARMState *env)
4306{
4307 ARMCPU *cpu = env_archcpu(env);
4308 uint64_t mpidr = cpu->mp_affinity;
4309
4310 if (arm_feature(env, ARM_FEATURE_V7MP)) {
4311 mpidr |= (1U << 31);
4312
4313
4314
4315
4316 if (cpu->mp_is_up) {
4317 mpidr |= (1u << 30);
4318 }
4319 }
4320 return mpidr;
4321}
4322
4323static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
4324{
4325 unsigned int cur_el = arm_current_el(env);
4326
4327 if (arm_is_el2_enabled(env) && cur_el == 1) {
4328 return env->cp15.vmpidr_el2;
4329 }
4330 return mpidr_read_val(env);
4331}
4332
4333static const ARMCPRegInfo lpae_cp_reginfo[] = {
4334
4335 { .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
4336 .opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
4337 .access = PL1_RW, .accessfn = access_tvm_trvm,
4338 .type = ARM_CP_CONST, .resetvalue = 0 },
4339
4340 { .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
4341 .access = PL1_RW, .accessfn = access_tvm_trvm,
4342 .type = ARM_CP_CONST, .resetvalue = 0 },
4343 { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
4344 .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
4345 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s),
4346 offsetof(CPUARMState, cp15.par_ns)} },
4347 { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
4348 .access = PL1_RW, .accessfn = access_tvm_trvm,
4349 .type = ARM_CP_64BIT | ARM_CP_ALIAS,
4350 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
4351 offsetof(CPUARMState, cp15.ttbr0_ns) },
4352 .writefn = vmsa_ttbr_write, },
4353 { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
4354 .access = PL1_RW, .accessfn = access_tvm_trvm,
4355 .type = ARM_CP_64BIT | ARM_CP_ALIAS,
4356 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
4357 offsetof(CPUARMState, cp15.ttbr1_ns) },
4358 .writefn = vmsa_ttbr_write, },
4359 REGINFO_SENTINEL
4360};
4361
4362static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
4363{
4364 return vfp_get_fpcr(env);
4365}
4366
4367static void aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
4368 uint64_t value)
4369{
4370 vfp_set_fpcr(env, value);
4371}
4372
4373static uint64_t aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri)
4374{
4375 return vfp_get_fpsr(env);
4376}
4377
4378static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
4379 uint64_t value)
4380{
4381 vfp_set_fpsr(env, value);
4382}
4383
4384static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri,
4385 bool isread)
4386{
4387 if (arm_current_el(env) == 0 && !(arm_sctlr(env, 0) & SCTLR_UMA)) {
4388 return CP_ACCESS_TRAP;
4389 }
4390 return CP_ACCESS_OK;
4391}
4392
4393static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri,
4394 uint64_t value)
4395{
4396 env->daif = value & PSTATE_DAIF;
4397}
4398
4399static uint64_t aa64_pan_read(CPUARMState *env, const ARMCPRegInfo *ri)
4400{
4401 return env->pstate & PSTATE_PAN;
4402}
4403
4404static void aa64_pan_write(CPUARMState *env, const ARMCPRegInfo *ri,
4405 uint64_t value)
4406{
4407 env->pstate = (env->pstate & ~PSTATE_PAN) | (value & PSTATE_PAN);
4408}
4409
4410static const ARMCPRegInfo pan_reginfo = {
4411 .name = "PAN", .state = ARM_CP_STATE_AA64,
4412 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 3,
4413 .type = ARM_CP_NO_RAW, .access = PL1_RW,
4414 .readfn = aa64_pan_read, .writefn = aa64_pan_write
4415};
4416
4417static uint64_t aa64_uao_read(CPUARMState *env, const ARMCPRegInfo *ri)
4418{
4419 return env->pstate & PSTATE_UAO;
4420}
4421
4422static void aa64_uao_write(CPUARMState *env, const ARMCPRegInfo *ri,
4423 uint64_t value)
4424{
4425 env->pstate = (env->pstate & ~PSTATE_UAO) | (value & PSTATE_UAO);
4426}
4427
4428static const ARMCPRegInfo uao_reginfo = {
4429 .name = "UAO", .state = ARM_CP_STATE_AA64,
4430 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 4,
4431 .type = ARM_CP_NO_RAW, .access = PL1_RW,
4432 .readfn = aa64_uao_read, .writefn = aa64_uao_write
4433};
4434
4435static uint64_t aa64_dit_read(CPUARMState *env, const ARMCPRegInfo *ri)
4436{
4437 return env->pstate & PSTATE_DIT;
4438}
4439
4440static void aa64_dit_write(CPUARMState *env, const ARMCPRegInfo *ri,
4441 uint64_t value)
4442{
4443 env->pstate = (env->pstate & ~PSTATE_DIT) | (value & PSTATE_DIT);
4444}
4445
4446static const ARMCPRegInfo dit_reginfo = {
4447 .name = "DIT", .state = ARM_CP_STATE_AA64,
4448 .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 5,
4449 .type = ARM_CP_NO_RAW, .access = PL0_RW,
4450 .readfn = aa64_dit_read, .writefn = aa64_dit_write
4451};
4452
4453static uint64_t aa64_ssbs_read(CPUARMState *env, const ARMCPRegInfo *ri)
4454{
4455 return env->pstate & PSTATE_SSBS;
4456}
4457
4458static void aa64_ssbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
4459 uint64_t value)
4460{
4461 env->pstate = (env->pstate & ~PSTATE_SSBS) | (value & PSTATE_SSBS);
4462}
4463
4464static const ARMCPRegInfo ssbs_reginfo = {
4465 .name = "SSBS", .state = ARM_CP_STATE_AA64,
4466 .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 6,
4467 .type = ARM_CP_NO_RAW, .access = PL0_RW,
4468 .readfn = aa64_ssbs_read, .writefn = aa64_ssbs_write
4469};
4470
4471static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
4472 const ARMCPRegInfo *ri,
4473 bool isread)
4474{
4475
4476 switch (arm_current_el(env)) {
4477 case 0:
4478
4479 if (!(arm_sctlr(env, 0) & SCTLR_UCI)) {
4480 return CP_ACCESS_TRAP;
4481 }
4482
4483 case 1:
4484
4485 if (arm_hcr_el2_eff(env) & HCR_TPCP) {
4486 return CP_ACCESS_TRAP_EL2;
4487 }
4488 break;
4489 }
4490 return CP_ACCESS_OK;
4491}
4492
4493static CPAccessResult aa64_cacheop_pou_access(CPUARMState *env,
4494 const ARMCPRegInfo *ri,
4495 bool isread)
4496{
4497
4498 switch (arm_current_el(env)) {
4499 case 0:
4500
4501 if (!(arm_sctlr(env, 0) & SCTLR_UCI)) {
4502 return CP_ACCESS_TRAP;
4503 }
4504
4505 case 1:
4506
4507 if (arm_hcr_el2_eff(env) & HCR_TPU) {
4508 return CP_ACCESS_TRAP_EL2;
4509 }
4510 break;
4511 }
4512 return CP_ACCESS_OK;
4513}
4514
4515
4516
4517
4518
4519static int vae1_tlbmask(CPUARMState *env)
4520{
4521 uint64_t hcr = arm_hcr_el2_eff(env);
4522 uint16_t mask;
4523
4524 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
4525 mask = ARMMMUIdxBit_E20_2 |
4526 ARMMMUIdxBit_E20_2_PAN |
4527 ARMMMUIdxBit_E20_0;
4528 } else {
4529 mask = ARMMMUIdxBit_E10_1 |
4530 ARMMMUIdxBit_E10_1_PAN |
4531 ARMMMUIdxBit_E10_0;
4532 }
4533
4534 if (arm_is_secure_below_el3(env)) {
4535 mask >>= ARM_MMU_IDX_A_NS;
4536 }
4537
4538 return mask;
4539}
4540
4541
4542static int tlbbits_for_regime(CPUARMState *env, ARMMMUIdx mmu_idx,
4543 uint64_t addr)
4544{
4545 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
4546 int tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
4547 int select = extract64(addr, 55, 1);
4548
4549 return (tbi >> select) & 1 ? 56 : 64;
4550}
4551
4552static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
4553{
4554 uint64_t hcr = arm_hcr_el2_eff(env);
4555 ARMMMUIdx mmu_idx;
4556
4557
4558 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
4559 mmu_idx = ARMMMUIdx_E20_0;
4560 } else {
4561 mmu_idx = ARMMMUIdx_E10_0;
4562 }
4563
4564 if (arm_is_secure_below_el3(env)) {
4565 mmu_idx &= ~ARM_MMU_IDX_A_NS;
4566 }
4567
4568 return tlbbits_for_regime(env, mmu_idx, addr);
4569}
4570
4571static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4572 uint64_t value)
4573{
4574 CPUState *cs = env_cpu(env);
4575 int mask = vae1_tlbmask(env);
4576
4577 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask);
4578}
4579
4580static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
4581 uint64_t value)
4582{
4583 CPUState *cs = env_cpu(env);
4584 int mask = vae1_tlbmask(env);
4585
4586 if (tlb_force_broadcast(env)) {
4587 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask);
4588 } else {
4589 tlb_flush_by_mmuidx(cs, mask);
4590 }
4591}
4592
4593static int alle1_tlbmask(CPUARMState *env)
4594{
4595
4596
4597
4598
4599
4600 if (arm_is_secure_below_el3(env)) {
4601 return ARMMMUIdxBit_SE10_1 |
4602 ARMMMUIdxBit_SE10_1_PAN |
4603 ARMMMUIdxBit_SE10_0;
4604 } else {
4605 return ARMMMUIdxBit_E10_1 |
4606 ARMMMUIdxBit_E10_1_PAN |
4607 ARMMMUIdxBit_E10_0;
4608 }
4609}
4610
4611static int e2_tlbmask(CPUARMState *env)
4612{
4613 if (arm_is_secure_below_el3(env)) {
4614 return ARMMMUIdxBit_SE20_0 |
4615 ARMMMUIdxBit_SE20_2 |
4616 ARMMMUIdxBit_SE20_2_PAN |
4617 ARMMMUIdxBit_SE2;
4618 } else {
4619 return ARMMMUIdxBit_E20_0 |
4620 ARMMMUIdxBit_E20_2 |
4621 ARMMMUIdxBit_E20_2_PAN |
4622 ARMMMUIdxBit_E2;
4623 }
4624}
4625
4626static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
4627 uint64_t value)
4628{
4629 CPUState *cs = env_cpu(env);
4630 int mask = alle1_tlbmask(env);
4631
4632 tlb_flush_by_mmuidx(cs, mask);
4633}
4634
4635static void tlbi_aa64_alle2_write(CPUARMState *env, const ARMCPRegInfo *ri,
4636 uint64_t value)
4637{
4638 CPUState *cs = env_cpu(env);
4639 int mask = e2_tlbmask(env);
4640
4641 tlb_flush_by_mmuidx(cs, mask);
4642}
4643
4644static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri,
4645 uint64_t value)
4646{
4647 ARMCPU *cpu = env_archcpu(env);
4648 CPUState *cs = CPU(cpu);
4649
4650 tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_SE3);
4651}
4652
4653static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4654 uint64_t value)
4655{
4656 CPUState *cs = env_cpu(env);
4657 int mask = alle1_tlbmask(env);
4658
4659 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask);
4660}
4661
4662static void tlbi_aa64_alle2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4663 uint64_t value)
4664{
4665 CPUState *cs = env_cpu(env);
4666 int mask = e2_tlbmask(env);
4667
4668 tlb_flush_by_mmuidx_all_cpus_synced(cs, mask);
4669}
4670
4671static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4672 uint64_t value)
4673{
4674 CPUState *cs = env_cpu(env);
4675
4676 tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_SE3);
4677}
4678
4679static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
4680 uint64_t value)
4681{
4682
4683
4684
4685
4686 CPUState *cs = env_cpu(env);
4687 int mask = e2_tlbmask(env);
4688 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4689
4690 tlb_flush_page_by_mmuidx(cs, pageaddr, mask);
4691}
4692
4693static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
4694 uint64_t value)
4695{
4696
4697
4698
4699
4700 ARMCPU *cpu = env_archcpu(env);
4701 CPUState *cs = CPU(cpu);
4702 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4703
4704 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_SE3);
4705}
4706
4707static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4708 uint64_t value)
4709{
4710 CPUState *cs = env_cpu(env);
4711 int mask = vae1_tlbmask(env);
4712 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4713 int bits = vae1_tlbbits(env, pageaddr);
4714
4715 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
4716}
4717
4718static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
4719 uint64_t value)
4720{
4721
4722
4723
4724
4725
4726 CPUState *cs = env_cpu(env);
4727 int mask = vae1_tlbmask(env);
4728 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4729 int bits = vae1_tlbbits(env, pageaddr);
4730
4731 if (tlb_force_broadcast(env)) {
4732 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
4733 } else {
4734 tlb_flush_page_bits_by_mmuidx(cs, pageaddr, mask, bits);
4735 }
4736}
4737
4738static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4739 uint64_t value)
4740{
4741 CPUState *cs = env_cpu(env);
4742 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4743 bool secure = arm_is_secure_below_el3(env);
4744 int mask = secure ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2;
4745 int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_E2 : ARMMMUIdx_SE2,
4746 pageaddr);
4747
4748 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
4749}
4750
4751static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4752 uint64_t value)
4753{
4754 CPUState *cs = env_cpu(env);
4755 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4756 int bits = tlbbits_for_regime(env, ARMMMUIdx_SE3, pageaddr);
4757
4758 tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
4759 ARMMMUIdxBit_SE3, bits);
4760}
4761
4762static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
4763 bool isread)
4764{
4765 int cur_el = arm_current_el(env);
4766
4767 if (cur_el < 2) {
4768 uint64_t hcr = arm_hcr_el2_eff(env);
4769
4770 if (cur_el == 0) {
4771 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
4772 if (!(env->cp15.sctlr_el[2] & SCTLR_DZE)) {
4773 return CP_ACCESS_TRAP_EL2;
4774 }
4775 } else {
4776 if (!(env->cp15.sctlr_el[1] & SCTLR_DZE)) {
4777 return CP_ACCESS_TRAP;
4778 }
4779 if (hcr & HCR_TDZ) {
4780 return CP_ACCESS_TRAP_EL2;
4781 }
4782 }
4783 } else if (hcr & HCR_TDZ) {
4784 return CP_ACCESS_TRAP_EL2;
4785 }
4786 }
4787 return CP_ACCESS_OK;
4788}
4789
4790static uint64_t aa64_dczid_read(CPUARMState *env, const ARMCPRegInfo *ri)
4791{
4792 ARMCPU *cpu = env_archcpu(env);
4793 int dzp_bit = 1 << 4;
4794
4795
4796 if (aa64_zva_access(env, NULL, false) == CP_ACCESS_OK) {
4797 dzp_bit = 0;
4798 }
4799 return cpu->dcz_blocksize | dzp_bit;
4800}
4801
4802static CPAccessResult sp_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
4803 bool isread)
4804{
4805 if (!(env->pstate & PSTATE_SP)) {
4806
4807
4808
4809 return CP_ACCESS_TRAP_UNCATEGORIZED;
4810 }
4811 return CP_ACCESS_OK;
4812}
4813
4814static uint64_t spsel_read(CPUARMState *env, const ARMCPRegInfo *ri)
4815{
4816 return env->pstate & PSTATE_SP;
4817}
4818
4819static void spsel_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
4820{
4821 update_spsel(env, val);
4822}
4823
4824static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
4825 uint64_t value)
4826{
4827 ARMCPU *cpu = env_archcpu(env);
4828
4829 if (arm_feature(env, ARM_FEATURE_PMSA) && !cpu->has_mpu) {
4830
4831 value &= ~SCTLR_M;
4832 }
4833
4834
4835
4836 if (ri->state == ARM_CP_STATE_AA64 && !cpu_isar_feature(aa64_mte, cpu)) {
4837 if (ri->opc1 == 6) {
4838 value &= ~(SCTLR_ITFSB | SCTLR_TCF | SCTLR_ATA);
4839 } else {
4840 value &= ~(SCTLR_ITFSB | SCTLR_TCF0 | SCTLR_TCF |
4841 SCTLR_ATA0 | SCTLR_ATA);
4842 }
4843 }
4844
4845 if (raw_read(env, ri) == value) {
4846
4847
4848
4849 return;
4850 }
4851
4852 raw_write(env, ri, value);
4853
4854
4855 tlb_flush(CPU(cpu));
4856
4857 if (ri->type & ARM_CP_SUPPRESS_TB_END) {
4858
4859
4860
4861
4862
4863
4864 arm_rebuild_hflags(env);
4865 }
4866}
4867
4868static CPAccessResult fpexc32_access(CPUARMState *env, const ARMCPRegInfo *ri,
4869 bool isread)
4870{
4871 if ((env->cp15.cptr_el[2] & CPTR_TFP) && arm_current_el(env) == 2) {
4872 return CP_ACCESS_TRAP_FP_EL2;
4873 }
4874 if (env->cp15.cptr_el[3] & CPTR_TFP) {
4875 return CP_ACCESS_TRAP_FP_EL3;
4876 }
4877 return CP_ACCESS_OK;
4878}
4879
4880static void sdcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
4881 uint64_t value)
4882{
4883 env->cp15.mdcr_el3 = value & SDCR_VALID_MASK;
4884}
4885
4886static const ARMCPRegInfo v8_cp_reginfo[] = {
4887
4888
4889
4890 { .name = "NZCV", .state = ARM_CP_STATE_AA64,
4891 .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 2,
4892 .access = PL0_RW, .type = ARM_CP_NZCV },
4893 { .name = "DAIF", .state = ARM_CP_STATE_AA64,
4894 .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 2,
4895 .type = ARM_CP_NO_RAW,
4896 .access = PL0_RW, .accessfn = aa64_daif_access,
4897 .fieldoffset = offsetof(CPUARMState, daif),
4898 .writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore },
4899 { .name = "FPCR", .state = ARM_CP_STATE_AA64,
4900 .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
4901 .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
4902 .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
4903 { .name = "FPSR", .state = ARM_CP_STATE_AA64,
4904 .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
4905 .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
4906 .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
4907 { .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64,
4908 .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
4909 .access = PL0_R, .type = ARM_CP_NO_RAW,
4910 .readfn = aa64_dczid_read },
4911 { .name = "DC_ZVA", .state = ARM_CP_STATE_AA64,
4912 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 1,
4913 .access = PL0_W, .type = ARM_CP_DC_ZVA,
4914#ifndef CONFIG_USER_ONLY
4915
4916 .accessfn = aa64_zva_access,
4917#endif
4918 },
4919 { .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
4920 .opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2,
4921 .access = PL1_R, .type = ARM_CP_CURRENTEL },
4922
4923 { .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
4924 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
4925 .access = PL1_W, .type = ARM_CP_NOP,
4926 .accessfn = aa64_cacheop_pou_access },
4927 { .name = "IC_IALLU", .state = ARM_CP_STATE_AA64,
4928 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
4929 .access = PL1_W, .type = ARM_CP_NOP,
4930 .accessfn = aa64_cacheop_pou_access },
4931 { .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
4932 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
4933 .access = PL0_W, .type = ARM_CP_NOP,
4934 .accessfn = aa64_cacheop_pou_access },
4935 { .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
4936 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
4937 .access = PL1_W, .accessfn = aa64_cacheop_poc_access,
4938 .type = ARM_CP_NOP },
4939 { .name = "DC_ISW", .state = ARM_CP_STATE_AA64,
4940 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
4941 .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
4942 { .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
4943 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
4944 .access = PL0_W, .type = ARM_CP_NOP,
4945 .accessfn = aa64_cacheop_poc_access },
4946 { .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
4947 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
4948 .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
4949 { .name = "DC_CVAU", .state = ARM_CP_STATE_AA64,
4950 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1,
4951 .access = PL0_W, .type = ARM_CP_NOP,
4952 .accessfn = aa64_cacheop_pou_access },
4953 { .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64,
4954 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1,
4955 .access = PL0_W, .type = ARM_CP_NOP,
4956 .accessfn = aa64_cacheop_poc_access },
4957 { .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
4958 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
4959 .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
4960
4961 { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
4962 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
4963 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
4964 .writefn = tlbi_aa64_vmalle1is_write },
4965 { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64,
4966 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
4967 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
4968 .writefn = tlbi_aa64_vae1is_write },
4969 { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64,
4970 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
4971 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
4972 .writefn = tlbi_aa64_vmalle1is_write },
4973 { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64,
4974 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
4975 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
4976 .writefn = tlbi_aa64_vae1is_write },
4977 { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64,
4978 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
4979 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
4980 .writefn = tlbi_aa64_vae1is_write },
4981 { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64,
4982 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
4983 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
4984 .writefn = tlbi_aa64_vae1is_write },
4985 { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64,
4986 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
4987 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
4988 .writefn = tlbi_aa64_vmalle1_write },
4989 { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64,
4990 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
4991 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
4992 .writefn = tlbi_aa64_vae1_write },
4993 { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64,
4994 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
4995 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
4996 .writefn = tlbi_aa64_vmalle1_write },
4997 { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64,
4998 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
4999 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5000 .writefn = tlbi_aa64_vae1_write },
5001 { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64,
5002 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
5003 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5004 .writefn = tlbi_aa64_vae1_write },
5005 { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64,
5006 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
5007 .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
5008 .writefn = tlbi_aa64_vae1_write },
5009 { .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
5010 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
5011 .access = PL2_W, .type = ARM_CP_NOP },
5012 { .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
5013 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
5014 .access = PL2_W, .type = ARM_CP_NOP },
5015 { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
5016 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
5017 .access = PL2_W, .type = ARM_CP_NO_RAW,
5018 .writefn = tlbi_aa64_alle1is_write },
5019 { .name = "TLBI_VMALLS12E1IS", .state = ARM_CP_STATE_AA64,
5020 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 6,
5021 .access = PL2_W, .type = ARM_CP_NO_RAW,
5022 .writefn = tlbi_aa64_alle1is_write },
5023 { .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
5024 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
5025 .access = PL2_W, .type = ARM_CP_NOP },
5026 { .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
5027 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
5028 .access = PL2_W, .type = ARM_CP_NOP },
5029 { .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
5030 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
5031 .access = PL2_W, .type = ARM_CP_NO_RAW,
5032 .writefn = tlbi_aa64_alle1_write },
5033 { .name = "TLBI_VMALLS12E1", .state = ARM_CP_STATE_AA64,
5034 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 6,
5035 .access = PL2_W, .type = ARM_CP_NO_RAW,
5036 .writefn = tlbi_aa64_alle1is_write },
5037#ifndef CONFIG_USER_ONLY
5038
5039 { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64,
5040 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0,
5041 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5042 .writefn = ats_write64 },
5043 { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
5044 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1,
5045 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5046 .writefn = ats_write64 },
5047 { .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64,
5048 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2,
5049 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5050 .writefn = ats_write64 },
5051 { .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64,
5052 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3,
5053 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5054 .writefn = ats_write64 },
5055 { .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64,
5056 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4,
5057 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5058 .writefn = ats_write64 },
5059 { .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64,
5060 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5,
5061 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5062 .writefn = ats_write64 },
5063 { .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64,
5064 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6,
5065 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5066 .writefn = ats_write64 },
5067 { .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64,
5068 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7,
5069 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5070 .writefn = ats_write64 },
5071
5072 { .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64,
5073 .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0,
5074 .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5075 .writefn = ats_write64 },
5076 { .name = "AT_S1E3W", .state = ARM_CP_STATE_AA64,
5077 .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 1,
5078 .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
5079 .writefn = ats_write64 },
5080 { .name = "PAR_EL1", .state = ARM_CP_STATE_AA64,
5081 .type = ARM_CP_ALIAS,
5082 .opc0 = 3, .opc1 = 0, .crn = 7, .crm = 4, .opc2 = 0,
5083 .access = PL1_RW, .resetvalue = 0,
5084 .fieldoffset = offsetof(CPUARMState, cp15.par_el[1]),
5085 .writefn = par_write },
5086#endif
5087
5088 { .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
5089 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
5090 .writefn = tlbimva_is_write },
5091 { .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
5092 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
5093 .writefn = tlbimvaa_is_write },
5094 { .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
5095 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
5096 .writefn = tlbimva_write },
5097 { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
5098 .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
5099 .writefn = tlbimvaa_write },
5100 { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
5101 .type = ARM_CP_NO_RAW, .access = PL2_W,
5102 .writefn = tlbimva_hyp_write },
5103 { .name = "TLBIMVALHIS",
5104 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
5105 .type = ARM_CP_NO_RAW, .access = PL2_W,
5106 .writefn = tlbimva_hyp_is_write },
5107 { .name = "TLBIIPAS2",
5108 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
5109 .type = ARM_CP_NOP, .access = PL2_W },
5110 { .name = "TLBIIPAS2IS",
5111 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
5112 .type = ARM_CP_NOP, .access = PL2_W },
5113 { .name = "TLBIIPAS2L",
5114 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
5115 .type = ARM_CP_NOP, .access = PL2_W },
5116 { .name = "TLBIIPAS2LIS",
5117 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
5118 .type = ARM_CP_NOP, .access = PL2_W },
5119
5120 { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
5121 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
5122 { .name = "BPIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 6,
5123 .type = ARM_CP_NOP, .access = PL1_W },
5124 { .name = "ICIALLU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
5125 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
5126 { .name = "ICIMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 1,
5127 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
5128 { .name = "BPIALL", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 6,
5129 .type = ARM_CP_NOP, .access = PL1_W },
5130 { .name = "BPIMVA", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 7,
5131 .type = ARM_CP_NOP, .access = PL1_W },
5132 { .name = "DCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
5133 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
5134 { .name = "DCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
5135 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
5136 { .name = "DCCMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 1,
5137 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
5138 { .name = "DCCSW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
5139 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
5140 { .name = "DCCMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 11, .opc2 = 1,
5141 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
5142 { .name = "DCCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 1,
5143 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
5144 { .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
5145 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
5146
5147 { .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0,
5148 .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
5149 .writefn = dacr_write, .raw_writefn = raw_write,
5150 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
5151 offsetoflow32(CPUARMState, cp15.dacr_ns) } },
5152 { .name = "ELR_EL1", .state = ARM_CP_STATE_AA64,
5153 .type = ARM_CP_ALIAS,
5154 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1,
5155 .access = PL1_RW,
5156 .fieldoffset = offsetof(CPUARMState, elr_el[1]) },
5157 { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
5158 .type = ARM_CP_ALIAS,
5159 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
5160 .access = PL1_RW,
5161 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
5162
5163
5164
5165
5166 { .name = "SP_EL0", .state = ARM_CP_STATE_AA64,
5167 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 1, .opc2 = 0,
5168 .access = PL1_RW, .accessfn = sp_el0_access,
5169 .type = ARM_CP_ALIAS,
5170 .fieldoffset = offsetof(CPUARMState, sp_el[0]) },
5171 { .name = "SP_EL1", .state = ARM_CP_STATE_AA64,
5172 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 1, .opc2 = 0,
5173 .access = PL2_RW, .type = ARM_CP_ALIAS,
5174 .fieldoffset = offsetof(CPUARMState, sp_el[1]) },
5175 { .name = "SPSel", .state = ARM_CP_STATE_AA64,
5176 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 0,
5177 .type = ARM_CP_NO_RAW,
5178 .access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
5179 { .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64,
5180 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0,
5181 .type = ARM_CP_ALIAS,
5182 .fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]),
5183 .access = PL2_RW, .accessfn = fpexc32_access },
5184 { .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
5185 .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
5186 .access = PL2_RW, .resetvalue = 0,
5187 .writefn = dacr_write, .raw_writefn = raw_write,
5188 .fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
5189 { .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
5190 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
5191 .access = PL2_RW, .resetvalue = 0,
5192 .fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
5193 { .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
5194 .type = ARM_CP_ALIAS,
5195 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0,
5196 .access = PL2_RW,
5197 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_IRQ]) },
5198 { .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64,
5199 .type = ARM_CP_ALIAS,
5200 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1,
5201 .access = PL2_RW,
5202 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_ABT]) },
5203 { .name = "SPSR_UND", .state = ARM_CP_STATE_AA64,
5204 .type = ARM_CP_ALIAS,
5205 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2,
5206 .access = PL2_RW,
5207 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_UND]) },
5208 { .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64,
5209 .type = ARM_CP_ALIAS,
5210 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3,
5211 .access = PL2_RW,
5212 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) },
5213 { .name = "MDCR_EL3", .state = ARM_CP_STATE_AA64,
5214 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 3, .opc2 = 1,
5215 .resetvalue = 0,
5216 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el3) },
5217 { .name = "SDCR", .type = ARM_CP_ALIAS,
5218 .cp = 15, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 1,
5219 .access = PL1_RW, .accessfn = access_trap_aa32s_el1,
5220 .writefn = sdcr_write,
5221 .fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) },
5222 REGINFO_SENTINEL
5223};
5224
5225
5226static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
5227 { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
5228 .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
5229 .access = PL2_RW,
5230 .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
5231 { .name = "HCR_EL2", .state = ARM_CP_STATE_BOTH,
5232 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
5233 .access = PL2_RW,
5234 .type = ARM_CP_CONST, .resetvalue = 0 },
5235 { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
5236 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
5237 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5238 { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
5239 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
5240 .access = PL2_RW,
5241 .type = ARM_CP_CONST, .resetvalue = 0 },
5242 { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
5243 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
5244 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5245 { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH,
5246 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0,
5247 .access = PL2_RW, .type = ARM_CP_CONST,
5248 .resetvalue = 0 },
5249 { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
5250 .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
5251 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5252 { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
5253 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
5254 .access = PL2_RW, .type = ARM_CP_CONST,
5255 .resetvalue = 0 },
5256 { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
5257 .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
5258 .access = PL2_RW, .type = ARM_CP_CONST,
5259 .resetvalue = 0 },
5260 { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
5261 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0,
5262 .access = PL2_RW, .type = ARM_CP_CONST,
5263 .resetvalue = 0 },
5264 { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH,
5265 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1,
5266 .access = PL2_RW, .type = ARM_CP_CONST,
5267 .resetvalue = 0 },
5268 { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
5269 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
5270 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5271 { .name = "VTCR_EL2", .state = ARM_CP_STATE_BOTH,
5272 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
5273 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5274 .type = ARM_CP_CONST, .resetvalue = 0 },
5275 { .name = "VTTBR", .state = ARM_CP_STATE_AA32,
5276 .cp = 15, .opc1 = 6, .crm = 2,
5277 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5278 .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
5279 { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
5280 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
5281 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5282 { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
5283 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
5284 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5285 { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
5286 .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
5287 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5288 { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
5289 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
5290 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5291 { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
5292 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
5293 .resetvalue = 0 },
5294 { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
5295 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
5296 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5297 { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64,
5298 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
5299 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5300 { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14,
5301 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
5302 .resetvalue = 0 },
5303 { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64,
5304 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2,
5305 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5306 { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14,
5307 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
5308 .resetvalue = 0 },
5309 { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH,
5310 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0,
5311 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5312 { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH,
5313 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1,
5314 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5315 { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
5316 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
5317 .access = PL2_RW, .accessfn = access_tda,
5318 .type = ARM_CP_CONST, .resetvalue = 0 },
5319 { .name = "HPFAR_EL2", .state = ARM_CP_STATE_BOTH,
5320 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
5321 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5322 .type = ARM_CP_CONST, .resetvalue = 0 },
5323 { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
5324 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
5325 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5326 { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
5327 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
5328 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5329 { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
5330 .type = ARM_CP_CONST,
5331 .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
5332 .access = PL2_RW, .resetvalue = 0 },
5333 REGINFO_SENTINEL
5334};
5335
5336
5337static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
5338 { .name = "HCR2", .state = ARM_CP_STATE_AA32,
5339 .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
5340 .access = PL2_RW,
5341 .type = ARM_CP_CONST, .resetvalue = 0 },
5342 REGINFO_SENTINEL
5343};
5344
5345static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
5346{
5347 ARMCPU *cpu = env_archcpu(env);
5348
5349 if (arm_feature(env, ARM_FEATURE_V8)) {
5350 valid_mask |= MAKE_64BIT_MASK(0, 34);
5351 } else {
5352 valid_mask |= MAKE_64BIT_MASK(0, 28);
5353 }
5354
5355 if (arm_feature(env, ARM_FEATURE_EL3)) {
5356 valid_mask &= ~HCR_HCD;
5357 } else if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
5358
5359
5360
5361
5362
5363
5364
5365 valid_mask &= ~HCR_TSC;
5366 }
5367
5368 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
5369 if (cpu_isar_feature(aa64_vh, cpu)) {
5370 valid_mask |= HCR_E2H;
5371 }
5372 if (cpu_isar_feature(aa64_lor, cpu)) {
5373 valid_mask |= HCR_TLOR;
5374 }
5375 if (cpu_isar_feature(aa64_pauth, cpu)) {
5376 valid_mask |= HCR_API | HCR_APK;
5377 }
5378 if (cpu_isar_feature(aa64_mte, cpu)) {
5379 valid_mask |= HCR_ATA | HCR_DCT | HCR_TID5;
5380 }
5381 }
5382
5383
5384 value &= valid_mask;
5385
5386
5387
5388
5389
5390
5391
5392
5393 if ((env->cp15.hcr_el2 ^ value) & (HCR_VM | HCR_PTW | HCR_DC | HCR_DCT)) {
5394 tlb_flush(CPU(cpu));
5395 }
5396 env->cp15.hcr_el2 = value;
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409 g_assert(qemu_mutex_iothread_locked());
5410 arm_cpu_update_virq(cpu);
5411 arm_cpu_update_vfiq(cpu);
5412}
5413
5414static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
5415{
5416 do_hcr_write(env, value, 0);
5417}
5418
5419static void hcr_writehigh(CPUARMState *env, const ARMCPRegInfo *ri,
5420 uint64_t value)
5421{
5422
5423 value = deposit64(env->cp15.hcr_el2, 32, 32, value);
5424 do_hcr_write(env, value, MAKE_64BIT_MASK(0, 32));
5425}
5426
5427static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
5428 uint64_t value)
5429{
5430
5431 value = deposit64(env->cp15.hcr_el2, 0, 32, value);
5432 do_hcr_write(env, value, MAKE_64BIT_MASK(32, 32));
5433}
5434
5435
5436
5437
5438
5439
5440uint64_t arm_hcr_el2_eff(CPUARMState *env)
5441{
5442 uint64_t ret = env->cp15.hcr_el2;
5443
5444 if (!arm_is_el2_enabled(env)) {
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460 return 0;
5461 }
5462
5463
5464
5465
5466
5467
5468 if (!arm_el_is_aa64(env, 2)) {
5469 uint64_t aa32_valid;
5470
5471
5472
5473
5474
5475
5476 aa32_valid = MAKE_64BIT_MASK(0, 32) & ~(HCR_RW | HCR_TDZ);
5477 aa32_valid |= (HCR_CD | HCR_ID | HCR_TERR | HCR_TEA | HCR_MIOCNCE |
5478 HCR_TID4 | HCR_TICAB | HCR_TOCU | HCR_TTLBIS);
5479 ret &= aa32_valid;
5480 }
5481
5482 if (ret & HCR_TGE) {
5483
5484 if (ret & HCR_E2H) {
5485 ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO |
5486 HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE |
5487 HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU |
5488 HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE |
5489 HCR_TID4 | HCR_TICAB | HCR_TOCU | HCR_ENSCXT |
5490 HCR_TTLBIS | HCR_TTLBOS | HCR_TID5);
5491 } else {
5492 ret |= HCR_FMO | HCR_IMO | HCR_AMO;
5493 }
5494 ret &= ~(HCR_SWIO | HCR_PTW | HCR_VF | HCR_VI | HCR_VSE |
5495 HCR_FB | HCR_TID1 | HCR_TID3 | HCR_TSC | HCR_TACR |
5496 HCR_TSW | HCR_TTLB | HCR_TVM | HCR_HCD | HCR_TRVM |
5497 HCR_TLOR);
5498 }
5499
5500 return ret;
5501}
5502
5503static void cptr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
5504 uint64_t value)
5505{
5506
5507
5508
5509
5510 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
5511 !arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
5512 value &= ~(0x3 << 10);
5513 value |= env->cp15.cptr_el[2] & (0x3 << 10);
5514 }
5515 env->cp15.cptr_el[2] = value;
5516}
5517
5518static uint64_t cptr_el2_read(CPUARMState *env, const ARMCPRegInfo *ri)
5519{
5520
5521
5522
5523
5524 uint64_t value = env->cp15.cptr_el[2];
5525
5526 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
5527 !arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
5528 value |= 0x3 << 10;
5529 }
5530 return value;
5531}
5532
5533static const ARMCPRegInfo el2_cp_reginfo[] = {
5534 { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
5535 .type = ARM_CP_IO,
5536 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
5537 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
5538 .writefn = hcr_write },
5539 { .name = "HCR", .state = ARM_CP_STATE_AA32,
5540 .type = ARM_CP_ALIAS | ARM_CP_IO,
5541 .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
5542 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
5543 .writefn = hcr_writelow },
5544 { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
5545 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
5546 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
5547 { .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
5548 .type = ARM_CP_ALIAS,
5549 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
5550 .access = PL2_RW,
5551 .fieldoffset = offsetof(CPUARMState, elr_el[2]) },
5552 { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
5553 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
5554 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
5555 { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
5556 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
5557 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) },
5558 { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
5559 .type = ARM_CP_ALIAS,
5560 .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
5561 .access = PL2_RW,
5562 .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[2]) },
5563 { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
5564 .type = ARM_CP_ALIAS,
5565 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
5566 .access = PL2_RW,
5567 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
5568 { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
5569 .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
5570 .access = PL2_RW, .writefn = vbar_write,
5571 .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]),
5572 .resetvalue = 0 },
5573 { .name = "SP_EL2", .state = ARM_CP_STATE_AA64,
5574 .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 1, .opc2 = 0,
5575 .access = PL3_RW, .type = ARM_CP_ALIAS,
5576 .fieldoffset = offsetof(CPUARMState, sp_el[2]) },
5577 { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
5578 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
5579 .access = PL2_RW, .accessfn = cptr_access, .resetvalue = 0,
5580 .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[2]),
5581 .readfn = cptr_el2_read, .writefn = cptr_el2_write },
5582 { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH,
5583 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0,
5584 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[2]),
5585 .resetvalue = 0 },
5586 { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
5587 .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
5588 .access = PL2_RW, .type = ARM_CP_ALIAS,
5589 .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el[2]) },
5590 { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
5591 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
5592 .access = PL2_RW, .type = ARM_CP_CONST,
5593 .resetvalue = 0 },
5594
5595 { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
5596 .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
5597 .access = PL2_RW, .type = ARM_CP_CONST,
5598 .resetvalue = 0 },
5599 { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
5600 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0,
5601 .access = PL2_RW, .type = ARM_CP_CONST,
5602 .resetvalue = 0 },
5603 { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH,
5604 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1,
5605 .access = PL2_RW, .type = ARM_CP_CONST,
5606 .resetvalue = 0 },
5607 { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
5608 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
5609 .access = PL2_RW, .writefn = vmsa_tcr_el12_write,
5610
5611 .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) },
5612 { .name = "VTCR", .state = ARM_CP_STATE_AA32,
5613 .cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
5614 .type = ARM_CP_ALIAS,
5615 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5616 .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) },
5617 { .name = "VTCR_EL2", .state = ARM_CP_STATE_AA64,
5618 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
5619 .access = PL2_RW,
5620
5621
5622
5623 .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) },
5624 { .name = "VTTBR", .state = ARM_CP_STATE_AA32,
5625 .cp = 15, .opc1 = 6, .crm = 2,
5626 .type = ARM_CP_64BIT | ARM_CP_ALIAS,
5627 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5628 .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2),
5629 .writefn = vttbr_write },
5630 { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
5631 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
5632 .access = PL2_RW, .writefn = vttbr_write,
5633 .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) },
5634 { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
5635 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
5636 .access = PL2_RW, .raw_writefn = raw_write, .writefn = sctlr_write,
5637 .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[2]) },
5638 { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
5639 .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
5640 .access = PL2_RW, .resetvalue = 0,
5641 .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) },
5642 { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
5643 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
5644 .access = PL2_RW, .resetvalue = 0, .writefn = vmsa_tcr_ttbr_el2_write,
5645 .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
5646 { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
5647 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
5648 .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
5649 { .name = "TLBIALLNSNH",
5650 .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
5651 .type = ARM_CP_NO_RAW, .access = PL2_W,
5652 .writefn = tlbiall_nsnh_write },
5653 { .name = "TLBIALLNSNHIS",
5654 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
5655 .type = ARM_CP_NO_RAW, .access = PL2_W,
5656 .writefn = tlbiall_nsnh_is_write },
5657 { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
5658 .type = ARM_CP_NO_RAW, .access = PL2_W,
5659 .writefn = tlbiall_hyp_write },
5660 { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0,
5661 .type = ARM_CP_NO_RAW, .access = PL2_W,
5662 .writefn = tlbiall_hyp_is_write },
5663 { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
5664 .type = ARM_CP_NO_RAW, .access = PL2_W,
5665 .writefn = tlbimva_hyp_write },
5666 { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
5667 .type = ARM_CP_NO_RAW, .access = PL2_W,
5668 .writefn = tlbimva_hyp_is_write },
5669 { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
5670 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
5671 .type = ARM_CP_NO_RAW, .access = PL2_W,
5672 .writefn = tlbi_aa64_alle2_write },
5673 { .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64,
5674 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
5675 .type = ARM_CP_NO_RAW, .access = PL2_W,
5676 .writefn = tlbi_aa64_vae2_write },
5677 { .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64,
5678 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
5679 .access = PL2_W, .type = ARM_CP_NO_RAW,
5680 .writefn = tlbi_aa64_vae2_write },
5681 { .name = "TLBI_ALLE2IS", .state = ARM_CP_STATE_AA64,
5682 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0,
5683 .access = PL2_W, .type = ARM_CP_NO_RAW,
5684 .writefn = tlbi_aa64_alle2is_write },
5685 { .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64,
5686 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
5687 .type = ARM_CP_NO_RAW, .access = PL2_W,
5688 .writefn = tlbi_aa64_vae2is_write },
5689 { .name = "TLBI_VALE2IS", .state = ARM_CP_STATE_AA64,
5690 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
5691 .access = PL2_W, .type = ARM_CP_NO_RAW,
5692 .writefn = tlbi_aa64_vae2is_write },
5693#ifndef CONFIG_USER_ONLY
5694
5695
5696
5697
5698 { .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64,
5699 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
5700 .access = PL2_W, .accessfn = at_s1e2_access,
5701 .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
5702 { .name = "AT_S1E2W", .state = ARM_CP_STATE_AA64,
5703 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
5704 .access = PL2_W, .accessfn = at_s1e2_access,
5705 .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
5706
5707
5708
5709
5710
5711 { .name = "ATS1HR", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
5712 .access = PL2_W,
5713 .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
5714 { .name = "ATS1HW", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
5715 .access = PL2_W,
5716 .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
5717 { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
5718 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
5719
5720
5721
5722
5723 .access = PL2_RW, .resetvalue = 3,
5724 .fieldoffset = offsetof(CPUARMState, cp15.cnthctl_el2) },
5725 { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64,
5726 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
5727 .access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 0,
5728 .writefn = gt_cntvoff_write,
5729 .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) },
5730 { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14,
5731 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS | ARM_CP_IO,
5732 .writefn = gt_cntvoff_write,
5733 .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) },
5734 { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64,
5735 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2,
5736 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval),
5737 .type = ARM_CP_IO, .access = PL2_RW,
5738 .writefn = gt_hyp_cval_write, .raw_writefn = raw_write },
5739 { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14,
5740 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval),
5741 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_IO,
5742 .writefn = gt_hyp_cval_write, .raw_writefn = raw_write },
5743 { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH,
5744 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0,
5745 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW,
5746 .resetfn = gt_hyp_timer_reset,
5747 .readfn = gt_hyp_tval_read, .writefn = gt_hyp_tval_write },
5748 { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH,
5749 .type = ARM_CP_IO,
5750 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1,
5751 .access = PL2_RW,
5752 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].ctl),
5753 .resetvalue = 0,
5754 .writefn = gt_hyp_ctl_write, .raw_writefn = raw_write },
5755#endif
5756
5757
5758
5759 { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
5760 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
5761 .access = PL2_RW, .resetvalue = PMCR_NUM_COUNTERS,
5762 .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), },
5763 { .name = "HPFAR", .state = ARM_CP_STATE_AA32,
5764 .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
5765 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5766 .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) },
5767 { .name = "HPFAR_EL2", .state = ARM_CP_STATE_AA64,
5768 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
5769 .access = PL2_RW,
5770 .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) },
5771 { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
5772 .cp = 15, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
5773 .access = PL2_RW,
5774 .fieldoffset = offsetof(CPUARMState, cp15.hstr_el2) },
5775 REGINFO_SENTINEL
5776};
5777
5778static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
5779 { .name = "HCR2", .state = ARM_CP_STATE_AA32,
5780 .type = ARM_CP_ALIAS | ARM_CP_IO,
5781 .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
5782 .access = PL2_RW,
5783 .fieldoffset = offsetofhigh32(CPUARMState, cp15.hcr_el2),
5784 .writefn = hcr_writehigh },
5785 REGINFO_SENTINEL
5786};
5787
5788static CPAccessResult sel2_access(CPUARMState *env, const ARMCPRegInfo *ri,
5789 bool isread)
5790{
5791 if (arm_current_el(env) == 3 || arm_is_secure_below_el3(env)) {
5792 return CP_ACCESS_OK;
5793 }
5794 return CP_ACCESS_TRAP_UNCATEGORIZED;
5795}
5796
5797static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
5798 { .name = "VSTTBR_EL2", .state = ARM_CP_STATE_AA64,
5799 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 0,
5800 .access = PL2_RW, .accessfn = sel2_access,
5801 .fieldoffset = offsetof(CPUARMState, cp15.vsttbr_el2) },
5802 { .name = "VSTCR_EL2", .state = ARM_CP_STATE_AA64,
5803 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 2,
5804 .access = PL2_RW, .accessfn = sel2_access,
5805 .fieldoffset = offsetof(CPUARMState, cp15.vstcr_el2) },
5806 REGINFO_SENTINEL
5807};
5808
5809static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
5810 bool isread)
5811{
5812
5813
5814
5815 if (arm_current_el(env) == 3) {
5816 return CP_ACCESS_OK;
5817 }
5818 if (arm_is_secure_below_el3(env)) {
5819 if (env->cp15.scr_el3 & SCR_EEL2) {
5820 return CP_ACCESS_TRAP_EL2;
5821 }
5822 return CP_ACCESS_TRAP_EL3;
5823 }
5824
5825 if (isread) {
5826 return CP_ACCESS_OK;
5827 }
5828 return CP_ACCESS_TRAP_UNCATEGORIZED;
5829}
5830
5831static const ARMCPRegInfo el3_cp_reginfo[] = {
5832 { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
5833 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
5834 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
5835 .resetfn = scr_reset, .writefn = scr_write },
5836 { .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
5837 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
5838 .access = PL1_RW, .accessfn = access_trap_aa32s_el1,
5839 .fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
5840 .writefn = scr_write },
5841 { .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64,
5842 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1,
5843 .access = PL3_RW, .resetvalue = 0,
5844 .fieldoffset = offsetof(CPUARMState, cp15.sder) },
5845 { .name = "SDER",
5846 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 1,
5847 .access = PL3_RW, .resetvalue = 0,
5848 .fieldoffset = offsetoflow32(CPUARMState, cp15.sder) },
5849 { .name = "MVBAR", .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
5850 .access = PL1_RW, .accessfn = access_trap_aa32s_el1,
5851 .writefn = vbar_write, .resetvalue = 0,
5852 .fieldoffset = offsetof(CPUARMState, cp15.mvbar) },
5853 { .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64,
5854 .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 0,
5855 .access = PL3_RW, .resetvalue = 0,
5856 .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[3]) },
5857 { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
5858 .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 2,
5859 .access = PL3_RW,
5860
5861
5862
5863
5864
5865 .resetfn = vmsa_ttbcr_reset, .raw_writefn = vmsa_ttbcr_raw_write,
5866 .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[3]) },
5867 { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
5868 .type = ARM_CP_ALIAS,
5869 .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
5870 .access = PL3_RW,
5871 .fieldoffset = offsetof(CPUARMState, elr_el[3]) },
5872 { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64,
5873 .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0,
5874 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[3]) },
5875 { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64,
5876 .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0,
5877 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[3]) },
5878 { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64,
5879 .type = ARM_CP_ALIAS,
5880 .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0,
5881 .access = PL3_RW,
5882 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_MON]) },
5883 { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
5884 .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
5885 .access = PL3_RW, .writefn = vbar_write,
5886 .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[3]),
5887 .resetvalue = 0 },
5888 { .name = "CPTR_EL3", .state = ARM_CP_STATE_AA64,
5889 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 2,
5890 .access = PL3_RW, .accessfn = cptr_access, .resetvalue = 0,
5891 .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[3]) },
5892 { .name = "TPIDR_EL3", .state = ARM_CP_STATE_AA64,
5893 .opc0 = 3, .opc1 = 6, .crn = 13, .crm = 0, .opc2 = 2,
5894 .access = PL3_RW, .resetvalue = 0,
5895 .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[3]) },
5896 { .name = "AMAIR_EL3", .state = ARM_CP_STATE_AA64,
5897 .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 3, .opc2 = 0,
5898 .access = PL3_RW, .type = ARM_CP_CONST,
5899 .resetvalue = 0 },
5900 { .name = "AFSR0_EL3", .state = ARM_CP_STATE_BOTH,
5901 .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 0,
5902 .access = PL3_RW, .type = ARM_CP_CONST,
5903 .resetvalue = 0 },
5904 { .name = "AFSR1_EL3", .state = ARM_CP_STATE_BOTH,
5905 .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 1,
5906 .access = PL3_RW, .type = ARM_CP_CONST,
5907 .resetvalue = 0 },
5908 { .name = "TLBI_ALLE3IS", .state = ARM_CP_STATE_AA64,
5909 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 0,
5910 .access = PL3_W, .type = ARM_CP_NO_RAW,
5911 .writefn = tlbi_aa64_alle3is_write },
5912 { .name = "TLBI_VAE3IS", .state = ARM_CP_STATE_AA64,
5913 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 1,
5914 .access = PL3_W, .type = ARM_CP_NO_RAW,
5915 .writefn = tlbi_aa64_vae3is_write },
5916 { .name = "TLBI_VALE3IS", .state = ARM_CP_STATE_AA64,
5917 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 5,
5918 .access = PL3_W, .type = ARM_CP_NO_RAW,
5919 .writefn = tlbi_aa64_vae3is_write },
5920 { .name = "TLBI_ALLE3", .state = ARM_CP_STATE_AA64,
5921 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 0,
5922 .access = PL3_W, .type = ARM_CP_NO_RAW,
5923 .writefn = tlbi_aa64_alle3_write },
5924 { .name = "TLBI_VAE3", .state = ARM_CP_STATE_AA64,
5925 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 1,
5926 .access = PL3_W, .type = ARM_CP_NO_RAW,
5927 .writefn = tlbi_aa64_vae3_write },
5928 { .name = "TLBI_VALE3", .state = ARM_CP_STATE_AA64,
5929 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 5,
5930 .access = PL3_W, .type = ARM_CP_NO_RAW,
5931 .writefn = tlbi_aa64_vae3_write },
5932 REGINFO_SENTINEL
5933};
5934
5935#ifndef CONFIG_USER_ONLY
5936
5937static bool redirect_for_e2h(CPUARMState *env)
5938{
5939 return arm_current_el(env) == 2 && (arm_hcr_el2_eff(env) & HCR_E2H);
5940}
5941
5942static uint64_t el2_e2h_read(CPUARMState *env, const ARMCPRegInfo *ri)
5943{
5944 CPReadFn *readfn;
5945
5946 if (redirect_for_e2h(env)) {
5947
5948 ri = ri->opaque;
5949 readfn = ri->readfn;
5950 } else {
5951 readfn = ri->orig_readfn;
5952 }
5953 if (readfn == NULL) {
5954 readfn = raw_read;
5955 }
5956 return readfn(env, ri);
5957}
5958
5959static void el2_e2h_write(CPUARMState *env, const ARMCPRegInfo *ri,
5960 uint64_t value)
5961{
5962 CPWriteFn *writefn;
5963
5964 if (redirect_for_e2h(env)) {
5965
5966 ri = ri->opaque;
5967 writefn = ri->writefn;
5968 } else {
5969 writefn = ri->orig_writefn;
5970 }
5971 if (writefn == NULL) {
5972 writefn = raw_write;
5973 }
5974 writefn(env, ri, value);
5975}
5976
5977static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
5978{
5979 struct E2HAlias {
5980 uint32_t src_key, dst_key, new_key;
5981 const char *src_name, *dst_name, *new_name;
5982 bool (*feature)(const ARMISARegisters *id);
5983 };
5984
5985#define K(op0, op1, crn, crm, op2) \
5986 ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, crn, crm, op0, op1, op2)
5987
5988 static const struct E2HAlias aliases[] = {
5989 { K(3, 0, 1, 0, 0), K(3, 4, 1, 0, 0), K(3, 5, 1, 0, 0),
5990 "SCTLR", "SCTLR_EL2", "SCTLR_EL12" },
5991 { K(3, 0, 1, 0, 2), K(3, 4, 1, 1, 2), K(3, 5, 1, 0, 2),
5992 "CPACR", "CPTR_EL2", "CPACR_EL12" },
5993 { K(3, 0, 2, 0, 0), K(3, 4, 2, 0, 0), K(3, 5, 2, 0, 0),
5994 "TTBR0_EL1", "TTBR0_EL2", "TTBR0_EL12" },
5995 { K(3, 0, 2, 0, 1), K(3, 4, 2, 0, 1), K(3, 5, 2, 0, 1),
5996 "TTBR1_EL1", "TTBR1_EL2", "TTBR1_EL12" },
5997 { K(3, 0, 2, 0, 2), K(3, 4, 2, 0, 2), K(3, 5, 2, 0, 2),
5998 "TCR_EL1", "TCR_EL2", "TCR_EL12" },
5999 { K(3, 0, 4, 0, 0), K(3, 4, 4, 0, 0), K(3, 5, 4, 0, 0),
6000 "SPSR_EL1", "SPSR_EL2", "SPSR_EL12" },
6001 { K(3, 0, 4, 0, 1), K(3, 4, 4, 0, 1), K(3, 5, 4, 0, 1),
6002 "ELR_EL1", "ELR_EL2", "ELR_EL12" },
6003 { K(3, 0, 5, 1, 0), K(3, 4, 5, 1, 0), K(3, 5, 5, 1, 0),
6004 "AFSR0_EL1", "AFSR0_EL2", "AFSR0_EL12" },
6005 { K(3, 0, 5, 1, 1), K(3, 4, 5, 1, 1), K(3, 5, 5, 1, 1),
6006 "AFSR1_EL1", "AFSR1_EL2", "AFSR1_EL12" },
6007 { K(3, 0, 5, 2, 0), K(3, 4, 5, 2, 0), K(3, 5, 5, 2, 0),
6008 "ESR_EL1", "ESR_EL2", "ESR_EL12" },
6009 { K(3, 0, 6, 0, 0), K(3, 4, 6, 0, 0), K(3, 5, 6, 0, 0),
6010 "FAR_EL1", "FAR_EL2", "FAR_EL12" },
6011 { K(3, 0, 10, 2, 0), K(3, 4, 10, 2, 0), K(3, 5, 10, 2, 0),
6012 "MAIR_EL1", "MAIR_EL2", "MAIR_EL12" },
6013 { K(3, 0, 10, 3, 0), K(3, 4, 10, 3, 0), K(3, 5, 10, 3, 0),
6014 "AMAIR0", "AMAIR_EL2", "AMAIR_EL12" },
6015 { K(3, 0, 12, 0, 0), K(3, 4, 12, 0, 0), K(3, 5, 12, 0, 0),
6016 "VBAR", "VBAR_EL2", "VBAR_EL12" },
6017 { K(3, 0, 13, 0, 1), K(3, 4, 13, 0, 1), K(3, 5, 13, 0, 1),
6018 "CONTEXTIDR_EL1", "CONTEXTIDR_EL2", "CONTEXTIDR_EL12" },
6019 { K(3, 0, 14, 1, 0), K(3, 4, 14, 1, 0), K(3, 5, 14, 1, 0),
6020 "CNTKCTL", "CNTHCTL_EL2", "CNTKCTL_EL12" },
6021
6022
6023
6024
6025
6026
6027 { K(3, 0, 1, 2, 0), K(3, 4, 1, 2, 0), K(3, 5, 1, 2, 0),
6028 "ZCR_EL1", "ZCR_EL2", "ZCR_EL12", isar_feature_aa64_sve },
6029
6030 { K(3, 0, 5, 6, 0), K(3, 4, 5, 6, 0), K(3, 5, 5, 6, 0),
6031 "TFSR_EL1", "TFSR_EL2", "TFSR_EL12", isar_feature_aa64_mte },
6032
6033
6034
6035 };
6036#undef K
6037
6038 size_t i;
6039
6040 for (i = 0; i < ARRAY_SIZE(aliases); i++) {
6041 const struct E2HAlias *a = &aliases[i];
6042 ARMCPRegInfo *src_reg, *dst_reg;
6043
6044 if (a->feature && !a->feature(&cpu->isar)) {
6045 continue;
6046 }
6047
6048 src_reg = g_hash_table_lookup(cpu->cp_regs, &a->src_key);
6049 dst_reg = g_hash_table_lookup(cpu->cp_regs, &a->dst_key);
6050 g_assert(src_reg != NULL);
6051 g_assert(dst_reg != NULL);
6052
6053
6054 g_assert(strcmp(src_reg->name, a->src_name) == 0);
6055 g_assert(strcmp(dst_reg->name, a->dst_name) == 0);
6056
6057
6058 g_assert(src_reg->opaque == NULL);
6059
6060
6061 if (a->new_key) {
6062 ARMCPRegInfo *new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
6063 uint32_t *new_key = g_memdup(&a->new_key, sizeof(uint32_t));
6064 bool ok;
6065
6066 new_reg->name = a->new_name;
6067 new_reg->type |= ARM_CP_ALIAS;
6068
6069 new_reg->access &= PL2_RW | PL3_RW;
6070
6071 ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg);
6072 g_assert(ok);
6073 }
6074
6075 src_reg->opaque = dst_reg;
6076 src_reg->orig_readfn = src_reg->readfn ?: raw_read;
6077 src_reg->orig_writefn = src_reg->writefn ?: raw_write;
6078 if (!src_reg->raw_readfn) {
6079 src_reg->raw_readfn = raw_read;
6080 }
6081 if (!src_reg->raw_writefn) {
6082 src_reg->raw_writefn = raw_write;
6083 }
6084 src_reg->readfn = el2_e2h_read;
6085 src_reg->writefn = el2_e2h_write;
6086 }
6087}
6088#endif
6089
6090static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
6091 bool isread)
6092{
6093 int cur_el = arm_current_el(env);
6094
6095 if (cur_el < 2) {
6096 uint64_t hcr = arm_hcr_el2_eff(env);
6097
6098 if (cur_el == 0) {
6099 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
6100 if (!(env->cp15.sctlr_el[2] & SCTLR_UCT)) {
6101 return CP_ACCESS_TRAP_EL2;
6102 }
6103 } else {
6104 if (!(env->cp15.sctlr_el[1] & SCTLR_UCT)) {
6105 return CP_ACCESS_TRAP;
6106 }
6107 if (hcr & HCR_TID2) {
6108 return CP_ACCESS_TRAP_EL2;
6109 }
6110 }
6111 } else if (hcr & HCR_TID2) {
6112 return CP_ACCESS_TRAP_EL2;
6113 }
6114 }
6115
6116 if (arm_current_el(env) < 2 && arm_hcr_el2_eff(env) & HCR_TID2) {
6117 return CP_ACCESS_TRAP_EL2;
6118 }
6119
6120 return CP_ACCESS_OK;
6121}
6122
6123static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
6124 uint64_t value)
6125{
6126
6127
6128
6129 int oslock;
6130
6131 if (ri->state == ARM_CP_STATE_AA32) {
6132 oslock = (value == 0xC5ACCE55);
6133 } else {
6134 oslock = value & 1;
6135 }
6136
6137 env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock);
6138}
6139
6140static const ARMCPRegInfo debug_cp_reginfo[] = {
6141
6142
6143
6144
6145
6146
6147 { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
6148 .access = PL0_R, .accessfn = access_tdra,
6149 .type = ARM_CP_CONST, .resetvalue = 0 },
6150 { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64,
6151 .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
6152 .access = PL1_R, .accessfn = access_tdra,
6153 .type = ARM_CP_CONST, .resetvalue = 0 },
6154 { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
6155 .access = PL0_R, .accessfn = access_tdra,
6156 .type = ARM_CP_CONST, .resetvalue = 0 },
6157
6158 { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH,
6159 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
6160 .access = PL1_RW, .accessfn = access_tda,
6161 .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
6162 .resetvalue = 0 },
6163
6164
6165
6166 { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_BOTH,
6167 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
6168 .type = ARM_CP_ALIAS,
6169 .access = PL1_R, .accessfn = access_tda,
6170 .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), },
6171 { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH,
6172 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,
6173 .access = PL1_W, .type = ARM_CP_NO_RAW,
6174 .accessfn = access_tdosa,
6175 .writefn = oslar_write },
6176 { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH,
6177 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4,
6178 .access = PL1_R, .resetvalue = 10,
6179 .accessfn = access_tdosa,
6180 .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) },
6181
6182 { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH,
6183 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,
6184 .access = PL1_RW, .accessfn = access_tdosa,
6185 .type = ARM_CP_NOP },
6186
6187
6188
6189 { .name = "DBGVCR",
6190 .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
6191 .access = PL1_RW, .accessfn = access_tda,
6192 .type = ARM_CP_NOP },
6193
6194
6195
6196 { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
6197 .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
6198 .access = PL2_RW, .accessfn = access_tda,
6199 .type = ARM_CP_NOP },
6200
6201
6202
6203
6204 { .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
6205 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
6206 .access = PL1_RW, .accessfn = access_tda,
6207 .type = ARM_CP_NOP },
6208 REGINFO_SENTINEL
6209};
6210
6211static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
6212
6213 { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0,
6214 .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
6215 { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
6216 .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
6217 REGINFO_SENTINEL
6218};
6219
6220
6221
6222
6223
6224
6225
6226int sve_exception_el(CPUARMState *env, int el)
6227{
6228#ifndef CONFIG_USER_ONLY
6229 uint64_t hcr_el2 = arm_hcr_el2_eff(env);
6230
6231 if (el <= 1 && (hcr_el2 & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
6232 bool disabled = false;
6233
6234
6235
6236
6237
6238
6239 if (!extract32(env->cp15.cpacr_el1, 16, 1)) {
6240 disabled = true;
6241 } else if (!extract32(env->cp15.cpacr_el1, 17, 1)) {
6242 disabled = el == 0;
6243 }
6244 if (disabled) {
6245
6246 return hcr_el2 & HCR_TGE ? 2 : 1;
6247 }
6248
6249
6250 if (!extract32(env->cp15.cpacr_el1, 20, 1)) {
6251 disabled = true;
6252 } else if (!extract32(env->cp15.cpacr_el1, 21, 1)) {
6253 disabled = el == 0;
6254 }
6255 if (disabled) {
6256 return 0;
6257 }
6258 }
6259
6260
6261
6262
6263 if (el <= 2 && arm_is_el2_enabled(env)) {
6264 if (env->cp15.cptr_el[2] & CPTR_TZ) {
6265 return 2;
6266 }
6267 if (env->cp15.cptr_el[2] & CPTR_TFP) {
6268 return 0;
6269 }
6270 }
6271
6272
6273 if (arm_feature(env, ARM_FEATURE_EL3)
6274 && !(env->cp15.cptr_el[3] & CPTR_EZ)) {
6275 return 3;
6276 }
6277#endif
6278 return 0;
6279}
6280
6281static uint32_t sve_zcr_get_valid_len(ARMCPU *cpu, uint32_t start_len)
6282{
6283 uint32_t end_len;
6284
6285 end_len = start_len &= 0xf;
6286 if (!test_bit(start_len, cpu->sve_vq_map)) {
6287 end_len = find_last_bit(cpu->sve_vq_map, start_len);
6288 assert(end_len < start_len);
6289 }
6290 return end_len;
6291}
6292
6293
6294
6295
6296uint32_t sve_zcr_len_for_el(CPUARMState *env, int el)
6297{
6298 ARMCPU *cpu = env_archcpu(env);
6299 uint32_t zcr_len = cpu->sve_max_vq - 1;
6300
6301 if (el <= 1) {
6302 zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
6303 }
6304 if (el <= 2 && arm_feature(env, ARM_FEATURE_EL2)) {
6305 zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
6306 }
6307 if (arm_feature(env, ARM_FEATURE_EL3)) {
6308 zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
6309 }
6310
6311 return sve_zcr_get_valid_len(cpu, zcr_len);
6312}
6313
6314static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
6315 uint64_t value)
6316{
6317 int cur_el = arm_current_el(env);
6318 int old_len = sve_zcr_len_for_el(env, cur_el);
6319 int new_len;
6320
6321
6322 QEMU_BUILD_BUG_ON(ARM_MAX_VQ > 16);
6323 raw_write(env, ri, value & 0xf);
6324
6325
6326
6327
6328
6329 new_len = sve_zcr_len_for_el(env, cur_el);
6330 if (new_len < old_len) {
6331 aarch64_sve_narrow_vq(env, new_len + 1);
6332 }
6333}
6334
6335static const ARMCPRegInfo zcr_el1_reginfo = {
6336 .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
6337 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
6338 .access = PL1_RW, .type = ARM_CP_SVE,
6339 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
6340 .writefn = zcr_write, .raw_writefn = raw_write
6341};
6342
6343static const ARMCPRegInfo zcr_el2_reginfo = {
6344 .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
6345 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
6346 .access = PL2_RW, .type = ARM_CP_SVE,
6347 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
6348 .writefn = zcr_write, .raw_writefn = raw_write
6349};
6350
6351static const ARMCPRegInfo zcr_no_el2_reginfo = {
6352 .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
6353 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
6354 .access = PL2_RW, .type = ARM_CP_SVE,
6355 .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
6356};
6357
6358static const ARMCPRegInfo zcr_el3_reginfo = {
6359 .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
6360 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
6361 .access = PL3_RW, .type = ARM_CP_SVE,
6362 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
6363 .writefn = zcr_write, .raw_writefn = raw_write
6364};
6365
6366void hw_watchpoint_update(ARMCPU *cpu, int n)
6367{
6368 CPUARMState *env = &cpu->env;
6369 vaddr len = 0;
6370 vaddr wvr = env->cp15.dbgwvr[n];
6371 uint64_t wcr = env->cp15.dbgwcr[n];
6372 int mask;
6373 int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
6374
6375 if (env->cpu_watchpoint[n]) {
6376 cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
6377 env->cpu_watchpoint[n] = NULL;
6378 }
6379
6380 if (!extract64(wcr, 0, 1)) {
6381
6382 return;
6383 }
6384
6385 switch (extract64(wcr, 3, 2)) {
6386 case 0:
6387
6388 return;
6389 case 1:
6390 flags |= BP_MEM_READ;
6391 break;
6392 case 2:
6393 flags |= BP_MEM_WRITE;
6394 break;
6395 case 3:
6396 flags |= BP_MEM_ACCESS;
6397 break;
6398 }
6399
6400
6401
6402
6403
6404 mask = extract64(wcr, 24, 4);
6405 if (mask == 1 || mask == 2) {
6406
6407
6408
6409
6410 return;
6411 } else if (mask) {
6412
6413 len = 1ULL << mask;
6414
6415
6416
6417
6418 wvr &= ~(len - 1);
6419 } else {
6420
6421 int bas = extract64(wcr, 5, 8);
6422 int basstart;
6423
6424 if (extract64(wvr, 2, 1)) {
6425
6426
6427
6428 bas &= 0xf;
6429 }
6430
6431 if (bas == 0) {
6432
6433 return;
6434 }
6435
6436
6437
6438
6439
6440
6441 basstart = ctz32(bas);
6442 len = cto32(bas >> basstart);
6443 wvr += basstart;
6444 }
6445
6446 cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
6447 &env->cpu_watchpoint[n]);
6448}
6449
6450void hw_watchpoint_update_all(ARMCPU *cpu)
6451{
6452 int i;
6453 CPUARMState *env = &cpu->env;
6454
6455
6456
6457
6458 cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
6459 memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
6460
6461 for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
6462 hw_watchpoint_update(cpu, i);
6463 }
6464}
6465
6466static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
6467 uint64_t value)
6468{
6469 ARMCPU *cpu = env_archcpu(env);
6470 int i = ri->crm;
6471
6472
6473
6474
6475
6476 value = sextract64(value, 0, 49) & ~3ULL;
6477
6478 raw_write(env, ri, value);
6479 hw_watchpoint_update(cpu, i);
6480}
6481
6482static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
6483 uint64_t value)
6484{
6485 ARMCPU *cpu = env_archcpu(env);
6486 int i = ri->crm;
6487
6488 raw_write(env, ri, value);
6489 hw_watchpoint_update(cpu, i);
6490}
6491
6492void hw_breakpoint_update(ARMCPU *cpu, int n)
6493{
6494 CPUARMState *env = &cpu->env;
6495 uint64_t bvr = env->cp15.dbgbvr[n];
6496 uint64_t bcr = env->cp15.dbgbcr[n];
6497 vaddr addr;
6498 int bt;
6499 int flags = BP_CPU;
6500
6501 if (env->cpu_breakpoint[n]) {
6502 cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
6503 env->cpu_breakpoint[n] = NULL;
6504 }
6505
6506 if (!extract64(bcr, 0, 1)) {
6507
6508 return;
6509 }
6510
6511 bt = extract64(bcr, 20, 4);
6512
6513 switch (bt) {
6514 case 4:
6515 case 5:
6516 qemu_log_mask(LOG_UNIMP,
6517 "arm: address mismatch breakpoint types not implemented\n");
6518 return;
6519 case 0:
6520 case 1:
6521 {
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537 int bas = extract64(bcr, 5, 4);
6538 addr = sextract64(bvr, 0, 49) & ~3ULL;
6539 if (bas == 0) {
6540 return;
6541 }
6542 if (bas == 0xc) {
6543 addr += 2;
6544 }
6545 break;
6546 }
6547 case 2:
6548 case 8:
6549 case 10:
6550 qemu_log_mask(LOG_UNIMP,
6551 "arm: unlinked context breakpoint types not implemented\n");
6552 return;
6553 case 9:
6554 case 11:
6555 case 3:
6556 default:
6557
6558
6559
6560
6561
6562 return;
6563 }
6564
6565 cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
6566}
6567
6568void hw_breakpoint_update_all(ARMCPU *cpu)
6569{
6570 int i;
6571 CPUARMState *env = &cpu->env;
6572
6573
6574
6575
6576 cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
6577 memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
6578
6579 for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
6580 hw_breakpoint_update(cpu, i);
6581 }
6582}
6583
6584static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
6585 uint64_t value)
6586{
6587 ARMCPU *cpu = env_archcpu(env);
6588 int i = ri->crm;
6589
6590 raw_write(env, ri, value);
6591 hw_breakpoint_update(cpu, i);
6592}
6593
6594static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
6595 uint64_t value)
6596{
6597 ARMCPU *cpu = env_archcpu(env);
6598 int i = ri->crm;
6599
6600
6601
6602
6603 value = deposit64(value, 6, 1, extract64(value, 5, 1));
6604 value = deposit64(value, 8, 1, extract64(value, 7, 1));
6605
6606 raw_write(env, ri, value);
6607 hw_breakpoint_update(cpu, i);
6608}
6609
6610static void define_debug_regs(ARMCPU *cpu)
6611{
6612
6613
6614
6615 int i;
6616 int wrps, brps, ctx_cmps;
6617
6618
6619
6620
6621
6622
6623 if (cpu->isar.dbgdidr != 0) {
6624 ARMCPRegInfo dbgdidr = {
6625 .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0,
6626 .opc1 = 0, .opc2 = 0,
6627 .access = PL0_R, .accessfn = access_tda,
6628 .type = ARM_CP_CONST, .resetvalue = cpu->isar.dbgdidr,
6629 };
6630 define_one_arm_cp_reg(cpu, &dbgdidr);
6631 }
6632
6633
6634 brps = arm_num_brps(cpu);
6635 wrps = arm_num_wrps(cpu);
6636 ctx_cmps = arm_num_ctx_cmps(cpu);
6637
6638 assert(ctx_cmps <= brps);
6639
6640 define_arm_cp_regs(cpu, debug_cp_reginfo);
6641
6642 if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
6643 define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
6644 }
6645
6646 for (i = 0; i < brps; i++) {
6647 ARMCPRegInfo dbgregs[] = {
6648 { .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,
6649 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
6650 .access = PL1_RW, .accessfn = access_tda,
6651 .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
6652 .writefn = dbgbvr_write, .raw_writefn = raw_write
6653 },
6654 { .name = "DBGBCR", .state = ARM_CP_STATE_BOTH,
6655 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
6656 .access = PL1_RW, .accessfn = access_tda,
6657 .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
6658 .writefn = dbgbcr_write, .raw_writefn = raw_write
6659 },
6660 REGINFO_SENTINEL
6661 };
6662 define_arm_cp_regs(cpu, dbgregs);
6663 }
6664
6665 for (i = 0; i < wrps; i++) {
6666 ARMCPRegInfo dbgregs[] = {
6667 { .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,
6668 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
6669 .access = PL1_RW, .accessfn = access_tda,
6670 .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
6671 .writefn = dbgwvr_write, .raw_writefn = raw_write
6672 },
6673 { .name = "DBGWCR", .state = ARM_CP_STATE_BOTH,
6674 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
6675 .access = PL1_RW, .accessfn = access_tda,
6676 .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
6677 .writefn = dbgwcr_write, .raw_writefn = raw_write
6678 },
6679 REGINFO_SENTINEL
6680 };
6681 define_arm_cp_regs(cpu, dbgregs);
6682 }
6683}
6684
6685static void define_pmu_regs(ARMCPU *cpu)
6686{
6687
6688
6689
6690
6691
6692 unsigned int i, pmcrn = PMCR_NUM_COUNTERS;
6693 ARMCPRegInfo pmcr = {
6694 .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
6695 .access = PL0_RW,
6696 .type = ARM_CP_IO | ARM_CP_ALIAS,
6697 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
6698 .accessfn = pmreg_access, .writefn = pmcr_write,
6699 .raw_writefn = raw_write,
6700 };
6701 ARMCPRegInfo pmcr64 = {
6702 .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
6703 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
6704 .access = PL0_RW, .accessfn = pmreg_access,
6705 .type = ARM_CP_IO,
6706 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
6707 .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) |
6708 PMCRLC,
6709 .writefn = pmcr_write, .raw_writefn = raw_write,
6710 };
6711 define_one_arm_cp_reg(cpu, &pmcr);
6712 define_one_arm_cp_reg(cpu, &pmcr64);
6713 for (i = 0; i < pmcrn; i++) {
6714 char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
6715 char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
6716 char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
6717 char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
6718 ARMCPRegInfo pmev_regs[] = {
6719 { .name = pmevcntr_name, .cp = 15, .crn = 14,
6720 .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
6721 .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
6722 .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
6723 .accessfn = pmreg_access },
6724 { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
6725 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
6726 .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
6727 .type = ARM_CP_IO,
6728 .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
6729 .raw_readfn = pmevcntr_rawread,
6730 .raw_writefn = pmevcntr_rawwrite },
6731 { .name = pmevtyper_name, .cp = 15, .crn = 14,
6732 .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
6733 .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
6734 .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
6735 .accessfn = pmreg_access },
6736 { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
6737 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
6738 .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
6739 .type = ARM_CP_IO,
6740 .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
6741 .raw_writefn = pmevtyper_rawwrite },
6742 REGINFO_SENTINEL
6743 };
6744 define_arm_cp_regs(cpu, pmev_regs);
6745 g_free(pmevcntr_name);
6746 g_free(pmevcntr_el0_name);
6747 g_free(pmevtyper_name);
6748 g_free(pmevtyper_el0_name);
6749 }
6750 if (cpu_isar_feature(aa32_pmu_8_1, cpu)) {
6751 ARMCPRegInfo v81_pmu_regs[] = {
6752 { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
6753 .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
6754 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6755 .resetvalue = extract64(cpu->pmceid0, 32, 32) },
6756 { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
6757 .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
6758 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6759 .resetvalue = extract64(cpu->pmceid1, 32, 32) },
6760 REGINFO_SENTINEL
6761 };
6762 define_arm_cp_regs(cpu, v81_pmu_regs);
6763 }
6764 if (cpu_isar_feature(any_pmu_8_4, cpu)) {
6765 static const ARMCPRegInfo v84_pmmir = {
6766 .name = "PMMIR_EL1", .state = ARM_CP_STATE_BOTH,
6767 .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 6,
6768 .access = PL1_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6769 .resetvalue = 0
6770 };
6771 define_one_arm_cp_reg(cpu, &v84_pmmir);
6772 }
6773}
6774
6775
6776
6777
6778
6779
6780static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
6781{
6782 ARMCPU *cpu = env_archcpu(env);
6783 uint64_t pfr1 = cpu->isar.id_pfr1;
6784
6785 if (env->gicv3state) {
6786 pfr1 |= 1 << 28;
6787 }
6788 return pfr1;
6789}
6790
6791#ifndef CONFIG_USER_ONLY
6792static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
6793{
6794 ARMCPU *cpu = env_archcpu(env);
6795 uint64_t pfr0 = cpu->isar.id_aa64pfr0;
6796
6797 if (env->gicv3state) {
6798 pfr0 |= 1 << 24;
6799 }
6800 return pfr0;
6801}
6802#endif
6803
6804
6805
6806
6807static CPAccessResult access_lor_ns(CPUARMState *env,
6808 const ARMCPRegInfo *ri, bool isread)
6809{
6810 int el = arm_current_el(env);
6811
6812 if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TLOR)) {
6813 return CP_ACCESS_TRAP_EL2;
6814 }
6815 if (el < 3 && (env->cp15.scr_el3 & SCR_TLOR)) {
6816 return CP_ACCESS_TRAP_EL3;
6817 }
6818 return CP_ACCESS_OK;
6819}
6820
6821static CPAccessResult access_lor_other(CPUARMState *env,
6822 const ARMCPRegInfo *ri, bool isread)
6823{
6824 if (arm_is_secure_below_el3(env)) {
6825
6826 return CP_ACCESS_TRAP;
6827 }
6828 return access_lor_ns(env, ri, isread);
6829}
6830
6831
6832
6833
6834
6835
6836static const ARMCPRegInfo lor_reginfo[] = {
6837 { .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64,
6838 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0,
6839 .access = PL1_RW, .accessfn = access_lor_other,
6840 .type = ARM_CP_CONST, .resetvalue = 0 },
6841 { .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64,
6842 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1,
6843 .access = PL1_RW, .accessfn = access_lor_other,
6844 .type = ARM_CP_CONST, .resetvalue = 0 },
6845 { .name = "LORN_EL1", .state = ARM_CP_STATE_AA64,
6846 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2,
6847 .access = PL1_RW, .accessfn = access_lor_other,
6848 .type = ARM_CP_CONST, .resetvalue = 0 },
6849 { .name = "LORC_EL1", .state = ARM_CP_STATE_AA64,
6850 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3,
6851 .access = PL1_RW, .accessfn = access_lor_other,
6852 .type = ARM_CP_CONST, .resetvalue = 0 },
6853 { .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
6854 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
6855 .access = PL1_R, .accessfn = access_lor_ns,
6856 .type = ARM_CP_CONST, .resetvalue = 0 },
6857 REGINFO_SENTINEL
6858};
6859
6860#ifdef TARGET_AARCH64
6861static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri,
6862 bool isread)
6863{
6864 int el = arm_current_el(env);
6865
6866 if (el < 2 &&
6867 arm_feature(env, ARM_FEATURE_EL2) &&
6868 !(arm_hcr_el2_eff(env) & HCR_APK)) {
6869 return CP_ACCESS_TRAP_EL2;
6870 }
6871 if (el < 3 &&
6872 arm_feature(env, ARM_FEATURE_EL3) &&
6873 !(env->cp15.scr_el3 & SCR_APK)) {
6874 return CP_ACCESS_TRAP_EL3;
6875 }
6876 return CP_ACCESS_OK;
6877}
6878
6879static const ARMCPRegInfo pauth_reginfo[] = {
6880 { .name = "APDAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
6881 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
6882 .access = PL1_RW, .accessfn = access_pauth,
6883 .fieldoffset = offsetof(CPUARMState, keys.apda.lo) },
6884 { .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
6885 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
6886 .access = PL1_RW, .accessfn = access_pauth,
6887 .fieldoffset = offsetof(CPUARMState, keys.apda.hi) },
6888 { .name = "APDBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
6889 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
6890 .access = PL1_RW, .accessfn = access_pauth,
6891 .fieldoffset = offsetof(CPUARMState, keys.apdb.lo) },
6892 { .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
6893 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
6894 .access = PL1_RW, .accessfn = access_pauth,
6895 .fieldoffset = offsetof(CPUARMState, keys.apdb.hi) },
6896 { .name = "APGAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
6897 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 0,
6898 .access = PL1_RW, .accessfn = access_pauth,
6899 .fieldoffset = offsetof(CPUARMState, keys.apga.lo) },
6900 { .name = "APGAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
6901 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 1,
6902 .access = PL1_RW, .accessfn = access_pauth,
6903 .fieldoffset = offsetof(CPUARMState, keys.apga.hi) },
6904 { .name = "APIAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
6905 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 0,
6906 .access = PL1_RW, .accessfn = access_pauth,
6907 .fieldoffset = offsetof(CPUARMState, keys.apia.lo) },
6908 { .name = "APIAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
6909 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 1,
6910 .access = PL1_RW, .accessfn = access_pauth,
6911 .fieldoffset = offsetof(CPUARMState, keys.apia.hi) },
6912 { .name = "APIBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
6913 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 2,
6914 .access = PL1_RW, .accessfn = access_pauth,
6915 .fieldoffset = offsetof(CPUARMState, keys.apib.lo) },
6916 { .name = "APIBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
6917 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
6918 .access = PL1_RW, .accessfn = access_pauth,
6919 .fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
6920 REGINFO_SENTINEL
6921};
6922
6923static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
6924{
6925 Error *err = NULL;
6926 uint64_t ret;
6927
6928
6929 env->NF = env->CF = env->VF = 0, env->ZF = 1;
6930
6931 if (qemu_guest_getrandom(&ret, sizeof(ret), &err) < 0) {
6932
6933
6934
6935
6936
6937
6938
6939 qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
6940 ri->name, error_get_pretty(err));
6941 error_free(err);
6942
6943 env->ZF = 0;
6944 return 0;
6945 }
6946 return ret;
6947}
6948
6949
6950static const ARMCPRegInfo rndr_reginfo[] = {
6951 { .name = "RNDR", .state = ARM_CP_STATE_AA64,
6952 .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
6953 .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 0,
6954 .access = PL0_R, .readfn = rndr_readfn },
6955 { .name = "RNDRRS", .state = ARM_CP_STATE_AA64,
6956 .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
6957 .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
6958 .access = PL0_R, .readfn = rndr_readfn },
6959 REGINFO_SENTINEL
6960};
6961
6962#ifndef CONFIG_USER_ONLY
6963static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
6964 uint64_t value)
6965{
6966 ARMCPU *cpu = env_archcpu(env);
6967
6968 uint64_t dline_size = 4 << ((cpu->ctr >> 16) & 0xF);
6969 uint64_t vaddr_in = (uint64_t) value;
6970 uint64_t vaddr = vaddr_in & ~(dline_size - 1);
6971 void *haddr;
6972 int mem_idx = cpu_mmu_index(env, false);
6973
6974
6975 haddr = probe_read(env, vaddr, dline_size, mem_idx, GETPC());
6976 if (haddr) {
6977
6978 ram_addr_t offset;
6979 MemoryRegion *mr;
6980
6981
6982 mr = memory_region_from_host(haddr, &offset);
6983
6984 if (mr) {
6985 memory_region_writeback(mr, offset, dline_size);
6986 }
6987 }
6988}
6989
6990static const ARMCPRegInfo dcpop_reg[] = {
6991 { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
6992 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
6993 .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
6994 .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
6995 REGINFO_SENTINEL
6996};
6997
6998static const ARMCPRegInfo dcpodp_reg[] = {
6999 { .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
7000 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
7001 .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
7002 .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
7003 REGINFO_SENTINEL
7004};
7005#endif
7006
7007static CPAccessResult access_aa64_tid5(CPUARMState *env, const ARMCPRegInfo *ri,
7008 bool isread)
7009{
7010 if ((arm_current_el(env) < 2) && (arm_hcr_el2_eff(env) & HCR_TID5)) {
7011 return CP_ACCESS_TRAP_EL2;
7012 }
7013
7014 return CP_ACCESS_OK;
7015}
7016
7017static CPAccessResult access_mte(CPUARMState *env, const ARMCPRegInfo *ri,
7018 bool isread)
7019{
7020 int el = arm_current_el(env);
7021
7022 if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
7023 uint64_t hcr = arm_hcr_el2_eff(env);
7024 if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
7025 return CP_ACCESS_TRAP_EL2;
7026 }
7027 }
7028 if (el < 3 &&
7029 arm_feature(env, ARM_FEATURE_EL3) &&
7030 !(env->cp15.scr_el3 & SCR_ATA)) {
7031 return CP_ACCESS_TRAP_EL3;
7032 }
7033 return CP_ACCESS_OK;
7034}
7035
7036static uint64_t tco_read(CPUARMState *env, const ARMCPRegInfo *ri)
7037{
7038 return env->pstate & PSTATE_TCO;
7039}
7040
7041static void tco_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
7042{
7043 env->pstate = (env->pstate & ~PSTATE_TCO) | (val & PSTATE_TCO);
7044}
7045
7046static const ARMCPRegInfo mte_reginfo[] = {
7047 { .name = "TFSRE0_EL1", .state = ARM_CP_STATE_AA64,
7048 .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 1,
7049 .access = PL1_RW, .accessfn = access_mte,
7050 .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[0]) },
7051 { .name = "TFSR_EL1", .state = ARM_CP_STATE_AA64,
7052 .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 6, .opc2 = 0,
7053 .access = PL1_RW, .accessfn = access_mte,
7054 .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[1]) },
7055 { .name = "TFSR_EL2", .state = ARM_CP_STATE_AA64,
7056 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 6, .opc2 = 0,
7057 .access = PL2_RW, .accessfn = access_mte,
7058 .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[2]) },
7059 { .name = "TFSR_EL3", .state = ARM_CP_STATE_AA64,
7060 .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 6, .opc2 = 0,
7061 .access = PL3_RW,
7062 .fieldoffset = offsetof(CPUARMState, cp15.tfsr_el[3]) },
7063 { .name = "RGSR_EL1", .state = ARM_CP_STATE_AA64,
7064 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 5,
7065 .access = PL1_RW, .accessfn = access_mte,
7066 .fieldoffset = offsetof(CPUARMState, cp15.rgsr_el1) },
7067 { .name = "GCR_EL1", .state = ARM_CP_STATE_AA64,
7068 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 6,
7069 .access = PL1_RW, .accessfn = access_mte,
7070 .fieldoffset = offsetof(CPUARMState, cp15.gcr_el1) },
7071 { .name = "GMID_EL1", .state = ARM_CP_STATE_AA64,
7072 .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 4,
7073 .access = PL1_R, .accessfn = access_aa64_tid5,
7074 .type = ARM_CP_CONST, .resetvalue = GMID_EL1_BS },
7075 { .name = "TCO", .state = ARM_CP_STATE_AA64,
7076 .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
7077 .type = ARM_CP_NO_RAW,
7078 .access = PL0_RW, .readfn = tco_read, .writefn = tco_write },
7079 { .name = "DC_IGVAC", .state = ARM_CP_STATE_AA64,
7080 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 3,
7081 .type = ARM_CP_NOP, .access = PL1_W,
7082 .accessfn = aa64_cacheop_poc_access },
7083 { .name = "DC_IGSW", .state = ARM_CP_STATE_AA64,
7084 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 4,
7085 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7086 { .name = "DC_IGDVAC", .state = ARM_CP_STATE_AA64,
7087 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 5,
7088 .type = ARM_CP_NOP, .access = PL1_W,
7089 .accessfn = aa64_cacheop_poc_access },
7090 { .name = "DC_IGDSW", .state = ARM_CP_STATE_AA64,
7091 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 6,
7092 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7093 { .name = "DC_CGSW", .state = ARM_CP_STATE_AA64,
7094 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 4,
7095 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7096 { .name = "DC_CGDSW", .state = ARM_CP_STATE_AA64,
7097 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 6,
7098 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7099 { .name = "DC_CIGSW", .state = ARM_CP_STATE_AA64,
7100 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 4,
7101 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7102 { .name = "DC_CIGDSW", .state = ARM_CP_STATE_AA64,
7103 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 6,
7104 .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
7105 REGINFO_SENTINEL
7106};
7107
7108static const ARMCPRegInfo mte_tco_ro_reginfo[] = {
7109 { .name = "TCO", .state = ARM_CP_STATE_AA64,
7110 .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
7111 .type = ARM_CP_CONST, .access = PL0_RW, },
7112 REGINFO_SENTINEL
7113};
7114
7115static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
7116 { .name = "DC_CGVAC", .state = ARM_CP_STATE_AA64,
7117 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 3,
7118 .type = ARM_CP_NOP, .access = PL0_W,
7119 .accessfn = aa64_cacheop_poc_access },
7120 { .name = "DC_CGDVAC", .state = ARM_CP_STATE_AA64,
7121 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 5,
7122 .type = ARM_CP_NOP, .access = PL0_W,
7123 .accessfn = aa64_cacheop_poc_access },
7124 { .name = "DC_CGVAP", .state = ARM_CP_STATE_AA64,
7125 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 3,
7126 .type = ARM_CP_NOP, .access = PL0_W,
7127 .accessfn = aa64_cacheop_poc_access },
7128 { .name = "DC_CGDVAP", .state = ARM_CP_STATE_AA64,
7129 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 5,
7130 .type = ARM_CP_NOP, .access = PL0_W,
7131 .accessfn = aa64_cacheop_poc_access },
7132 { .name = "DC_CGVADP", .state = ARM_CP_STATE_AA64,
7133 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 3,
7134 .type = ARM_CP_NOP, .access = PL0_W,
7135 .accessfn = aa64_cacheop_poc_access },
7136 { .name = "DC_CGDVADP", .state = ARM_CP_STATE_AA64,
7137 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 5,
7138 .type = ARM_CP_NOP, .access = PL0_W,
7139 .accessfn = aa64_cacheop_poc_access },
7140 { .name = "DC_CIGVAC", .state = ARM_CP_STATE_AA64,
7141 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 3,
7142 .type = ARM_CP_NOP, .access = PL0_W,
7143 .accessfn = aa64_cacheop_poc_access },
7144 { .name = "DC_CIGDVAC", .state = ARM_CP_STATE_AA64,
7145 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 5,
7146 .type = ARM_CP_NOP, .access = PL0_W,
7147 .accessfn = aa64_cacheop_poc_access },
7148 { .name = "DC_GVA", .state = ARM_CP_STATE_AA64,
7149 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 3,
7150 .access = PL0_W, .type = ARM_CP_DC_GVA,
7151#ifndef CONFIG_USER_ONLY
7152
7153 .accessfn = aa64_zva_access,
7154#endif
7155 },
7156 { .name = "DC_GZVA", .state = ARM_CP_STATE_AA64,
7157 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 4,
7158 .access = PL0_W, .type = ARM_CP_DC_GZVA,
7159#ifndef CONFIG_USER_ONLY
7160
7161 .accessfn = aa64_zva_access,
7162#endif
7163 },
7164 REGINFO_SENTINEL
7165};
7166
7167#endif
7168
7169static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
7170 bool isread)
7171{
7172 int el = arm_current_el(env);
7173
7174 if (el == 0) {
7175 uint64_t sctlr = arm_sctlr(env, el);
7176 if (!(sctlr & SCTLR_EnRCTX)) {
7177 return CP_ACCESS_TRAP;
7178 }
7179 } else if (el == 1) {
7180 uint64_t hcr = arm_hcr_el2_eff(env);
7181 if (hcr & HCR_NV) {
7182 return CP_ACCESS_TRAP_EL2;
7183 }
7184 }
7185 return CP_ACCESS_OK;
7186}
7187
7188static const ARMCPRegInfo predinv_reginfo[] = {
7189 { .name = "CFP_RCTX", .state = ARM_CP_STATE_AA64,
7190 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 4,
7191 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7192 { .name = "DVP_RCTX", .state = ARM_CP_STATE_AA64,
7193 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 5,
7194 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7195 { .name = "CPP_RCTX", .state = ARM_CP_STATE_AA64,
7196 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 7,
7197 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7198
7199
7200
7201 { .name = "CFPRCTX", .state = ARM_CP_STATE_AA32,
7202 .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 4,
7203 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7204 { .name = "DVPRCTX", .state = ARM_CP_STATE_AA32,
7205 .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 5,
7206 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7207 { .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
7208 .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
7209 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
7210 REGINFO_SENTINEL
7211};
7212
7213static uint64_t ccsidr2_read(CPUARMState *env, const ARMCPRegInfo *ri)
7214{
7215
7216 return extract64(ccsidr_read(env, ri), 32, 32);
7217}
7218
7219static const ARMCPRegInfo ccsidr2_reginfo[] = {
7220 { .name = "CCSIDR2", .state = ARM_CP_STATE_BOTH,
7221 .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 2,
7222 .access = PL1_R,
7223 .accessfn = access_aa64_tid2,
7224 .readfn = ccsidr2_read, .type = ARM_CP_NO_RAW },
7225 REGINFO_SENTINEL
7226};
7227
7228static CPAccessResult access_aa64_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
7229 bool isread)
7230{
7231 if ((arm_current_el(env) < 2) && (arm_hcr_el2_eff(env) & HCR_TID3)) {
7232 return CP_ACCESS_TRAP_EL2;
7233 }
7234
7235 return CP_ACCESS_OK;
7236}
7237
7238static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
7239 bool isread)
7240{
7241 if (arm_feature(env, ARM_FEATURE_V8)) {
7242 return access_aa64_tid3(env, ri, isread);
7243 }
7244
7245 return CP_ACCESS_OK;
7246}
7247
7248static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
7249 bool isread)
7250{
7251 if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID0)) {
7252 return CP_ACCESS_TRAP_EL2;
7253 }
7254
7255 return CP_ACCESS_OK;
7256}
7257
7258static const ARMCPRegInfo jazelle_regs[] = {
7259 { .name = "JIDR",
7260 .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
7261 .access = PL1_R, .accessfn = access_jazelle,
7262 .type = ARM_CP_CONST, .resetvalue = 0 },
7263 { .name = "JOSCR",
7264 .cp = 14, .crn = 1, .crm = 0, .opc1 = 7, .opc2 = 0,
7265 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
7266 { .name = "JMCR",
7267 .cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
7268 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
7269 REGINFO_SENTINEL
7270};
7271
7272static const ARMCPRegInfo vhe_reginfo[] = {
7273 { .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
7274 .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
7275 .access = PL2_RW,
7276 .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2]) },
7277 { .name = "TTBR1_EL2", .state = ARM_CP_STATE_AA64,
7278 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 1,
7279 .access = PL2_RW, .writefn = vmsa_tcr_ttbr_el2_write,
7280 .fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el[2]) },
7281#ifndef CONFIG_USER_ONLY
7282 { .name = "CNTHV_CVAL_EL2", .state = ARM_CP_STATE_AA64,
7283 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 3, .opc2 = 2,
7284 .fieldoffset =
7285 offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYPVIRT].cval),
7286 .type = ARM_CP_IO, .access = PL2_RW,
7287 .writefn = gt_hv_cval_write, .raw_writefn = raw_write },
7288 { .name = "CNTHV_TVAL_EL2", .state = ARM_CP_STATE_BOTH,
7289 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 3, .opc2 = 0,
7290 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW,
7291 .resetfn = gt_hv_timer_reset,
7292 .readfn = gt_hv_tval_read, .writefn = gt_hv_tval_write },
7293 { .name = "CNTHV_CTL_EL2", .state = ARM_CP_STATE_BOTH,
7294 .type = ARM_CP_IO,
7295 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 3, .opc2 = 1,
7296 .access = PL2_RW,
7297 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYPVIRT].ctl),
7298 .writefn = gt_hv_ctl_write, .raw_writefn = raw_write },
7299 { .name = "CNTP_CTL_EL02", .state = ARM_CP_STATE_AA64,
7300 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 1,
7301 .type = ARM_CP_IO | ARM_CP_ALIAS,
7302 .access = PL2_RW, .accessfn = e2h_access,
7303 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
7304 .writefn = gt_phys_ctl_write, .raw_writefn = raw_write },
7305 { .name = "CNTV_CTL_EL02", .state = ARM_CP_STATE_AA64,
7306 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 1,
7307 .type = ARM_CP_IO | ARM_CP_ALIAS,
7308 .access = PL2_RW, .accessfn = e2h_access,
7309 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
7310 .writefn = gt_virt_ctl_write, .raw_writefn = raw_write },
7311 { .name = "CNTP_TVAL_EL02", .state = ARM_CP_STATE_AA64,
7312 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 0,
7313 .type = ARM_CP_NO_RAW | ARM_CP_IO | ARM_CP_ALIAS,
7314 .access = PL2_RW, .accessfn = e2h_access,
7315 .readfn = gt_phys_tval_read, .writefn = gt_phys_tval_write },
7316 { .name = "CNTV_TVAL_EL02", .state = ARM_CP_STATE_AA64,
7317 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 0,
7318 .type = ARM_CP_NO_RAW | ARM_CP_IO | ARM_CP_ALIAS,
7319 .access = PL2_RW, .accessfn = e2h_access,
7320 .readfn = gt_virt_tval_read, .writefn = gt_virt_tval_write },
7321 { .name = "CNTP_CVAL_EL02", .state = ARM_CP_STATE_AA64,
7322 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 2,
7323 .type = ARM_CP_IO | ARM_CP_ALIAS,
7324 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
7325 .access = PL2_RW, .accessfn = e2h_access,
7326 .writefn = gt_phys_cval_write, .raw_writefn = raw_write },
7327 { .name = "CNTV_CVAL_EL02", .state = ARM_CP_STATE_AA64,
7328 .opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 2,
7329 .type = ARM_CP_IO | ARM_CP_ALIAS,
7330 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
7331 .access = PL2_RW, .accessfn = e2h_access,
7332 .writefn = gt_virt_cval_write, .raw_writefn = raw_write },
7333#endif
7334 REGINFO_SENTINEL
7335};
7336
7337#ifndef CONFIG_USER_ONLY
7338static const ARMCPRegInfo ats1e1_reginfo[] = {
7339 { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64,
7340 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
7341 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
7342 .writefn = ats_write64 },
7343 { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
7344 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
7345 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
7346 .writefn = ats_write64 },
7347 REGINFO_SENTINEL
7348};
7349
7350static const ARMCPRegInfo ats1cp_reginfo[] = {
7351 { .name = "ATS1CPRP",
7352 .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 0,
7353 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
7354 .writefn = ats_write },
7355 { .name = "ATS1CPWP",
7356 .cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
7357 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
7358 .writefn = ats_write },
7359 REGINFO_SENTINEL
7360};
7361#endif
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
7373 { .name = "ACTLR2", .state = ARM_CP_STATE_AA32,
7374 .cp = 15, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 3,
7375 .access = PL1_RW, .accessfn = access_tacr,
7376 .type = ARM_CP_CONST, .resetvalue = 0 },
7377 { .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
7378 .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
7379 .access = PL2_RW, .type = ARM_CP_CONST,
7380 .resetvalue = 0 },
7381 REGINFO_SENTINEL
7382};
7383
7384void register_cp_regs_for_features(ARMCPU *cpu)
7385{
7386
7387 CPUARMState *env = &cpu->env;
7388 if (arm_feature(env, ARM_FEATURE_M)) {
7389
7390 return;
7391 }
7392
7393 define_arm_cp_regs(cpu, cp_reginfo);
7394 if (!arm_feature(env, ARM_FEATURE_V8)) {
7395
7396
7397
7398 define_arm_cp_regs(cpu, not_v8_cp_reginfo);
7399 }
7400
7401 if (arm_feature(env, ARM_FEATURE_V6)) {
7402
7403 ARMCPRegInfo v6_idregs[] = {
7404 { .name = "ID_PFR0", .state = ARM_CP_STATE_BOTH,
7405 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
7406 .access = PL1_R, .type = ARM_CP_CONST,
7407 .accessfn = access_aa32_tid3,
7408 .resetvalue = cpu->isar.id_pfr0 },
7409
7410
7411
7412 { .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH,
7413 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1,
7414 .access = PL1_R, .type = ARM_CP_NO_RAW,
7415 .accessfn = access_aa32_tid3,
7416 .readfn = id_pfr1_read,
7417 .writefn = arm_cp_write_ignore },
7418 { .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH,
7419 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
7420 .access = PL1_R, .type = ARM_CP_CONST,
7421 .accessfn = access_aa32_tid3,
7422 .resetvalue = cpu->isar.id_dfr0 },
7423 { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
7424 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
7425 .access = PL1_R, .type = ARM_CP_CONST,
7426 .accessfn = access_aa32_tid3,
7427 .resetvalue = cpu->id_afr0 },
7428 { .name = "ID_MMFR0", .state = ARM_CP_STATE_BOTH,
7429 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4,
7430 .access = PL1_R, .type = ARM_CP_CONST,
7431 .accessfn = access_aa32_tid3,
7432 .resetvalue = cpu->isar.id_mmfr0 },
7433 { .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,
7434 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,
7435 .access = PL1_R, .type = ARM_CP_CONST,
7436 .accessfn = access_aa32_tid3,
7437 .resetvalue = cpu->isar.id_mmfr1 },
7438 { .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,
7439 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,
7440 .access = PL1_R, .type = ARM_CP_CONST,
7441 .accessfn = access_aa32_tid3,
7442 .resetvalue = cpu->isar.id_mmfr2 },
7443 { .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,
7444 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,
7445 .access = PL1_R, .type = ARM_CP_CONST,
7446 .accessfn = access_aa32_tid3,
7447 .resetvalue = cpu->isar.id_mmfr3 },
7448 { .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
7449 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
7450 .access = PL1_R, .type = ARM_CP_CONST,
7451 .accessfn = access_aa32_tid3,
7452 .resetvalue = cpu->isar.id_isar0 },
7453 { .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH,
7454 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1,
7455 .access = PL1_R, .type = ARM_CP_CONST,
7456 .accessfn = access_aa32_tid3,
7457 .resetvalue = cpu->isar.id_isar1 },
7458 { .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH,
7459 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
7460 .access = PL1_R, .type = ARM_CP_CONST,
7461 .accessfn = access_aa32_tid3,
7462 .resetvalue = cpu->isar.id_isar2 },
7463 { .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH,
7464 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3,
7465 .access = PL1_R, .type = ARM_CP_CONST,
7466 .accessfn = access_aa32_tid3,
7467 .resetvalue = cpu->isar.id_isar3 },
7468 { .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH,
7469 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4,
7470 .access = PL1_R, .type = ARM_CP_CONST,
7471 .accessfn = access_aa32_tid3,
7472 .resetvalue = cpu->isar.id_isar4 },
7473 { .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH,
7474 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,
7475 .access = PL1_R, .type = ARM_CP_CONST,
7476 .accessfn = access_aa32_tid3,
7477 .resetvalue = cpu->isar.id_isar5 },
7478 { .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
7479 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
7480 .access = PL1_R, .type = ARM_CP_CONST,
7481 .accessfn = access_aa32_tid3,
7482 .resetvalue = cpu->isar.id_mmfr4 },
7483 { .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
7484 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
7485 .access = PL1_R, .type = ARM_CP_CONST,
7486 .accessfn = access_aa32_tid3,
7487 .resetvalue = cpu->isar.id_isar6 },
7488 REGINFO_SENTINEL
7489 };
7490 define_arm_cp_regs(cpu, v6_idregs);
7491 define_arm_cp_regs(cpu, v6_cp_reginfo);
7492 } else {
7493 define_arm_cp_regs(cpu, not_v6_cp_reginfo);
7494 }
7495 if (arm_feature(env, ARM_FEATURE_V6K)) {
7496 define_arm_cp_regs(cpu, v6k_cp_reginfo);
7497 }
7498 if (arm_feature(env, ARM_FEATURE_V7MP) &&
7499 !arm_feature(env, ARM_FEATURE_PMSA)) {
7500 define_arm_cp_regs(cpu, v7mp_cp_reginfo);
7501 }
7502 if (arm_feature(env, ARM_FEATURE_V7VE)) {
7503 define_arm_cp_regs(cpu, pmovsset_cp_reginfo);
7504 }
7505 if (arm_feature(env, ARM_FEATURE_V7)) {
7506 ARMCPRegInfo clidr = {
7507 .name = "CLIDR", .state = ARM_CP_STATE_BOTH,
7508 .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
7509 .access = PL1_R, .type = ARM_CP_CONST,
7510 .accessfn = access_aa64_tid2,
7511 .resetvalue = cpu->clidr
7512 };
7513 define_one_arm_cp_reg(cpu, &clidr);
7514 define_arm_cp_regs(cpu, v7_cp_reginfo);
7515 define_debug_regs(cpu);
7516 define_pmu_regs(cpu);
7517 } else {
7518 define_arm_cp_regs(cpu, not_v7_cp_reginfo);
7519 }
7520 if (arm_feature(env, ARM_FEATURE_V8)) {
7521
7522
7523
7524
7525
7526 ARMCPRegInfo v8_idregs[] = {
7527
7528
7529
7530
7531
7532 { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64,
7533 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0,
7534 .access = PL1_R,
7535#ifdef CONFIG_USER_ONLY
7536 .type = ARM_CP_CONST,
7537 .resetvalue = cpu->isar.id_aa64pfr0
7538#else
7539 .type = ARM_CP_NO_RAW,
7540 .accessfn = access_aa64_tid3,
7541 .readfn = id_aa64pfr0_read,
7542 .writefn = arm_cp_write_ignore
7543#endif
7544 },
7545 { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64,
7546 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
7547 .access = PL1_R, .type = ARM_CP_CONST,
7548 .accessfn = access_aa64_tid3,
7549 .resetvalue = cpu->isar.id_aa64pfr1},
7550 { .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7551 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,
7552 .access = PL1_R, .type = ARM_CP_CONST,
7553 .accessfn = access_aa64_tid3,
7554 .resetvalue = 0 },
7555 { .name = "ID_AA64PFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7556 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 3,
7557 .access = PL1_R, .type = ARM_CP_CONST,
7558 .accessfn = access_aa64_tid3,
7559 .resetvalue = 0 },
7560 { .name = "ID_AA64ZFR0_EL1", .state = ARM_CP_STATE_AA64,
7561 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4,
7562 .access = PL1_R, .type = ARM_CP_CONST,
7563 .accessfn = access_aa64_tid3,
7564
7565 .resetvalue = 0 },
7566 { .name = "ID_AA64PFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7567 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,
7568 .access = PL1_R, .type = ARM_CP_CONST,
7569 .accessfn = access_aa64_tid3,
7570 .resetvalue = 0 },
7571 { .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7572 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6,
7573 .access = PL1_R, .type = ARM_CP_CONST,
7574 .accessfn = access_aa64_tid3,
7575 .resetvalue = 0 },
7576 { .name = "ID_AA64PFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7577 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 7,
7578 .access = PL1_R, .type = ARM_CP_CONST,
7579 .accessfn = access_aa64_tid3,
7580 .resetvalue = 0 },
7581 { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64,
7582 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
7583 .access = PL1_R, .type = ARM_CP_CONST,
7584 .accessfn = access_aa64_tid3,
7585 .resetvalue = cpu->isar.id_aa64dfr0 },
7586 { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
7587 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
7588 .access = PL1_R, .type = ARM_CP_CONST,
7589 .accessfn = access_aa64_tid3,
7590 .resetvalue = cpu->isar.id_aa64dfr1 },
7591 { .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7592 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
7593 .access = PL1_R, .type = ARM_CP_CONST,
7594 .accessfn = access_aa64_tid3,
7595 .resetvalue = 0 },
7596 { .name = "ID_AA64DFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7597 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 3,
7598 .access = PL1_R, .type = ARM_CP_CONST,
7599 .accessfn = access_aa64_tid3,
7600 .resetvalue = 0 },
7601 { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64,
7602 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4,
7603 .access = PL1_R, .type = ARM_CP_CONST,
7604 .accessfn = access_aa64_tid3,
7605 .resetvalue = cpu->id_aa64afr0 },
7606 { .name = "ID_AA64AFR1_EL1", .state = ARM_CP_STATE_AA64,
7607 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5,
7608 .access = PL1_R, .type = ARM_CP_CONST,
7609 .accessfn = access_aa64_tid3,
7610 .resetvalue = cpu->id_aa64afr1 },
7611 { .name = "ID_AA64AFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7612 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 6,
7613 .access = PL1_R, .type = ARM_CP_CONST,
7614 .accessfn = access_aa64_tid3,
7615 .resetvalue = 0 },
7616 { .name = "ID_AA64AFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7617 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 7,
7618 .access = PL1_R, .type = ARM_CP_CONST,
7619 .accessfn = access_aa64_tid3,
7620 .resetvalue = 0 },
7621 { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,
7622 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
7623 .access = PL1_R, .type = ARM_CP_CONST,
7624 .accessfn = access_aa64_tid3,
7625 .resetvalue = cpu->isar.id_aa64isar0 },
7626 { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
7627 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
7628 .access = PL1_R, .type = ARM_CP_CONST,
7629 .accessfn = access_aa64_tid3,
7630 .resetvalue = cpu->isar.id_aa64isar1 },
7631 { .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7632 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
7633 .access = PL1_R, .type = ARM_CP_CONST,
7634 .accessfn = access_aa64_tid3,
7635 .resetvalue = 0 },
7636 { .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7637 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3,
7638 .access = PL1_R, .type = ARM_CP_CONST,
7639 .accessfn = access_aa64_tid3,
7640 .resetvalue = 0 },
7641 { .name = "ID_AA64ISAR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7642 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 4,
7643 .access = PL1_R, .type = ARM_CP_CONST,
7644 .accessfn = access_aa64_tid3,
7645 .resetvalue = 0 },
7646 { .name = "ID_AA64ISAR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7647 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 5,
7648 .access = PL1_R, .type = ARM_CP_CONST,
7649 .accessfn = access_aa64_tid3,
7650 .resetvalue = 0 },
7651 { .name = "ID_AA64ISAR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7652 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 6,
7653 .access = PL1_R, .type = ARM_CP_CONST,
7654 .accessfn = access_aa64_tid3,
7655 .resetvalue = 0 },
7656 { .name = "ID_AA64ISAR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7657 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 7,
7658 .access = PL1_R, .type = ARM_CP_CONST,
7659 .accessfn = access_aa64_tid3,
7660 .resetvalue = 0 },
7661 { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,
7662 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
7663 .access = PL1_R, .type = ARM_CP_CONST,
7664 .accessfn = access_aa64_tid3,
7665 .resetvalue = cpu->isar.id_aa64mmfr0 },
7666 { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
7667 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
7668 .access = PL1_R, .type = ARM_CP_CONST,
7669 .accessfn = access_aa64_tid3,
7670 .resetvalue = cpu->isar.id_aa64mmfr1 },
7671 { .name = "ID_AA64MMFR2_EL1", .state = ARM_CP_STATE_AA64,
7672 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
7673 .access = PL1_R, .type = ARM_CP_CONST,
7674 .accessfn = access_aa64_tid3,
7675 .resetvalue = cpu->isar.id_aa64mmfr2 },
7676 { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7677 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
7678 .access = PL1_R, .type = ARM_CP_CONST,
7679 .accessfn = access_aa64_tid3,
7680 .resetvalue = 0 },
7681 { .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7682 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
7683 .access = PL1_R, .type = ARM_CP_CONST,
7684 .accessfn = access_aa64_tid3,
7685 .resetvalue = 0 },
7686 { .name = "ID_AA64MMFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7687 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 5,
7688 .access = PL1_R, .type = ARM_CP_CONST,
7689 .accessfn = access_aa64_tid3,
7690 .resetvalue = 0 },
7691 { .name = "ID_AA64MMFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7692 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 6,
7693 .access = PL1_R, .type = ARM_CP_CONST,
7694 .accessfn = access_aa64_tid3,
7695 .resetvalue = 0 },
7696 { .name = "ID_AA64MMFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7697 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 7,
7698 .access = PL1_R, .type = ARM_CP_CONST,
7699 .accessfn = access_aa64_tid3,
7700 .resetvalue = 0 },
7701 { .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64,
7702 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0,
7703 .access = PL1_R, .type = ARM_CP_CONST,
7704 .accessfn = access_aa64_tid3,
7705 .resetvalue = cpu->isar.mvfr0 },
7706 { .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64,
7707 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1,
7708 .access = PL1_R, .type = ARM_CP_CONST,
7709 .accessfn = access_aa64_tid3,
7710 .resetvalue = cpu->isar.mvfr1 },
7711 { .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64,
7712 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
7713 .access = PL1_R, .type = ARM_CP_CONST,
7714 .accessfn = access_aa64_tid3,
7715 .resetvalue = cpu->isar.mvfr2 },
7716 { .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7717 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3,
7718 .access = PL1_R, .type = ARM_CP_CONST,
7719 .accessfn = access_aa64_tid3,
7720 .resetvalue = 0 },
7721 { .name = "ID_PFR2", .state = ARM_CP_STATE_BOTH,
7722 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
7723 .access = PL1_R, .type = ARM_CP_CONST,
7724 .accessfn = access_aa64_tid3,
7725 .resetvalue = cpu->isar.id_pfr2 },
7726 { .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7727 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
7728 .access = PL1_R, .type = ARM_CP_CONST,
7729 .accessfn = access_aa64_tid3,
7730 .resetvalue = 0 },
7731 { .name = "MVFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7732 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
7733 .access = PL1_R, .type = ARM_CP_CONST,
7734 .accessfn = access_aa64_tid3,
7735 .resetvalue = 0 },
7736 { .name = "MVFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
7737 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,
7738 .access = PL1_R, .type = ARM_CP_CONST,
7739 .accessfn = access_aa64_tid3,
7740 .resetvalue = 0 },
7741 { .name = "PMCEID0", .state = ARM_CP_STATE_AA32,
7742 .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6,
7743 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
7744 .resetvalue = extract64(cpu->pmceid0, 0, 32) },
7745 { .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64,
7746 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6,
7747 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
7748 .resetvalue = cpu->pmceid0 },
7749 { .name = "PMCEID1", .state = ARM_CP_STATE_AA32,
7750 .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 7,
7751 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
7752 .resetvalue = extract64(cpu->pmceid1, 0, 32) },
7753 { .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64,
7754 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,
7755 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
7756 .resetvalue = cpu->pmceid1 },
7757 REGINFO_SENTINEL
7758 };
7759#ifdef CONFIG_USER_ONLY
7760 ARMCPRegUserSpaceInfo v8_user_idregs[] = {
7761 { .name = "ID_AA64PFR0_EL1",
7762 .exported_bits = 0x000f000f00ff0000,
7763 .fixed_bits = 0x0000000000000011 },
7764 { .name = "ID_AA64PFR1_EL1",
7765 .exported_bits = 0x00000000000000f0 },
7766 { .name = "ID_AA64PFR*_EL1_RESERVED",
7767 .is_glob = true },
7768 { .name = "ID_AA64ZFR0_EL1" },
7769 { .name = "ID_AA64MMFR0_EL1",
7770 .fixed_bits = 0x00000000ff000000 },
7771 { .name = "ID_AA64MMFR1_EL1" },
7772 { .name = "ID_AA64MMFR*_EL1_RESERVED",
7773 .is_glob = true },
7774 { .name = "ID_AA64DFR0_EL1",
7775 .fixed_bits = 0x0000000000000006 },
7776 { .name = "ID_AA64DFR1_EL1" },
7777 { .name = "ID_AA64DFR*_EL1_RESERVED",
7778 .is_glob = true },
7779 { .name = "ID_AA64AFR*",
7780 .is_glob = true },
7781 { .name = "ID_AA64ISAR0_EL1",
7782 .exported_bits = 0x00fffffff0fffff0 },
7783 { .name = "ID_AA64ISAR1_EL1",
7784 .exported_bits = 0x000000f0ffffffff },
7785 { .name = "ID_AA64ISAR*_EL1_RESERVED",
7786 .is_glob = true },
7787 REGUSERINFO_SENTINEL
7788 };
7789 modify_arm_cp_regs(v8_idregs, v8_user_idregs);
7790#endif
7791
7792 if (!arm_feature(env, ARM_FEATURE_EL3) &&
7793 !arm_feature(env, ARM_FEATURE_EL2)) {
7794 ARMCPRegInfo rvbar = {
7795 .name = "RVBAR_EL1", .state = ARM_CP_STATE_AA64,
7796 .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
7797 .type = ARM_CP_CONST, .access = PL1_R, .resetvalue = cpu->rvbar
7798 };
7799 define_one_arm_cp_reg(cpu, &rvbar);
7800 }
7801 define_arm_cp_regs(cpu, v8_idregs);
7802 define_arm_cp_regs(cpu, v8_cp_reginfo);
7803 }
7804 if (arm_feature(env, ARM_FEATURE_EL2)) {
7805 uint64_t vmpidr_def = mpidr_read_val(env);
7806 ARMCPRegInfo vpidr_regs[] = {
7807 { .name = "VPIDR", .state = ARM_CP_STATE_AA32,
7808 .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
7809 .access = PL2_RW, .accessfn = access_el3_aa32ns,
7810 .resetvalue = cpu->midr, .type = ARM_CP_ALIAS,
7811 .fieldoffset = offsetoflow32(CPUARMState, cp15.vpidr_el2) },
7812 { .name = "VPIDR_EL2", .state = ARM_CP_STATE_AA64,
7813 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
7814 .access = PL2_RW, .resetvalue = cpu->midr,
7815 .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
7816 { .name = "VMPIDR", .state = ARM_CP_STATE_AA32,
7817 .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
7818 .access = PL2_RW, .accessfn = access_el3_aa32ns,
7819 .resetvalue = vmpidr_def, .type = ARM_CP_ALIAS,
7820 .fieldoffset = offsetoflow32(CPUARMState, cp15.vmpidr_el2) },
7821 { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_AA64,
7822 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
7823 .access = PL2_RW,
7824 .resetvalue = vmpidr_def,
7825 .fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
7826 REGINFO_SENTINEL
7827 };
7828 define_arm_cp_regs(cpu, vpidr_regs);
7829 define_arm_cp_regs(cpu, el2_cp_reginfo);
7830 if (arm_feature(env, ARM_FEATURE_V8)) {
7831 define_arm_cp_regs(cpu, el2_v8_cp_reginfo);
7832 }
7833 if (cpu_isar_feature(aa64_sel2, cpu)) {
7834 define_arm_cp_regs(cpu, el2_sec_cp_reginfo);
7835 }
7836
7837 if (!arm_feature(env, ARM_FEATURE_EL3)) {
7838 ARMCPRegInfo rvbar = {
7839 .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
7840 .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
7841 .type = ARM_CP_CONST, .access = PL2_R, .resetvalue = cpu->rvbar
7842 };
7843 define_one_arm_cp_reg(cpu, &rvbar);
7844 }
7845 } else {
7846
7847
7848
7849 if (arm_feature(env, ARM_FEATURE_EL3)) {
7850
7851
7852
7853 ARMCPRegInfo vpidr_regs[] = {
7854 { .name = "VPIDR_EL2", .state = ARM_CP_STATE_BOTH,
7855 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
7856 .access = PL2_RW, .accessfn = access_el3_aa32ns,
7857 .type = ARM_CP_CONST, .resetvalue = cpu->midr,
7858 .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
7859 { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_BOTH,
7860 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
7861 .access = PL2_RW, .accessfn = access_el3_aa32ns,
7862 .type = ARM_CP_NO_RAW,
7863 .writefn = arm_cp_write_ignore, .readfn = mpidr_read },
7864 REGINFO_SENTINEL
7865 };
7866 define_arm_cp_regs(cpu, vpidr_regs);
7867 define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);
7868 if (arm_feature(env, ARM_FEATURE_V8)) {
7869 define_arm_cp_regs(cpu, el3_no_el2_v8_cp_reginfo);
7870 }
7871 }
7872 }
7873 if (arm_feature(env, ARM_FEATURE_EL3)) {
7874 define_arm_cp_regs(cpu, el3_cp_reginfo);
7875 ARMCPRegInfo el3_regs[] = {
7876 { .name = "RVBAR_EL3", .state = ARM_CP_STATE_AA64,
7877 .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 1,
7878 .type = ARM_CP_CONST, .access = PL3_R, .resetvalue = cpu->rvbar },
7879 { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64,
7880 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 0,
7881 .access = PL3_RW,
7882 .raw_writefn = raw_write, .writefn = sctlr_write,
7883 .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]),
7884 .resetvalue = cpu->reset_sctlr },
7885 REGINFO_SENTINEL
7886 };
7887
7888 define_arm_cp_regs(cpu, el3_regs);
7889 }
7890
7891
7892
7893
7894
7895
7896
7897
7898 if (arm_feature(env, ARM_FEATURE_EL3)) {
7899 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
7900 ARMCPRegInfo nsacr = {
7901 .name = "NSACR", .type = ARM_CP_CONST,
7902 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
7903 .access = PL1_RW, .accessfn = nsacr_access,
7904 .resetvalue = 0xc00
7905 };
7906 define_one_arm_cp_reg(cpu, &nsacr);
7907 } else {
7908 ARMCPRegInfo nsacr = {
7909 .name = "NSACR",
7910 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
7911 .access = PL3_RW | PL1_R,
7912 .resetvalue = 0,
7913 .fieldoffset = offsetof(CPUARMState, cp15.nsacr)
7914 };
7915 define_one_arm_cp_reg(cpu, &nsacr);
7916 }
7917 } else {
7918 if (arm_feature(env, ARM_FEATURE_V8)) {
7919 ARMCPRegInfo nsacr = {
7920 .name = "NSACR", .type = ARM_CP_CONST,
7921 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
7922 .access = PL1_R,
7923 .resetvalue = 0xc00
7924 };
7925 define_one_arm_cp_reg(cpu, &nsacr);
7926 }
7927 }
7928
7929 if (arm_feature(env, ARM_FEATURE_PMSA)) {
7930 if (arm_feature(env, ARM_FEATURE_V6)) {
7931
7932 assert(arm_feature(env, ARM_FEATURE_V7));
7933 define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
7934 define_arm_cp_regs(cpu, pmsav7_cp_reginfo);
7935 } else {
7936 define_arm_cp_regs(cpu, pmsav5_cp_reginfo);
7937 }
7938 } else {
7939 define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
7940 define_arm_cp_regs(cpu, vmsa_cp_reginfo);
7941
7942 if (cpu_isar_feature(aa32_hpd, cpu)) {
7943 define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
7944 }
7945 }
7946 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
7947 define_arm_cp_regs(cpu, t2ee_cp_reginfo);
7948 }
7949 if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
7950 define_arm_cp_regs(cpu, generic_timer_cp_reginfo);
7951 }
7952 if (arm_feature(env, ARM_FEATURE_VAPA)) {
7953 define_arm_cp_regs(cpu, vapa_cp_reginfo);
7954 }
7955 if (arm_feature(env, ARM_FEATURE_CACHE_TEST_CLEAN)) {
7956 define_arm_cp_regs(cpu, cache_test_clean_cp_reginfo);
7957 }
7958 if (arm_feature(env, ARM_FEATURE_CACHE_DIRTY_REG)) {
7959 define_arm_cp_regs(cpu, cache_dirty_status_cp_reginfo);
7960 }
7961 if (arm_feature(env, ARM_FEATURE_CACHE_BLOCK_OPS)) {
7962 define_arm_cp_regs(cpu, cache_block_ops_cp_reginfo);
7963 }
7964 if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
7965 define_arm_cp_regs(cpu, omap_cp_reginfo);
7966 }
7967 if (arm_feature(env, ARM_FEATURE_STRONGARM)) {
7968 define_arm_cp_regs(cpu, strongarm_cp_reginfo);
7969 }
7970 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
7971 define_arm_cp_regs(cpu, xscale_cp_reginfo);
7972 }
7973 if (arm_feature(env, ARM_FEATURE_DUMMY_C15_REGS)) {
7974 define_arm_cp_regs(cpu, dummy_c15_cp_reginfo);
7975 }
7976 if (arm_feature(env, ARM_FEATURE_LPAE)) {
7977 define_arm_cp_regs(cpu, lpae_cp_reginfo);
7978 }
7979 if (cpu_isar_feature(aa32_jazelle, cpu)) {
7980 define_arm_cp_regs(cpu, jazelle_regs);
7981 }
7982
7983
7984
7985
7986 {
7987 ARMCPRegInfo id_pre_v8_midr_cp_reginfo[] = {
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997 { .name = "MIDR",
7998 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = CP_ANY,
7999 .access = PL1_R, .resetvalue = cpu->midr,
8000 .writefn = arm_cp_write_ignore, .raw_writefn = raw_write,
8001 .readfn = midr_read,
8002 .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
8003 .type = ARM_CP_OVERRIDE },
8004
8005 { .name = "DUMMY",
8006 .cp = 15, .crn = 0, .crm = 3, .opc1 = 0, .opc2 = CP_ANY,
8007 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
8008 { .name = "DUMMY",
8009 .cp = 15, .crn = 0, .crm = 4, .opc1 = 0, .opc2 = CP_ANY,
8010 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
8011 { .name = "DUMMY",
8012 .cp = 15, .crn = 0, .crm = 5, .opc1 = 0, .opc2 = CP_ANY,
8013 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
8014 { .name = "DUMMY",
8015 .cp = 15, .crn = 0, .crm = 6, .opc1 = 0, .opc2 = CP_ANY,
8016 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
8017 { .name = "DUMMY",
8018 .cp = 15, .crn = 0, .crm = 7, .opc1 = 0, .opc2 = CP_ANY,
8019 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
8020 REGINFO_SENTINEL
8021 };
8022 ARMCPRegInfo id_v8_midr_cp_reginfo[] = {
8023 { .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH,
8024 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 0,
8025 .access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr,
8026 .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
8027 .readfn = midr_read },
8028
8029 { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
8030 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
8031 .access = PL1_R, .resetvalue = cpu->midr },
8032 { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
8033 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7,
8034 .access = PL1_R, .resetvalue = cpu->midr },
8035 { .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,
8036 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
8037 .access = PL1_R,
8038 .accessfn = access_aa64_tid1,
8039 .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
8040 REGINFO_SENTINEL
8041 };
8042 ARMCPRegInfo id_cp_reginfo[] = {
8043
8044 { .name = "CTR",
8045 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
8046 .access = PL1_R, .accessfn = ctr_el0_access,
8047 .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
8048 { .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
8049 .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
8050 .access = PL0_R, .accessfn = ctr_el0_access,
8051 .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
8052
8053 { .name = "TCMTR",
8054 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2,
8055 .access = PL1_R,
8056 .accessfn = access_aa32_tid1,
8057 .type = ARM_CP_CONST, .resetvalue = 0 },
8058 REGINFO_SENTINEL
8059 };
8060
8061 ARMCPRegInfo id_tlbtr_reginfo = {
8062 .name = "TLBTR",
8063 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3,
8064 .access = PL1_R,
8065 .accessfn = access_aa32_tid1,
8066 .type = ARM_CP_CONST, .resetvalue = 0,
8067 };
8068
8069 ARMCPRegInfo id_mpuir_reginfo = {
8070 .name = "MPUIR",
8071 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
8072 .access = PL1_R, .type = ARM_CP_CONST,
8073 .resetvalue = cpu->pmsav7_dregion << 8
8074 };
8075 ARMCPRegInfo crn0_wi_reginfo = {
8076 .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
8077 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
8078 .type = ARM_CP_NOP | ARM_CP_OVERRIDE
8079 };
8080#ifdef CONFIG_USER_ONLY
8081 ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
8082 { .name = "MIDR_EL1",
8083 .exported_bits = 0x00000000ffffffff },
8084 { .name = "REVIDR_EL1" },
8085 REGUSERINFO_SENTINEL
8086 };
8087 modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo);
8088#endif
8089 if (arm_feature(env, ARM_FEATURE_OMAPCP) ||
8090 arm_feature(env, ARM_FEATURE_STRONGARM)) {
8091 ARMCPRegInfo *r;
8092
8093
8094
8095
8096
8097 define_one_arm_cp_reg(cpu, &crn0_wi_reginfo);
8098 for (r = id_pre_v8_midr_cp_reginfo;
8099 r->type != ARM_CP_SENTINEL; r++) {
8100 r->access = PL1_RW;
8101 }
8102 for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) {
8103 r->access = PL1_RW;
8104 }
8105 id_mpuir_reginfo.access = PL1_RW;
8106 id_tlbtr_reginfo.access = PL1_RW;
8107 }
8108 if (arm_feature(env, ARM_FEATURE_V8)) {
8109 define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo);
8110 } else {
8111 define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo);
8112 }
8113 define_arm_cp_regs(cpu, id_cp_reginfo);
8114 if (!arm_feature(env, ARM_FEATURE_PMSA)) {
8115 define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);
8116 } else if (arm_feature(env, ARM_FEATURE_V7)) {
8117 define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
8118 }
8119 }
8120
8121 if (arm_feature(env, ARM_FEATURE_MPIDR)) {
8122 ARMCPRegInfo mpidr_cp_reginfo[] = {
8123 { .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH,
8124 .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
8125 .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
8126 REGINFO_SENTINEL
8127 };
8128#ifdef CONFIG_USER_ONLY
8129 ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
8130 { .name = "MPIDR_EL1",
8131 .fixed_bits = 0x0000000080000000 },
8132 REGUSERINFO_SENTINEL
8133 };
8134 modify_arm_cp_regs(mpidr_cp_reginfo, mpidr_user_cp_reginfo);
8135#endif
8136 define_arm_cp_regs(cpu, mpidr_cp_reginfo);
8137 }
8138
8139 if (arm_feature(env, ARM_FEATURE_AUXCR)) {
8140 ARMCPRegInfo auxcr_reginfo[] = {
8141 { .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH,
8142 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1,
8143 .access = PL1_RW, .accessfn = access_tacr,
8144 .type = ARM_CP_CONST, .resetvalue = cpu->reset_auxcr },
8145 { .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH,
8146 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1,
8147 .access = PL2_RW, .type = ARM_CP_CONST,
8148 .resetvalue = 0 },
8149 { .name = "ACTLR_EL3", .state = ARM_CP_STATE_AA64,
8150 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 1,
8151 .access = PL3_RW, .type = ARM_CP_CONST,
8152 .resetvalue = 0 },
8153 REGINFO_SENTINEL
8154 };
8155 define_arm_cp_regs(cpu, auxcr_reginfo);
8156 if (cpu_isar_feature(aa32_ac2, cpu)) {
8157 define_arm_cp_regs(cpu, actlr2_hactlr2_reginfo);
8158 }
8159 }
8160
8161 if (arm_feature(env, ARM_FEATURE_CBAR)) {
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
8176
8177 uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
8178 | extract64(cpu->reset_cbar, 32, 12);
8179 ARMCPRegInfo cbar_reginfo[] = {
8180 { .name = "CBAR",
8181 .type = ARM_CP_CONST,
8182 .cp = 15, .crn = 15, .crm = 3, .opc1 = 1, .opc2 = 0,
8183 .access = PL1_R, .resetvalue = cbar32 },
8184 { .name = "CBAR_EL1", .state = ARM_CP_STATE_AA64,
8185 .type = ARM_CP_CONST,
8186 .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 0,
8187 .access = PL1_R, .resetvalue = cpu->reset_cbar },
8188 REGINFO_SENTINEL
8189 };
8190
8191 assert(arm_feature(env, ARM_FEATURE_CBAR_RO));
8192 define_arm_cp_regs(cpu, cbar_reginfo);
8193 } else {
8194 ARMCPRegInfo cbar = {
8195 .name = "CBAR",
8196 .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0,
8197 .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar,
8198 .fieldoffset = offsetof(CPUARMState,
8199 cp15.c15_config_base_address)
8200 };
8201 if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
8202 cbar.access = PL1_R;
8203 cbar.fieldoffset = 0;
8204 cbar.type = ARM_CP_CONST;
8205 }
8206 define_one_arm_cp_reg(cpu, &cbar);
8207 }
8208 }
8209
8210 if (arm_feature(env, ARM_FEATURE_VBAR)) {
8211 ARMCPRegInfo vbar_cp_reginfo[] = {
8212 { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
8213 .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
8214 .access = PL1_RW, .writefn = vbar_write,
8215 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
8216 offsetof(CPUARMState, cp15.vbar_ns) },
8217 .resetvalue = 0 },
8218 REGINFO_SENTINEL
8219 };
8220 define_arm_cp_regs(cpu, vbar_cp_reginfo);
8221 }
8222
8223
8224 {
8225 ARMCPRegInfo sctlr = {
8226 .name = "SCTLR", .state = ARM_CP_STATE_BOTH,
8227 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
8228 .access = PL1_RW, .accessfn = access_tvm_trvm,
8229 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
8230 offsetof(CPUARMState, cp15.sctlr_ns) },
8231 .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
8232 .raw_writefn = raw_write,
8233 };
8234 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
8235
8236
8237
8238
8239 sctlr.type |= ARM_CP_SUPPRESS_TB_END;
8240 }
8241 define_one_arm_cp_reg(cpu, &sctlr);
8242 }
8243
8244 if (cpu_isar_feature(aa64_lor, cpu)) {
8245 define_arm_cp_regs(cpu, lor_reginfo);
8246 }
8247 if (cpu_isar_feature(aa64_pan, cpu)) {
8248 define_one_arm_cp_reg(cpu, &pan_reginfo);
8249 }
8250#ifndef CONFIG_USER_ONLY
8251 if (cpu_isar_feature(aa64_ats1e1, cpu)) {
8252 define_arm_cp_regs(cpu, ats1e1_reginfo);
8253 }
8254 if (cpu_isar_feature(aa32_ats1e1, cpu)) {
8255 define_arm_cp_regs(cpu, ats1cp_reginfo);
8256 }
8257#endif
8258 if (cpu_isar_feature(aa64_uao, cpu)) {
8259 define_one_arm_cp_reg(cpu, &uao_reginfo);
8260 }
8261
8262 if (cpu_isar_feature(aa64_dit, cpu)) {
8263 define_one_arm_cp_reg(cpu, &dit_reginfo);
8264 }
8265 if (cpu_isar_feature(aa64_ssbs, cpu)) {
8266 define_one_arm_cp_reg(cpu, &ssbs_reginfo);
8267 }
8268
8269 if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
8270 define_arm_cp_regs(cpu, vhe_reginfo);
8271 }
8272
8273 if (cpu_isar_feature(aa64_sve, cpu)) {
8274 define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
8275 if (arm_feature(env, ARM_FEATURE_EL2)) {
8276 define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
8277 } else {
8278 define_one_arm_cp_reg(cpu, &zcr_no_el2_reginfo);
8279 }
8280 if (arm_feature(env, ARM_FEATURE_EL3)) {
8281 define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
8282 }
8283 }
8284
8285#ifdef TARGET_AARCH64
8286 if (cpu_isar_feature(aa64_pauth, cpu)) {
8287 define_arm_cp_regs(cpu, pauth_reginfo);
8288 }
8289 if (cpu_isar_feature(aa64_rndr, cpu)) {
8290 define_arm_cp_regs(cpu, rndr_reginfo);
8291 }
8292#ifndef CONFIG_USER_ONLY
8293
8294 if (cpu_isar_feature(aa64_dcpop, cpu)) {
8295 define_one_arm_cp_reg(cpu, dcpop_reg);
8296
8297 if (cpu_isar_feature(aa64_dcpodp, cpu)) {
8298 define_one_arm_cp_reg(cpu, dcpodp_reg);
8299 }
8300 }
8301#endif
8302
8303
8304
8305
8306
8307
8308 if (cpu_isar_feature(aa64_mte, cpu)) {
8309 define_arm_cp_regs(cpu, mte_reginfo);
8310 define_arm_cp_regs(cpu, mte_el0_cacheop_reginfo);
8311 } else if (cpu_isar_feature(aa64_mte_insn_reg, cpu)) {
8312 define_arm_cp_regs(cpu, mte_tco_ro_reginfo);
8313 define_arm_cp_regs(cpu, mte_el0_cacheop_reginfo);
8314 }
8315#endif
8316
8317 if (cpu_isar_feature(any_predinv, cpu)) {
8318 define_arm_cp_regs(cpu, predinv_reginfo);
8319 }
8320
8321 if (cpu_isar_feature(any_ccidx, cpu)) {
8322 define_arm_cp_regs(cpu, ccsidr2_reginfo);
8323 }
8324
8325#ifndef CONFIG_USER_ONLY
8326
8327
8328
8329
8330 if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
8331 define_arm_vh_e2h_redirects_aliases(cpu);
8332 }
8333#endif
8334}
8335
8336void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
8337{
8338 CPUState *cs = CPU(cpu);
8339 CPUARMState *env = &cpu->env;
8340
8341 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
8342
8343
8344
8345
8346#ifdef TARGET_AARCH64
8347 if (isar_feature_aa64_sve(&cpu->isar)) {
8348 gdb_register_coprocessor(cs, arm_gdb_get_svereg, arm_gdb_set_svereg,
8349 arm_gen_dynamic_svereg_xml(cs, cs->gdb_num_regs),
8350 "sve-registers.xml", 0);
8351 } else
8352#endif
8353 {
8354 gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg,
8355 aarch64_fpu_gdb_set_reg,
8356 34, "aarch64-fpu.xml", 0);
8357 }
8358 } else if (arm_feature(env, ARM_FEATURE_NEON)) {
8359 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
8360 51, "arm-neon.xml", 0);
8361 } else if (cpu_isar_feature(aa32_simd_r32, cpu)) {
8362 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
8363 35, "arm-vfp3.xml", 0);
8364 } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
8365 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
8366 19, "arm-vfp.xml", 0);
8367 }
8368 gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
8369 arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
8370 "system-registers.xml", 0);
8371
8372}
8373
8374
8375static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b)
8376{
8377 ObjectClass *class_a = (ObjectClass *)a;
8378 ObjectClass *class_b = (ObjectClass *)b;
8379 const char *name_a, *name_b;
8380
8381 name_a = object_class_get_name(class_a);
8382 name_b = object_class_get_name(class_b);
8383 if (strcmp(name_a, "any-" TYPE_ARM_CPU) == 0) {
8384 return 1;
8385 } else if (strcmp(name_b, "any-" TYPE_ARM_CPU) == 0) {
8386 return -1;
8387 } else {
8388 return strcmp(name_a, name_b);
8389 }
8390}
8391
8392static void arm_cpu_list_entry(gpointer data, gpointer user_data)
8393{
8394 ObjectClass *oc = data;
8395 const char *typename;
8396 char *name;
8397
8398 typename = object_class_get_name(oc);
8399 name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_ARM_CPU));
8400 qemu_printf(" %s\n", name);
8401 g_free(name);
8402}
8403
8404void arm_cpu_list(void)
8405{
8406 GSList *list;
8407
8408 list = object_class_get_list(TYPE_ARM_CPU, false);
8409 list = g_slist_sort(list, arm_cpu_list_compare);
8410 qemu_printf("Available CPUs:\n");
8411 g_slist_foreach(list, arm_cpu_list_entry, NULL);
8412 g_slist_free(list);
8413}
8414
8415static void arm_cpu_add_definition(gpointer data, gpointer user_data)
8416{
8417 ObjectClass *oc = data;
8418 CpuDefinitionInfoList **cpu_list = user_data;
8419 CpuDefinitionInfo *info;
8420 const char *typename;
8421
8422 typename = object_class_get_name(oc);
8423 info = g_malloc0(sizeof(*info));
8424 info->name = g_strndup(typename,
8425 strlen(typename) - strlen("-" TYPE_ARM_CPU));
8426 info->q_typename = g_strdup(typename);
8427
8428 QAPI_LIST_PREPEND(*cpu_list, info);
8429}
8430
8431CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
8432{
8433 CpuDefinitionInfoList *cpu_list = NULL;
8434 GSList *list;
8435
8436 list = object_class_get_list(TYPE_ARM_CPU, false);
8437 g_slist_foreach(list, arm_cpu_add_definition, &cpu_list);
8438 g_slist_free(list);
8439
8440 return cpu_list;
8441}
8442
8443static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
8444 void *opaque, int state, int secstate,
8445 int crm, int opc1, int opc2,
8446 const char *name)
8447{
8448
8449
8450
8451 uint32_t *key = g_new(uint32_t, 1);
8452 ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
8453 int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
8454 int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
8455
8456 r2->name = g_strdup(name);
8457
8458
8459
8460 r2->secure = secstate;
8461
8462 if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
8463
8464
8465
8466
8467 r2->fieldoffset = r->bank_fieldoffsets[ns];
8468 }
8469
8470 if (state == ARM_CP_STATE_AA32) {
8471 if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482 if ((r->state == ARM_CP_STATE_BOTH && ns) ||
8483 (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
8484 r2->type |= ARM_CP_ALIAS;
8485 }
8486 } else if ((secstate != r->secure) && !ns) {
8487
8488
8489
8490 r2->type |= ARM_CP_ALIAS;
8491 }
8492
8493 if (r->state == ARM_CP_STATE_BOTH) {
8494
8495
8496 if (r2->cp == 0) {
8497 r2->cp = 15;
8498 }
8499
8500#ifdef HOST_WORDS_BIGENDIAN
8501 if (r2->fieldoffset) {
8502 r2->fieldoffset += sizeof(uint32_t);
8503 }
8504#endif
8505 }
8506 }
8507 if (state == ARM_CP_STATE_AA64) {
8508
8509
8510
8511
8512
8513
8514
8515 if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
8516 r2->cp = CP_REG_ARM64_SYSREG_CP;
8517 }
8518 *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
8519 r2->opc0, opc1, opc2);
8520 } else {
8521 *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
8522 }
8523 if (opaque) {
8524 r2->opaque = opaque;
8525 }
8526
8527
8528
8529 r2->state = state;
8530
8531
8532
8533 r2->crm = crm;
8534 r2->opc1 = opc1;
8535 r2->opc2 = opc2;
8536
8537
8538
8539
8540
8541
8542 if ((r->type & ARM_CP_SPECIAL)) {
8543 r2->type |= ARM_CP_NO_RAW;
8544 }
8545 if (((r->crm == CP_ANY) && crm != 0) ||
8546 ((r->opc1 == CP_ANY) && opc1 != 0) ||
8547 ((r->opc2 == CP_ANY) && opc2 != 0)) {
8548 r2->type |= ARM_CP_ALIAS | ARM_CP_NO_GDB;
8549 }
8550
8551
8552
8553
8554
8555 if (!(r2->type & ARM_CP_NO_RAW)) {
8556 assert(!raw_accessors_invalid(r2));
8557 }
8558
8559
8560
8561
8562 if (!(r->type & ARM_CP_OVERRIDE)) {
8563 ARMCPRegInfo *oldreg;
8564 oldreg = g_hash_table_lookup(cpu->cp_regs, key);
8565 if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
8566 fprintf(stderr, "Register redefined: cp=%d %d bit "
8567 "crn=%d crm=%d opc1=%d opc2=%d, "
8568 "was %s, now %s\n", r2->cp, 32 + 32 * is64,
8569 r2->crn, r2->crm, r2->opc1, r2->opc2,
8570 oldreg->name, r2->name);
8571 g_assert_not_reached();
8572 }
8573 }
8574 g_hash_table_insert(cpu->cp_regs, key, r2);
8575}
8576
8577
8578void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
8579 const ARMCPRegInfo *r, void *opaque)
8580{
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604 int crm, opc1, opc2, state;
8605 int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
8606 int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
8607 int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
8608 int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
8609 int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
8610 int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
8611
8612 assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
8613
8614 assert((r->state != ARM_CP_STATE_AA32) || (r->opc0 == 0));
8615
8616 assert((r->state != ARM_CP_STATE_AA64) || !(r->type & ARM_CP_64BIT));
8617
8618
8619
8620
8621
8622
8623
8624
8625 switch (r->state) {
8626 case ARM_CP_STATE_BOTH:
8627
8628 if (r->cp == 0) {
8629 break;
8630 }
8631
8632 case ARM_CP_STATE_AA32:
8633 if (arm_feature(&cpu->env, ARM_FEATURE_V8) &&
8634 !arm_feature(&cpu->env, ARM_FEATURE_M)) {
8635 assert(r->cp >= 14 && r->cp <= 15);
8636 } else {
8637 assert(r->cp < 8 || (r->cp >= 14 && r->cp <= 15));
8638 }
8639 break;
8640 case ARM_CP_STATE_AA64:
8641 assert(r->cp == 0 || r->cp == CP_REG_ARM64_SYSREG_CP);
8642 break;
8643 default:
8644 g_assert_not_reached();
8645 }
8646
8647
8648
8649
8650
8651
8652 if (r->state != ARM_CP_STATE_AA32) {
8653 int mask = 0;
8654 switch (r->opc1) {
8655 case 0:
8656
8657 mask = PL0U_R | PL1_RW;
8658 break;
8659 case 1: case 2:
8660
8661 mask = PL1_RW;
8662 break;
8663 case 3:
8664
8665 mask = PL0_RW;
8666 break;
8667 case 4:
8668 case 5:
8669
8670 mask = PL2_RW;
8671 break;
8672 case 6:
8673
8674 mask = PL3_RW;
8675 break;
8676 case 7:
8677
8678 mask = PL1_RW;
8679 break;
8680 default:
8681
8682 assert(false);
8683 break;
8684 }
8685
8686 assert((r->access & ~mask) == 0);
8687 }
8688
8689
8690
8691
8692 if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
8693 if (r->access & PL3_R) {
8694 assert((r->fieldoffset ||
8695 (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
8696 r->readfn);
8697 }
8698 if (r->access & PL3_W) {
8699 assert((r->fieldoffset ||
8700 (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
8701 r->writefn);
8702 }
8703 }
8704
8705 assert(cptype_valid(r->type));
8706 for (crm = crmmin; crm <= crmmax; crm++) {
8707 for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
8708 for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
8709 for (state = ARM_CP_STATE_AA32;
8710 state <= ARM_CP_STATE_AA64; state++) {
8711 if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
8712 continue;
8713 }
8714 if (state == ARM_CP_STATE_AA32) {
8715
8716
8717
8718 char *name;
8719
8720 switch (r->secure) {
8721 case ARM_CP_SECSTATE_S:
8722 case ARM_CP_SECSTATE_NS:
8723 add_cpreg_to_hashtable(cpu, r, opaque, state,
8724 r->secure, crm, opc1, opc2,
8725 r->name);
8726 break;
8727 default:
8728 name = g_strdup_printf("%s_S", r->name);
8729 add_cpreg_to_hashtable(cpu, r, opaque, state,
8730 ARM_CP_SECSTATE_S,
8731 crm, opc1, opc2, name);
8732 g_free(name);
8733 add_cpreg_to_hashtable(cpu, r, opaque, state,
8734 ARM_CP_SECSTATE_NS,
8735 crm, opc1, opc2, r->name);
8736 break;
8737 }
8738 } else {
8739
8740
8741 add_cpreg_to_hashtable(cpu, r, opaque, state,
8742 ARM_CP_SECSTATE_NS,
8743 crm, opc1, opc2, r->name);
8744 }
8745 }
8746 }
8747 }
8748 }
8749}
8750
8751void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
8752 const ARMCPRegInfo *regs, void *opaque)
8753{
8754
8755 const ARMCPRegInfo *r;
8756 for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
8757 define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
8758 }
8759}
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
8770{
8771 const ARMCPRegUserSpaceInfo *m;
8772 ARMCPRegInfo *r;
8773
8774 for (m = mods; m->name; m++) {
8775 GPatternSpec *pat = NULL;
8776 if (m->is_glob) {
8777 pat = g_pattern_spec_new(m->name);
8778 }
8779 for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
8780 if (pat && g_pattern_match_string(pat, r->name)) {
8781 r->type = ARM_CP_CONST;
8782 r->access = PL0U_R;
8783 r->resetvalue = 0;
8784
8785 } else if (strcmp(r->name, m->name) == 0) {
8786 r->type = ARM_CP_CONST;
8787 r->access = PL0U_R;
8788 r->resetvalue &= m->exported_bits;
8789 r->resetvalue |= m->fixed_bits;
8790 break;
8791 }
8792 }
8793 if (pat) {
8794 g_pattern_spec_free(pat);
8795 }
8796 }
8797}
8798
8799const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
8800{
8801 return g_hash_table_lookup(cpregs, &encoded_cp);
8802}
8803
8804void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
8805 uint64_t value)
8806{
8807
8808}
8809
8810uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
8811{
8812
8813 return 0;
8814}
8815
8816void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
8817{
8818
8819}
8820
8821static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
8822{
8823
8824
8825
8826
8827
8828
8829 if (write_type == CPSRWriteByInstr &&
8830 ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_HYP ||
8831 mode == ARM_CPU_MODE_HYP)) {
8832 return 1;
8833 }
8834
8835 switch (mode) {
8836 case ARM_CPU_MODE_USR:
8837 return 0;
8838 case ARM_CPU_MODE_SYS:
8839 case ARM_CPU_MODE_SVC:
8840 case ARM_CPU_MODE_ABT:
8841 case ARM_CPU_MODE_UND:
8842 case ARM_CPU_MODE_IRQ:
8843 case ARM_CPU_MODE_FIQ:
8844
8845
8846
8847
8848
8849
8850 if (write_type == CPSRWriteByInstr &&
8851 (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON &&
8852 (arm_hcr_el2_eff(env) & HCR_TGE)) {
8853 return 1;
8854 }
8855 return 0;
8856 case ARM_CPU_MODE_HYP:
8857 return !arm_is_el2_enabled(env) || arm_current_el(env) < 2;
8858 case ARM_CPU_MODE_MON:
8859 return arm_current_el(env) < 3;
8860 default:
8861 return 1;
8862 }
8863}
8864
8865uint32_t cpsr_read(CPUARMState *env)
8866{
8867 int ZF;
8868 ZF = (env->ZF == 0);
8869 return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) |
8870 (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
8871 | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
8872 | ((env->condexec_bits & 0xfc) << 8)
8873 | (env->GE << 16) | (env->daif & CPSR_AIF);
8874}
8875
8876void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
8877 CPSRWriteType write_type)
8878{
8879 uint32_t changed_daif;
8880
8881 if (mask & CPSR_NZCV) {
8882 env->ZF = (~val) & CPSR_Z;
8883 env->NF = val;
8884 env->CF = (val >> 29) & 1;
8885 env->VF = (val << 3) & 0x80000000;
8886 }
8887 if (mask & CPSR_Q)
8888 env->QF = ((val & CPSR_Q) != 0);
8889 if (mask & CPSR_T)
8890 env->thumb = ((val & CPSR_T) != 0);
8891 if (mask & CPSR_IT_0_1) {
8892 env->condexec_bits &= ~3;
8893 env->condexec_bits |= (val >> 25) & 3;
8894 }
8895 if (mask & CPSR_IT_2_7) {
8896 env->condexec_bits &= 3;
8897 env->condexec_bits |= (val >> 8) & 0xfc;
8898 }
8899 if (mask & CPSR_GE) {
8900 env->GE = (val >> 16) & 0xf;
8901 }
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911 if (write_type != CPSRWriteRaw && !arm_feature(env, ARM_FEATURE_V8) &&
8912 arm_feature(env, ARM_FEATURE_EL3) &&
8913 !arm_feature(env, ARM_FEATURE_EL2) &&
8914 !arm_is_secure(env)) {
8915
8916 changed_daif = (env->daif ^ val) & mask;
8917
8918 if (changed_daif & CPSR_A) {
8919
8920
8921
8922 if (!(env->cp15.scr_el3 & SCR_AW)) {
8923 qemu_log_mask(LOG_GUEST_ERROR,
8924 "Ignoring attempt to switch CPSR_A flag from "
8925 "non-secure world with SCR.AW bit clear\n");
8926 mask &= ~CPSR_A;
8927 }
8928 }
8929
8930 if (changed_daif & CPSR_F) {
8931
8932
8933
8934 if (!(env->cp15.scr_el3 & SCR_FW)) {
8935 qemu_log_mask(LOG_GUEST_ERROR,
8936 "Ignoring attempt to switch CPSR_F flag from "
8937 "non-secure world with SCR.FW bit clear\n");
8938 mask &= ~CPSR_F;
8939 }
8940
8941
8942
8943
8944
8945 if ((A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_NMFI) &&
8946 (val & CPSR_F)) {
8947 qemu_log_mask(LOG_GUEST_ERROR,
8948 "Ignoring attempt to enable CPSR_F flag "
8949 "(non-maskable FIQ [NMFI] support enabled)\n");
8950 mask &= ~CPSR_F;
8951 }
8952 }
8953 }
8954
8955 env->daif &= ~(CPSR_AIF & mask);
8956 env->daif |= val & CPSR_AIF & mask;
8957
8958 if (write_type != CPSRWriteRaw &&
8959 ((env->uncached_cpsr ^ val) & mask & CPSR_M)) {
8960 if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) {
8961
8962
8963
8964
8965
8966
8967 mask &= ~CPSR_M;
8968 } else if (bad_mode_switch(env, val & CPSR_M, write_type)) {
8969
8970
8971
8972
8973
8974
8975
8976
8977 mask &= ~CPSR_M;
8978 if (write_type != CPSRWriteByGDBStub &&
8979 arm_feature(env, ARM_FEATURE_V8)) {
8980 mask |= CPSR_IL;
8981 val |= CPSR_IL;
8982 }
8983 qemu_log_mask(LOG_GUEST_ERROR,
8984 "Illegal AArch32 mode switch attempt from %s to %s\n",
8985 aarch32_mode_name(env->uncached_cpsr),
8986 aarch32_mode_name(val));
8987 } else {
8988 qemu_log_mask(CPU_LOG_INT, "%s %s to %s PC 0x%" PRIx32 "\n",
8989 write_type == CPSRWriteExceptionReturn ?
8990 "Exception return from AArch32" :
8991 "AArch32 mode switch from",
8992 aarch32_mode_name(env->uncached_cpsr),
8993 aarch32_mode_name(val), env->regs[15]);
8994 switch_mode(env, val & CPSR_M);
8995 }
8996 }
8997 mask &= ~CACHED_CPSR_BITS;
8998 env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
8999}
9000
9001
9002uint32_t HELPER(sxtb16)(uint32_t x)
9003{
9004 uint32_t res;
9005 res = (uint16_t)(int8_t)x;
9006 res |= (uint32_t)(int8_t)(x >> 16) << 16;
9007 return res;
9008}
9009
9010uint32_t HELPER(uxtb16)(uint32_t x)
9011{
9012 uint32_t res;
9013 res = (uint16_t)(uint8_t)x;
9014 res |= (uint32_t)(uint8_t)(x >> 16) << 16;
9015 return res;
9016}
9017
9018int32_t HELPER(sdiv)(int32_t num, int32_t den)
9019{
9020 if (den == 0)
9021 return 0;
9022 if (num == INT_MIN && den == -1)
9023 return INT_MIN;
9024 return num / den;
9025}
9026
9027uint32_t HELPER(udiv)(uint32_t num, uint32_t den)
9028{
9029 if (den == 0)
9030 return 0;
9031 return num / den;
9032}
9033
9034uint32_t HELPER(rbit)(uint32_t x)
9035{
9036 return revbit32(x);
9037}
9038
9039#ifdef CONFIG_USER_ONLY
9040
9041static void switch_mode(CPUARMState *env, int mode)
9042{
9043 ARMCPU *cpu = env_archcpu(env);
9044
9045 if (mode != ARM_CPU_MODE_USR) {
9046 cpu_abort(CPU(cpu), "Tried to switch out of user mode\n");
9047 }
9048}
9049
9050uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
9051 uint32_t cur_el, bool secure)
9052{
9053 return 1;
9054}
9055
9056void aarch64_sync_64_to_32(CPUARMState *env)
9057{
9058 g_assert_not_reached();
9059}
9060
9061#else
9062
9063static void switch_mode(CPUARMState *env, int mode)
9064{
9065 int old_mode;
9066 int i;
9067
9068 old_mode = env->uncached_cpsr & CPSR_M;
9069 if (mode == old_mode)
9070 return;
9071
9072 if (old_mode == ARM_CPU_MODE_FIQ) {
9073 memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
9074 memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
9075 } else if (mode == ARM_CPU_MODE_FIQ) {
9076 memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
9077 memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
9078 }
9079
9080 i = bank_number(old_mode);
9081 env->banked_r13[i] = env->regs[13];
9082 env->banked_spsr[i] = env->spsr;
9083
9084 i = bank_number(mode);
9085 env->regs[13] = env->banked_r13[i];
9086 env->spsr = env->banked_spsr[i];
9087
9088 env->banked_r14[r14_bank_number(old_mode)] = env->regs[14];
9089 env->regs[14] = env->banked_r14[r14_bank_number(mode)];
9090}
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129static const int8_t target_el_table[2][2][2][2][2][4] = {
9130 {{{{{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },},
9131 {{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},},
9132 {{{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },},
9133 {{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},},},
9134 {{{{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},
9135 {{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},},
9136 {{{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},
9137 {{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},},},},
9138 {{{{{ 1, 1, 2, -1 },{ 1, 1, -1, 1 },},
9139 {{ 2, 2, 2, -1 },{ 2, 2, -1, 1 },},},
9140 {{{ 1, 1, 1, -1 },{ 1, 1, 1, 1 },},
9141 {{ 2, 2, 2, -1 },{ 2, 2, 2, 1 },},},},
9142 {{{{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},
9143 {{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},},
9144 {{{ 3, 3, 3, -1 },{ 3, 3, 3, 3 },},
9145 {{ 3, 3, 3, -1 },{ 3, 3, 3, 3 },},},},},
9146};
9147
9148
9149
9150
9151uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
9152 uint32_t cur_el, bool secure)
9153{
9154 CPUARMState *env = cs->env_ptr;
9155 bool rw;
9156 bool scr;
9157 bool hcr;
9158 int target_el;
9159
9160 bool is64 = arm_feature(env, ARM_FEATURE_AARCH64);
9161 uint64_t hcr_el2;
9162
9163 if (arm_feature(env, ARM_FEATURE_EL3)) {
9164 rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
9165 } else {
9166
9167
9168
9169
9170 rw = is64;
9171 }
9172
9173 hcr_el2 = arm_hcr_el2_eff(env);
9174 switch (excp_idx) {
9175 case EXCP_IRQ:
9176 scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
9177 hcr = hcr_el2 & HCR_IMO;
9178 break;
9179 case EXCP_FIQ:
9180 scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
9181 hcr = hcr_el2 & HCR_FMO;
9182 break;
9183 default:
9184 scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA);
9185 hcr = hcr_el2 & HCR_AMO;
9186 break;
9187 };
9188
9189
9190
9191
9192
9193 hcr |= (hcr_el2 & HCR_TGE) != 0;
9194
9195
9196 target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el];
9197
9198 assert(target_el > 0);
9199
9200 return target_el;
9201}
9202
9203void arm_log_exception(int idx)
9204{
9205 if (qemu_loglevel_mask(CPU_LOG_INT)) {
9206 const char *exc = NULL;
9207 static const char * const excnames[] = {
9208 [EXCP_UDEF] = "Undefined Instruction",
9209 [EXCP_SWI] = "SVC",
9210 [EXCP_PREFETCH_ABORT] = "Prefetch Abort",
9211 [EXCP_DATA_ABORT] = "Data Abort",
9212 [EXCP_IRQ] = "IRQ",
9213 [EXCP_FIQ] = "FIQ",
9214 [EXCP_BKPT] = "Breakpoint",
9215 [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
9216 [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
9217 [EXCP_HVC] = "Hypervisor Call",
9218 [EXCP_HYP_TRAP] = "Hypervisor Trap",
9219 [EXCP_SMC] = "Secure Monitor Call",
9220 [EXCP_VIRQ] = "Virtual IRQ",
9221 [EXCP_VFIQ] = "Virtual FIQ",
9222 [EXCP_SEMIHOST] = "Semihosting call",
9223 [EXCP_NOCP] = "v7M NOCP UsageFault",
9224 [EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
9225 [EXCP_STKOF] = "v8M STKOF UsageFault",
9226 [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
9227 [EXCP_LSERR] = "v8M LSERR UsageFault",
9228 [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
9229 };
9230
9231 if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
9232 exc = excnames[idx];
9233 }
9234 if (!exc) {
9235 exc = "unknown";
9236 }
9237 qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
9238 }
9239}
9240
9241
9242
9243
9244
9245
9246void aarch64_sync_32_to_64(CPUARMState *env)
9247{
9248 int i;
9249 uint32_t mode = env->uncached_cpsr & CPSR_M;
9250
9251
9252 for (i = 0; i < 8; i++) {
9253 env->xregs[i] = env->regs[i];
9254 }
9255
9256
9257
9258
9259
9260 if (mode == ARM_CPU_MODE_FIQ) {
9261 for (i = 8; i < 13; i++) {
9262 env->xregs[i] = env->usr_regs[i - 8];
9263 }
9264 } else {
9265 for (i = 8; i < 13; i++) {
9266 env->xregs[i] = env->regs[i];
9267 }
9268 }
9269
9270
9271
9272
9273
9274
9275 if (mode == ARM_CPU_MODE_USR || mode == ARM_CPU_MODE_SYS) {
9276 env->xregs[13] = env->regs[13];
9277 env->xregs[14] = env->regs[14];
9278 } else {
9279 env->xregs[13] = env->banked_r13[bank_number(ARM_CPU_MODE_USR)];
9280
9281 if (mode == ARM_CPU_MODE_HYP) {
9282 env->xregs[14] = env->regs[14];
9283 } else {
9284 env->xregs[14] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_USR)];
9285 }
9286 }
9287
9288 if (mode == ARM_CPU_MODE_HYP) {
9289 env->xregs[15] = env->regs[13];
9290 } else {
9291 env->xregs[15] = env->banked_r13[bank_number(ARM_CPU_MODE_HYP)];
9292 }
9293
9294 if (mode == ARM_CPU_MODE_IRQ) {
9295 env->xregs[16] = env->regs[14];
9296 env->xregs[17] = env->regs[13];
9297 } else {
9298 env->xregs[16] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_IRQ)];
9299 env->xregs[17] = env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)];
9300 }
9301
9302 if (mode == ARM_CPU_MODE_SVC) {
9303 env->xregs[18] = env->regs[14];
9304 env->xregs[19] = env->regs[13];
9305 } else {
9306 env->xregs[18] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_SVC)];
9307 env->xregs[19] = env->banked_r13[bank_number(ARM_CPU_MODE_SVC)];
9308 }
9309
9310 if (mode == ARM_CPU_MODE_ABT) {
9311 env->xregs[20] = env->regs[14];
9312 env->xregs[21] = env->regs[13];
9313 } else {
9314 env->xregs[20] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_ABT)];
9315 env->xregs[21] = env->banked_r13[bank_number(ARM_CPU_MODE_ABT)];
9316 }
9317
9318 if (mode == ARM_CPU_MODE_UND) {
9319 env->xregs[22] = env->regs[14];
9320 env->xregs[23] = env->regs[13];
9321 } else {
9322 env->xregs[22] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_UND)];
9323 env->xregs[23] = env->banked_r13[bank_number(ARM_CPU_MODE_UND)];
9324 }
9325
9326
9327
9328
9329
9330
9331 if (mode == ARM_CPU_MODE_FIQ) {
9332 for (i = 24; i < 31; i++) {
9333 env->xregs[i] = env->regs[i - 16];
9334 }
9335 } else {
9336 for (i = 24; i < 29; i++) {
9337 env->xregs[i] = env->fiq_regs[i - 24];
9338 }
9339 env->xregs[29] = env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)];
9340 env->xregs[30] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_FIQ)];
9341 }
9342
9343 env->pc = env->regs[15];
9344}
9345
9346
9347
9348
9349
9350
9351void aarch64_sync_64_to_32(CPUARMState *env)
9352{
9353 int i;
9354 uint32_t mode = env->uncached_cpsr & CPSR_M;
9355
9356
9357 for (i = 0; i < 8; i++) {
9358 env->regs[i] = env->xregs[i];
9359 }
9360
9361
9362
9363
9364
9365 if (mode == ARM_CPU_MODE_FIQ) {
9366 for (i = 8; i < 13; i++) {
9367 env->usr_regs[i - 8] = env->xregs[i];
9368 }
9369 } else {
9370 for (i = 8; i < 13; i++) {
9371 env->regs[i] = env->xregs[i];
9372 }
9373 }
9374
9375
9376
9377
9378
9379
9380
9381 if (mode == ARM_CPU_MODE_USR || mode == ARM_CPU_MODE_SYS) {
9382 env->regs[13] = env->xregs[13];
9383 env->regs[14] = env->xregs[14];
9384 } else {
9385 env->banked_r13[bank_number(ARM_CPU_MODE_USR)] = env->xregs[13];
9386
9387
9388
9389
9390
9391 if (mode == ARM_CPU_MODE_HYP) {
9392 env->regs[14] = env->xregs[14];
9393 } else {
9394 env->banked_r14[r14_bank_number(ARM_CPU_MODE_USR)] = env->xregs[14];
9395 }
9396 }
9397
9398 if (mode == ARM_CPU_MODE_HYP) {
9399 env->regs[13] = env->xregs[15];
9400 } else {
9401 env->banked_r13[bank_number(ARM_CPU_MODE_HYP)] = env->xregs[15];
9402 }
9403
9404 if (mode == ARM_CPU_MODE_IRQ) {
9405 env->regs[14] = env->xregs[16];
9406 env->regs[13] = env->xregs[17];
9407 } else {
9408 env->banked_r14[r14_bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[16];
9409 env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[17];
9410 }
9411
9412 if (mode == ARM_CPU_MODE_SVC) {
9413 env->regs[14] = env->xregs[18];
9414 env->regs[13] = env->xregs[19];
9415 } else {
9416 env->banked_r14[r14_bank_number(ARM_CPU_MODE_SVC)] = env->xregs[18];
9417 env->banked_r13[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[19];
9418 }
9419
9420 if (mode == ARM_CPU_MODE_ABT) {
9421 env->regs[14] = env->xregs[20];
9422 env->regs[13] = env->xregs[21];
9423 } else {
9424 env->banked_r14[r14_bank_number(ARM_CPU_MODE_ABT)] = env->xregs[20];
9425 env->banked_r13[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[21];
9426 }
9427
9428 if (mode == ARM_CPU_MODE_UND) {
9429 env->regs[14] = env->xregs[22];
9430 env->regs[13] = env->xregs[23];
9431 } else {
9432 env->banked_r14[r14_bank_number(ARM_CPU_MODE_UND)] = env->xregs[22];
9433 env->banked_r13[bank_number(ARM_CPU_MODE_UND)] = env->xregs[23];
9434 }
9435
9436
9437
9438
9439
9440 if (mode == ARM_CPU_MODE_FIQ) {
9441 for (i = 24; i < 31; i++) {
9442 env->regs[i - 16] = env->xregs[i];
9443 }
9444 } else {
9445 for (i = 24; i < 29; i++) {
9446 env->fiq_regs[i - 24] = env->xregs[i];
9447 }
9448 env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[29];
9449 env->banked_r14[r14_bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[30];
9450 }
9451
9452 env->regs[15] = env->pc;
9453}
9454
9455static void take_aarch32_exception(CPUARMState *env, int new_mode,
9456 uint32_t mask, uint32_t offset,
9457 uint32_t newpc)
9458{
9459 int new_el;
9460
9461
9462 switch_mode(env, new_mode);
9463
9464
9465
9466
9467
9468 env->pstate &= ~PSTATE_SS;
9469 env->spsr = cpsr_read(env);
9470
9471 env->condexec_bits = 0;
9472
9473 env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
9474
9475
9476 new_el = arm_current_el(env);
9477
9478
9479 env->uncached_cpsr &= ~CPSR_E;
9480 if (env->cp15.sctlr_el[new_el] & SCTLR_EE) {
9481 env->uncached_cpsr |= CPSR_E;
9482 }
9483
9484 env->uncached_cpsr &= ~(CPSR_IL | CPSR_J);
9485 env->daif |= mask;
9486
9487 if (cpu_isar_feature(aa32_ssbs, env_archcpu(env))) {
9488 if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_32) {
9489 env->uncached_cpsr |= CPSR_SSBS;
9490 } else {
9491 env->uncached_cpsr &= ~CPSR_SSBS;
9492 }
9493 }
9494
9495 if (new_mode == ARM_CPU_MODE_HYP) {
9496 env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
9497 env->elr_el[2] = env->regs[15];
9498 } else {
9499
9500 if (cpu_isar_feature(aa32_pan, env_archcpu(env))) {
9501 switch (new_el) {
9502 case 3:
9503 if (!arm_is_secure_below_el3(env)) {
9504
9505 env->uncached_cpsr &= ~CPSR_PAN;
9506 break;
9507 }
9508
9509
9510 case 1:
9511
9512 if (!(env->cp15.sctlr_el[new_el] & SCTLR_SPAN)) {
9513 env->uncached_cpsr |= CPSR_PAN;
9514 }
9515 break;
9516 }
9517 }
9518
9519
9520
9521
9522 if (arm_feature(env, ARM_FEATURE_V4T)) {
9523 env->thumb =
9524 (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) != 0;
9525 }
9526 env->regs[14] = env->regs[15] + offset;
9527 }
9528 env->regs[15] = newpc;
9529 arm_rebuild_hflags(env);
9530}
9531
9532static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
9533{
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
9545 uint32_t addr, mask;
9546 ARMCPU *cpu = ARM_CPU(cs);
9547 CPUARMState *env = &cpu->env;
9548
9549 switch (cs->exception_index) {
9550 case EXCP_UDEF:
9551 addr = 0x04;
9552 break;
9553 case EXCP_SWI:
9554 addr = 0x14;
9555 break;
9556 case EXCP_BKPT:
9557
9558 case EXCP_PREFETCH_ABORT:
9559 env->cp15.ifar_s = env->exception.vaddress;
9560 qemu_log_mask(CPU_LOG_INT, "...with HIFAR 0x%x\n",
9561 (uint32_t)env->exception.vaddress);
9562 addr = 0x0c;
9563 break;
9564 case EXCP_DATA_ABORT:
9565 env->cp15.dfar_s = env->exception.vaddress;
9566 qemu_log_mask(CPU_LOG_INT, "...with HDFAR 0x%x\n",
9567 (uint32_t)env->exception.vaddress);
9568 addr = 0x10;
9569 break;
9570 case EXCP_IRQ:
9571 addr = 0x18;
9572 break;
9573 case EXCP_FIQ:
9574 addr = 0x1c;
9575 break;
9576 case EXCP_HVC:
9577 addr = 0x08;
9578 break;
9579 case EXCP_HYP_TRAP:
9580 addr = 0x14;
9581 break;
9582 default:
9583 cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
9584 }
9585
9586 if (cs->exception_index != EXCP_IRQ && cs->exception_index != EXCP_FIQ) {
9587 if (!arm_feature(env, ARM_FEATURE_V8)) {
9588
9589
9590
9591
9592
9593 if (cs->exception_index == EXCP_PREFETCH_ABORT ||
9594 (cs->exception_index == EXCP_DATA_ABORT &&
9595 !(env->exception.syndrome & ARM_EL_ISV)) ||
9596 syn_get_ec(env->exception.syndrome) == EC_UNCATEGORIZED) {
9597 env->exception.syndrome &= ~ARM_EL_IL;
9598 }
9599 }
9600 env->cp15.esr_el[2] = env->exception.syndrome;
9601 }
9602
9603 if (arm_current_el(env) != 2 && addr < 0x14) {
9604 addr = 0x14;
9605 }
9606
9607 mask = 0;
9608 if (!(env->cp15.scr_el3 & SCR_EA)) {
9609 mask |= CPSR_A;
9610 }
9611 if (!(env->cp15.scr_el3 & SCR_IRQ)) {
9612 mask |= CPSR_I;
9613 }
9614 if (!(env->cp15.scr_el3 & SCR_FIQ)) {
9615 mask |= CPSR_F;
9616 }
9617
9618 addr += env->cp15.hvbar;
9619
9620 take_aarch32_exception(env, ARM_CPU_MODE_HYP, mask, 0, addr);
9621}
9622
9623static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
9624{
9625 ARMCPU *cpu = ARM_CPU(cs);
9626 CPUARMState *env = &cpu->env;
9627 uint32_t addr;
9628 uint32_t mask;
9629 int new_mode;
9630 uint32_t offset;
9631 uint32_t moe;
9632
9633
9634 switch (syn_get_ec(env->exception.syndrome)) {
9635 case EC_BREAKPOINT:
9636 case EC_BREAKPOINT_SAME_EL:
9637 moe = 1;
9638 break;
9639 case EC_WATCHPOINT:
9640 case EC_WATCHPOINT_SAME_EL:
9641 moe = 10;
9642 break;
9643 case EC_AA32_BKPT:
9644 moe = 3;
9645 break;
9646 case EC_VECTORCATCH:
9647 moe = 5;
9648 break;
9649 default:
9650 moe = 0;
9651 break;
9652 }
9653
9654 if (moe) {
9655 env->cp15.mdscr_el1 = deposit64(env->cp15.mdscr_el1, 2, 4, moe);
9656 }
9657
9658 if (env->exception.target_el == 2) {
9659 arm_cpu_do_interrupt_aarch32_hyp(cs);
9660 return;
9661 }
9662
9663 switch (cs->exception_index) {
9664 case EXCP_UDEF:
9665 new_mode = ARM_CPU_MODE_UND;
9666 addr = 0x04;
9667 mask = CPSR_I;
9668 if (env->thumb)
9669 offset = 2;
9670 else
9671 offset = 4;
9672 break;
9673 case EXCP_SWI:
9674 new_mode = ARM_CPU_MODE_SVC;
9675 addr = 0x08;
9676 mask = CPSR_I;
9677
9678 offset = 0;
9679 break;
9680 case EXCP_BKPT:
9681
9682 case EXCP_PREFETCH_ABORT:
9683 A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr);
9684 A32_BANKED_CURRENT_REG_SET(env, ifar, env->exception.vaddress);
9685 qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",
9686 env->exception.fsr, (uint32_t)env->exception.vaddress);
9687 new_mode = ARM_CPU_MODE_ABT;
9688 addr = 0x0c;
9689 mask = CPSR_A | CPSR_I;
9690 offset = 4;
9691 break;
9692 case EXCP_DATA_ABORT:
9693 A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr);
9694 A32_BANKED_CURRENT_REG_SET(env, dfar, env->exception.vaddress);
9695 qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",
9696 env->exception.fsr,
9697 (uint32_t)env->exception.vaddress);
9698 new_mode = ARM_CPU_MODE_ABT;
9699 addr = 0x10;
9700 mask = CPSR_A | CPSR_I;
9701 offset = 8;
9702 break;
9703 case EXCP_IRQ:
9704 new_mode = ARM_CPU_MODE_IRQ;
9705 addr = 0x18;
9706
9707 mask = CPSR_A | CPSR_I;
9708 offset = 4;
9709 if (env->cp15.scr_el3 & SCR_IRQ) {
9710
9711 new_mode = ARM_CPU_MODE_MON;
9712 mask |= CPSR_F;
9713 }
9714 break;
9715 case EXCP_FIQ:
9716 new_mode = ARM_CPU_MODE_FIQ;
9717 addr = 0x1c;
9718
9719 mask = CPSR_A | CPSR_I | CPSR_F;
9720 if (env->cp15.scr_el3 & SCR_FIQ) {
9721
9722 new_mode = ARM_CPU_MODE_MON;
9723 }
9724 offset = 4;
9725 break;
9726 case EXCP_VIRQ:
9727 new_mode = ARM_CPU_MODE_IRQ;
9728 addr = 0x18;
9729
9730 mask = CPSR_A | CPSR_I;
9731 offset = 4;
9732 break;
9733 case EXCP_VFIQ:
9734 new_mode = ARM_CPU_MODE_FIQ;
9735 addr = 0x1c;
9736
9737 mask = CPSR_A | CPSR_I | CPSR_F;
9738 offset = 4;
9739 break;
9740 case EXCP_SMC:
9741 new_mode = ARM_CPU_MODE_MON;
9742 addr = 0x08;
9743 mask = CPSR_A | CPSR_I | CPSR_F;
9744 offset = 0;
9745 break;
9746 default:
9747 cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
9748 return;
9749 }
9750
9751 if (new_mode == ARM_CPU_MODE_MON) {
9752 addr += env->cp15.mvbar;
9753 } else if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
9754
9755 addr += 0xffff0000;
9756 } else {
9757
9758
9759
9760
9761
9762 addr += A32_BANKED_CURRENT_REG_GET(env, vbar);
9763 }
9764
9765 if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
9766 env->cp15.scr_el3 &= ~SCR_NS;
9767 }
9768
9769 take_aarch32_exception(env, new_mode, mask, offset, addr);
9770}
9771
9772static int aarch64_regnum(CPUARMState *env, int aarch32_reg)
9773{
9774
9775
9776
9777
9778
9779 int mode = env->uncached_cpsr & CPSR_M;
9780
9781 switch (aarch32_reg) {
9782 case 0 ... 7:
9783 return aarch32_reg;
9784 case 8 ... 12:
9785 return mode == ARM_CPU_MODE_FIQ ? aarch32_reg + 16 : aarch32_reg;
9786 case 13:
9787 switch (mode) {
9788 case ARM_CPU_MODE_USR:
9789 case ARM_CPU_MODE_SYS:
9790 return 13;
9791 case ARM_CPU_MODE_HYP:
9792 return 15;
9793 case ARM_CPU_MODE_IRQ:
9794 return 17;
9795 case ARM_CPU_MODE_SVC:
9796 return 19;
9797 case ARM_CPU_MODE_ABT:
9798 return 21;
9799 case ARM_CPU_MODE_UND:
9800 return 23;
9801 case ARM_CPU_MODE_FIQ:
9802 return 29;
9803 default:
9804 g_assert_not_reached();
9805 }
9806 case 14:
9807 switch (mode) {
9808 case ARM_CPU_MODE_USR:
9809 case ARM_CPU_MODE_SYS:
9810 case ARM_CPU_MODE_HYP:
9811 return 14;
9812 case ARM_CPU_MODE_IRQ:
9813 return 16;
9814 case ARM_CPU_MODE_SVC:
9815 return 18;
9816 case ARM_CPU_MODE_ABT:
9817 return 20;
9818 case ARM_CPU_MODE_UND:
9819 return 22;
9820 case ARM_CPU_MODE_FIQ:
9821 return 30;
9822 default:
9823 g_assert_not_reached();
9824 }
9825 case 15:
9826 return 31;
9827 default:
9828 g_assert_not_reached();
9829 }
9830}
9831
9832static uint32_t cpsr_read_for_spsr_elx(CPUARMState *env)
9833{
9834 uint32_t ret = cpsr_read(env);
9835
9836
9837 if (ret & CPSR_DIT) {
9838 ret &= ~CPSR_DIT;
9839 ret |= PSTATE_DIT;
9840 }
9841
9842 ret |= env->pstate & PSTATE_SS;
9843
9844 return ret;
9845}
9846
9847
9848static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
9849{
9850 ARMCPU *cpu = ARM_CPU(cs);
9851 CPUARMState *env = &cpu->env;
9852 unsigned int new_el = env->exception.target_el;
9853 target_ulong addr = env->cp15.vbar_el[new_el];
9854 unsigned int new_mode = aarch64_pstate_mode(new_el, true);
9855 unsigned int old_mode;
9856 unsigned int cur_el = arm_current_el(env);
9857 int rt;
9858
9859
9860
9861
9862
9863 aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
9864
9865 if (cur_el < new_el) {
9866
9867
9868
9869 bool is_aa64;
9870 uint64_t hcr;
9871
9872 switch (new_el) {
9873 case 3:
9874 is_aa64 = (env->cp15.scr_el3 & SCR_RW) != 0;
9875 break;
9876 case 2:
9877 hcr = arm_hcr_el2_eff(env);
9878 if ((hcr & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
9879 is_aa64 = (hcr & HCR_RW) != 0;
9880 break;
9881 }
9882
9883 case 1:
9884 is_aa64 = is_a64(env);
9885 break;
9886 default:
9887 g_assert_not_reached();
9888 }
9889
9890 if (is_aa64) {
9891 addr += 0x400;
9892 } else {
9893 addr += 0x600;
9894 }
9895 } else if (pstate_read(env) & PSTATE_SP) {
9896 addr += 0x200;
9897 }
9898
9899 switch (cs->exception_index) {
9900 case EXCP_PREFETCH_ABORT:
9901 case EXCP_DATA_ABORT:
9902 env->cp15.far_el[new_el] = env->exception.vaddress;
9903 qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n",
9904 env->cp15.far_el[new_el]);
9905
9906 case EXCP_BKPT:
9907 case EXCP_UDEF:
9908 case EXCP_SWI:
9909 case EXCP_HVC:
9910 case EXCP_HYP_TRAP:
9911 case EXCP_SMC:
9912 switch (syn_get_ec(env->exception.syndrome)) {
9913 case EC_ADVSIMDFPACCESSTRAP:
9914
9915
9916
9917
9918
9919
9920 env->exception.syndrome &= ~MAKE_64BIT_MASK(0, 20);
9921 break;
9922 case EC_CP14RTTRAP:
9923 case EC_CP15RTTRAP:
9924 case EC_CP14DTTRAP:
9925
9926
9927
9928
9929
9930
9931
9932 rt = extract32(env->exception.syndrome, 5, 4);
9933 rt = aarch64_regnum(env, rt);
9934 env->exception.syndrome = deposit32(env->exception.syndrome,
9935 5, 5, rt);
9936 break;
9937 case EC_CP15RRTTRAP:
9938 case EC_CP14RRTTRAP:
9939
9940 rt = extract32(env->exception.syndrome, 5, 4);
9941 rt = aarch64_regnum(env, rt);
9942 env->exception.syndrome = deposit32(env->exception.syndrome,
9943 5, 5, rt);
9944 rt = extract32(env->exception.syndrome, 10, 4);
9945 rt = aarch64_regnum(env, rt);
9946 env->exception.syndrome = deposit32(env->exception.syndrome,
9947 10, 5, rt);
9948 break;
9949 }
9950 env->cp15.esr_el[new_el] = env->exception.syndrome;
9951 break;
9952 case EXCP_IRQ:
9953 case EXCP_VIRQ:
9954 addr += 0x80;
9955 break;
9956 case EXCP_FIQ:
9957 case EXCP_VFIQ:
9958 addr += 0x100;
9959 break;
9960 default:
9961 cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
9962 }
9963
9964 if (is_a64(env)) {
9965 old_mode = pstate_read(env);
9966 aarch64_save_sp(env, arm_current_el(env));
9967 env->elr_el[new_el] = env->pc;
9968 } else {
9969 old_mode = cpsr_read_for_spsr_elx(env);
9970 env->elr_el[new_el] = env->regs[15];
9971
9972 aarch64_sync_32_to_64(env);
9973
9974 env->condexec_bits = 0;
9975 }
9976 env->banked_spsr[aarch64_banked_spsr_index(new_el)] = old_mode;
9977
9978 qemu_log_mask(CPU_LOG_INT, "...with ELR 0x%" PRIx64 "\n",
9979 env->elr_el[new_el]);
9980
9981 if (cpu_isar_feature(aa64_pan, cpu)) {
9982
9983 new_mode |= old_mode & PSTATE_PAN;
9984 switch (new_el) {
9985 case 2:
9986
9987 if ((arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE))
9988 != (HCR_E2H | HCR_TGE)) {
9989 break;
9990 }
9991
9992 case 1:
9993
9994
9995 if ((env->cp15.sctlr_el[new_el] & SCTLR_SPAN) == 0) {
9996 new_mode |= PSTATE_PAN;
9997 }
9998 break;
9999 }
10000 }
10001 if (cpu_isar_feature(aa64_mte, cpu)) {
10002 new_mode |= PSTATE_TCO;
10003 }
10004
10005 if (cpu_isar_feature(aa64_ssbs, cpu)) {
10006 if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_64) {
10007 new_mode |= PSTATE_SSBS;
10008 } else {
10009 new_mode &= ~PSTATE_SSBS;
10010 }
10011 }
10012
10013 pstate_write(env, PSTATE_DAIF | new_mode);
10014 env->aarch64 = 1;
10015 aarch64_restore_sp(env, new_el);
10016 helper_rebuild_hflags_a64(env, new_el);
10017
10018 env->pc = addr;
10019
10020 qemu_log_mask(CPU_LOG_INT, "...to EL%d PC 0x%" PRIx64 " PSTATE 0x%x\n",
10021 new_el, env->pc, pstate_read(env));
10022}
10023
10024
10025
10026
10027
10028
10029
10030
10031#ifdef CONFIG_TCG
10032static void handle_semihosting(CPUState *cs)
10033{
10034 ARMCPU *cpu = ARM_CPU(cs);
10035 CPUARMState *env = &cpu->env;
10036
10037 if (is_a64(env)) {
10038 qemu_log_mask(CPU_LOG_INT,
10039 "...handling as semihosting call 0x%" PRIx64 "\n",
10040 env->xregs[0]);
10041 env->xregs[0] = do_common_semihosting(cs);
10042 env->pc += 4;
10043 } else {
10044 qemu_log_mask(CPU_LOG_INT,
10045 "...handling as semihosting call 0x%x\n",
10046 env->regs[0]);
10047 env->regs[0] = do_common_semihosting(cs);
10048 env->regs[15] += env->thumb ? 2 : 4;
10049 }
10050}
10051#endif
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062void arm_cpu_do_interrupt(CPUState *cs)
10063{
10064 ARMCPU *cpu = ARM_CPU(cs);
10065 CPUARMState *env = &cpu->env;
10066 unsigned int new_el = env->exception.target_el;
10067
10068 assert(!arm_feature(env, ARM_FEATURE_M));
10069
10070 arm_log_exception(cs->exception_index);
10071 qemu_log_mask(CPU_LOG_INT, "...from EL%d to EL%d\n", arm_current_el(env),
10072 new_el);
10073 if (qemu_loglevel_mask(CPU_LOG_INT)
10074 && !excp_is_internal(cs->exception_index)) {
10075 qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%x/0x%" PRIx32 "\n",
10076 syn_get_ec(env->exception.syndrome),
10077 env->exception.syndrome);
10078 }
10079
10080 if (arm_is_psci_call(cpu, cs->exception_index)) {
10081 arm_handle_psci_call(cpu);
10082 qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
10083 return;
10084 }
10085
10086
10087
10088
10089
10090
10091#ifdef CONFIG_TCG
10092 if (cs->exception_index == EXCP_SEMIHOST) {
10093 handle_semihosting(cs);
10094 return;
10095 }
10096#endif
10097
10098
10099
10100
10101
10102 g_assert(qemu_mutex_iothread_locked());
10103
10104 arm_call_pre_el_change_hook(cpu);
10105
10106 assert(!excp_is_internal(cs->exception_index));
10107 if (arm_el_is_aa64(env, new_el)) {
10108 arm_cpu_do_interrupt_aarch64(cs);
10109 } else {
10110 arm_cpu_do_interrupt_aarch32(cs);
10111 }
10112
10113 arm_call_el_change_hook(cpu);
10114
10115 if (!kvm_enabled()) {
10116 cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
10117 }
10118}
10119#endif
10120
10121uint64_t arm_sctlr(CPUARMState *env, int el)
10122{
10123
10124 if (el == 0) {
10125 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, 0);
10126 el = (mmu_idx == ARMMMUIdx_E20_0 || mmu_idx == ARMMMUIdx_SE20_0)
10127 ? 2 : 1;
10128 }
10129 return env->cp15.sctlr_el[el];
10130}
10131
10132
10133static inline uint64_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
10134{
10135 return env->cp15.sctlr_el[regime_el(env, mmu_idx)];
10136}
10137
10138#ifndef CONFIG_USER_ONLY
10139
10140
10141static inline bool regime_translation_disabled(CPUARMState *env,
10142 ARMMMUIdx mmu_idx)
10143{
10144 uint64_t hcr_el2;
10145
10146 if (arm_feature(env, ARM_FEATURE_M)) {
10147 switch (env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] &
10148 (R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
10149 case R_V7M_MPU_CTRL_ENABLE_MASK:
10150
10151 return mmu_idx & ARM_MMU_IDX_M_NEGPRI;
10152 case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK:
10153
10154 return false;
10155 case 0:
10156 default:
10157
10158
10159
10160 return true;
10161 }
10162 }
10163
10164 hcr_el2 = arm_hcr_el2_eff(env);
10165
10166 if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
10167
10168 return (hcr_el2 & (HCR_DC | HCR_VM)) == 0;
10169 }
10170
10171 if (hcr_el2 & HCR_TGE) {
10172
10173 if (!regime_is_secure(env, mmu_idx) && regime_el(env, mmu_idx) == 1) {
10174 return true;
10175 }
10176 }
10177
10178 if ((hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
10179
10180 return true;
10181 }
10182
10183 return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
10184}
10185
10186static inline bool regime_translation_big_endian(CPUARMState *env,
10187 ARMMMUIdx mmu_idx)
10188{
10189 return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0;
10190}
10191
10192
10193static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
10194 int ttbrn)
10195{
10196 if (mmu_idx == ARMMMUIdx_Stage2) {
10197 return env->cp15.vttbr_el2;
10198 }
10199 if (mmu_idx == ARMMMUIdx_Stage2_S) {
10200 return env->cp15.vsttbr_el2;
10201 }
10202 if (ttbrn == 0) {
10203 return env->cp15.ttbr0_el[regime_el(env, mmu_idx)];
10204 } else {
10205 return env->cp15.ttbr1_el[regime_el(env, mmu_idx)];
10206 }
10207}
10208
10209#endif
10210
10211
10212
10213
10214static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
10215{
10216 switch (mmu_idx) {
10217 case ARMMMUIdx_SE10_0:
10218 return ARMMMUIdx_Stage1_SE0;
10219 case ARMMMUIdx_SE10_1:
10220 return ARMMMUIdx_Stage1_SE1;
10221 case ARMMMUIdx_SE10_1_PAN:
10222 return ARMMMUIdx_Stage1_SE1_PAN;
10223 case ARMMMUIdx_E10_0:
10224 return ARMMMUIdx_Stage1_E0;
10225 case ARMMMUIdx_E10_1:
10226 return ARMMMUIdx_Stage1_E1;
10227 case ARMMMUIdx_E10_1_PAN:
10228 return ARMMMUIdx_Stage1_E1_PAN;
10229 default:
10230 return mmu_idx;
10231 }
10232}
10233
10234
10235static inline bool regime_using_lpae_format(CPUARMState *env,
10236 ARMMMUIdx mmu_idx)
10237{
10238 int el = regime_el(env, mmu_idx);
10239 if (el == 2 || arm_el_is_aa64(env, el)) {
10240 return true;
10241 }
10242 if (arm_feature(env, ARM_FEATURE_LPAE)
10243 && (regime_tcr(env, mmu_idx)->raw_tcr & TTBCR_EAE)) {
10244 return true;
10245 }
10246 return false;
10247}
10248
10249
10250
10251
10252bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
10253{
10254 mmu_idx = stage_1_mmu_idx(mmu_idx);
10255
10256 return regime_using_lpae_format(env, mmu_idx);
10257}
10258
10259#ifndef CONFIG_USER_ONLY
10260static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
10261{
10262 switch (mmu_idx) {
10263 case ARMMMUIdx_SE10_0:
10264 case ARMMMUIdx_E20_0:
10265 case ARMMMUIdx_SE20_0:
10266 case ARMMMUIdx_Stage1_E0:
10267 case ARMMMUIdx_Stage1_SE0:
10268 case ARMMMUIdx_MUser:
10269 case ARMMMUIdx_MSUser:
10270 case ARMMMUIdx_MUserNegPri:
10271 case ARMMMUIdx_MSUserNegPri:
10272 return true;
10273 default:
10274 return false;
10275 case ARMMMUIdx_E10_0:
10276 case ARMMMUIdx_E10_1:
10277 case ARMMMUIdx_E10_1_PAN:
10278 g_assert_not_reached();
10279 }
10280}
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290static inline int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx,
10291 int ap, int domain_prot)
10292{
10293 bool is_user = regime_is_user(env, mmu_idx);
10294
10295 if (domain_prot == 3) {
10296 return PAGE_READ | PAGE_WRITE;
10297 }
10298
10299 switch (ap) {
10300 case 0:
10301 if (arm_feature(env, ARM_FEATURE_V7)) {
10302 return 0;
10303 }
10304 switch (regime_sctlr(env, mmu_idx) & (SCTLR_S | SCTLR_R)) {
10305 case SCTLR_S:
10306 return is_user ? 0 : PAGE_READ;
10307 case SCTLR_R:
10308 return PAGE_READ;
10309 default:
10310 return 0;
10311 }
10312 case 1:
10313 return is_user ? 0 : PAGE_READ | PAGE_WRITE;
10314 case 2:
10315 if (is_user) {
10316 return PAGE_READ;
10317 } else {
10318 return PAGE_READ | PAGE_WRITE;
10319 }
10320 case 3:
10321 return PAGE_READ | PAGE_WRITE;
10322 case 4:
10323 return 0;
10324 case 5:
10325 return is_user ? 0 : PAGE_READ;
10326 case 6:
10327 return PAGE_READ;
10328 case 7:
10329 if (!arm_feature(env, ARM_FEATURE_V6K)) {
10330 return 0;
10331 }
10332 return PAGE_READ;
10333 default:
10334 g_assert_not_reached();
10335 }
10336}
10337
10338
10339
10340
10341
10342
10343
10344static inline int simple_ap_to_rw_prot_is_user(int ap, bool is_user)
10345{
10346 switch (ap) {
10347 case 0:
10348 return is_user ? 0 : PAGE_READ | PAGE_WRITE;
10349 case 1:
10350 return PAGE_READ | PAGE_WRITE;
10351 case 2:
10352 return is_user ? 0 : PAGE_READ;
10353 case 3:
10354 return PAGE_READ;
10355 default:
10356 g_assert_not_reached();
10357 }
10358}
10359
10360static inline int
10361simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
10362{
10363 return simple_ap_to_rw_prot_is_user(ap, regime_is_user(env, mmu_idx));
10364}
10365
10366
10367
10368
10369
10370
10371
10372
10373static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
10374{
10375 int prot = 0;
10376
10377 if (s2ap & 1) {
10378 prot |= PAGE_READ;
10379 }
10380 if (s2ap & 2) {
10381 prot |= PAGE_WRITE;
10382 }
10383
10384 if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
10385 switch (xn) {
10386 case 0:
10387 prot |= PAGE_EXEC;
10388 break;
10389 case 1:
10390 if (s1_is_el0) {
10391 prot |= PAGE_EXEC;
10392 }
10393 break;
10394 case 2:
10395 break;
10396 case 3:
10397 if (!s1_is_el0) {
10398 prot |= PAGE_EXEC;
10399 }
10400 break;
10401 default:
10402 g_assert_not_reached();
10403 }
10404 } else {
10405 if (!extract32(xn, 1, 1)) {
10406 if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
10407 prot |= PAGE_EXEC;
10408 }
10409 }
10410 }
10411 return prot;
10412}
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
10424static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
10425 int ap, int ns, int xn, int pxn)
10426{
10427 bool is_user = regime_is_user(env, mmu_idx);
10428 int prot_rw, user_rw;
10429 bool have_wxn;
10430 int wxn = 0;
10431
10432 assert(mmu_idx != ARMMMUIdx_Stage2);
10433 assert(mmu_idx != ARMMMUIdx_Stage2_S);
10434
10435 user_rw = simple_ap_to_rw_prot_is_user(ap, true);
10436 if (is_user) {
10437 prot_rw = user_rw;
10438 } else {
10439 if (user_rw && regime_is_pan(env, mmu_idx)) {
10440
10441 prot_rw = 0;
10442 } else {
10443 prot_rw = simple_ap_to_rw_prot_is_user(ap, false);
10444 }
10445 }
10446
10447 if (ns && arm_is_secure(env) && (env->cp15.scr_el3 & SCR_SIF)) {
10448 return prot_rw;
10449 }
10450
10451
10452
10453
10454
10455
10456 have_wxn = arm_feature(env, ARM_FEATURE_LPAE);
10457
10458 if (have_wxn) {
10459 wxn = regime_sctlr(env, mmu_idx) & SCTLR_WXN;
10460 }
10461
10462 if (is_aa64) {
10463 if (regime_has_2_ranges(mmu_idx) && !is_user) {
10464 xn = pxn || (user_rw & PAGE_WRITE);
10465 }
10466 } else if (arm_feature(env, ARM_FEATURE_V7)) {
10467 switch (regime_el(env, mmu_idx)) {
10468 case 1:
10469 case 3:
10470 if (is_user) {
10471 xn = xn || !(user_rw & PAGE_READ);
10472 } else {
10473 int uwxn = 0;
10474 if (have_wxn) {
10475 uwxn = regime_sctlr(env, mmu_idx) & SCTLR_UWXN;
10476 }
10477 xn = xn || !(prot_rw & PAGE_READ) || pxn ||
10478 (uwxn && (user_rw & PAGE_WRITE));
10479 }
10480 break;
10481 case 2:
10482 break;
10483 }
10484 } else {
10485 xn = wxn = 0;
10486 }
10487
10488 if (xn || (wxn && (prot_rw & PAGE_WRITE))) {
10489 return prot_rw;
10490 }
10491 return prot_rw | PAGE_EXEC;
10492}
10493
10494static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
10495 uint32_t *table, uint32_t address)
10496{
10497
10498 TCR *tcr = regime_tcr(env, mmu_idx);
10499
10500 if (address & tcr->mask) {
10501 if (tcr->raw_tcr & TTBCR_PD1) {
10502
10503 return false;
10504 }
10505 *table = regime_ttbr(env, mmu_idx, 1) & 0xffffc000;
10506 } else {
10507 if (tcr->raw_tcr & TTBCR_PD0) {
10508
10509 return false;
10510 }
10511 *table = regime_ttbr(env, mmu_idx, 0) & tcr->base_mask;
10512 }
10513 *table |= (address >> 18) & 0x3ffc;
10514 return true;
10515}
10516
10517
10518static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
10519 hwaddr addr, bool *is_secure,
10520 ARMMMUFaultInfo *fi)
10521{
10522 if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
10523 !regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
10524 target_ulong s2size;
10525 hwaddr s2pa;
10526 int s2prot;
10527 int ret;
10528 ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S
10529 : ARMMMUIdx_Stage2;
10530 ARMCacheAttrs cacheattrs = {};
10531 MemTxAttrs txattrs = {};
10532
10533 ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx, false,
10534 &s2pa, &txattrs, &s2prot, &s2size, fi,
10535 &cacheattrs);
10536 if (ret) {
10537 assert(fi->type != ARMFault_None);
10538 fi->s2addr = addr;
10539 fi->stage2 = true;
10540 fi->s1ptw = true;
10541 fi->s1ns = !*is_secure;
10542 return ~0;
10543 }
10544 if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
10545 (cacheattrs.attrs & 0xf0) == 0) {
10546
10547
10548
10549
10550 fi->type = ARMFault_Permission;
10551 fi->s2addr = addr;
10552 fi->stage2 = true;
10553 fi->s1ptw = true;
10554 fi->s1ns = !*is_secure;
10555 return ~0;
10556 }
10557
10558 if (arm_is_secure_below_el3(env)) {
10559
10560 if (*is_secure) {
10561 *is_secure = !(env->cp15.vstcr_el2.raw_tcr & VSTCR_SW);
10562 } else {
10563 *is_secure = !(env->cp15.vtcr_el2.raw_tcr & VTCR_NSW);
10564 }
10565 } else {
10566 assert(!*is_secure);
10567 }
10568
10569 addr = s2pa;
10570 }
10571 return addr;
10572}
10573
10574
10575static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
10576 ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
10577{
10578 ARMCPU *cpu = ARM_CPU(cs);
10579 CPUARMState *env = &cpu->env;
10580 MemTxAttrs attrs = {};
10581 MemTxResult result = MEMTX_OK;
10582 AddressSpace *as;
10583 uint32_t data;
10584
10585 addr = S1_ptw_translate(env, mmu_idx, addr, &is_secure, fi);
10586 attrs.secure = is_secure;
10587 as = arm_addressspace(cs, attrs);
10588 if (fi->s1ptw) {
10589 return 0;
10590 }
10591 if (regime_translation_big_endian(env, mmu_idx)) {
10592 data = address_space_ldl_be(as, addr, attrs, &result);
10593 } else {
10594 data = address_space_ldl_le(as, addr, attrs, &result);
10595 }
10596 if (result == MEMTX_OK) {
10597 return data;
10598 }
10599 fi->type = ARMFault_SyncExternalOnWalk;
10600 fi->ea = arm_extabort_type(result);
10601 return 0;
10602}
10603
10604static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
10605 ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
10606{
10607 ARMCPU *cpu = ARM_CPU(cs);
10608 CPUARMState *env = &cpu->env;
10609 MemTxAttrs attrs = {};
10610 MemTxResult result = MEMTX_OK;
10611 AddressSpace *as;
10612 uint64_t data;
10613
10614 addr = S1_ptw_translate(env, mmu_idx, addr, &is_secure, fi);
10615 attrs.secure = is_secure;
10616 as = arm_addressspace(cs, attrs);
10617 if (fi->s1ptw) {
10618 return 0;
10619 }
10620 if (regime_translation_big_endian(env, mmu_idx)) {
10621 data = address_space_ldq_be(as, addr, attrs, &result);
10622 } else {
10623 data = address_space_ldq_le(as, addr, attrs, &result);
10624 }
10625 if (result == MEMTX_OK) {
10626 return data;
10627 }
10628 fi->type = ARMFault_SyncExternalOnWalk;
10629 fi->ea = arm_extabort_type(result);
10630 return 0;
10631}
10632
10633static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
10634 MMUAccessType access_type, ARMMMUIdx mmu_idx,
10635 hwaddr *phys_ptr, int *prot,
10636 target_ulong *page_size,
10637 ARMMMUFaultInfo *fi)
10638{
10639 CPUState *cs = env_cpu(env);
10640 int level = 1;
10641 uint32_t table;
10642 uint32_t desc;
10643 int type;
10644 int ap;
10645 int domain = 0;
10646 int domain_prot;
10647 hwaddr phys_addr;
10648 uint32_t dacr;
10649
10650
10651
10652 if (!get_level1_table_address(env, mmu_idx, &table, address)) {
10653
10654 fi->type = ARMFault_Translation;
10655 goto do_fault;
10656 }
10657 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
10658 mmu_idx, fi);
10659 if (fi->type != ARMFault_None) {
10660 goto do_fault;
10661 }
10662 type = (desc & 3);
10663 domain = (desc >> 5) & 0x0f;
10664 if (regime_el(env, mmu_idx) == 1) {
10665 dacr = env->cp15.dacr_ns;
10666 } else {
10667 dacr = env->cp15.dacr_s;
10668 }
10669 domain_prot = (dacr >> (domain * 2)) & 3;
10670 if (type == 0) {
10671
10672 fi->type = ARMFault_Translation;
10673 goto do_fault;
10674 }
10675 if (type != 2) {
10676 level = 2;
10677 }
10678 if (domain_prot == 0 || domain_prot == 2) {
10679 fi->type = ARMFault_Domain;
10680 goto do_fault;
10681 }
10682 if (type == 2) {
10683
10684 phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
10685 ap = (desc >> 10) & 3;
10686 *page_size = 1024 * 1024;
10687 } else {
10688
10689 if (type == 1) {
10690
10691 table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
10692 } else {
10693
10694 table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
10695 }
10696 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
10697 mmu_idx, fi);
10698 if (fi->type != ARMFault_None) {
10699 goto do_fault;
10700 }
10701 switch (desc & 3) {
10702 case 0:
10703 fi->type = ARMFault_Translation;
10704 goto do_fault;
10705 case 1:
10706 phys_addr = (desc & 0xffff0000) | (address & 0xffff);
10707 ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
10708 *page_size = 0x10000;
10709 break;
10710 case 2:
10711 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
10712 ap = (desc >> (4 + ((address >> 9) & 6))) & 3;
10713 *page_size = 0x1000;
10714 break;
10715 case 3:
10716 if (type == 1) {
10717
10718 if (arm_feature(env, ARM_FEATURE_XSCALE)
10719 || arm_feature(env, ARM_FEATURE_V6)) {
10720 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
10721 *page_size = 0x1000;
10722 } else {
10723
10724
10725
10726 fi->type = ARMFault_Translation;
10727 goto do_fault;
10728 }
10729 } else {
10730 phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
10731 *page_size = 0x400;
10732 }
10733 ap = (desc >> 4) & 3;
10734 break;
10735 default:
10736
10737 abort();
10738 }
10739 }
10740 *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
10741 *prot |= *prot ? PAGE_EXEC : 0;
10742 if (!(*prot & (1 << access_type))) {
10743
10744 fi->type = ARMFault_Permission;
10745 goto do_fault;
10746 }
10747 *phys_ptr = phys_addr;
10748 return false;
10749do_fault:
10750 fi->domain = domain;
10751 fi->level = level;
10752 return true;
10753}
10754
10755static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
10756 MMUAccessType access_type, ARMMMUIdx mmu_idx,
10757 hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
10758 target_ulong *page_size, ARMMMUFaultInfo *fi)
10759{
10760 CPUState *cs = env_cpu(env);
10761 ARMCPU *cpu = env_archcpu(env);
10762 int level = 1;
10763 uint32_t table;
10764 uint32_t desc;
10765 uint32_t xn;
10766 uint32_t pxn = 0;
10767 int type;
10768 int ap;
10769 int domain = 0;
10770 int domain_prot;
10771 hwaddr phys_addr;
10772 uint32_t dacr;
10773 bool ns;
10774
10775
10776
10777 if (!get_level1_table_address(env, mmu_idx, &table, address)) {
10778
10779 fi->type = ARMFault_Translation;
10780 goto do_fault;
10781 }
10782 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
10783 mmu_idx, fi);
10784 if (fi->type != ARMFault_None) {
10785 goto do_fault;
10786 }
10787 type = (desc & 3);
10788 if (type == 0 || (type == 3 && !cpu_isar_feature(aa32_pxn, cpu))) {
10789
10790
10791
10792 fi->type = ARMFault_Translation;
10793 goto do_fault;
10794 }
10795 if ((type == 1) || !(desc & (1 << 18))) {
10796
10797 domain = (desc >> 5) & 0x0f;
10798 }
10799 if (regime_el(env, mmu_idx) == 1) {
10800 dacr = env->cp15.dacr_ns;
10801 } else {
10802 dacr = env->cp15.dacr_s;
10803 }
10804 if (type == 1) {
10805 level = 2;
10806 }
10807 domain_prot = (dacr >> (domain * 2)) & 3;
10808 if (domain_prot == 0 || domain_prot == 2) {
10809
10810 fi->type = ARMFault_Domain;
10811 goto do_fault;
10812 }
10813 if (type != 1) {
10814 if (desc & (1 << 18)) {
10815
10816 phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
10817 phys_addr |= (uint64_t)extract32(desc, 20, 4) << 32;
10818 phys_addr |= (uint64_t)extract32(desc, 5, 4) << 36;
10819 *page_size = 0x1000000;
10820 } else {
10821
10822 phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
10823 *page_size = 0x100000;
10824 }
10825 ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
10826 xn = desc & (1 << 4);
10827 pxn = desc & 1;
10828 ns = extract32(desc, 19, 1);
10829 } else {
10830 if (cpu_isar_feature(aa32_pxn, cpu)) {
10831 pxn = (desc >> 2) & 1;
10832 }
10833 ns = extract32(desc, 3, 1);
10834
10835 table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
10836 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
10837 mmu_idx, fi);
10838 if (fi->type != ARMFault_None) {
10839 goto do_fault;
10840 }
10841 ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
10842 switch (desc & 3) {
10843 case 0:
10844 fi->type = ARMFault_Translation;
10845 goto do_fault;
10846 case 1:
10847 phys_addr = (desc & 0xffff0000) | (address & 0xffff);
10848 xn = desc & (1 << 15);
10849 *page_size = 0x10000;
10850 break;
10851 case 2: case 3:
10852 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
10853 xn = desc & 1;
10854 *page_size = 0x1000;
10855 break;
10856 default:
10857
10858 abort();
10859 }
10860 }
10861 if (domain_prot == 3) {
10862 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
10863 } else {
10864 if (pxn && !regime_is_user(env, mmu_idx)) {
10865 xn = 1;
10866 }
10867 if (xn && access_type == MMU_INST_FETCH) {
10868 fi->type = ARMFault_Permission;
10869 goto do_fault;
10870 }
10871
10872 if (arm_feature(env, ARM_FEATURE_V6K) &&
10873 (regime_sctlr(env, mmu_idx) & SCTLR_AFE)) {
10874
10875 if ((ap & 1) == 0) {
10876
10877 fi->type = ARMFault_AccessFlag;
10878 goto do_fault;
10879 }
10880 *prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
10881 } else {
10882 *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
10883 }
10884 if (*prot && !xn) {
10885 *prot |= PAGE_EXEC;
10886 }
10887 if (!(*prot & (1 << access_type))) {
10888
10889 fi->type = ARMFault_Permission;
10890 goto do_fault;
10891 }
10892 }
10893 if (ns) {
10894
10895
10896
10897
10898 attrs->secure = false;
10899 }
10900 *phys_ptr = phys_addr;
10901 return false;
10902do_fault:
10903 fi->domain = domain;
10904 fi->level = level;
10905 return true;
10906}
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
10920 int inputsize, int stride)
10921{
10922 const int grainsize = stride + 3;
10923 int startsizecheck;
10924
10925
10926 if (level < 0) {
10927 return false;
10928 }
10929
10930 startsizecheck = inputsize - ((3 - level) * stride + grainsize);
10931 if (startsizecheck < 1 || startsizecheck > stride + 4) {
10932 return false;
10933 }
10934
10935 if (is_aa64) {
10936 CPUARMState *env = &cpu->env;
10937 unsigned int pamax = arm_pamax(cpu);
10938
10939 switch (stride) {
10940 case 13:
10941 if (level == 0 || (level == 1 && pamax <= 42)) {
10942 return false;
10943 }
10944 break;
10945 case 11:
10946 if (level == 0 || (level == 1 && pamax <= 40)) {
10947 return false;
10948 }
10949 break;
10950 case 9:
10951 if (level == 0 && pamax <= 42) {
10952 return false;
10953 }
10954 break;
10955 default:
10956 g_assert_not_reached();
10957 }
10958
10959
10960 if (inputsize > pamax &&
10961 (arm_el_is_aa64(env, 1) || inputsize > 40)) {
10962
10963 return false;
10964 }
10965 } else {
10966
10967 assert(stride == 9);
10968
10969 if (level == 0) {
10970 return false;
10971 }
10972 }
10973 return true;
10974}
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
10985{
10986 uint8_t hiattr = extract32(s2attrs, 2, 2);
10987 uint8_t loattr = extract32(s2attrs, 0, 2);
10988 uint8_t hihint = 0, lohint = 0;
10989
10990 if (hiattr != 0) {
10991 if (arm_hcr_el2_eff(env) & HCR_CD) {
10992 hiattr = loattr = 1;
10993 } else {
10994 if (hiattr != 1) {
10995 hihint = 3;
10996 }
10997 if (loattr != 1) {
10998 lohint = 3;
10999 }
11000 }
11001 }
11002
11003 return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
11004}
11005#endif
11006
11007static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
11008{
11009 if (regime_has_2_ranges(mmu_idx)) {
11010 return extract64(tcr, 37, 2);
11011 } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11012 return 0;
11013 } else {
11014
11015 return extract32(tcr, 20, 1) * 3;
11016 }
11017}
11018
11019static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
11020{
11021 if (regime_has_2_ranges(mmu_idx)) {
11022 return extract64(tcr, 51, 2);
11023 } else if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11024 return 0;
11025 } else {
11026
11027 return extract32(tcr, 29, 1) * 3;
11028 }
11029}
11030
11031static int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx)
11032{
11033 if (regime_has_2_ranges(mmu_idx)) {
11034 return extract64(tcr, 57, 2);
11035 } else {
11036
11037 return extract32(tcr, 30, 1) * 3;
11038 }
11039}
11040
11041ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
11042 ARMMMUIdx mmu_idx, bool data)
11043{
11044 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
11045 bool epd, hpd, using16k, using64k;
11046 int select, tsz, tbi, max_tsz;
11047
11048 if (!regime_has_2_ranges(mmu_idx)) {
11049 select = 0;
11050 tsz = extract32(tcr, 0, 6);
11051 using64k = extract32(tcr, 14, 1);
11052 using16k = extract32(tcr, 15, 1);
11053 if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11054
11055 hpd = false;
11056 } else {
11057 hpd = extract32(tcr, 24, 1);
11058 }
11059 epd = false;
11060 } else {
11061
11062
11063
11064
11065 select = extract64(va, 55, 1);
11066 if (!select) {
11067 tsz = extract32(tcr, 0, 6);
11068 epd = extract32(tcr, 7, 1);
11069 using64k = extract32(tcr, 14, 1);
11070 using16k = extract32(tcr, 15, 1);
11071 hpd = extract64(tcr, 41, 1);
11072 } else {
11073 int tg = extract32(tcr, 30, 2);
11074 using16k = tg == 1;
11075 using64k = tg == 3;
11076 tsz = extract32(tcr, 16, 6);
11077 epd = extract32(tcr, 23, 1);
11078 hpd = extract64(tcr, 42, 1);
11079 }
11080 }
11081
11082 if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
11083 max_tsz = 48 - using64k;
11084 } else {
11085 max_tsz = 39;
11086 }
11087
11088 tsz = MIN(tsz, max_tsz);
11089 tsz = MAX(tsz, 16);
11090
11091
11092 tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
11093 if (!data) {
11094 tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
11095 }
11096 tbi = (tbi >> select) & 1;
11097
11098 return (ARMVAParameters) {
11099 .tsz = tsz,
11100 .select = select,
11101 .tbi = tbi,
11102 .epd = epd,
11103 .hpd = hpd,
11104 .using16k = using16k,
11105 .using64k = using64k,
11106 };
11107}
11108
11109#ifndef CONFIG_USER_ONLY
11110static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
11111 ARMMMUIdx mmu_idx)
11112{
11113 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
11114 uint32_t el = regime_el(env, mmu_idx);
11115 int select, tsz;
11116 bool epd, hpd;
11117
11118 assert(mmu_idx != ARMMMUIdx_Stage2_S);
11119
11120 if (mmu_idx == ARMMMUIdx_Stage2) {
11121
11122 bool sext = extract32(tcr, 4, 1);
11123 bool sign = extract32(tcr, 3, 1);
11124
11125
11126
11127
11128
11129 if (sign != sext) {
11130 qemu_log_mask(LOG_GUEST_ERROR,
11131 "AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
11132 }
11133 tsz = sextract32(tcr, 0, 4) + 8;
11134 select = 0;
11135 hpd = false;
11136 epd = false;
11137 } else if (el == 2) {
11138
11139 tsz = extract32(tcr, 0, 3);
11140 select = 0;
11141 hpd = extract64(tcr, 24, 1);
11142 epd = false;
11143 } else {
11144 int t0sz = extract32(tcr, 0, 3);
11145 int t1sz = extract32(tcr, 16, 3);
11146
11147 if (t1sz == 0) {
11148 select = va > (0xffffffffu >> t0sz);
11149 } else {
11150
11151 select = va >= ~(0xffffffffu >> t1sz);
11152 }
11153 if (!select) {
11154 tsz = t0sz;
11155 epd = extract32(tcr, 7, 1);
11156 hpd = extract64(tcr, 41, 1);
11157 } else {
11158 tsz = t1sz;
11159 epd = extract32(tcr, 23, 1);
11160 hpd = extract64(tcr, 42, 1);
11161 }
11162
11163 hpd &= extract32(tcr, 6, 1);
11164 }
11165
11166 return (ARMVAParameters) {
11167 .tsz = tsz,
11168 .select = select,
11169 .epd = epd,
11170 .hpd = hpd,
11171 };
11172}
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
11198 MMUAccessType access_type, ARMMMUIdx mmu_idx,
11199 bool s1_is_el0,
11200 hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
11201 target_ulong *page_size_ptr,
11202 ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
11203{
11204 ARMCPU *cpu = env_archcpu(env);
11205 CPUState *cs = CPU(cpu);
11206
11207 ARMFaultType fault_type = ARMFault_Translation;
11208 uint32_t level;
11209 ARMVAParameters param;
11210 uint64_t ttbr;
11211 hwaddr descaddr, indexmask, indexmask_grainsize;
11212 uint32_t tableattrs;
11213 target_ulong page_size;
11214 uint32_t attrs;
11215 int32_t stride;
11216 int addrsize, inputsize;
11217 TCR *tcr = regime_tcr(env, mmu_idx);
11218 int ap, ns, xn, pxn;
11219 uint32_t el = regime_el(env, mmu_idx);
11220 uint64_t descaddrmask;
11221 bool aarch64 = arm_el_is_aa64(env, el);
11222 bool guarded = false;
11223
11224
11225 if (aarch64) {
11226 param = aa64_va_parameters(env, address, mmu_idx,
11227 access_type != MMU_INST_FETCH);
11228 level = 0;
11229 addrsize = 64 - 8 * param.tbi;
11230 inputsize = 64 - param.tsz;
11231 } else {
11232 param = aa32_va_parameters(env, address, mmu_idx);
11233 level = 1;
11234 addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
11235 inputsize = addrsize - param.tsz;
11236 }
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247 if (inputsize < addrsize) {
11248 target_ulong top_bits = sextract64(address, inputsize,
11249 addrsize - inputsize);
11250 if (-top_bits != param.select) {
11251
11252 fault_type = ARMFault_Translation;
11253 goto do_fault;
11254 }
11255 }
11256
11257 if (param.using64k) {
11258 stride = 13;
11259 } else if (param.using16k) {
11260 stride = 11;
11261 } else {
11262 stride = 9;
11263 }
11264
11265
11266
11267
11268
11269
11270
11271
11272 ttbr = regime_ttbr(env, mmu_idx, param.select);
11273
11274
11275
11276
11277
11278 if (param.epd) {
11279
11280
11281
11282 goto do_fault;
11283 }
11284
11285 if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297 level = 4 - (inputsize - 4) / stride;
11298 } else {
11299
11300
11301
11302 uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2);
11303 uint32_t startlevel;
11304 bool ok;
11305
11306 if (!aarch64 || stride == 9) {
11307
11308 startlevel = 2 - sl0;
11309
11310 if (cpu_isar_feature(aa64_st, cpu)) {
11311 startlevel &= 3;
11312 }
11313 } else {
11314
11315 startlevel = 3 - sl0;
11316 }
11317
11318
11319 ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
11320 inputsize, stride);
11321 if (!ok) {
11322 fault_type = ARMFault_Translation;
11323 goto do_fault;
11324 }
11325 level = startlevel;
11326 }
11327
11328 indexmask_grainsize = (1ULL << (stride + 3)) - 1;
11329 indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
11330
11331
11332 descaddr = extract64(ttbr, 0, 48);
11333
11334
11335
11336
11337 descaddr &= ~indexmask;
11338
11339
11340
11341
11342
11343
11344 descaddrmask = ((1ull << (aarch64 ? 48 : 40)) - 1) &
11345 ~indexmask_grainsize;
11346
11347
11348
11349
11350
11351
11352 tableattrs = regime_is_secure(env, mmu_idx) ? 0 : (1 << 4);
11353 for (;;) {
11354 uint64_t descriptor;
11355 bool nstable;
11356
11357 descaddr |= (address >> (stride * (4 - level))) & indexmask;
11358 descaddr &= ~7ULL;
11359 nstable = extract32(tableattrs, 4, 1);
11360 descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fi);
11361 if (fi->type != ARMFault_None) {
11362 goto do_fault;
11363 }
11364
11365 if (!(descriptor & 1) ||
11366 (!(descriptor & 2) && (level == 3))) {
11367
11368 goto do_fault;
11369 }
11370 descaddr = descriptor & descaddrmask;
11371
11372 if ((descriptor & 2) && (level < 3)) {
11373
11374
11375
11376
11377
11378 tableattrs |= extract64(descriptor, 59, 5);
11379 level++;
11380 indexmask = indexmask_grainsize;
11381 continue;
11382 }
11383
11384
11385
11386
11387 page_size = (1ULL << ((stride * (4 - level)) + 3));
11388 descaddr |= (address & (page_size - 1));
11389
11390 attrs = extract64(descriptor, 2, 10)
11391 | (extract64(descriptor, 52, 12) << 10);
11392
11393 if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11394
11395 break;
11396 }
11397
11398 attrs |= nstable << 3;
11399 guarded = extract64(descriptor, 50, 1);
11400 if (param.hpd) {
11401
11402 break;
11403 }
11404 attrs |= extract32(tableattrs, 0, 2) << 11;
11405
11406
11407
11408 attrs &= ~(extract32(tableattrs, 2, 1) << 4);
11409 attrs |= extract32(tableattrs, 3, 1) << 5;
11410 break;
11411 }
11412
11413
11414
11415 fault_type = ARMFault_AccessFlag;
11416 if ((attrs & (1 << 8)) == 0) {
11417
11418 goto do_fault;
11419 }
11420
11421 ap = extract32(attrs, 4, 2);
11422
11423 if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11424 ns = mmu_idx == ARMMMUIdx_Stage2;
11425 xn = extract32(attrs, 11, 2);
11426 *prot = get_S2prot(env, ap, xn, s1_is_el0);
11427 } else {
11428 ns = extract32(attrs, 3, 1);
11429 xn = extract32(attrs, 12, 1);
11430 pxn = extract32(attrs, 11, 1);
11431 *prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
11432 }
11433
11434 fault_type = ARMFault_Permission;
11435 if (!(*prot & (1 << access_type))) {
11436 goto do_fault;
11437 }
11438
11439 if (ns) {
11440
11441
11442
11443
11444 txattrs->secure = false;
11445 }
11446
11447 if (aarch64 && guarded && cpu_isar_feature(aa64_bti, cpu)) {
11448 arm_tlb_bti_gp(txattrs) = true;
11449 }
11450
11451 if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
11452 cacheattrs->attrs = convert_stage2_attrs(env, extract32(attrs, 0, 4));
11453 } else {
11454
11455 uint8_t attrindx = extract32(attrs, 0, 3);
11456 uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
11457 assert(attrindx <= 7);
11458 cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
11459 }
11460 cacheattrs->shareability = extract32(attrs, 6, 2);
11461
11462 *phys_ptr = descaddr;
11463 *page_size_ptr = page_size;
11464 return false;
11465
11466do_fault:
11467 fi->type = fault_type;
11468 fi->level = level;
11469
11470 fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_Stage2 ||
11471 mmu_idx == ARMMMUIdx_Stage2_S);
11472 fi->s1ns = mmu_idx == ARMMMUIdx_Stage2;
11473 return true;
11474}
11475
11476static inline void get_phys_addr_pmsav7_default(CPUARMState *env,
11477 ARMMMUIdx mmu_idx,
11478 int32_t address, int *prot)
11479{
11480 if (!arm_feature(env, ARM_FEATURE_M)) {
11481 *prot = PAGE_READ | PAGE_WRITE;
11482 switch (address) {
11483 case 0xF0000000 ... 0xFFFFFFFF:
11484 if (regime_sctlr(env, mmu_idx) & SCTLR_V) {
11485
11486 *prot |= PAGE_EXEC;
11487 }
11488 break;
11489 case 0x00000000 ... 0x7FFFFFFF:
11490 *prot |= PAGE_EXEC;
11491 break;
11492 }
11493 } else {
11494
11495
11496
11497
11498 switch (address) {
11499 case 0x00000000 ... 0x1fffffff:
11500 case 0x20000000 ... 0x3fffffff:
11501 case 0x60000000 ... 0x7fffffff:
11502 case 0x80000000 ... 0x9fffffff:
11503 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
11504 break;
11505 case 0x40000000 ... 0x5fffffff:
11506 case 0xa0000000 ... 0xbfffffff:
11507 case 0xc0000000 ... 0xdfffffff:
11508 case 0xe0000000 ... 0xffffffff:
11509 *prot = PAGE_READ | PAGE_WRITE;
11510 break;
11511 default:
11512 g_assert_not_reached();
11513 }
11514 }
11515}
11516
11517static bool pmsav7_use_background_region(ARMCPU *cpu,
11518 ARMMMUIdx mmu_idx, bool is_user)
11519{
11520
11521
11522
11523 CPUARMState *env = &cpu->env;
11524
11525 if (is_user) {
11526 return false;
11527 }
11528
11529 if (arm_feature(env, ARM_FEATURE_M)) {
11530 return env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)]
11531 & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
11532 } else {
11533 return regime_sctlr(env, mmu_idx) & SCTLR_BR;
11534 }
11535}
11536
11537static inline bool m_is_ppb_region(CPUARMState *env, uint32_t address)
11538{
11539
11540 return arm_feature(env, ARM_FEATURE_M) &&
11541 extract32(address, 20, 12) == 0xe00;
11542}
11543
11544static inline bool m_is_system_region(CPUARMState *env, uint32_t address)
11545{
11546
11547
11548
11549 return arm_feature(env, ARM_FEATURE_M) && extract32(address, 29, 3) == 0x7;
11550}
11551
11552static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
11553 MMUAccessType access_type, ARMMMUIdx mmu_idx,
11554 hwaddr *phys_ptr, int *prot,
11555 target_ulong *page_size,
11556 ARMMMUFaultInfo *fi)
11557{
11558 ARMCPU *cpu = env_archcpu(env);
11559 int n;
11560 bool is_user = regime_is_user(env, mmu_idx);
11561
11562 *phys_ptr = address;
11563 *page_size = TARGET_PAGE_SIZE;
11564 *prot = 0;
11565
11566 if (regime_translation_disabled(env, mmu_idx) ||
11567 m_is_ppb_region(env, address)) {
11568
11569
11570
11571
11572
11573
11574
11575 get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
11576 } else {
11577 for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
11578
11579 uint32_t base = env->pmsav7.drbar[n];
11580 uint32_t rsize = extract32(env->pmsav7.drsr[n], 1, 5);
11581 uint32_t rmask;
11582 bool srdis = false;
11583
11584 if (!(env->pmsav7.drsr[n] & 0x1)) {
11585 continue;
11586 }
11587
11588 if (!rsize) {
11589 qemu_log_mask(LOG_GUEST_ERROR,
11590 "DRSR[%d]: Rsize field cannot be 0\n", n);
11591 continue;
11592 }
11593 rsize++;
11594 rmask = (1ull << rsize) - 1;
11595
11596 if (base & rmask) {
11597 qemu_log_mask(LOG_GUEST_ERROR,
11598 "DRBAR[%d]: 0x%" PRIx32 " misaligned "
11599 "to DRSR region size, mask = 0x%" PRIx32 "\n",
11600 n, base, rmask);
11601 continue;
11602 }
11603
11604 if (address < base || address > base + rmask) {
11605
11606
11607
11608
11609
11610
11611
11612
11613
11614 if (ranges_overlap(base, rmask,
11615 address & TARGET_PAGE_MASK,
11616 TARGET_PAGE_SIZE)) {
11617 *page_size = 1;
11618 }
11619 continue;
11620 }
11621
11622
11623
11624 if (rsize >= 8) {
11625 int i, snd;
11626 uint32_t srdis_mask;
11627
11628 rsize -= 3;
11629 snd = ((address - base) >> rsize) & 0x7;
11630 srdis = extract32(env->pmsav7.drsr[n], snd + 8, 1);
11631
11632 srdis_mask = srdis ? 0x3 : 0x0;
11633 for (i = 2; i <= 8 && rsize < TARGET_PAGE_BITS; i *= 2) {
11634
11635
11636
11637
11638
11639
11640 int snd_rounded = snd & ~(i - 1);
11641 uint32_t srdis_multi = extract32(env->pmsav7.drsr[n],
11642 snd_rounded + 8, i);
11643 if (srdis_mask ^ srdis_multi) {
11644 break;
11645 }
11646 srdis_mask = (srdis_mask << i) | srdis_mask;
11647 rsize++;
11648 }
11649 }
11650 if (srdis) {
11651 continue;
11652 }
11653 if (rsize < TARGET_PAGE_BITS) {
11654 *page_size = 1 << rsize;
11655 }
11656 break;
11657 }
11658
11659 if (n == -1) {
11660 if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
11661
11662 fi->type = ARMFault_Background;
11663 return true;
11664 }
11665 get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
11666 } else {
11667 uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3);
11668 uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1);
11669
11670 if (m_is_system_region(env, address)) {
11671
11672 xn = 1;
11673 }
11674
11675 if (is_user) {
11676 switch (ap) {
11677 case 0:
11678 case 1:
11679 case 5:
11680 break;
11681 case 3:
11682 *prot |= PAGE_WRITE;
11683
11684 case 2:
11685 case 6:
11686 *prot |= PAGE_READ | PAGE_EXEC;
11687 break;
11688 case 7:
11689
11690 if (arm_feature(env, ARM_FEATURE_M)) {
11691 *prot |= PAGE_READ | PAGE_EXEC;
11692 break;
11693 }
11694
11695 default:
11696 qemu_log_mask(LOG_GUEST_ERROR,
11697 "DRACR[%d]: Bad value for AP bits: 0x%"
11698 PRIx32 "\n", n, ap);
11699 }
11700 } else {
11701 switch (ap) {
11702 case 0:
11703 break;
11704 case 1:
11705 case 2:
11706 case 3:
11707 *prot |= PAGE_WRITE;
11708
11709 case 5:
11710 case 6:
11711 *prot |= PAGE_READ | PAGE_EXEC;
11712 break;
11713 case 7:
11714
11715 if (arm_feature(env, ARM_FEATURE_M)) {
11716 *prot |= PAGE_READ | PAGE_EXEC;
11717 break;
11718 }
11719
11720 default:
11721 qemu_log_mask(LOG_GUEST_ERROR,
11722 "DRACR[%d]: Bad value for AP bits: 0x%"
11723 PRIx32 "\n", n, ap);
11724 }
11725 }
11726
11727
11728 if (xn) {
11729 *prot &= ~PAGE_EXEC;
11730 }
11731 }
11732 }
11733
11734 fi->type = ARMFault_Permission;
11735 fi->level = 1;
11736 return !(*prot & (1 << access_type));
11737}
11738
11739static bool v8m_is_sau_exempt(CPUARMState *env,
11740 uint32_t address, MMUAccessType access_type)
11741{
11742
11743
11744
11745 return
11746 (access_type == MMU_INST_FETCH && m_is_system_region(env, address)) ||
11747 (address >= 0xe0000000 && address <= 0xe0002fff) ||
11748 (address >= 0xe000e000 && address <= 0xe000efff) ||
11749 (address >= 0xe002e000 && address <= 0xe002efff) ||
11750 (address >= 0xe0040000 && address <= 0xe0041fff) ||
11751 (address >= 0xe00ff000 && address <= 0xe00fffff);
11752}
11753
11754void v8m_security_lookup(CPUARMState *env, uint32_t address,
11755 MMUAccessType access_type, ARMMMUIdx mmu_idx,
11756 V8M_SAttributes *sattrs)
11757{
11758
11759
11760
11761
11762 ARMCPU *cpu = env_archcpu(env);
11763 int r;
11764 bool idau_exempt = false, idau_ns = true, idau_nsc = true;
11765 int idau_region = IREGION_NOTVALID;
11766 uint32_t addr_page_base = address & TARGET_PAGE_MASK;
11767 uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
11768
11769 if (cpu->idau) {
11770 IDAUInterfaceClass *iic = IDAU_INTERFACE_GET_CLASS(cpu->idau);
11771 IDAUInterface *ii = IDAU_INTERFACE(cpu->idau);
11772
11773 iic->check(ii, address, &idau_region, &idau_exempt, &idau_ns,
11774 &idau_nsc);
11775 }
11776
11777 if (access_type == MMU_INST_FETCH && extract32(address, 28, 4) == 0xf) {
11778
11779 return;
11780 }
11781
11782 if (idau_exempt || v8m_is_sau_exempt(env, address, access_type)) {
11783 sattrs->ns = !regime_is_secure(env, mmu_idx);
11784 return;
11785 }
11786
11787 if (idau_region != IREGION_NOTVALID) {
11788 sattrs->irvalid = true;
11789 sattrs->iregion = idau_region;
11790 }
11791
11792 switch (env->sau.ctrl & 3) {
11793 case 0:
11794 break;
11795 case 2:
11796 sattrs->ns = true;
11797 break;
11798 default:
11799 for (r = 0; r < cpu->sau_sregion; r++) {
11800 if (env->sau.rlar[r] & 1) {
11801 uint32_t base = env->sau.rbar[r] & ~0x1f;
11802 uint32_t limit = env->sau.rlar[r] | 0x1f;
11803
11804 if (base <= address && limit >= address) {
11805 if (base > addr_page_base || limit < addr_page_limit) {
11806 sattrs->subpage = true;
11807 }
11808 if (sattrs->srvalid) {
11809
11810
11811
11812
11813 sattrs->ns = false;
11814 sattrs->nsc = false;
11815 sattrs->sregion = 0;
11816 sattrs->srvalid = false;
11817 break;
11818 } else {
11819 if (env->sau.rlar[r] & 2) {
11820 sattrs->nsc = true;
11821 } else {
11822 sattrs->ns = true;
11823 }
11824 sattrs->srvalid = true;
11825 sattrs->sregion = r;
11826 }
11827 } else {
11828
11829
11830
11831
11832
11833
11834
11835
11836
11837 if (limit >= base &&
11838 ranges_overlap(base, limit - base + 1,
11839 addr_page_base,
11840 TARGET_PAGE_SIZE)) {
11841 sattrs->subpage = true;
11842 }
11843 }
11844 }
11845 }
11846 break;
11847 }
11848
11849
11850
11851
11852
11853 if (!idau_ns) {
11854 if (sattrs->ns || (!idau_nsc && sattrs->nsc)) {
11855 sattrs->ns = false;
11856 sattrs->nsc = idau_nsc;
11857 }
11858 }
11859}
11860
11861bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
11862 MMUAccessType access_type, ARMMMUIdx mmu_idx,
11863 hwaddr *phys_ptr, MemTxAttrs *txattrs,
11864 int *prot, bool *is_subpage,
11865 ARMMMUFaultInfo *fi, uint32_t *mregion)
11866{
11867
11868
11869
11870
11871
11872
11873
11874
11875 ARMCPU *cpu = env_archcpu(env);
11876 bool is_user = regime_is_user(env, mmu_idx);
11877 uint32_t secure = regime_is_secure(env, mmu_idx);
11878 int n;
11879 int matchregion = -1;
11880 bool hit = false;
11881 uint32_t addr_page_base = address & TARGET_PAGE_MASK;
11882 uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
11883
11884 *is_subpage = false;
11885 *phys_ptr = address;
11886 *prot = 0;
11887 if (mregion) {
11888 *mregion = -1;
11889 }
11890
11891
11892
11893
11894
11895
11896
11897 if (regime_translation_disabled(env, mmu_idx)) {
11898 hit = true;
11899 } else if (m_is_ppb_region(env, address)) {
11900 hit = true;
11901 } else {
11902 if (pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
11903 hit = true;
11904 }
11905
11906 for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
11907
11908
11909
11910
11911
11912 uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
11913 uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
11914
11915 if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
11916
11917 continue;
11918 }
11919
11920 if (address < base || address > limit) {
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930 if (limit >= base &&
11931 ranges_overlap(base, limit - base + 1,
11932 addr_page_base,
11933 TARGET_PAGE_SIZE)) {
11934 *is_subpage = true;
11935 }
11936 continue;
11937 }
11938
11939 if (base > addr_page_base || limit < addr_page_limit) {
11940 *is_subpage = true;
11941 }
11942
11943 if (matchregion != -1) {
11944
11945
11946
11947 fi->type = ARMFault_Permission;
11948 fi->level = 1;
11949 return true;
11950 }
11951
11952 matchregion = n;
11953 hit = true;
11954 }
11955 }
11956
11957 if (!hit) {
11958
11959 fi->type = ARMFault_Background;
11960 return true;
11961 }
11962
11963 if (matchregion == -1) {
11964
11965 get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
11966 } else {
11967 uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
11968 uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
11969 bool pxn = false;
11970
11971 if (arm_feature(env, ARM_FEATURE_V8_1M)) {
11972 pxn = extract32(env->pmsav8.rlar[secure][matchregion], 4, 1);
11973 }
11974
11975 if (m_is_system_region(env, address)) {
11976
11977 xn = 1;
11978 }
11979
11980 *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
11981 if (*prot && !xn && !(pxn && !is_user)) {
11982 *prot |= PAGE_EXEC;
11983 }
11984
11985
11986
11987 if (mregion) {
11988 *mregion = matchregion;
11989 }
11990 }
11991
11992 fi->type = ARMFault_Permission;
11993 fi->level = 1;
11994 return !(*prot & (1 << access_type));
11995}
11996
11997
11998static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
11999 MMUAccessType access_type, ARMMMUIdx mmu_idx,
12000 hwaddr *phys_ptr, MemTxAttrs *txattrs,
12001 int *prot, target_ulong *page_size,
12002 ARMMMUFaultInfo *fi)
12003{
12004 uint32_t secure = regime_is_secure(env, mmu_idx);
12005 V8M_SAttributes sattrs = {};
12006 bool ret;
12007 bool mpu_is_subpage;
12008
12009 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
12010 v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
12011 if (access_type == MMU_INST_FETCH) {
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029 if (sattrs.ns != !secure) {
12030 if (sattrs.nsc) {
12031 fi->type = ARMFault_QEMU_NSCExec;
12032 } else {
12033 fi->type = ARMFault_QEMU_SFault;
12034 }
12035 *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
12036 *phys_ptr = address;
12037 *prot = 0;
12038 return true;
12039 }
12040 } else {
12041
12042
12043
12044
12045 if (sattrs.ns) {
12046 txattrs->secure = false;
12047 } else if (!secure) {
12048
12049
12050
12051
12052
12053
12054
12055
12056
12057 fi->type = ARMFault_QEMU_SFault;
12058 *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
12059 *phys_ptr = address;
12060 *prot = 0;
12061 return true;
12062 }
12063 }
12064 }
12065
12066 ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
12067 txattrs, prot, &mpu_is_subpage, fi, NULL);
12068 *page_size = sattrs.subpage || mpu_is_subpage ? 1 : TARGET_PAGE_SIZE;
12069 return ret;
12070}
12071
12072static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
12073 MMUAccessType access_type, ARMMMUIdx mmu_idx,
12074 hwaddr *phys_ptr, int *prot,
12075 ARMMMUFaultInfo *fi)
12076{
12077 int n;
12078 uint32_t mask;
12079 uint32_t base;
12080 bool is_user = regime_is_user(env, mmu_idx);
12081
12082 if (regime_translation_disabled(env, mmu_idx)) {
12083
12084 *phys_ptr = address;
12085 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
12086 return false;
12087 }
12088
12089 *phys_ptr = address;
12090 for (n = 7; n >= 0; n--) {
12091 base = env->cp15.c6_region[n];
12092 if ((base & 1) == 0) {
12093 continue;
12094 }
12095 mask = 1 << ((base >> 1) & 0x1f);
12096
12097
12098 mask = (mask << 1) - 1;
12099 if (((base ^ address) & ~mask) == 0) {
12100 break;
12101 }
12102 }
12103 if (n < 0) {
12104 fi->type = ARMFault_Background;
12105 return true;
12106 }
12107
12108 if (access_type == MMU_INST_FETCH) {
12109 mask = env->cp15.pmsav5_insn_ap;
12110 } else {
12111 mask = env->cp15.pmsav5_data_ap;
12112 }
12113 mask = (mask >> (n * 4)) & 0xf;
12114 switch (mask) {
12115 case 0:
12116 fi->type = ARMFault_Permission;
12117 fi->level = 1;
12118 return true;
12119 case 1:
12120 if (is_user) {
12121 fi->type = ARMFault_Permission;
12122 fi->level = 1;
12123 return true;
12124 }
12125 *prot = PAGE_READ | PAGE_WRITE;
12126 break;
12127 case 2:
12128 *prot = PAGE_READ;
12129 if (!is_user) {
12130 *prot |= PAGE_WRITE;
12131 }
12132 break;
12133 case 3:
12134 *prot = PAGE_READ | PAGE_WRITE;
12135 break;
12136 case 5:
12137 if (is_user) {
12138 fi->type = ARMFault_Permission;
12139 fi->level = 1;
12140 return true;
12141 }
12142 *prot = PAGE_READ;
12143 break;
12144 case 6:
12145 *prot = PAGE_READ;
12146 break;
12147 default:
12148
12149 fi->type = ARMFault_Permission;
12150 fi->level = 1;
12151 return true;
12152 }
12153 *prot |= PAGE_EXEC;
12154 return false;
12155}
12156
12157
12158
12159
12160
12161
12162
12163
12164static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2)
12165{
12166 if (s1 == 4 || s2 == 4) {
12167
12168 return 4;
12169 } else if (extract32(s1, 2, 2) == 0 || extract32(s1, 2, 2) == 2) {
12170
12171 return s1;
12172 } else if (extract32(s2, 2, 2) == 2) {
12173
12174
12175
12176 return (2 << 2) | extract32(s1, 0, 2);
12177 } else {
12178 return s1;
12179 }
12180}
12181
12182
12183
12184
12185
12186
12187
12188static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2)
12189{
12190 uint8_t s1lo, s2lo, s1hi, s2hi;
12191 ARMCacheAttrs ret;
12192 bool tagged = false;
12193
12194 if (s1.attrs == 0xf0) {
12195 tagged = true;
12196 s1.attrs = 0xff;
12197 }
12198
12199 s1lo = extract32(s1.attrs, 0, 4);
12200 s2lo = extract32(s2.attrs, 0, 4);
12201 s1hi = extract32(s1.attrs, 4, 4);
12202 s2hi = extract32(s2.attrs, 4, 4);
12203
12204
12205 if (s1.shareability == 2 || s2.shareability == 2) {
12206
12207 ret.shareability = 2;
12208 } else if (s1.shareability == 3 || s2.shareability == 3) {
12209
12210 ret.shareability = 3;
12211 } else {
12212
12213 ret.shareability = 0;
12214 }
12215
12216
12217 if (s1hi == 0 || s2hi == 0) {
12218
12219 if (s1lo == 0 || s2lo == 0) {
12220
12221 ret.attrs = 0;
12222 } else if (s1lo == 4 || s2lo == 4) {
12223
12224 ret.attrs = 4;
12225 } else if (s1lo == 8 || s2lo == 8) {
12226
12227 ret.attrs = 8;
12228 } else {
12229 ret.attrs = 0xc;
12230 }
12231
12232
12233
12234
12235 ret.shareability = 2;
12236 } else {
12237
12238 ret.attrs = combine_cacheattr_nibble(s1hi, s2hi) << 4
12239 | combine_cacheattr_nibble(s1lo, s2lo);
12240
12241 if (ret.attrs == 0x44) {
12242
12243
12244
12245
12246 ret.shareability = 2;
12247 }
12248 }
12249
12250
12251 if (tagged && ret.attrs == 0xff) {
12252 ret.attrs = 0xf0;
12253 }
12254
12255 return ret;
12256}
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285bool get_phys_addr(CPUARMState *env, target_ulong address,
12286 MMUAccessType access_type, ARMMMUIdx mmu_idx,
12287 hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
12288 target_ulong *page_size,
12289 ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
12290{
12291 ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
12292
12293 if (mmu_idx != s1_mmu_idx) {
12294
12295
12296
12297 if (arm_feature(env, ARM_FEATURE_EL2)) {
12298 hwaddr ipa;
12299 int s2_prot;
12300 int ret;
12301 ARMCacheAttrs cacheattrs2 = {};
12302 ARMMMUIdx s2_mmu_idx;
12303 bool is_el0;
12304
12305 ret = get_phys_addr(env, address, access_type, s1_mmu_idx, &ipa,
12306 attrs, prot, page_size, fi, cacheattrs);
12307
12308
12309 if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
12310 *phys_ptr = ipa;
12311 return ret;
12312 }
12313
12314 s2_mmu_idx = attrs->secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
12315 is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
12316
12317
12318 ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx, is_el0,
12319 phys_ptr, attrs, &s2_prot,
12320 page_size, fi, &cacheattrs2);
12321 fi->s2addr = ipa;
12322
12323 *prot &= s2_prot;
12324
12325
12326 if (ret) {
12327 return ret;
12328 }
12329
12330
12331 if (arm_hcr_el2_eff(env) & HCR_DC) {
12332
12333
12334
12335
12336
12337
12338
12339 if (cacheattrs->attrs != 0xf0) {
12340 cacheattrs->attrs = 0xff;
12341 }
12342 cacheattrs->shareability = 0;
12343 }
12344 *cacheattrs = combine_cacheattrs(*cacheattrs, cacheattrs2);
12345
12346
12347 if (arm_is_secure_below_el3(env)) {
12348 if (attrs->secure) {
12349 attrs->secure =
12350 !(env->cp15.vstcr_el2.raw_tcr & (VSTCR_SA | VSTCR_SW));
12351 } else {
12352 attrs->secure =
12353 !((env->cp15.vtcr_el2.raw_tcr & (VTCR_NSA | VTCR_NSW))
12354 || (env->cp15.vstcr_el2.raw_tcr & VSTCR_SA));
12355 }
12356 }
12357 return 0;
12358 } else {
12359
12360
12361
12362 mmu_idx = stage_1_mmu_idx(mmu_idx);
12363 }
12364 }
12365
12366
12367
12368
12369
12370 attrs->secure = regime_is_secure(env, mmu_idx);
12371 attrs->user = regime_is_user(env, mmu_idx);
12372
12373
12374
12375
12376 if (address < 0x02000000 && mmu_idx != ARMMMUIdx_Stage2
12377 && !arm_feature(env, ARM_FEATURE_V8)) {
12378 if (regime_el(env, mmu_idx) == 3) {
12379 address += env->cp15.fcseidr_s;
12380 } else {
12381 address += env->cp15.fcseidr_ns;
12382 }
12383 }
12384
12385 if (arm_feature(env, ARM_FEATURE_PMSA)) {
12386 bool ret;
12387 *page_size = TARGET_PAGE_SIZE;
12388
12389 if (arm_feature(env, ARM_FEATURE_V8)) {
12390
12391 ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
12392 phys_ptr, attrs, prot, page_size, fi);
12393 } else if (arm_feature(env, ARM_FEATURE_V7)) {
12394
12395 ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
12396 phys_ptr, prot, page_size, fi);
12397 } else {
12398
12399 ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
12400 phys_ptr, prot, fi);
12401 }
12402 qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
12403 " mmu_idx %u -> %s (prot %c%c%c)\n",
12404 access_type == MMU_DATA_LOAD ? "reading" :
12405 (access_type == MMU_DATA_STORE ? "writing" : "execute"),
12406 (uint32_t)address, mmu_idx,
12407 ret ? "Miss" : "Hit",
12408 *prot & PAGE_READ ? 'r' : '-',
12409 *prot & PAGE_WRITE ? 'w' : '-',
12410 *prot & PAGE_EXEC ? 'x' : '-');
12411
12412 return ret;
12413 }
12414
12415
12416
12417 if (regime_translation_disabled(env, mmu_idx)) {
12418 uint64_t hcr;
12419 uint8_t memattr;
12420
12421
12422
12423
12424
12425 if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
12426 int r_el = regime_el(env, mmu_idx);
12427 if (arm_el_is_aa64(env, r_el)) {
12428 int pamax = arm_pamax(env_archcpu(env));
12429 uint64_t tcr = env->cp15.tcr_el[r_el].raw_tcr;
12430 int addrtop, tbi;
12431
12432 tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
12433 if (access_type == MMU_INST_FETCH) {
12434 tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
12435 }
12436 tbi = (tbi >> extract64(address, 55, 1)) & 1;
12437 addrtop = (tbi ? 55 : 63);
12438
12439 if (extract64(address, pamax, addrtop - pamax + 1) != 0) {
12440 fi->type = ARMFault_AddressSize;
12441 fi->level = 0;
12442 fi->stage2 = false;
12443 return 1;
12444 }
12445
12446
12447
12448
12449
12450
12451
12452 address = extract64(address, 0, 52);
12453 }
12454 }
12455 *phys_ptr = address;
12456 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
12457 *page_size = TARGET_PAGE_SIZE;
12458
12459
12460 hcr = arm_hcr_el2_eff(env);
12461 cacheattrs->shareability = 0;
12462 if (hcr & HCR_DC) {
12463 if (hcr & HCR_DCT) {
12464 memattr = 0xf0;
12465 } else {
12466 memattr = 0xff;
12467 }
12468 } else if (access_type == MMU_INST_FETCH) {
12469 if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
12470 memattr = 0xee;
12471 } else {
12472 memattr = 0x44;
12473 }
12474 cacheattrs->shareability = 2;
12475 } else {
12476 memattr = 0x00;
12477 }
12478 cacheattrs->attrs = memattr;
12479 return 0;
12480 }
12481
12482 if (regime_using_lpae_format(env, mmu_idx)) {
12483 return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
12484 phys_ptr, attrs, prot, page_size,
12485 fi, cacheattrs);
12486 } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
12487 return get_phys_addr_v6(env, address, access_type, mmu_idx,
12488 phys_ptr, attrs, prot, page_size, fi);
12489 } else {
12490 return get_phys_addr_v5(env, address, access_type, mmu_idx,
12491 phys_ptr, prot, page_size, fi);
12492 }
12493}
12494
12495hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
12496 MemTxAttrs *attrs)
12497{
12498 ARMCPU *cpu = ARM_CPU(cs);
12499 CPUARMState *env = &cpu->env;
12500 hwaddr phys_addr;
12501 target_ulong page_size;
12502 int prot;
12503 bool ret;
12504 ARMMMUFaultInfo fi = {};
12505 ARMMMUIdx mmu_idx = arm_mmu_idx(env);
12506 ARMCacheAttrs cacheattrs = {};
12507
12508 *attrs = (MemTxAttrs) {};
12509
12510 ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &phys_addr,
12511 attrs, &prot, &page_size, &fi, &cacheattrs);
12512
12513 if (ret) {
12514 return -1;
12515 }
12516 return phys_addr;
12517}
12518
12519#endif
12520
12521
12522
12523
12524
12525
12526
12527
12528static inline uint16_t add16_sat(uint16_t a, uint16_t b)
12529{
12530 uint16_t res;
12531
12532 res = a + b;
12533 if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
12534 if (a & 0x8000)
12535 res = 0x8000;
12536 else
12537 res = 0x7fff;
12538 }
12539 return res;
12540}
12541
12542
12543static inline uint8_t add8_sat(uint8_t a, uint8_t b)
12544{
12545 uint8_t res;
12546
12547 res = a + b;
12548 if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
12549 if (a & 0x80)
12550 res = 0x80;
12551 else
12552 res = 0x7f;
12553 }
12554 return res;
12555}
12556
12557
12558static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
12559{
12560 uint16_t res;
12561
12562 res = a - b;
12563 if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
12564 if (a & 0x8000)
12565 res = 0x8000;
12566 else
12567 res = 0x7fff;
12568 }
12569 return res;
12570}
12571
12572
12573static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
12574{
12575 uint8_t res;
12576
12577 res = a - b;
12578 if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
12579 if (a & 0x80)
12580 res = 0x80;
12581 else
12582 res = 0x7f;
12583 }
12584 return res;
12585}
12586
12587#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
12588#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
12589#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
12590#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
12591#define PFX q
12592
12593#include "op_addsub.h"
12594
12595
12596static inline uint16_t add16_usat(uint16_t a, uint16_t b)
12597{
12598 uint16_t res;
12599 res = a + b;
12600 if (res < a)
12601 res = 0xffff;
12602 return res;
12603}
12604
12605static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
12606{
12607 if (a > b)
12608 return a - b;
12609 else
12610 return 0;
12611}
12612
12613static inline uint8_t add8_usat(uint8_t a, uint8_t b)
12614{
12615 uint8_t res;
12616 res = a + b;
12617 if (res < a)
12618 res = 0xff;
12619 return res;
12620}
12621
12622static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
12623{
12624 if (a > b)
12625 return a - b;
12626 else
12627 return 0;
12628}
12629
12630#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
12631#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
12632#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
12633#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
12634#define PFX uq
12635
12636#include "op_addsub.h"
12637
12638
12639#define SARITH16(a, b, n, op) do { \
12640 int32_t sum; \
12641 sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \
12642 RESULT(sum, n, 16); \
12643 if (sum >= 0) \
12644 ge |= 3 << (n * 2); \
12645 } while(0)
12646
12647#define SARITH8(a, b, n, op) do { \
12648 int32_t sum; \
12649 sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \
12650 RESULT(sum, n, 8); \
12651 if (sum >= 0) \
12652 ge |= 1 << n; \
12653 } while(0)
12654
12655
12656#define ADD16(a, b, n) SARITH16(a, b, n, +)
12657#define SUB16(a, b, n) SARITH16(a, b, n, -)
12658#define ADD8(a, b, n) SARITH8(a, b, n, +)
12659#define SUB8(a, b, n) SARITH8(a, b, n, -)
12660#define PFX s
12661#define ARITH_GE
12662
12663#include "op_addsub.h"
12664
12665
12666#define ADD16(a, b, n) do { \
12667 uint32_t sum; \
12668 sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
12669 RESULT(sum, n, 16); \
12670 if ((sum >> 16) == 1) \
12671 ge |= 3 << (n * 2); \
12672 } while(0)
12673
12674#define ADD8(a, b, n) do { \
12675 uint32_t sum; \
12676 sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
12677 RESULT(sum, n, 8); \
12678 if ((sum >> 8) == 1) \
12679 ge |= 1 << n; \
12680 } while(0)
12681
12682#define SUB16(a, b, n) do { \
12683 uint32_t sum; \
12684 sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
12685 RESULT(sum, n, 16); \
12686 if ((sum >> 16) == 0) \
12687 ge |= 3 << (n * 2); \
12688 } while(0)
12689
12690#define SUB8(a, b, n) do { \
12691 uint32_t sum; \
12692 sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
12693 RESULT(sum, n, 8); \
12694 if ((sum >> 8) == 0) \
12695 ge |= 1 << n; \
12696 } while(0)
12697
12698#define PFX u
12699#define ARITH_GE
12700
12701#include "op_addsub.h"
12702
12703
12704#define ADD16(a, b, n) \
12705 RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
12706#define SUB16(a, b, n) \
12707 RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
12708#define ADD8(a, b, n) \
12709 RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
12710#define SUB8(a, b, n) \
12711 RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
12712#define PFX sh
12713
12714#include "op_addsub.h"
12715
12716
12717#define ADD16(a, b, n) \
12718 RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
12719#define SUB16(a, b, n) \
12720 RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
12721#define ADD8(a, b, n) \
12722 RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
12723#define SUB8(a, b, n) \
12724 RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
12725#define PFX uh
12726
12727#include "op_addsub.h"
12728
12729static inline uint8_t do_usad(uint8_t a, uint8_t b)
12730{
12731 if (a > b)
12732 return a - b;
12733 else
12734 return b - a;
12735}
12736
12737
12738uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
12739{
12740 uint32_t sum;
12741 sum = do_usad(a, b);
12742 sum += do_usad(a >> 8, b >> 8);
12743 sum += do_usad(a >> 16, b >> 16);
12744 sum += do_usad(a >> 24, b >> 24);
12745 return sum;
12746}
12747
12748
12749uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
12750{
12751 uint32_t mask;
12752
12753 mask = 0;
12754 if (flags & 1)
12755 mask |= 0xff;
12756 if (flags & 2)
12757 mask |= 0xff00;
12758 if (flags & 4)
12759 mask |= 0xff0000;
12760 if (flags & 8)
12761 mask |= 0xff000000;
12762 return (a & mask) | (b & ~mask);
12763}
12764
12765
12766
12767
12768
12769uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes)
12770{
12771 uint8_t buf[4];
12772
12773 stl_le_p(buf, val);
12774
12775
12776 return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
12777}
12778
12779uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
12780{
12781 uint8_t buf[4];
12782
12783 stl_le_p(buf, val);
12784
12785
12786 return crc32c(acc, buf, bytes) ^ 0xffffffff;
12787}
12788
12789
12790
12791
12792int fp_exception_el(CPUARMState *env, int cur_el)
12793{
12794#ifndef CONFIG_USER_ONLY
12795
12796
12797
12798 if (!arm_feature(env, ARM_FEATURE_V6)) {
12799 return 0;
12800 }
12801
12802 if (arm_feature(env, ARM_FEATURE_M)) {
12803
12804 if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
12805 return 1;
12806 }
12807
12808 if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
12809 if (!extract32(env->v7m.nsacr, 10, 1)) {
12810
12811 return 3;
12812 }
12813 }
12814
12815 return 0;
12816 }
12817
12818
12819
12820
12821
12822
12823
12824 if ((arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
12825 int fpen = extract32(env->cp15.cpacr_el1, 20, 2);
12826
12827 switch (fpen) {
12828 case 0:
12829 case 2:
12830 if (cur_el == 0 || cur_el == 1) {
12831
12832 if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
12833 return 3;
12834 }
12835 return 1;
12836 }
12837 if (cur_el == 3 && !is_a64(env)) {
12838
12839 return 3;
12840 }
12841 break;
12842 case 1:
12843 if (cur_el == 0) {
12844 return 1;
12845 }
12846 break;
12847 case 3:
12848 break;
12849 }
12850 }
12851
12852
12853
12854
12855
12856
12857 if ((arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
12858 cur_el <= 2 && !arm_is_secure_below_el3(env))) {
12859 if (!extract32(env->cp15.nsacr, 10, 1)) {
12860
12861 return cur_el == 2 ? 2 : 1;
12862 }
12863 }
12864
12865
12866
12867
12868
12869
12870 if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1)
12871 && arm_is_el2_enabled(env)) {
12872
12873 return 2;
12874 }
12875
12876
12877 if (extract32(env->cp15.cptr_el[3], 10, 1)) {
12878
12879 return 3;
12880 }
12881#endif
12882 return 0;
12883}
12884
12885
12886int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
12887{
12888 if (mmu_idx & ARM_MMU_IDX_M) {
12889 return mmu_idx & ARM_MMU_IDX_M_PRIV;
12890 }
12891
12892 switch (mmu_idx) {
12893 case ARMMMUIdx_E10_0:
12894 case ARMMMUIdx_E20_0:
12895 case ARMMMUIdx_SE10_0:
12896 case ARMMMUIdx_SE20_0:
12897 return 0;
12898 case ARMMMUIdx_E10_1:
12899 case ARMMMUIdx_E10_1_PAN:
12900 case ARMMMUIdx_SE10_1:
12901 case ARMMMUIdx_SE10_1_PAN:
12902 return 1;
12903 case ARMMMUIdx_E2:
12904 case ARMMMUIdx_E20_2:
12905 case ARMMMUIdx_E20_2_PAN:
12906 case ARMMMUIdx_SE2:
12907 case ARMMMUIdx_SE20_2:
12908 case ARMMMUIdx_SE20_2_PAN:
12909 return 2;
12910 case ARMMMUIdx_SE3:
12911 return 3;
12912 default:
12913 g_assert_not_reached();
12914 }
12915}
12916
12917#ifndef CONFIG_TCG
12918ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
12919{
12920 g_assert_not_reached();
12921}
12922#endif
12923
12924ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
12925{
12926 ARMMMUIdx idx;
12927 uint64_t hcr;
12928
12929 if (arm_feature(env, ARM_FEATURE_M)) {
12930 return arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
12931 }
12932
12933
12934 switch (el) {
12935 case 0:
12936 hcr = arm_hcr_el2_eff(env);
12937 if ((hcr & (HCR_E2H | HCR_TGE)) == (HCR_E2H | HCR_TGE)) {
12938 idx = ARMMMUIdx_E20_0;
12939 } else {
12940 idx = ARMMMUIdx_E10_0;
12941 }
12942 break;
12943 case 1:
12944 if (env->pstate & PSTATE_PAN) {
12945 idx = ARMMMUIdx_E10_1_PAN;
12946 } else {
12947 idx = ARMMMUIdx_E10_1;
12948 }
12949 break;
12950 case 2:
12951
12952 if (arm_hcr_el2_eff(env) & HCR_E2H) {
12953 if (env->pstate & PSTATE_PAN) {
12954 idx = ARMMMUIdx_E20_2_PAN;
12955 } else {
12956 idx = ARMMMUIdx_E20_2;
12957 }
12958 } else {
12959 idx = ARMMMUIdx_E2;
12960 }
12961 break;
12962 case 3:
12963 return ARMMMUIdx_SE3;
12964 default:
12965 g_assert_not_reached();
12966 }
12967
12968 if (arm_is_secure_below_el3(env)) {
12969 idx &= ~ARM_MMU_IDX_A_NS;
12970 }
12971
12972 return idx;
12973}
12974
12975ARMMMUIdx arm_mmu_idx(CPUARMState *env)
12976{
12977 return arm_mmu_idx_el(env, arm_current_el(env));
12978}
12979
12980#ifndef CONFIG_USER_ONLY
12981ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
12982{
12983 return stage_1_mmu_idx(arm_mmu_idx(env));
12984}
12985#endif
12986
12987static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
12988 ARMMMUIdx mmu_idx, uint32_t flags)
12989{
12990 flags = FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el);
12991 flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX,
12992 arm_to_core_mmu_idx(mmu_idx));
12993
12994 if (arm_singlestep_active(env)) {
12995 flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
12996 }
12997 return flags;
12998}
12999
13000static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
13001 ARMMMUIdx mmu_idx, uint32_t flags)
13002{
13003 bool sctlr_b = arm_sctlr_b(env);
13004
13005 if (sctlr_b) {
13006 flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, 1);
13007 }
13008 if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
13009 flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
13010 }
13011 flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
13012
13013 return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
13014}
13015
13016static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
13017 ARMMMUIdx mmu_idx)
13018{
13019 uint32_t flags = 0;
13020
13021 if (arm_v7m_is_handler_mode(env)) {
13022 flags = FIELD_DP32(flags, TBFLAG_M32, HANDLER, 1);
13023 }
13024
13025
13026
13027
13028
13029
13030 if (arm_feature(env, ARM_FEATURE_V8) &&
13031 !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
13032 (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
13033 flags = FIELD_DP32(flags, TBFLAG_M32, STACKCHECK, 1);
13034 }
13035
13036 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
13037}
13038
13039static uint32_t rebuild_hflags_aprofile(CPUARMState *env)
13040{
13041 int flags = 0;
13042
13043 flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL,
13044 arm_debug_target_el(env));
13045 return flags;
13046}
13047
13048static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
13049 ARMMMUIdx mmu_idx)
13050{
13051 uint32_t flags = rebuild_hflags_aprofile(env);
13052
13053 if (arm_el_is_aa64(env, 1)) {
13054 flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
13055 }
13056
13057 if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
13058 (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
13059 flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
13060 }
13061
13062 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
13063}
13064
13065static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
13066 ARMMMUIdx mmu_idx)
13067{
13068 uint32_t flags = rebuild_hflags_aprofile(env);
13069 ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
13070 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
13071 uint64_t sctlr;
13072 int tbii, tbid;
13073
13074 flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
13075
13076
13077 tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
13078 tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
13079
13080 flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
13081 flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
13082
13083 if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
13084 int sve_el = sve_exception_el(env, el);
13085 uint32_t zcr_len;
13086
13087
13088
13089
13090
13091 if (sve_el != 0 && fp_el == 0) {
13092 zcr_len = 0;
13093 } else {
13094 zcr_len = sve_zcr_len_for_el(env, el);
13095 }
13096 flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
13097 flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
13098 }
13099
13100 sctlr = regime_sctlr(env, stage1);
13101
13102 if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
13103 flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
13104 }
13105
13106 if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
13107
13108
13109
13110
13111
13112
13113 if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
13114 flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
13115 }
13116 }
13117
13118 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
13119
13120 if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
13121 flags = FIELD_DP32(flags, TBFLAG_A64, BT, 1);
13122 }
13123 }
13124
13125
13126 if (!(env->pstate & PSTATE_UAO)) {
13127 switch (mmu_idx) {
13128 case ARMMMUIdx_E10_1:
13129 case ARMMMUIdx_E10_1_PAN:
13130 case ARMMMUIdx_SE10_1:
13131 case ARMMMUIdx_SE10_1_PAN:
13132
13133 flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
13134 break;
13135 case ARMMMUIdx_E20_2:
13136 case ARMMMUIdx_E20_2_PAN:
13137 case ARMMMUIdx_SE20_2:
13138 case ARMMMUIdx_SE20_2_PAN:
13139
13140
13141
13142
13143 if (env->cp15.hcr_el2 & HCR_TGE) {
13144 flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
13145 }
13146 break;
13147 default:
13148 break;
13149 }
13150 }
13151
13152 if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
13153
13154
13155
13156
13157
13158
13159
13160
13161 if (allocation_tag_access_enabled(env, el, sctlr)) {
13162 flags = FIELD_DP32(flags, TBFLAG_A64, ATA, 1);
13163 if (tbid
13164 && !(env->pstate & PSTATE_TCO)
13165 && (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) {
13166 flags = FIELD_DP32(flags, TBFLAG_A64, MTE_ACTIVE, 1);
13167 }
13168 }
13169
13170 if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
13171 && tbid
13172 && !(env->pstate & PSTATE_TCO)
13173 && (sctlr & SCTLR_TCF0)
13174 && allocation_tag_access_enabled(env, 0, sctlr)) {
13175 flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
13176 }
13177
13178 flags = FIELD_DP32(flags, TBFLAG_A64, TCMA,
13179 aa64_va_parameter_tcma(tcr, mmu_idx));
13180 }
13181
13182 return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
13183}
13184
13185static uint32_t rebuild_hflags_internal(CPUARMState *env)
13186{
13187 int el = arm_current_el(env);
13188 int fp_el = fp_exception_el(env, el);
13189 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13190
13191 if (is_a64(env)) {
13192 return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
13193 } else if (arm_feature(env, ARM_FEATURE_M)) {
13194 return rebuild_hflags_m32(env, fp_el, mmu_idx);
13195 } else {
13196 return rebuild_hflags_a32(env, fp_el, mmu_idx);
13197 }
13198}
13199
13200void arm_rebuild_hflags(CPUARMState *env)
13201{
13202 env->hflags = rebuild_hflags_internal(env);
13203}
13204
13205
13206
13207
13208
13209void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env)
13210{
13211 int el = arm_current_el(env);
13212 int fp_el = fp_exception_el(env, el);
13213 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13214 env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
13215}
13216
13217void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
13218{
13219 int fp_el = fp_exception_el(env, el);
13220 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13221
13222 env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
13223}
13224
13225
13226
13227
13228
13229void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
13230{
13231 int el = arm_current_el(env);
13232 int fp_el = fp_exception_el(env, el);
13233 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13234 env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
13235}
13236
13237void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
13238{
13239 int fp_el = fp_exception_el(env, el);
13240 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13241
13242 env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
13243}
13244
13245void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
13246{
13247 int fp_el = fp_exception_el(env, el);
13248 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
13249
13250 env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx);
13251}
13252
13253static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
13254{
13255#ifdef CONFIG_DEBUG_TCG
13256 uint32_t env_flags_current = env->hflags;
13257 uint32_t env_flags_rebuilt = rebuild_hflags_internal(env);
13258
13259 if (unlikely(env_flags_current != env_flags_rebuilt)) {
13260 fprintf(stderr, "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
13261 env_flags_current, env_flags_rebuilt);
13262 abort();
13263 }
13264#endif
13265}
13266
13267void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
13268 target_ulong *cs_base, uint32_t *pflags)
13269{
13270 uint32_t flags = env->hflags;
13271
13272 *cs_base = 0;
13273 assert_hflags_rebuild_correctly(env);
13274
13275 if (FIELD_EX32(flags, TBFLAG_ANY, AARCH64_STATE)) {
13276 *pc = env->pc;
13277 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
13278 flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
13279 }
13280 } else {
13281 *pc = env->regs[15];
13282
13283 if (arm_feature(env, ARM_FEATURE_M)) {
13284 if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
13285 FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S)
13286 != env->v7m.secure) {
13287 flags = FIELD_DP32(flags, TBFLAG_M32, FPCCR_S_WRONG, 1);
13288 }
13289
13290 if ((env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
13291 (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
13292 (env->v7m.secure &&
13293 !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
13294
13295
13296
13297
13298
13299 flags = FIELD_DP32(flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED, 1);
13300 }
13301
13302 bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
13303 if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
13304 flags = FIELD_DP32(flags, TBFLAG_M32, LSPACT, 1);
13305 }
13306 } else {
13307
13308
13309
13310
13311 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
13312 flags = FIELD_DP32(flags, TBFLAG_A32,
13313 XSCALE_CPAR, env->cp15.c15_cpar);
13314 } else {
13315 flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN,
13316 env->vfp.vec_len);
13317 flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE,
13318 env->vfp.vec_stride);
13319 }
13320 if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
13321 flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
13322 }
13323 }
13324
13325 flags = FIELD_DP32(flags, TBFLAG_AM32, THUMB, env->thumb);
13326 flags = FIELD_DP32(flags, TBFLAG_AM32, CONDEXEC, env->condexec_bits);
13327 }
13328
13329
13330
13331
13332
13333
13334
13335
13336
13337
13338 if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) &&
13339 (env->pstate & PSTATE_SS)) {
13340 flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
13341 }
13342
13343 *pflags = flags;
13344}
13345
13346#ifdef TARGET_AARCH64
13347
13348
13349
13350
13351
13352
13353
13354
13355
13356
13357
13358
13359
13360
13361void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
13362{
13363 int i, j;
13364 uint64_t pmask;
13365
13366 assert(vq >= 1 && vq <= ARM_MAX_VQ);
13367 assert(vq <= env_archcpu(env)->sve_max_vq);
13368
13369
13370 for (i = 0; i < 32; i++) {
13371 memset(&env->vfp.zregs[i].d[2 * vq], 0, 16 * (ARM_MAX_VQ - vq));
13372 }
13373
13374
13375 pmask = 0;
13376 if (vq & 3) {
13377 pmask = ~(-1ULL << (16 * (vq & 3)));
13378 }
13379 for (j = vq / 4; j < ARM_MAX_VQ / 4; j++) {
13380 for (i = 0; i < 17; ++i) {
13381 env->vfp.pregs[i].p[j] &= pmask;
13382 }
13383 pmask = 0;
13384 }
13385}
13386
13387
13388
13389
13390void aarch64_sve_change_el(CPUARMState *env, int old_el,
13391 int new_el, bool el0_a64)
13392{
13393 ARMCPU *cpu = env_archcpu(env);
13394 int old_len, new_len;
13395 bool old_a64, new_a64;
13396
13397
13398 if (!cpu_isar_feature(aa64_sve, cpu)) {
13399 return;
13400 }
13401
13402
13403 if (fp_exception_el(env, old_el) || fp_exception_el(env, new_el)) {
13404 return;
13405 }
13406
13407
13408
13409
13410
13411
13412
13413
13414
13415
13416
13417
13418
13419 old_a64 = old_el ? arm_el_is_aa64(env, old_el) : el0_a64;
13420 old_len = (old_a64 && !sve_exception_el(env, old_el)
13421 ? sve_zcr_len_for_el(env, old_el) : 0);
13422 new_a64 = new_el ? arm_el_is_aa64(env, new_el) : el0_a64;
13423 new_len = (new_a64 && !sve_exception_el(env, new_el)
13424 ? sve_zcr_len_for_el(env, new_el) : 0);
13425
13426
13427 if (new_len < old_len) {
13428 aarch64_sve_narrow_vq(env, new_len + 1);
13429 }
13430}
13431#endif
13432