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 "hw/semihosting/semihost.h"
26#include "sysemu/cpus.h"
27#include "sysemu/kvm.h"
28#include "qemu/range.h"
29#include "qapi/qapi-commands-machine-target.h"
30#include "qapi/error.h"
31#include "qemu/guest-random.h"
32#ifdef CONFIG_TCG
33#include "arm_ldst.h"
34#include "exec/cpu_ldst.h"
35#endif
36
37#define ARM_CPU_FREQ 1000000000
38
39#ifndef CONFIG_USER_ONLY
40
41static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
42 MMUAccessType access_type, ARMMMUIdx mmu_idx,
43 hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
44 target_ulong *page_size_ptr,
45 ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
46#endif
47
48static void switch_mode(CPUARMState *env, int mode);
49
50static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
51{
52 int nregs;
53
54
55 nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
56 if (reg < nregs) {
57 stq_le_p(buf, *aa32_vfp_dreg(env, reg));
58 return 8;
59 }
60 if (arm_feature(env, ARM_FEATURE_NEON)) {
61
62 nregs += 16;
63 if (reg < nregs) {
64 uint64_t *q = aa32_vfp_qreg(env, reg - 32);
65 stq_le_p(buf, q[0]);
66 stq_le_p(buf + 8, q[1]);
67 return 16;
68 }
69 }
70 switch (reg - nregs) {
71 case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4;
72 case 1: stl_p(buf, vfp_get_fpscr(env)); return 4;
73 case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4;
74 }
75 return 0;
76}
77
78static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
79{
80 int nregs;
81
82 nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
83 if (reg < nregs) {
84 *aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
85 return 8;
86 }
87 if (arm_feature(env, ARM_FEATURE_NEON)) {
88 nregs += 16;
89 if (reg < nregs) {
90 uint64_t *q = aa32_vfp_qreg(env, reg - 32);
91 q[0] = ldq_le_p(buf);
92 q[1] = ldq_le_p(buf + 8);
93 return 16;
94 }
95 }
96 switch (reg - nregs) {
97 case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
98 case 1: vfp_set_fpscr(env, ldl_p(buf)); return 4;
99 case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4;
100 }
101 return 0;
102}
103
104static int aarch64_fpu_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
105{
106 switch (reg) {
107 case 0 ... 31:
108
109 {
110 uint64_t *q = aa64_vfp_qreg(env, reg);
111 stq_le_p(buf, q[0]);
112 stq_le_p(buf + 8, q[1]);
113 return 16;
114 }
115 case 32:
116
117 stl_p(buf, vfp_get_fpsr(env));
118 return 4;
119 case 33:
120
121 stl_p(buf, vfp_get_fpcr(env));
122 return 4;
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
211static int arm_gdb_get_sysreg(CPUARMState *env, uint8_t *buf, int reg)
212{
213 ARMCPU *cpu = env_archcpu(env);
214 const ARMCPRegInfo *ri;
215 uint32_t key;
216
217 key = cpu->dyn_xml.cpregs_keys[reg];
218 ri = get_arm_cp_reginfo(cpu->cp_regs, key);
219 if (ri) {
220 if (cpreg_field_is_64bit(ri)) {
221 return gdb_get_reg64(buf, (uint64_t)read_raw_cp_reg(env, ri));
222 } else {
223 return gdb_get_reg32(buf, (uint32_t)read_raw_cp_reg(env, ri));
224 }
225 }
226 return 0;
227}
228
229static int arm_gdb_set_sysreg(CPUARMState *env, uint8_t *buf, int reg)
230{
231 return 0;
232}
233
234static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
235{
236
237
238
239
240
241
242
243
244
245
246
247 if ((ri->type & ARM_CP_CONST) ||
248 ri->fieldoffset ||
249 ((ri->raw_writefn || ri->writefn) && (ri->raw_readfn || ri->readfn))) {
250 return false;
251 }
252 return true;
253}
254
255bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
256{
257
258 int i;
259 bool ok = true;
260
261 for (i = 0; i < cpu->cpreg_array_len; i++) {
262 uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
263 const ARMCPRegInfo *ri;
264 uint64_t newval;
265
266 ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
267 if (!ri) {
268 ok = false;
269 continue;
270 }
271 if (ri->type & ARM_CP_NO_RAW) {
272 continue;
273 }
274
275 newval = read_raw_cp_reg(&cpu->env, ri);
276 if (kvm_sync) {
277
278
279
280
281
282
283 uint64_t oldval = cpu->cpreg_values[i];
284
285 if (oldval == newval) {
286 continue;
287 }
288
289 write_raw_cp_reg(&cpu->env, ri, oldval);
290 if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
291 continue;
292 }
293
294 write_raw_cp_reg(&cpu->env, ri, newval);
295 }
296 cpu->cpreg_values[i] = newval;
297 }
298 return ok;
299}
300
301bool write_list_to_cpustate(ARMCPU *cpu)
302{
303 int i;
304 bool ok = true;
305
306 for (i = 0; i < cpu->cpreg_array_len; i++) {
307 uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
308 uint64_t v = cpu->cpreg_values[i];
309 const ARMCPRegInfo *ri;
310
311 ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
312 if (!ri) {
313 ok = false;
314 continue;
315 }
316 if (ri->type & ARM_CP_NO_RAW) {
317 continue;
318 }
319
320
321
322
323 write_raw_cp_reg(&cpu->env, ri, v);
324 if (read_raw_cp_reg(&cpu->env, ri) != v) {
325 ok = false;
326 }
327 }
328 return ok;
329}
330
331static void add_cpreg_to_list(gpointer key, gpointer opaque)
332{
333 ARMCPU *cpu = opaque;
334 uint64_t regidx;
335 const ARMCPRegInfo *ri;
336
337 regidx = *(uint32_t *)key;
338 ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
339
340 if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
341 cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
342
343 cpu->cpreg_array_len++;
344 }
345}
346
347static void count_cpreg(gpointer key, gpointer opaque)
348{
349 ARMCPU *cpu = opaque;
350 uint64_t regidx;
351 const ARMCPRegInfo *ri;
352
353 regidx = *(uint32_t *)key;
354 ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
355
356 if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
357 cpu->cpreg_array_len++;
358 }
359}
360
361static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
362{
363 uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a);
364 uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b);
365
366 if (aidx > bidx) {
367 return 1;
368 }
369 if (aidx < bidx) {
370 return -1;
371 }
372 return 0;
373}
374
375void init_cpreg_list(ARMCPU *cpu)
376{
377
378
379
380 GList *keys;
381 int arraylen;
382
383 keys = g_hash_table_get_keys(cpu->cp_regs);
384 keys = g_list_sort(keys, cpreg_key_compare);
385
386 cpu->cpreg_array_len = 0;
387
388 g_list_foreach(keys, count_cpreg, cpu);
389
390 arraylen = cpu->cpreg_array_len;
391 cpu->cpreg_indexes = g_new(uint64_t, arraylen);
392 cpu->cpreg_values = g_new(uint64_t, arraylen);
393 cpu->cpreg_vmstate_indexes = g_new(uint64_t, arraylen);
394 cpu->cpreg_vmstate_values = g_new(uint64_t, arraylen);
395 cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len;
396 cpu->cpreg_array_len = 0;
397
398 g_list_foreach(keys, add_cpreg_to_list, cpu);
399
400 assert(cpu->cpreg_array_len == arraylen);
401
402 g_list_free(keys);
403}
404
405
406
407
408
409
410
411
412static CPAccessResult access_el3_aa32ns(CPUARMState *env,
413 const ARMCPRegInfo *ri,
414 bool isread)
415{
416 bool secure = arm_is_secure_below_el3(env);
417
418 assert(!arm_el_is_aa64(env, 3));
419 if (secure) {
420 return CP_ACCESS_TRAP_UNCATEGORIZED;
421 }
422 return CP_ACCESS_OK;
423}
424
425static CPAccessResult access_el3_aa32ns_aa64any(CPUARMState *env,
426 const ARMCPRegInfo *ri,
427 bool isread)
428{
429 if (!arm_el_is_aa64(env, 3)) {
430 return access_el3_aa32ns(env, ri, isread);
431 }
432 return CP_ACCESS_OK;
433}
434
435
436
437
438
439
440static CPAccessResult access_trap_aa32s_el1(CPUARMState *env,
441 const ARMCPRegInfo *ri,
442 bool isread)
443{
444 if (arm_current_el(env) == 3) {
445 return CP_ACCESS_OK;
446 }
447 if (arm_is_secure_below_el3(env)) {
448 return CP_ACCESS_TRAP_EL3;
449 }
450
451 return CP_ACCESS_TRAP_UNCATEGORIZED;
452}
453
454
455
456
457static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,
458 bool isread)
459{
460 int el = arm_current_el(env);
461 bool mdcr_el2_tdosa = (env->cp15.mdcr_el2 & MDCR_TDOSA) ||
462 (env->cp15.mdcr_el2 & MDCR_TDE) ||
463 (arm_hcr_el2_eff(env) & HCR_TGE);
464
465 if (el < 2 && mdcr_el2_tdosa && !arm_is_secure_below_el3(env)) {
466 return CP_ACCESS_TRAP_EL2;
467 }
468 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDOSA)) {
469 return CP_ACCESS_TRAP_EL3;
470 }
471 return CP_ACCESS_OK;
472}
473
474
475
476
477static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,
478 bool isread)
479{
480 int el = arm_current_el(env);
481 bool mdcr_el2_tdra = (env->cp15.mdcr_el2 & MDCR_TDRA) ||
482 (env->cp15.mdcr_el2 & MDCR_TDE) ||
483 (arm_hcr_el2_eff(env) & HCR_TGE);
484
485 if (el < 2 && mdcr_el2_tdra && !arm_is_secure_below_el3(env)) {
486 return CP_ACCESS_TRAP_EL2;
487 }
488 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
489 return CP_ACCESS_TRAP_EL3;
490 }
491 return CP_ACCESS_OK;
492}
493
494
495
496
497static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
498 bool isread)
499{
500 int el = arm_current_el(env);
501 bool mdcr_el2_tda = (env->cp15.mdcr_el2 & MDCR_TDA) ||
502 (env->cp15.mdcr_el2 & MDCR_TDE) ||
503 (arm_hcr_el2_eff(env) & HCR_TGE);
504
505 if (el < 2 && mdcr_el2_tda && !arm_is_secure_below_el3(env)) {
506 return CP_ACCESS_TRAP_EL2;
507 }
508 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TDA)) {
509 return CP_ACCESS_TRAP_EL3;
510 }
511 return CP_ACCESS_OK;
512}
513
514
515
516
517static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
518 bool isread)
519{
520 int el = arm_current_el(env);
521
522 if (el < 2 && (env->cp15.mdcr_el2 & MDCR_TPM)
523 && !arm_is_secure_below_el3(env)) {
524 return CP_ACCESS_TRAP_EL2;
525 }
526 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TPM)) {
527 return CP_ACCESS_TRAP_EL3;
528 }
529 return CP_ACCESS_OK;
530}
531
532static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
533{
534 ARMCPU *cpu = env_archcpu(env);
535
536 raw_write(env, ri, value);
537 tlb_flush(CPU(cpu));
538}
539
540static void fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
541{
542 ARMCPU *cpu = env_archcpu(env);
543
544 if (raw_read(env, ri) != value) {
545
546
547
548 tlb_flush(CPU(cpu));
549 raw_write(env, ri, value);
550 }
551}
552
553static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
554 uint64_t value)
555{
556 ARMCPU *cpu = env_archcpu(env);
557
558 if (raw_read(env, ri) != value && !arm_feature(env, ARM_FEATURE_PMSA)
559 && !extended_addresses_enabled(env)) {
560
561
562
563
564 tlb_flush(CPU(cpu));
565 }
566 raw_write(env, ri, value);
567}
568
569
570static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
571 uint64_t value)
572{
573 CPUState *cs = env_cpu(env);
574
575 tlb_flush_all_cpus_synced(cs);
576}
577
578static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
579 uint64_t value)
580{
581 CPUState *cs = env_cpu(env);
582
583 tlb_flush_all_cpus_synced(cs);
584}
585
586static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
587 uint64_t value)
588{
589 CPUState *cs = env_cpu(env);
590
591 tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
592}
593
594static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
595 uint64_t value)
596{
597 CPUState *cs = env_cpu(env);
598
599 tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
600}
601
602
603
604
605
606
607static bool tlb_force_broadcast(CPUARMState *env)
608{
609 return (env->cp15.hcr_el2 & HCR_FB) &&
610 arm_current_el(env) == 1 && arm_is_secure_below_el3(env);
611}
612
613static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
614 uint64_t value)
615{
616
617 ARMCPU *cpu = env_archcpu(env);
618
619 if (tlb_force_broadcast(env)) {
620 tlbiall_is_write(env, NULL, value);
621 return;
622 }
623
624 tlb_flush(CPU(cpu));
625}
626
627static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
628 uint64_t value)
629{
630
631 ARMCPU *cpu = env_archcpu(env);
632
633 if (tlb_force_broadcast(env)) {
634 tlbimva_is_write(env, NULL, value);
635 return;
636 }
637
638 tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
639}
640
641static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
642 uint64_t value)
643{
644
645 ARMCPU *cpu = env_archcpu(env);
646
647 if (tlb_force_broadcast(env)) {
648 tlbiasid_is_write(env, NULL, value);
649 return;
650 }
651
652 tlb_flush(CPU(cpu));
653}
654
655static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
656 uint64_t value)
657{
658
659 ARMCPU *cpu = env_archcpu(env);
660
661 if (tlb_force_broadcast(env)) {
662 tlbimvaa_is_write(env, NULL, value);
663 return;
664 }
665
666 tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
667}
668
669static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
670 uint64_t value)
671{
672 CPUState *cs = env_cpu(env);
673
674 tlb_flush_by_mmuidx(cs,
675 ARMMMUIdxBit_S12NSE1 |
676 ARMMMUIdxBit_S12NSE0 |
677 ARMMMUIdxBit_S2NS);
678}
679
680static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
681 uint64_t value)
682{
683 CPUState *cs = env_cpu(env);
684
685 tlb_flush_by_mmuidx_all_cpus_synced(cs,
686 ARMMMUIdxBit_S12NSE1 |
687 ARMMMUIdxBit_S12NSE0 |
688 ARMMMUIdxBit_S2NS);
689}
690
691static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
692 uint64_t value)
693{
694
695
696
697
698
699
700 CPUState *cs = env_cpu(env);
701 uint64_t pageaddr;
702
703 if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
704 return;
705 }
706
707 pageaddr = sextract64(value << 12, 0, 40);
708
709 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S2NS);
710}
711
712static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
713 uint64_t value)
714{
715 CPUState *cs = env_cpu(env);
716 uint64_t pageaddr;
717
718 if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
719 return;
720 }
721
722 pageaddr = sextract64(value << 12, 0, 40);
723
724 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
725 ARMMMUIdxBit_S2NS);
726}
727
728static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
729 uint64_t value)
730{
731 CPUState *cs = env_cpu(env);
732
733 tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_S1E2);
734}
735
736static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
737 uint64_t value)
738{
739 CPUState *cs = env_cpu(env);
740
741 tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E2);
742}
743
744static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
745 uint64_t value)
746{
747 CPUState *cs = env_cpu(env);
748 uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
749
750 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S1E2);
751}
752
753static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
754 uint64_t value)
755{
756 CPUState *cs = env_cpu(env);
757 uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
758
759 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
760 ARMMMUIdxBit_S1E2);
761}
762
763static const ARMCPRegInfo cp_reginfo[] = {
764
765
766
767
768
769 { .name = "FCSEIDR",
770 .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0,
771 .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS,
772 .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_ns),
773 .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
774 { .name = "FCSEIDR_S",
775 .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 0,
776 .access = PL1_RW, .secure = ARM_CP_SECSTATE_S,
777 .fieldoffset = offsetof(CPUARMState, cp15.fcseidr_s),
778 .resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
779
780
781
782
783
784
785 { .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH,
786 .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
787 .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS,
788 .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]),
789 .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
790 { .name = "CONTEXTIDR_S", .state = ARM_CP_STATE_AA32,
791 .cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
792 .access = PL1_RW, .secure = ARM_CP_SECSTATE_S,
793 .fieldoffset = offsetof(CPUARMState, cp15.contextidr_s),
794 .resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
795 REGINFO_SENTINEL
796};
797
798static const ARMCPRegInfo not_v8_cp_reginfo[] = {
799
800
801
802
803 { .name = "DACR",
804 .cp = 15, .opc1 = CP_ANY, .crn = 3, .crm = CP_ANY, .opc2 = CP_ANY,
805 .access = PL1_RW, .resetvalue = 0,
806 .writefn = dacr_write, .raw_writefn = raw_write,
807 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
808 offsetoflow32(CPUARMState, cp15.dacr_ns) } },
809
810
811
812 { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 0,
813 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
814 { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 1,
815 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
816 { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 4,
817 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
818 { .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 8,
819 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_NOP },
820
821 { .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
822 .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
823 .type = ARM_CP_NOP | ARM_CP_OVERRIDE },
824 REGINFO_SENTINEL
825};
826
827static const ARMCPRegInfo not_v6_cp_reginfo[] = {
828
829
830
831 { .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2,
832 .access = PL1_W, .type = ARM_CP_WFI },
833 REGINFO_SENTINEL
834};
835
836static const ARMCPRegInfo not_v7_cp_reginfo[] = {
837
838
839
840 { .name = "WFI_v6", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
841 .access = PL1_W, .type = ARM_CP_WFI },
842
843
844
845
846 { .name = "DLOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 0,
847 .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_data),
848 .resetvalue = 0 },
849 { .name = "ILOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 0, .opc2 = 1,
850 .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_insn),
851 .resetvalue = 0 },
852
853 { .name = "DUMMY", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = CP_ANY,
854 .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
855 .resetvalue = 0 },
856
857
858
859
860
861 { .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
862 .access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 },
863
864
865
866 { .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY,
867 .opc1 = CP_ANY, .opc2 = 0, .access = PL1_W, .writefn = tlbiall_write,
868 .type = ARM_CP_NO_RAW },
869 { .name = "TLBIMVA", .cp = 15, .crn = 8, .crm = CP_ANY,
870 .opc1 = CP_ANY, .opc2 = 1, .access = PL1_W, .writefn = tlbimva_write,
871 .type = ARM_CP_NO_RAW },
872 { .name = "TLBIASID", .cp = 15, .crn = 8, .crm = CP_ANY,
873 .opc1 = CP_ANY, .opc2 = 2, .access = PL1_W, .writefn = tlbiasid_write,
874 .type = ARM_CP_NO_RAW },
875 { .name = "TLBIMVAA", .cp = 15, .crn = 8, .crm = CP_ANY,
876 .opc1 = CP_ANY, .opc2 = 3, .access = PL1_W, .writefn = tlbimvaa_write,
877 .type = ARM_CP_NO_RAW },
878 { .name = "PRRR", .cp = 15, .crn = 10, .crm = 2,
879 .opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_NOP },
880 { .name = "NMRR", .cp = 15, .crn = 10, .crm = 2,
881 .opc1 = 0, .opc2 = 1, .access = PL1_RW, .type = ARM_CP_NOP },
882 REGINFO_SENTINEL
883};
884
885static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
886 uint64_t value)
887{
888 uint32_t mask = 0;
889
890
891 if (!arm_feature(env, ARM_FEATURE_V8)) {
892
893
894
895
896 if (arm_feature(env, ARM_FEATURE_VFP)) {
897
898 mask |= (1 << 31) | (1 << 30) | (0xf << 20);
899
900 if (!arm_feature(env, ARM_FEATURE_NEON)) {
901
902 value |= (1 << 31);
903 }
904
905
906
907
908 if (!arm_feature(env, ARM_FEATURE_NEON) ||
909 !arm_feature(env, ARM_FEATURE_VFP3)) {
910
911 value |= (1 << 30);
912 }
913 }
914 value &= mask;
915 }
916
917
918
919
920
921 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
922 !arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
923 value &= ~(0xf << 20);
924 value |= env->cp15.cpacr_el1 & (0xf << 20);
925 }
926
927 env->cp15.cpacr_el1 = value;
928}
929
930static uint64_t cpacr_read(CPUARMState *env, const ARMCPRegInfo *ri)
931{
932
933
934
935
936 uint64_t value = env->cp15.cpacr_el1;
937
938 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
939 !arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
940 value &= ~(0xf << 20);
941 }
942 return value;
943}
944
945
946static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
947{
948
949
950
951 cpacr_write(env, ri, 0);
952}
953
954static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
955 bool isread)
956{
957 if (arm_feature(env, ARM_FEATURE_V8)) {
958
959 if (arm_current_el(env) == 1 &&
960 (env->cp15.cptr_el[2] & CPTR_TCPAC) && !arm_is_secure(env)) {
961 return CP_ACCESS_TRAP_EL2;
962
963 } else if (arm_current_el(env) < 3 &&
964 (env->cp15.cptr_el[3] & CPTR_TCPAC)) {
965 return CP_ACCESS_TRAP_EL3;
966 }
967 }
968
969 return CP_ACCESS_OK;
970}
971
972static CPAccessResult cptr_access(CPUARMState *env, const ARMCPRegInfo *ri,
973 bool isread)
974{
975
976 if (arm_current_el(env) == 2 && (env->cp15.cptr_el[3] & CPTR_TCPAC)) {
977 return CP_ACCESS_TRAP_EL3;
978 }
979
980 return CP_ACCESS_OK;
981}
982
983static const ARMCPRegInfo v6_cp_reginfo[] = {
984
985 { .name = "MVA_prefetch",
986 .cp = 15, .crn = 7, .crm = 13, .opc1 = 0, .opc2 = 1,
987 .access = PL1_W, .type = ARM_CP_NOP },
988
989
990
991
992 { .name = "ISB", .cp = 15, .crn = 7, .crm = 5, .opc1 = 0, .opc2 = 4,
993 .access = PL0_W, .type = ARM_CP_NO_RAW, .writefn = arm_cp_write_ignore },
994 { .name = "DSB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 4,
995 .access = PL0_W, .type = ARM_CP_NOP },
996 { .name = "DMB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 5,
997 .access = PL0_W, .type = ARM_CP_NOP },
998 { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2,
999 .access = PL1_RW,
1000 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s),
1001 offsetof(CPUARMState, cp15.ifar_ns) },
1002 .resetvalue = 0, },
1003
1004
1005
1006 { .name = "WFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
1007 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0, },
1008 { .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
1009 .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
1010 .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
1011 .resetfn = cpacr_reset, .writefn = cpacr_write, .readfn = cpacr_read },
1012 REGINFO_SENTINEL
1013};
1014
1015
1016#define PMCRN_MASK 0xf800
1017#define PMCRN_SHIFT 11
1018#define PMCRLC 0x40
1019#define PMCRDP 0x10
1020#define PMCRD 0x8
1021#define PMCRC 0x4
1022#define PMCRP 0x2
1023#define PMCRE 0x1
1024
1025#define PMXEVTYPER_P 0x80000000
1026#define PMXEVTYPER_U 0x40000000
1027#define PMXEVTYPER_NSK 0x20000000
1028#define PMXEVTYPER_NSU 0x10000000
1029#define PMXEVTYPER_NSH 0x08000000
1030#define PMXEVTYPER_M 0x04000000
1031#define PMXEVTYPER_MT 0x02000000
1032#define PMXEVTYPER_EVTCOUNT 0x0000ffff
1033#define PMXEVTYPER_MASK (PMXEVTYPER_P | PMXEVTYPER_U | PMXEVTYPER_NSK | \
1034 PMXEVTYPER_NSU | PMXEVTYPER_NSH | \
1035 PMXEVTYPER_M | PMXEVTYPER_MT | \
1036 PMXEVTYPER_EVTCOUNT)
1037
1038#define PMCCFILTR 0xf8000000
1039#define PMCCFILTR_M PMXEVTYPER_M
1040#define PMCCFILTR_EL0 (PMCCFILTR | PMCCFILTR_M)
1041
1042static inline uint32_t pmu_num_counters(CPUARMState *env)
1043{
1044 return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
1045}
1046
1047
1048static inline uint64_t pmu_counter_mask(CPUARMState *env)
1049{
1050 return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
1051}
1052
1053typedef struct pm_event {
1054 uint16_t number;
1055
1056 bool (*supported)(CPUARMState *);
1057
1058
1059
1060
1061 uint64_t (*get_count)(CPUARMState *);
1062
1063
1064
1065
1066
1067
1068 int64_t (*ns_per_count)(uint64_t);
1069} pm_event;
1070
1071static bool event_always_supported(CPUARMState *env)
1072{
1073 return true;
1074}
1075
1076static uint64_t swinc_get_count(CPUARMState *env)
1077{
1078
1079
1080
1081
1082 return 0;
1083}
1084
1085static int64_t swinc_ns_per(uint64_t ignored)
1086{
1087 return -1;
1088}
1089
1090
1091
1092
1093
1094static uint64_t cycles_get_count(CPUARMState *env)
1095{
1096#ifndef CONFIG_USER_ONLY
1097 return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
1098 ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
1099#else
1100 return cpu_get_host_ticks();
1101#endif
1102}
1103
1104#ifndef CONFIG_USER_ONLY
1105static int64_t cycles_ns_per(uint64_t cycles)
1106{
1107 return (ARM_CPU_FREQ / NANOSECONDS_PER_SECOND) * cycles;
1108}
1109
1110static bool instructions_supported(CPUARMState *env)
1111{
1112 return use_icount == 1 ;
1113}
1114
1115static uint64_t instructions_get_count(CPUARMState *env)
1116{
1117 return (uint64_t)cpu_get_icount_raw();
1118}
1119
1120static int64_t instructions_ns_per(uint64_t icount)
1121{
1122 return cpu_icount_to_ns((int64_t)icount);
1123}
1124#endif
1125
1126static const pm_event pm_events[] = {
1127 { .number = 0x000,
1128 .supported = event_always_supported,
1129 .get_count = swinc_get_count,
1130 .ns_per_count = swinc_ns_per,
1131 },
1132#ifndef CONFIG_USER_ONLY
1133 { .number = 0x008,
1134 .supported = instructions_supported,
1135 .get_count = instructions_get_count,
1136 .ns_per_count = instructions_ns_per,
1137 },
1138 { .number = 0x011,
1139 .supported = event_always_supported,
1140 .get_count = cycles_get_count,
1141 .ns_per_count = cycles_ns_per,
1142 }
1143#endif
1144};
1145
1146
1147
1148
1149
1150
1151
1152#define MAX_EVENT_ID 0x11
1153#define UNSUPPORTED_EVENT UINT16_MAX
1154static uint16_t supported_event_map[MAX_EVENT_ID + 1];
1155
1156
1157
1158
1159
1160
1161
1162void pmu_init(ARMCPU *cpu)
1163{
1164 unsigned int i;
1165
1166
1167
1168
1169
1170 for (i = 0; i < ARRAY_SIZE(supported_event_map); i++) {
1171 supported_event_map[i] = UNSUPPORTED_EVENT;
1172 }
1173 cpu->pmceid0 = 0;
1174 cpu->pmceid1 = 0;
1175
1176 for (i = 0; i < ARRAY_SIZE(pm_events); i++) {
1177 const pm_event *cnt = &pm_events[i];
1178 assert(cnt->number <= MAX_EVENT_ID);
1179
1180 assert(cnt->number <= 0x3f);
1181
1182 if (cnt->supported(&cpu->env)) {
1183 supported_event_map[cnt->number] = i;
1184 uint64_t event_mask = 1ULL << (cnt->number & 0x1f);
1185 if (cnt->number & 0x20) {
1186 cpu->pmceid1 |= event_mask;
1187 } else {
1188 cpu->pmceid0 |= event_mask;
1189 }
1190 }
1191 }
1192}
1193
1194
1195
1196
1197static bool event_supported(uint16_t number)
1198{
1199 if (number > MAX_EVENT_ID) {
1200 return false;
1201 }
1202 return supported_event_map[number] != UNSUPPORTED_EVENT;
1203}
1204
1205static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
1206 bool isread)
1207{
1208
1209
1210
1211
1212 int el = arm_current_el(env);
1213
1214 if (el == 0 && !(env->cp15.c9_pmuserenr & 1)) {
1215 return CP_ACCESS_TRAP;
1216 }
1217 if (el < 2 && (env->cp15.mdcr_el2 & MDCR_TPM)
1218 && !arm_is_secure_below_el3(env)) {
1219 return CP_ACCESS_TRAP_EL2;
1220 }
1221 if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TPM)) {
1222 return CP_ACCESS_TRAP_EL3;
1223 }
1224
1225 return CP_ACCESS_OK;
1226}
1227
1228static CPAccessResult pmreg_access_xevcntr(CPUARMState *env,
1229 const ARMCPRegInfo *ri,
1230 bool isread)
1231{
1232
1233 if (arm_feature(env, ARM_FEATURE_V8)
1234 && arm_current_el(env) == 0
1235 && (env->cp15.c9_pmuserenr & (1 << 3)) != 0
1236 && isread) {
1237 return CP_ACCESS_OK;
1238 }
1239
1240 return pmreg_access(env, ri, isread);
1241}
1242
1243static CPAccessResult pmreg_access_swinc(CPUARMState *env,
1244 const ARMCPRegInfo *ri,
1245 bool isread)
1246{
1247
1248 if (arm_feature(env, ARM_FEATURE_V8)
1249 && arm_current_el(env) == 0
1250 && (env->cp15.c9_pmuserenr & (1 << 1)) != 0
1251 && !isread) {
1252 return CP_ACCESS_OK;
1253 }
1254
1255 return pmreg_access(env, ri, isread);
1256}
1257
1258static CPAccessResult pmreg_access_selr(CPUARMState *env,
1259 const ARMCPRegInfo *ri,
1260 bool isread)
1261{
1262
1263 if (arm_feature(env, ARM_FEATURE_V8)
1264 && arm_current_el(env) == 0
1265 && (env->cp15.c9_pmuserenr & (1 << 3)) != 0) {
1266 return CP_ACCESS_OK;
1267 }
1268
1269 return pmreg_access(env, ri, isread);
1270}
1271
1272static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
1273 const ARMCPRegInfo *ri,
1274 bool isread)
1275{
1276
1277 if (arm_feature(env, ARM_FEATURE_V8)
1278 && arm_current_el(env) == 0
1279 && (env->cp15.c9_pmuserenr & (1 << 2)) != 0
1280 && isread) {
1281 return CP_ACCESS_OK;
1282 }
1283
1284 return pmreg_access(env, ri, isread);
1285}
1286
1287
1288
1289
1290static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
1291{
1292 uint64_t filter;
1293 bool e, p, u, nsk, nsu, nsh, m;
1294 bool enabled, prohibited, filtered;
1295 bool secure = arm_is_secure(env);
1296 int el = arm_current_el(env);
1297 uint8_t hpmn = env->cp15.mdcr_el2 & MDCR_HPMN;
1298
1299 if (!arm_feature(env, ARM_FEATURE_PMU)) {
1300 return false;
1301 }
1302
1303 if (!arm_feature(env, ARM_FEATURE_EL2) ||
1304 (counter < hpmn || counter == 31)) {
1305 e = env->cp15.c9_pmcr & PMCRE;
1306 } else {
1307 e = env->cp15.mdcr_el2 & MDCR_HPME;
1308 }
1309 enabled = e && (env->cp15.c9_pmcnten & (1 << counter));
1310
1311 if (!secure) {
1312 if (el == 2 && (counter < hpmn || counter == 31)) {
1313 prohibited = env->cp15.mdcr_el2 & MDCR_HPMD;
1314 } else {
1315 prohibited = false;
1316 }
1317 } else {
1318 prohibited = arm_feature(env, ARM_FEATURE_EL3) &&
1319 (env->cp15.mdcr_el3 & MDCR_SPME);
1320 }
1321
1322 if (prohibited && counter == 31) {
1323 prohibited = env->cp15.c9_pmcr & PMCRDP;
1324 }
1325
1326 if (counter == 31) {
1327 filter = env->cp15.pmccfiltr_el0;
1328 } else {
1329 filter = env->cp15.c14_pmevtyper[counter];
1330 }
1331
1332 p = filter & PMXEVTYPER_P;
1333 u = filter & PMXEVTYPER_U;
1334 nsk = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSK);
1335 nsu = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSU);
1336 nsh = arm_feature(env, ARM_FEATURE_EL2) && (filter & PMXEVTYPER_NSH);
1337 m = arm_el_is_aa64(env, 1) &&
1338 arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_M);
1339
1340 if (el == 0) {
1341 filtered = secure ? u : u != nsu;
1342 } else if (el == 1) {
1343 filtered = secure ? p : p != nsk;
1344 } else if (el == 2) {
1345 filtered = !nsh;
1346 } else {
1347 filtered = m != p;
1348 }
1349
1350 if (counter != 31) {
1351
1352
1353
1354
1355 uint16_t event = filter & PMXEVTYPER_EVTCOUNT;
1356 if (!event_supported(event)) {
1357 return false;
1358 }
1359 }
1360
1361 return enabled && !prohibited && !filtered;
1362}
1363
1364static void pmu_update_irq(CPUARMState *env)
1365{
1366 ARMCPU *cpu = env_archcpu(env);
1367 qemu_set_irq(cpu->pmu_interrupt, (env->cp15.c9_pmcr & PMCRE) &&
1368 (env->cp15.c9_pminten & env->cp15.c9_pmovsr));
1369}
1370
1371
1372
1373
1374
1375
1376
1377static void pmccntr_op_start(CPUARMState *env)
1378{
1379 uint64_t cycles = cycles_get_count(env);
1380
1381 if (pmu_counter_enabled(env, 31)) {
1382 uint64_t eff_cycles = cycles;
1383 if (env->cp15.c9_pmcr & PMCRD) {
1384
1385 eff_cycles /= 64;
1386 }
1387
1388 uint64_t new_pmccntr = eff_cycles - env->cp15.c15_ccnt_delta;
1389
1390 uint64_t overflow_mask = env->cp15.c9_pmcr & PMCRLC ? \
1391 1ull << 63 : 1ull << 31;
1392 if (env->cp15.c15_ccnt & ~new_pmccntr & overflow_mask) {
1393 env->cp15.c9_pmovsr |= (1 << 31);
1394 pmu_update_irq(env);
1395 }
1396
1397 env->cp15.c15_ccnt = new_pmccntr;
1398 }
1399 env->cp15.c15_ccnt_delta = cycles;
1400}
1401
1402
1403
1404
1405
1406
1407static void pmccntr_op_finish(CPUARMState *env)
1408{
1409 if (pmu_counter_enabled(env, 31)) {
1410#ifndef CONFIG_USER_ONLY
1411
1412 uint64_t remaining_cycles = -env->cp15.c15_ccnt;
1413 if (!(env->cp15.c9_pmcr & PMCRLC)) {
1414 remaining_cycles = (uint32_t)remaining_cycles;
1415 }
1416 int64_t overflow_in = cycles_ns_per(remaining_cycles);
1417
1418 if (overflow_in > 0) {
1419 int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
1420 overflow_in;
1421 ARMCPU *cpu = env_archcpu(env);
1422 timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
1423 }
1424#endif
1425
1426 uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
1427 if (env->cp15.c9_pmcr & PMCRD) {
1428
1429 prev_cycles /= 64;
1430 }
1431 env->cp15.c15_ccnt_delta = prev_cycles - env->cp15.c15_ccnt;
1432 }
1433}
1434
1435static void pmevcntr_op_start(CPUARMState *env, uint8_t counter)
1436{
1437
1438 uint16_t event = env->cp15.c14_pmevtyper[counter] & PMXEVTYPER_EVTCOUNT;
1439 uint64_t count = 0;
1440 if (event_supported(event)) {
1441 uint16_t event_idx = supported_event_map[event];
1442 count = pm_events[event_idx].get_count(env);
1443 }
1444
1445 if (pmu_counter_enabled(env, counter)) {
1446 uint32_t new_pmevcntr = count - env->cp15.c14_pmevcntr_delta[counter];
1447
1448 if (env->cp15.c14_pmevcntr[counter] & ~new_pmevcntr & INT32_MIN) {
1449 env->cp15.c9_pmovsr |= (1 << counter);
1450 pmu_update_irq(env);
1451 }
1452 env->cp15.c14_pmevcntr[counter] = new_pmevcntr;
1453 }
1454 env->cp15.c14_pmevcntr_delta[counter] = count;
1455}
1456
1457static void pmevcntr_op_finish(CPUARMState *env, uint8_t counter)
1458{
1459 if (pmu_counter_enabled(env, counter)) {
1460#ifndef CONFIG_USER_ONLY
1461 uint16_t event = env->cp15.c14_pmevtyper[counter] & PMXEVTYPER_EVTCOUNT;
1462 uint16_t event_idx = supported_event_map[event];
1463 uint64_t delta = UINT32_MAX -
1464 (uint32_t)env->cp15.c14_pmevcntr[counter] + 1;
1465 int64_t overflow_in = pm_events[event_idx].ns_per_count(delta);
1466
1467 if (overflow_in > 0) {
1468 int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
1469 overflow_in;
1470 ARMCPU *cpu = env_archcpu(env);
1471 timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
1472 }
1473#endif
1474
1475 env->cp15.c14_pmevcntr_delta[counter] -=
1476 env->cp15.c14_pmevcntr[counter];
1477 }
1478}
1479
1480void pmu_op_start(CPUARMState *env)
1481{
1482 unsigned int i;
1483 pmccntr_op_start(env);
1484 for (i = 0; i < pmu_num_counters(env); i++) {
1485 pmevcntr_op_start(env, i);
1486 }
1487}
1488
1489void pmu_op_finish(CPUARMState *env)
1490{
1491 unsigned int i;
1492 pmccntr_op_finish(env);
1493 for (i = 0; i < pmu_num_counters(env); i++) {
1494 pmevcntr_op_finish(env, i);
1495 }
1496}
1497
1498void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
1499{
1500 pmu_op_start(&cpu->env);
1501}
1502
1503void pmu_post_el_change(ARMCPU *cpu, void *ignored)
1504{
1505 pmu_op_finish(&cpu->env);
1506}
1507
1508void arm_pmu_timer_cb(void *opaque)
1509{
1510 ARMCPU *cpu = opaque;
1511
1512
1513
1514
1515
1516
1517
1518 pmu_op_start(&cpu->env);
1519 pmu_op_finish(&cpu->env);
1520}
1521
1522static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1523 uint64_t value)
1524{
1525 pmu_op_start(env);
1526
1527 if (value & PMCRC) {
1528
1529 env->cp15.c15_ccnt = 0;
1530 }
1531
1532 if (value & PMCRP) {
1533 unsigned int i;
1534 for (i = 0; i < pmu_num_counters(env); i++) {
1535 env->cp15.c14_pmevcntr[i] = 0;
1536 }
1537 }
1538
1539
1540 env->cp15.c9_pmcr &= ~0x39;
1541 env->cp15.c9_pmcr |= (value & 0x39);
1542
1543 pmu_op_finish(env);
1544}
1545
1546static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
1547 uint64_t value)
1548{
1549 unsigned int i;
1550 for (i = 0; i < pmu_num_counters(env); i++) {
1551
1552 if ((value & (1 << i)) &&
1553
1554 pmu_counter_enabled(env, i) &&
1555
1556 (env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) {
1557 pmevcntr_op_start(env, i);
1558
1559
1560
1561
1562
1563 uint32_t new_pmswinc = env->cp15.c14_pmevcntr[i] + 1;
1564
1565 if (env->cp15.c14_pmevcntr[i] & ~new_pmswinc & INT32_MIN) {
1566 env->cp15.c9_pmovsr |= (1 << i);
1567 pmu_update_irq(env);
1568 }
1569
1570 env->cp15.c14_pmevcntr[i] = new_pmswinc;
1571
1572 pmevcntr_op_finish(env, i);
1573 }
1574 }
1575}
1576
1577static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
1578{
1579 uint64_t ret;
1580 pmccntr_op_start(env);
1581 ret = env->cp15.c15_ccnt;
1582 pmccntr_op_finish(env);
1583 return ret;
1584}
1585
1586static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1587 uint64_t value)
1588{
1589
1590
1591
1592
1593
1594 env->cp15.c9_pmselr = value & 0x1f;
1595}
1596
1597static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1598 uint64_t value)
1599{
1600 pmccntr_op_start(env);
1601 env->cp15.c15_ccnt = value;
1602 pmccntr_op_finish(env);
1603}
1604
1605static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
1606 uint64_t value)
1607{
1608 uint64_t cur_val = pmccntr_read(env, NULL);
1609
1610 pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value));
1611}
1612
1613static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1614 uint64_t value)
1615{
1616 pmccntr_op_start(env);
1617 env->cp15.pmccfiltr_el0 = value & PMCCFILTR_EL0;
1618 pmccntr_op_finish(env);
1619}
1620
1621static void pmccfiltr_write_a32(CPUARMState *env, const ARMCPRegInfo *ri,
1622 uint64_t value)
1623{
1624 pmccntr_op_start(env);
1625
1626 env->cp15.pmccfiltr_el0 = (env->cp15.pmccfiltr_el0 & PMCCFILTR_M) |
1627 (value & PMCCFILTR);
1628 pmccntr_op_finish(env);
1629}
1630
1631static uint64_t pmccfiltr_read_a32(CPUARMState *env, const ARMCPRegInfo *ri)
1632{
1633
1634 return env->cp15.pmccfiltr_el0 & PMCCFILTR;
1635}
1636
1637static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
1638 uint64_t value)
1639{
1640 value &= pmu_counter_mask(env);
1641 env->cp15.c9_pmcnten |= value;
1642}
1643
1644static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1645 uint64_t value)
1646{
1647 value &= pmu_counter_mask(env);
1648 env->cp15.c9_pmcnten &= ~value;
1649}
1650
1651static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1652 uint64_t value)
1653{
1654 value &= pmu_counter_mask(env);
1655 env->cp15.c9_pmovsr &= ~value;
1656 pmu_update_irq(env);
1657}
1658
1659static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
1660 uint64_t value)
1661{
1662 value &= pmu_counter_mask(env);
1663 env->cp15.c9_pmovsr |= value;
1664 pmu_update_irq(env);
1665}
1666
1667static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
1668 uint64_t value, const uint8_t counter)
1669{
1670 if (counter == 31) {
1671 pmccfiltr_write(env, ri, value);
1672 } else if (counter < pmu_num_counters(env)) {
1673 pmevcntr_op_start(env, counter);
1674
1675
1676
1677
1678
1679
1680
1681 uint16_t old_event = env->cp15.c14_pmevtyper[counter] &
1682 PMXEVTYPER_EVTCOUNT;
1683 uint16_t new_event = value & PMXEVTYPER_EVTCOUNT;
1684 if (old_event != new_event) {
1685 uint64_t count = 0;
1686 if (event_supported(new_event)) {
1687 uint16_t event_idx = supported_event_map[new_event];
1688 count = pm_events[event_idx].get_count(env);
1689 }
1690 env->cp15.c14_pmevcntr_delta[counter] = count;
1691 }
1692
1693 env->cp15.c14_pmevtyper[counter] = value & PMXEVTYPER_MASK;
1694 pmevcntr_op_finish(env, counter);
1695 }
1696
1697
1698
1699
1700}
1701
1702static uint64_t pmevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri,
1703 const uint8_t counter)
1704{
1705 if (counter == 31) {
1706 return env->cp15.pmccfiltr_el0;
1707 } else if (counter < pmu_num_counters(env)) {
1708 return env->cp15.c14_pmevtyper[counter];
1709 } else {
1710
1711
1712
1713
1714 return 0;
1715 }
1716}
1717
1718static void pmevtyper_writefn(CPUARMState *env, const ARMCPRegInfo *ri,
1719 uint64_t value)
1720{
1721 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1722 pmevtyper_write(env, ri, value, counter);
1723}
1724
1725static void pmevtyper_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri,
1726 uint64_t value)
1727{
1728 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1729 env->cp15.c14_pmevtyper[counter] = value;
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740 uint16_t event = value & PMXEVTYPER_EVTCOUNT;
1741 if (event_supported(event)) {
1742 uint16_t event_idx = supported_event_map[event];
1743 env->cp15.c14_pmevcntr_delta[counter] =
1744 pm_events[event_idx].get_count(env);
1745 }
1746}
1747
1748static uint64_t pmevtyper_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
1749{
1750 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1751 return pmevtyper_read(env, ri, counter);
1752}
1753
1754static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
1755 uint64_t value)
1756{
1757 pmevtyper_write(env, ri, value, env->cp15.c9_pmselr & 31);
1758}
1759
1760static uint64_t pmxevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri)
1761{
1762 return pmevtyper_read(env, ri, env->cp15.c9_pmselr & 31);
1763}
1764
1765static void pmevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1766 uint64_t value, uint8_t counter)
1767{
1768 if (counter < pmu_num_counters(env)) {
1769 pmevcntr_op_start(env, counter);
1770 env->cp15.c14_pmevcntr[counter] = value;
1771 pmevcntr_op_finish(env, counter);
1772 }
1773
1774
1775
1776
1777}
1778
1779static uint64_t pmevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri,
1780 uint8_t counter)
1781{
1782 if (counter < pmu_num_counters(env)) {
1783 uint64_t ret;
1784 pmevcntr_op_start(env, counter);
1785 ret = env->cp15.c14_pmevcntr[counter];
1786 pmevcntr_op_finish(env, counter);
1787 return ret;
1788 } else {
1789
1790
1791 return 0;
1792 }
1793}
1794
1795static void pmevcntr_writefn(CPUARMState *env, const ARMCPRegInfo *ri,
1796 uint64_t value)
1797{
1798 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1799 pmevcntr_write(env, ri, value, counter);
1800}
1801
1802static uint64_t pmevcntr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
1803{
1804 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1805 return pmevcntr_read(env, ri, counter);
1806}
1807
1808static void pmevcntr_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri,
1809 uint64_t value)
1810{
1811 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1812 assert(counter < pmu_num_counters(env));
1813 env->cp15.c14_pmevcntr[counter] = value;
1814 pmevcntr_write(env, ri, value, counter);
1815}
1816
1817static uint64_t pmevcntr_rawread(CPUARMState *env, const ARMCPRegInfo *ri)
1818{
1819 uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
1820 assert(counter < pmu_num_counters(env));
1821 return env->cp15.c14_pmevcntr[counter];
1822}
1823
1824static void pmxevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1825 uint64_t value)
1826{
1827 pmevcntr_write(env, ri, value, env->cp15.c9_pmselr & 31);
1828}
1829
1830static uint64_t pmxevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
1831{
1832 return pmevcntr_read(env, ri, env->cp15.c9_pmselr & 31);
1833}
1834
1835static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1836 uint64_t value)
1837{
1838 if (arm_feature(env, ARM_FEATURE_V8)) {
1839 env->cp15.c9_pmuserenr = value & 0xf;
1840 } else {
1841 env->cp15.c9_pmuserenr = value & 1;
1842 }
1843}
1844
1845static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
1846 uint64_t value)
1847{
1848
1849 value &= pmu_counter_mask(env);
1850 env->cp15.c9_pminten |= value;
1851 pmu_update_irq(env);
1852}
1853
1854static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1855 uint64_t value)
1856{
1857 value &= pmu_counter_mask(env);
1858 env->cp15.c9_pminten &= ~value;
1859 pmu_update_irq(env);
1860}
1861
1862static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
1863 uint64_t value)
1864{
1865
1866
1867
1868
1869
1870
1871 raw_write(env, ri, value & ~0x1FULL);
1872}
1873
1874static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
1875{
1876
1877 uint32_t valid_mask = 0x3fff;
1878 ARMCPU *cpu = env_archcpu(env);
1879
1880 if (arm_el_is_aa64(env, 3)) {
1881 value |= SCR_FW | SCR_AW;
1882 valid_mask &= ~SCR_NET;
1883 } else {
1884 valid_mask &= ~(SCR_RW | SCR_ST);
1885 }
1886
1887 if (!arm_feature(env, ARM_FEATURE_EL2)) {
1888 valid_mask &= ~SCR_HCE;
1889
1890
1891
1892
1893
1894
1895
1896 if (arm_feature(env, ARM_FEATURE_V7) &&
1897 !arm_feature(env, ARM_FEATURE_V8)) {
1898 valid_mask &= ~SCR_SMD;
1899 }
1900 }
1901 if (cpu_isar_feature(aa64_lor, cpu)) {
1902 valid_mask |= SCR_TLOR;
1903 }
1904 if (cpu_isar_feature(aa64_pauth, cpu)) {
1905 valid_mask |= SCR_API | SCR_APK;
1906 }
1907
1908
1909 value &= valid_mask;
1910 raw_write(env, ri, value);
1911}
1912
1913static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
1914{
1915 ARMCPU *cpu = env_archcpu(env);
1916
1917
1918
1919
1920 uint32_t index = A32_BANKED_REG_GET(env, csselr,
1921 ri->secure & ARM_CP_SECSTATE_S);
1922
1923 return cpu->ccsidr[index];
1924}
1925
1926static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
1927 uint64_t value)
1928{
1929 raw_write(env, ri, value & 0xf);
1930}
1931
1932static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
1933{
1934 CPUState *cs = env_cpu(env);
1935 uint64_t hcr_el2 = arm_hcr_el2_eff(env);
1936 uint64_t ret = 0;
1937 bool allow_virt = (arm_current_el(env) == 1 &&
1938 (!arm_is_secure_below_el3(env) ||
1939 (env->cp15.scr_el3 & SCR_EEL2)));
1940
1941 if (allow_virt && (hcr_el2 & HCR_IMO)) {
1942 if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
1943 ret |= CPSR_I;
1944 }
1945 } else {
1946 if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
1947 ret |= CPSR_I;
1948 }
1949 }
1950
1951 if (allow_virt && (hcr_el2 & HCR_FMO)) {
1952 if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
1953 ret |= CPSR_F;
1954 }
1955 } else {
1956 if (cs->interrupt_request & CPU_INTERRUPT_FIQ) {
1957 ret |= CPSR_F;
1958 }
1959 }
1960
1961
1962 return ret;
1963}
1964
1965static const ARMCPRegInfo v7_cp_reginfo[] = {
1966
1967 { .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
1968 .access = PL1_W, .type = ARM_CP_NOP },
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980 { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
1981 .access = PL0_RW, .type = ARM_CP_ALIAS,
1982 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
1983 .writefn = pmcntenset_write,
1984 .accessfn = pmreg_access,
1985 .raw_writefn = raw_write },
1986 { .name = "PMCNTENSET_EL0", .state = ARM_CP_STATE_AA64,
1987 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 1,
1988 .access = PL0_RW, .accessfn = pmreg_access,
1989 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .resetvalue = 0,
1990 .writefn = pmcntenset_write, .raw_writefn = raw_write },
1991 { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
1992 .access = PL0_RW,
1993 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
1994 .accessfn = pmreg_access,
1995 .writefn = pmcntenclr_write,
1996 .type = ARM_CP_ALIAS },
1997 { .name = "PMCNTENCLR_EL0", .state = ARM_CP_STATE_AA64,
1998 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 2,
1999 .access = PL0_RW, .accessfn = pmreg_access,
2000 .type = ARM_CP_ALIAS,
2001 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
2002 .writefn = pmcntenclr_write },
2003 { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
2004 .access = PL0_RW, .type = ARM_CP_IO,
2005 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
2006 .accessfn = pmreg_access,
2007 .writefn = pmovsr_write,
2008 .raw_writefn = raw_write },
2009 { .name = "PMOVSCLR_EL0", .state = ARM_CP_STATE_AA64,
2010 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 3,
2011 .access = PL0_RW, .accessfn = pmreg_access,
2012 .type = ARM_CP_ALIAS | ARM_CP_IO,
2013 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
2014 .writefn = pmovsr_write,
2015 .raw_writefn = raw_write },
2016 { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
2017 .access = PL0_W, .accessfn = pmreg_access_swinc,
2018 .type = ARM_CP_NO_RAW | ARM_CP_IO,
2019 .writefn = pmswinc_write },
2020 { .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
2021 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
2022 .access = PL0_W, .accessfn = pmreg_access_swinc,
2023 .type = ARM_CP_NO_RAW | ARM_CP_IO,
2024 .writefn = pmswinc_write },
2025 { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
2026 .access = PL0_RW, .type = ARM_CP_ALIAS,
2027 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
2028 .accessfn = pmreg_access_selr, .writefn = pmselr_write,
2029 .raw_writefn = raw_write},
2030 { .name = "PMSELR_EL0", .state = ARM_CP_STATE_AA64,
2031 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 5,
2032 .access = PL0_RW, .accessfn = pmreg_access_selr,
2033 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmselr),
2034 .writefn = pmselr_write, .raw_writefn = raw_write, },
2035 { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
2036 .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_ALIAS | ARM_CP_IO,
2037 .readfn = pmccntr_read, .writefn = pmccntr_write32,
2038 .accessfn = pmreg_access_ccntr },
2039 { .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64,
2040 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0,
2041 .access = PL0_RW, .accessfn = pmreg_access_ccntr,
2042 .type = ARM_CP_IO,
2043 .fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt),
2044 .readfn = pmccntr_read, .writefn = pmccntr_write,
2045 .raw_readfn = raw_read, .raw_writefn = raw_write, },
2046 { .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7,
2047 .writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32,
2048 .access = PL0_RW, .accessfn = pmreg_access,
2049 .type = ARM_CP_ALIAS | ARM_CP_IO,
2050 .resetvalue = 0, },
2051 { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
2052 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
2053 .writefn = pmccfiltr_write, .raw_writefn = raw_write,
2054 .access = PL0_RW, .accessfn = pmreg_access,
2055 .type = ARM_CP_IO,
2056 .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
2057 .resetvalue = 0, },
2058 { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
2059 .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
2060 .accessfn = pmreg_access,
2061 .writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
2062 { .name = "PMXEVTYPER_EL0", .state = ARM_CP_STATE_AA64,
2063 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 1,
2064 .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
2065 .accessfn = pmreg_access,
2066 .writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
2067 { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2,
2068 .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
2069 .accessfn = pmreg_access_xevcntr,
2070 .writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
2071 { .name = "PMXEVCNTR_EL0", .state = ARM_CP_STATE_AA64,
2072 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 2,
2073 .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
2074 .accessfn = pmreg_access_xevcntr,
2075 .writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
2076 { .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0,
2077 .access = PL0_R | PL1_RW, .accessfn = access_tpm,
2078 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmuserenr),
2079 .resetvalue = 0,
2080 .writefn = pmuserenr_write, .raw_writefn = raw_write },
2081 { .name = "PMUSERENR_EL0", .state = ARM_CP_STATE_AA64,
2082 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 0,
2083 .access = PL0_R | PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS,
2084 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr),
2085 .resetvalue = 0,
2086 .writefn = pmuserenr_write, .raw_writefn = raw_write },
2087 { .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1,
2088 .access = PL1_RW, .accessfn = access_tpm,
2089 .type = ARM_CP_ALIAS | ARM_CP_IO,
2090 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten),
2091 .resetvalue = 0,
2092 .writefn = pmintenset_write, .raw_writefn = raw_write },
2093 { .name = "PMINTENSET_EL1", .state = ARM_CP_STATE_AA64,
2094 .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 1,
2095 .access = PL1_RW, .accessfn = access_tpm,
2096 .type = ARM_CP_IO,
2097 .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
2098 .writefn = pmintenset_write, .raw_writefn = raw_write,
2099 .resetvalue = 0x0 },
2100 { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2,
2101 .access = PL1_RW, .accessfn = access_tpm,
2102 .type = ARM_CP_ALIAS | ARM_CP_IO,
2103 .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
2104 .writefn = pmintenclr_write, },
2105 { .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64,
2106 .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 2,
2107 .access = PL1_RW, .accessfn = access_tpm,
2108 .type = ARM_CP_ALIAS | ARM_CP_IO,
2109 .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
2110 .writefn = pmintenclr_write },
2111 { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
2112 .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
2113 .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
2114 { .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
2115 .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
2116 .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
2117 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
2118 offsetof(CPUARMState, cp15.csselr_ns) } },
2119
2120
2121
2122 { .name = "AIDR", .state = ARM_CP_STATE_BOTH,
2123 .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7,
2124 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
2125
2126
2127
2128 { .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH,
2129 .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0,
2130 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
2131 { .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH,
2132 .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
2133 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
2134
2135
2136
2137 { .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
2138 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
2139 .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
2140 .resetvalue = 0 },
2141 { .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64,
2142 .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 2, .opc2 = 0,
2143 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[3]),
2144 .resetvalue = 0 },
2145
2146
2147
2148
2149
2150
2151
2152 { .name = "MAIR0", .state = ARM_CP_STATE_AA32,
2153 .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW,
2154 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair0_s),
2155 offsetof(CPUARMState, cp15.mair0_ns) },
2156 .resetfn = arm_cp_reset_ignore },
2157 { .name = "MAIR1", .state = ARM_CP_STATE_AA32,
2158 .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW,
2159 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair1_s),
2160 offsetof(CPUARMState, cp15.mair1_ns) },
2161 .resetfn = arm_cp_reset_ignore },
2162 { .name = "ISR_EL1", .state = ARM_CP_STATE_BOTH,
2163 .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 0,
2164 .type = ARM_CP_NO_RAW, .access = PL1_R, .readfn = isr_read },
2165
2166 { .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0,
2167 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
2168 { .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
2169 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
2170 { .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 2,
2171 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
2172
2173 { .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 0,
2174 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
2175 { .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
2176 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
2177 { .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 2,
2178 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
2179
2180 { .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
2181 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
2182 { .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
2183 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
2184 { .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
2185 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
2186 { .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
2187 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write },
2188 REGINFO_SENTINEL
2189};
2190
2191static const ARMCPRegInfo v7mp_cp_reginfo[] = {
2192
2193 { .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
2194 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_is_write },
2195 { .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
2196 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write },
2197 { .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
2198 .type = ARM_CP_NO_RAW, .access = PL1_W,
2199 .writefn = tlbiasid_is_write },
2200 { .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
2201 .type = ARM_CP_NO_RAW, .access = PL1_W,
2202 .writefn = tlbimvaa_is_write },
2203 REGINFO_SENTINEL
2204};
2205
2206static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
2207
2208 { .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3,
2209 .access = PL0_RW, .accessfn = pmreg_access,
2210 .type = ARM_CP_ALIAS | ARM_CP_IO,
2211 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
2212 .writefn = pmovsset_write,
2213 .raw_writefn = raw_write },
2214 { .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64,
2215 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3,
2216 .access = PL0_RW, .accessfn = pmreg_access,
2217 .type = ARM_CP_ALIAS | ARM_CP_IO,
2218 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
2219 .writefn = pmovsset_write,
2220 .raw_writefn = raw_write },
2221 REGINFO_SENTINEL
2222};
2223
2224static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
2225 uint64_t value)
2226{
2227 value &= 1;
2228 env->teecr = value;
2229}
2230
2231static CPAccessResult teehbr_access(CPUARMState *env, const ARMCPRegInfo *ri,
2232 bool isread)
2233{
2234 if (arm_current_el(env) == 0 && (env->teecr & 1)) {
2235 return CP_ACCESS_TRAP;
2236 }
2237 return CP_ACCESS_OK;
2238}
2239
2240static const ARMCPRegInfo t2ee_cp_reginfo[] = {
2241 { .name = "TEECR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 6, .opc2 = 0,
2242 .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, teecr),
2243 .resetvalue = 0,
2244 .writefn = teecr_write },
2245 { .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
2246 .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
2247 .accessfn = teehbr_access, .resetvalue = 0 },
2248 REGINFO_SENTINEL
2249};
2250
2251static const ARMCPRegInfo v6k_cp_reginfo[] = {
2252 { .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64,
2253 .opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0,
2254 .access = PL0_RW,
2255 .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[0]), .resetvalue = 0 },
2256 { .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
2257 .access = PL0_RW,
2258 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrurw_s),
2259 offsetoflow32(CPUARMState, cp15.tpidrurw_ns) },
2260 .resetfn = arm_cp_reset_ignore },
2261 { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
2262 .opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
2263 .access = PL0_R|PL1_W,
2264 .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[0]),
2265 .resetvalue = 0},
2266 { .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
2267 .access = PL0_R|PL1_W,
2268 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
2269 offsetoflow32(CPUARMState, cp15.tpidruro_ns) },
2270 .resetfn = arm_cp_reset_ignore },
2271 { .name = "TPIDR_EL1", .state = ARM_CP_STATE_AA64,
2272 .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
2273 .access = PL1_RW,
2274 .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[1]), .resetvalue = 0 },
2275 { .name = "TPIDRPRW", .opc1 = 0, .cp = 15, .crn = 13, .crm = 0, .opc2 = 4,
2276 .access = PL1_RW,
2277 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrprw_s),
2278 offsetoflow32(CPUARMState, cp15.tpidrprw_ns) },
2279 .resetvalue = 0 },
2280 REGINFO_SENTINEL
2281};
2282
2283#ifndef CONFIG_USER_ONLY
2284
2285static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri,
2286 bool isread)
2287{
2288
2289
2290
2291 int el = arm_current_el(env);
2292
2293 switch (el) {
2294 case 0:
2295 if (!extract32(env->cp15.c14_cntkctl, 0, 2)) {
2296 return CP_ACCESS_TRAP;
2297 }
2298 break;
2299 case 1:
2300 if (!isread && ri->state == ARM_CP_STATE_AA32 &&
2301 arm_is_secure_below_el3(env)) {
2302
2303 return CP_ACCESS_TRAP_UNCATEGORIZED;
2304 }
2305 break;
2306 case 2:
2307 case 3:
2308 break;
2309 }
2310
2311 if (!isread && el < arm_highest_el(env)) {
2312 return CP_ACCESS_TRAP_UNCATEGORIZED;
2313 }
2314
2315 return CP_ACCESS_OK;
2316}
2317
2318static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
2319 bool isread)
2320{
2321 unsigned int cur_el = arm_current_el(env);
2322 bool secure = arm_is_secure(env);
2323
2324
2325 if (cur_el == 0 &&
2326 !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
2327 return CP_ACCESS_TRAP;
2328 }
2329
2330 if (arm_feature(env, ARM_FEATURE_EL2) &&
2331 timeridx == GTIMER_PHYS && !secure && cur_el < 2 &&
2332 !extract32(env->cp15.cnthctl_el2, 0, 1)) {
2333 return CP_ACCESS_TRAP_EL2;
2334 }
2335 return CP_ACCESS_OK;
2336}
2337
2338static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx,
2339 bool isread)
2340{
2341 unsigned int cur_el = arm_current_el(env);
2342 bool secure = arm_is_secure(env);
2343
2344
2345
2346
2347 if (cur_el == 0 &&
2348 !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
2349 return CP_ACCESS_TRAP;
2350 }
2351
2352 if (arm_feature(env, ARM_FEATURE_EL2) &&
2353 timeridx == GTIMER_PHYS && !secure && cur_el < 2 &&
2354 !extract32(env->cp15.cnthctl_el2, 1, 1)) {
2355 return CP_ACCESS_TRAP_EL2;
2356 }
2357 return CP_ACCESS_OK;
2358}
2359
2360static CPAccessResult gt_pct_access(CPUARMState *env,
2361 const ARMCPRegInfo *ri,
2362 bool isread)
2363{
2364 return gt_counter_access(env, GTIMER_PHYS, isread);
2365}
2366
2367static CPAccessResult gt_vct_access(CPUARMState *env,
2368 const ARMCPRegInfo *ri,
2369 bool isread)
2370{
2371 return gt_counter_access(env, GTIMER_VIRT, isread);
2372}
2373
2374static CPAccessResult gt_ptimer_access(CPUARMState *env, const ARMCPRegInfo *ri,
2375 bool isread)
2376{
2377 return gt_timer_access(env, GTIMER_PHYS, isread);
2378}
2379
2380static CPAccessResult gt_vtimer_access(CPUARMState *env, const ARMCPRegInfo *ri,
2381 bool isread)
2382{
2383 return gt_timer_access(env, GTIMER_VIRT, isread);
2384}
2385
2386static CPAccessResult gt_stimer_access(CPUARMState *env,
2387 const ARMCPRegInfo *ri,
2388 bool isread)
2389{
2390
2391
2392
2393
2394 switch (arm_current_el(env)) {
2395 case 1:
2396 if (!arm_is_secure(env)) {
2397 return CP_ACCESS_TRAP;
2398 }
2399 if (!(env->cp15.scr_el3 & SCR_ST)) {
2400 return CP_ACCESS_TRAP_EL3;
2401 }
2402 return CP_ACCESS_OK;
2403 case 0:
2404 case 2:
2405 return CP_ACCESS_TRAP;
2406 case 3:
2407 return CP_ACCESS_OK;
2408 default:
2409 g_assert_not_reached();
2410 }
2411}
2412
2413static uint64_t gt_get_countervalue(CPUARMState *env)
2414{
2415 return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / GTIMER_SCALE;
2416}
2417
2418static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
2419{
2420 ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
2421
2422 if (gt->ctl & 1) {
2423
2424
2425
2426 uint64_t offset = timeridx == GTIMER_VIRT ?
2427 cpu->env.cp15.cntvoff_el2 : 0;
2428 uint64_t count = gt_get_countervalue(&cpu->env);
2429
2430 int istatus = count - offset >= gt->cval;
2431 uint64_t nexttick;
2432 int irqstate;
2433
2434 gt->ctl = deposit32(gt->ctl, 2, 1, istatus);
2435
2436 irqstate = (istatus && !(gt->ctl & 2));
2437 qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
2438
2439 if (istatus) {
2440
2441 nexttick = UINT64_MAX;
2442 } else {
2443
2444 nexttick = gt->cval + offset;
2445 }
2446
2447
2448
2449
2450
2451 if (nexttick > INT64_MAX / GTIMER_SCALE) {
2452 nexttick = INT64_MAX / GTIMER_SCALE;
2453 }
2454 timer_mod(cpu->gt_timer[timeridx], nexttick);
2455 trace_arm_gt_recalc(timeridx, irqstate, nexttick);
2456 } else {
2457
2458 gt->ctl &= ~4;
2459 qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0);
2460 timer_del(cpu->gt_timer[timeridx]);
2461 trace_arm_gt_recalc_disabled(timeridx);
2462 }
2463}
2464
2465static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
2466 int timeridx)
2467{
2468 ARMCPU *cpu = env_archcpu(env);
2469
2470 timer_del(cpu->gt_timer[timeridx]);
2471}
2472
2473static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
2474{
2475 return gt_get_countervalue(env);
2476}
2477
2478static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
2479{
2480 return gt_get_countervalue(env) - env->cp15.cntvoff_el2;
2481}
2482
2483static void gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2484 int timeridx,
2485 uint64_t value)
2486{
2487 trace_arm_gt_cval_write(timeridx, value);
2488 env->cp15.c14_timer[timeridx].cval = value;
2489 gt_recalc_timer(env_archcpu(env), timeridx);
2490}
2491
2492static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
2493 int timeridx)
2494{
2495 uint64_t offset = timeridx == GTIMER_VIRT ? env->cp15.cntvoff_el2 : 0;
2496
2497 return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
2498 (gt_get_countervalue(env) - offset));
2499}
2500
2501static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2502 int timeridx,
2503 uint64_t value)
2504{
2505 uint64_t offset = timeridx == GTIMER_VIRT ? env->cp15.cntvoff_el2 : 0;
2506
2507 trace_arm_gt_tval_write(timeridx, value);
2508 env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) - offset +
2509 sextract64(value, 0, 32);
2510 gt_recalc_timer(env_archcpu(env), timeridx);
2511}
2512
2513static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
2514 int timeridx,
2515 uint64_t value)
2516{
2517 ARMCPU *cpu = env_archcpu(env);
2518 uint32_t oldval = env->cp15.c14_timer[timeridx].ctl;
2519
2520 trace_arm_gt_ctl_write(timeridx, value);
2521 env->cp15.c14_timer[timeridx].ctl = deposit64(oldval, 0, 2, value);
2522 if ((oldval ^ value) & 1) {
2523
2524 gt_recalc_timer(cpu, timeridx);
2525 } else if ((oldval ^ value) & 2) {
2526
2527
2528
2529 int irqstate = (oldval & 4) && !(value & 2);
2530
2531 trace_arm_gt_imask_toggle(timeridx, irqstate);
2532 qemu_set_irq(cpu->gt_timer_outputs[timeridx], irqstate);
2533 }
2534}
2535
2536static void gt_phys_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
2537{
2538 gt_timer_reset(env, ri, GTIMER_PHYS);
2539}
2540
2541static void gt_phys_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2542 uint64_t value)
2543{
2544 gt_cval_write(env, ri, GTIMER_PHYS, value);
2545}
2546
2547static uint64_t gt_phys_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
2548{
2549 return gt_tval_read(env, ri, GTIMER_PHYS);
2550}
2551
2552static void gt_phys_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2553 uint64_t value)
2554{
2555 gt_tval_write(env, ri, GTIMER_PHYS, value);
2556}
2557
2558static void gt_phys_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
2559 uint64_t value)
2560{
2561 gt_ctl_write(env, ri, GTIMER_PHYS, value);
2562}
2563
2564static void gt_virt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
2565{
2566 gt_timer_reset(env, ri, GTIMER_VIRT);
2567}
2568
2569static void gt_virt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2570 uint64_t value)
2571{
2572 gt_cval_write(env, ri, GTIMER_VIRT, value);
2573}
2574
2575static uint64_t gt_virt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
2576{
2577 return gt_tval_read(env, ri, GTIMER_VIRT);
2578}
2579
2580static void gt_virt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2581 uint64_t value)
2582{
2583 gt_tval_write(env, ri, GTIMER_VIRT, value);
2584}
2585
2586static void gt_virt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
2587 uint64_t value)
2588{
2589 gt_ctl_write(env, ri, GTIMER_VIRT, value);
2590}
2591
2592static void gt_cntvoff_write(CPUARMState *env, const ARMCPRegInfo *ri,
2593 uint64_t value)
2594{
2595 ARMCPU *cpu = env_archcpu(env);
2596
2597 trace_arm_gt_cntvoff_write(value);
2598 raw_write(env, ri, value);
2599 gt_recalc_timer(cpu, GTIMER_VIRT);
2600}
2601
2602static void gt_hyp_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
2603{
2604 gt_timer_reset(env, ri, GTIMER_HYP);
2605}
2606
2607static void gt_hyp_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2608 uint64_t value)
2609{
2610 gt_cval_write(env, ri, GTIMER_HYP, value);
2611}
2612
2613static uint64_t gt_hyp_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
2614{
2615 return gt_tval_read(env, ri, GTIMER_HYP);
2616}
2617
2618static void gt_hyp_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2619 uint64_t value)
2620{
2621 gt_tval_write(env, ri, GTIMER_HYP, value);
2622}
2623
2624static void gt_hyp_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
2625 uint64_t value)
2626{
2627 gt_ctl_write(env, ri, GTIMER_HYP, value);
2628}
2629
2630static void gt_sec_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri)
2631{
2632 gt_timer_reset(env, ri, GTIMER_SEC);
2633}
2634
2635static void gt_sec_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2636 uint64_t value)
2637{
2638 gt_cval_write(env, ri, GTIMER_SEC, value);
2639}
2640
2641static uint64_t gt_sec_tval_read(CPUARMState *env, const ARMCPRegInfo *ri)
2642{
2643 return gt_tval_read(env, ri, GTIMER_SEC);
2644}
2645
2646static void gt_sec_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
2647 uint64_t value)
2648{
2649 gt_tval_write(env, ri, GTIMER_SEC, value);
2650}
2651
2652static void gt_sec_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
2653 uint64_t value)
2654{
2655 gt_ctl_write(env, ri, GTIMER_SEC, value);
2656}
2657
2658void arm_gt_ptimer_cb(void *opaque)
2659{
2660 ARMCPU *cpu = opaque;
2661
2662 gt_recalc_timer(cpu, GTIMER_PHYS);
2663}
2664
2665void arm_gt_vtimer_cb(void *opaque)
2666{
2667 ARMCPU *cpu = opaque;
2668
2669 gt_recalc_timer(cpu, GTIMER_VIRT);
2670}
2671
2672void arm_gt_htimer_cb(void *opaque)
2673{
2674 ARMCPU *cpu = opaque;
2675
2676 gt_recalc_timer(cpu, GTIMER_HYP);
2677}
2678
2679void arm_gt_stimer_cb(void *opaque)
2680{
2681 ARMCPU *cpu = opaque;
2682
2683 gt_recalc_timer(cpu, GTIMER_SEC);
2684}
2685
2686static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
2687
2688
2689
2690
2691 { .name = "CNTFRQ", .cp = 15, .crn = 14, .crm = 0, .opc1 = 0, .opc2 = 0,
2692 .type = ARM_CP_ALIAS,
2693 .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access,
2694 .fieldoffset = offsetoflow32(CPUARMState, cp15.c14_cntfrq),
2695 },
2696 { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64,
2697 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
2698 .access = PL1_RW | PL0_R, .accessfn = gt_cntfrq_access,
2699 .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
2700 .resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE,
2701 },
2702
2703 { .name = "CNTKCTL", .state = ARM_CP_STATE_BOTH,
2704 .opc0 = 3, .opc1 = 0, .crn = 14, .crm = 1, .opc2 = 0,
2705 .access = PL1_RW,
2706 .fieldoffset = offsetof(CPUARMState, cp15.c14_cntkctl),
2707 .resetvalue = 0,
2708 },
2709
2710 { .name = "CNTP_CTL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1,
2711 .secure = ARM_CP_SECSTATE_NS,
2712 .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL0_RW,
2713 .accessfn = gt_ptimer_access,
2714 .fieldoffset = offsetoflow32(CPUARMState,
2715 cp15.c14_timer[GTIMER_PHYS].ctl),
2716 .writefn = gt_phys_ctl_write, .raw_writefn = raw_write,
2717 },
2718 { .name = "CNTP_CTL_S",
2719 .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1,
2720 .secure = ARM_CP_SECSTATE_S,
2721 .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL0_RW,
2722 .accessfn = gt_ptimer_access,
2723 .fieldoffset = offsetoflow32(CPUARMState,
2724 cp15.c14_timer[GTIMER_SEC].ctl),
2725 .writefn = gt_sec_ctl_write, .raw_writefn = raw_write,
2726 },
2727 { .name = "CNTP_CTL_EL0", .state = ARM_CP_STATE_AA64,
2728 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 1,
2729 .type = ARM_CP_IO, .access = PL0_RW,
2730 .accessfn = gt_ptimer_access,
2731 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
2732 .resetvalue = 0,
2733 .writefn = gt_phys_ctl_write, .raw_writefn = raw_write,
2734 },
2735 { .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1,
2736 .type = ARM_CP_IO | ARM_CP_ALIAS, .access = PL0_RW,
2737 .accessfn = gt_vtimer_access,
2738 .fieldoffset = offsetoflow32(CPUARMState,
2739 cp15.c14_timer[GTIMER_VIRT].ctl),
2740 .writefn = gt_virt_ctl_write, .raw_writefn = raw_write,
2741 },
2742 { .name = "CNTV_CTL_EL0", .state = ARM_CP_STATE_AA64,
2743 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 1,
2744 .type = ARM_CP_IO, .access = PL0_RW,
2745 .accessfn = gt_vtimer_access,
2746 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
2747 .resetvalue = 0,
2748 .writefn = gt_virt_ctl_write, .raw_writefn = raw_write,
2749 },
2750
2751 { .name = "CNTP_TVAL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0,
2752 .secure = ARM_CP_SECSTATE_NS,
2753 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL0_RW,
2754 .accessfn = gt_ptimer_access,
2755 .readfn = gt_phys_tval_read, .writefn = gt_phys_tval_write,
2756 },
2757 { .name = "CNTP_TVAL_S",
2758 .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0,
2759 .secure = ARM_CP_SECSTATE_S,
2760 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL0_RW,
2761 .accessfn = gt_ptimer_access,
2762 .readfn = gt_sec_tval_read, .writefn = gt_sec_tval_write,
2763 },
2764 { .name = "CNTP_TVAL_EL0", .state = ARM_CP_STATE_AA64,
2765 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 0,
2766 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL0_RW,
2767 .accessfn = gt_ptimer_access, .resetfn = gt_phys_timer_reset,
2768 .readfn = gt_phys_tval_read, .writefn = gt_phys_tval_write,
2769 },
2770 { .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0,
2771 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL0_RW,
2772 .accessfn = gt_vtimer_access,
2773 .readfn = gt_virt_tval_read, .writefn = gt_virt_tval_write,
2774 },
2775 { .name = "CNTV_TVAL_EL0", .state = ARM_CP_STATE_AA64,
2776 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 0,
2777 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL0_RW,
2778 .accessfn = gt_vtimer_access, .resetfn = gt_virt_timer_reset,
2779 .readfn = gt_virt_tval_read, .writefn = gt_virt_tval_write,
2780 },
2781
2782 { .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0,
2783 .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO,
2784 .accessfn = gt_pct_access,
2785 .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore,
2786 },
2787 { .name = "CNTPCT_EL0", .state = ARM_CP_STATE_AA64,
2788 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 1,
2789 .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
2790 .accessfn = gt_pct_access, .readfn = gt_cnt_read,
2791 },
2792 { .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1,
2793 .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO,
2794 .accessfn = gt_vct_access,
2795 .readfn = gt_virt_cnt_read, .resetfn = arm_cp_reset_ignore,
2796 },
2797 { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
2798 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
2799 .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
2800 .accessfn = gt_vct_access, .readfn = gt_virt_cnt_read,
2801 },
2802
2803 { .name = "CNTP_CVAL", .cp = 15, .crm = 14, .opc1 = 2,
2804 .secure = ARM_CP_SECSTATE_NS,
2805 .access = PL0_RW,
2806 .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS,
2807 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
2808 .accessfn = gt_ptimer_access,
2809 .writefn = gt_phys_cval_write, .raw_writefn = raw_write,
2810 },
2811 { .name = "CNTP_CVAL_S", .cp = 15, .crm = 14, .opc1 = 2,
2812 .secure = ARM_CP_SECSTATE_S,
2813 .access = PL0_RW,
2814 .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS,
2815 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval),
2816 .accessfn = gt_ptimer_access,
2817 .writefn = gt_sec_cval_write, .raw_writefn = raw_write,
2818 },
2819 { .name = "CNTP_CVAL_EL0", .state = ARM_CP_STATE_AA64,
2820 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 2, .opc2 = 2,
2821 .access = PL0_RW,
2822 .type = ARM_CP_IO,
2823 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
2824 .resetvalue = 0, .accessfn = gt_ptimer_access,
2825 .writefn = gt_phys_cval_write, .raw_writefn = raw_write,
2826 },
2827 { .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3,
2828 .access = PL0_RW,
2829 .type = ARM_CP_64BIT | ARM_CP_IO | ARM_CP_ALIAS,
2830 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
2831 .accessfn = gt_vtimer_access,
2832 .writefn = gt_virt_cval_write, .raw_writefn = raw_write,
2833 },
2834 { .name = "CNTV_CVAL_EL0", .state = ARM_CP_STATE_AA64,
2835 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 3, .opc2 = 2,
2836 .access = PL0_RW,
2837 .type = ARM_CP_IO,
2838 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
2839 .resetvalue = 0, .accessfn = gt_vtimer_access,
2840 .writefn = gt_virt_cval_write, .raw_writefn = raw_write,
2841 },
2842
2843
2844
2845 { .name = "CNTPS_TVAL_EL1", .state = ARM_CP_STATE_AA64,
2846 .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 0,
2847 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL1_RW,
2848 .accessfn = gt_stimer_access,
2849 .readfn = gt_sec_tval_read,
2850 .writefn = gt_sec_tval_write,
2851 .resetfn = gt_sec_timer_reset,
2852 },
2853 { .name = "CNTPS_CTL_EL1", .state = ARM_CP_STATE_AA64,
2854 .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 1,
2855 .type = ARM_CP_IO, .access = PL1_RW,
2856 .accessfn = gt_stimer_access,
2857 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].ctl),
2858 .resetvalue = 0,
2859 .writefn = gt_sec_ctl_write, .raw_writefn = raw_write,
2860 },
2861 { .name = "CNTPS_CVAL_EL1", .state = ARM_CP_STATE_AA64,
2862 .opc0 = 3, .opc1 = 7, .crn = 14, .crm = 2, .opc2 = 2,
2863 .type = ARM_CP_IO, .access = PL1_RW,
2864 .accessfn = gt_stimer_access,
2865 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval),
2866 .writefn = gt_sec_cval_write, .raw_writefn = raw_write,
2867 },
2868 REGINFO_SENTINEL
2869};
2870
2871#else
2872
2873
2874
2875
2876
2877static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
2878{
2879
2880
2881
2882
2883 return cpu_get_clock() / GTIMER_SCALE;
2884}
2885
2886static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
2887 { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64,
2888 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
2889 .type = ARM_CP_CONST, .access = PL0_R ,
2890 .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
2891 .resetvalue = NANOSECONDS_PER_SECOND / GTIMER_SCALE,
2892 },
2893 { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
2894 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
2895 .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
2896 .readfn = gt_virt_cnt_read,
2897 },
2898 REGINFO_SENTINEL
2899};
2900
2901#endif
2902
2903static void par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
2904{
2905 if (arm_feature(env, ARM_FEATURE_LPAE)) {
2906 raw_write(env, ri, value);
2907 } else if (arm_feature(env, ARM_FEATURE_V7)) {
2908 raw_write(env, ri, value & 0xfffff6ff);
2909 } else {
2910 raw_write(env, ri, value & 0xfffff1ff);
2911 }
2912}
2913
2914#ifndef CONFIG_USER_ONLY
2915
2916
2917static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
2918 bool isread)
2919{
2920 if (ri->opc2 & 4) {
2921
2922
2923
2924
2925
2926 if (arm_current_el(env) == 1) {
2927 if (arm_is_secure_below_el3(env)) {
2928 return CP_ACCESS_TRAP_UNCATEGORIZED_EL3;
2929 }
2930 return CP_ACCESS_TRAP_UNCATEGORIZED;
2931 }
2932 }
2933 return CP_ACCESS_OK;
2934}
2935
2936static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
2937 MMUAccessType access_type, ARMMMUIdx mmu_idx)
2938{
2939 hwaddr phys_addr;
2940 target_ulong page_size;
2941 int prot;
2942 bool ret;
2943 uint64_t par64;
2944 bool format64 = false;
2945 MemTxAttrs attrs = {};
2946 ARMMMUFaultInfo fi = {};
2947 ARMCacheAttrs cacheattrs = {};
2948
2949 ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
2950 &prot, &page_size, &fi, &cacheattrs);
2951
2952 if (ret) {
2953
2954
2955
2956
2957 int current_el = arm_current_el(env);
2958 int target_el;
2959 uint32_t syn, fsr, fsc;
2960 bool take_exc = false;
2961
2962 if (fi.s1ptw && current_el == 1 && !arm_is_secure(env)
2963 && (mmu_idx == ARMMMUIdx_S1NSE1 || mmu_idx == ARMMMUIdx_S1NSE0)) {
2964
2965
2966
2967
2968
2969
2970
2971
2972 if (fi.type == ARMFault_SyncExternalOnWalk &&
2973 (env->cp15.scr_el3 & SCR_EA)) {
2974 target_el = 3;
2975 } else {
2976 env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4;
2977 target_el = 2;
2978 }
2979 take_exc = true;
2980 } else if (fi.type == ARMFault_SyncExternalOnWalk) {
2981
2982
2983
2984
2985 if (fi.stage2) {
2986 if (current_el == 3) {
2987 target_el = 3;
2988 } else {
2989 target_el = 2;
2990 }
2991 } else {
2992 target_el = exception_target_el(env);
2993 }
2994 take_exc = true;
2995 }
2996
2997 if (take_exc) {
2998
2999 if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
3000 arm_s1_regime_using_lpae_format(env, mmu_idx)) {
3001 fsr = arm_fi_to_lfsc(&fi);
3002 fsc = extract32(fsr, 0, 6);
3003 } else {
3004 fsr = arm_fi_to_sfsc(&fi);
3005 fsc = 0x3f;
3006 }
3007
3008
3009
3010
3011 syn = syn_data_abort_no_iss(current_el == target_el,
3012 fi.ea, 1, fi.s1ptw, 1, fsc);
3013 env->exception.vaddress = value;
3014 env->exception.fsr = fsr;
3015 raise_exception(env, EXCP_DATA_ABORT, syn, target_el);
3016 }
3017 }
3018
3019 if (is_a64(env)) {
3020 format64 = true;
3021 } else if (arm_feature(env, ARM_FEATURE_LPAE)) {
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036 format64 = arm_s1_regime_using_lpae_format(env, mmu_idx);
3037
3038 if (arm_feature(env, ARM_FEATURE_EL2)) {
3039 if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
3040 format64 |= env->cp15.hcr_el2 & (HCR_VM | HCR_DC);
3041 } else {
3042 format64 |= arm_current_el(env) == 2;
3043 }
3044 }
3045 }
3046
3047 if (format64) {
3048
3049 par64 = (1 << 11);
3050 if (!ret) {
3051 par64 |= phys_addr & ~0xfffULL;
3052 if (!attrs.secure) {
3053 par64 |= (1 << 9);
3054 }
3055 par64 |= (uint64_t)cacheattrs.attrs << 56;
3056 par64 |= cacheattrs.shareability << 7;
3057 } else {
3058 uint32_t fsr = arm_fi_to_lfsc(&fi);
3059
3060 par64 |= 1;
3061 par64 |= (fsr & 0x3f) << 1;
3062 if (fi.stage2) {
3063 par64 |= (1 << 9);
3064 }
3065 if (fi.s1ptw) {
3066 par64 |= (1 << 8);
3067 }
3068 }
3069 } else {
3070
3071
3072
3073
3074 if (!ret) {
3075
3076 if (page_size == (1 << 24)
3077 && arm_feature(env, ARM_FEATURE_V7)) {
3078 par64 = (phys_addr & 0xff000000) | (1 << 1);
3079 } else {
3080 par64 = phys_addr & 0xfffff000;
3081 }
3082 if (!attrs.secure) {
3083 par64 |= (1 << 9);
3084 }
3085 } else {
3086 uint32_t fsr = arm_fi_to_sfsc(&fi);
3087
3088 par64 = ((fsr & (1 << 10)) >> 5) | ((fsr & (1 << 12)) >> 6) |
3089 ((fsr & 0xf) << 1) | 1;
3090 }
3091 }
3092 return par64;
3093}
3094
3095static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
3096{
3097 MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
3098 uint64_t par64;
3099 ARMMMUIdx mmu_idx;
3100 int el = arm_current_el(env);
3101 bool secure = arm_is_secure_below_el3(env);
3102
3103 switch (ri->opc2 & 6) {
3104 case 0:
3105
3106 switch (el) {
3107 case 3:
3108 mmu_idx = ARMMMUIdx_S1E3;
3109 break;
3110 case 2:
3111 mmu_idx = ARMMMUIdx_S1NSE1;
3112 break;
3113 case 1:
3114 mmu_idx = secure ? ARMMMUIdx_S1SE1 : ARMMMUIdx_S1NSE1;
3115 break;
3116 default:
3117 g_assert_not_reached();
3118 }
3119 break;
3120 case 2:
3121
3122 switch (el) {
3123 case 3:
3124 mmu_idx = ARMMMUIdx_S1SE0;
3125 break;
3126 case 2:
3127 mmu_idx = ARMMMUIdx_S1NSE0;
3128 break;
3129 case 1:
3130 mmu_idx = secure ? ARMMMUIdx_S1SE0 : ARMMMUIdx_S1NSE0;
3131 break;
3132 default:
3133 g_assert_not_reached();
3134 }
3135 break;
3136 case 4:
3137
3138 mmu_idx = ARMMMUIdx_S12NSE1;
3139 break;
3140 case 6:
3141
3142 mmu_idx = ARMMMUIdx_S12NSE0;
3143 break;
3144 default:
3145 g_assert_not_reached();
3146 }
3147
3148 par64 = do_ats_write(env, value, access_type, mmu_idx);
3149
3150 A32_BANKED_CURRENT_REG_SET(env, par, par64);
3151}
3152
3153static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
3154 uint64_t value)
3155{
3156 MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
3157 uint64_t par64;
3158
3159 par64 = do_ats_write(env, value, access_type, ARMMMUIdx_S1E2);
3160
3161 A32_BANKED_CURRENT_REG_SET(env, par, par64);
3162}
3163
3164static CPAccessResult at_s1e2_access(CPUARMState *env, const ARMCPRegInfo *ri,
3165 bool isread)
3166{
3167 if (arm_current_el(env) == 3 && !(env->cp15.scr_el3 & SCR_NS)) {
3168 return CP_ACCESS_TRAP;
3169 }
3170 return CP_ACCESS_OK;
3171}
3172
3173static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
3174 uint64_t value)
3175{
3176 MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
3177 ARMMMUIdx mmu_idx;
3178 int secure = arm_is_secure_below_el3(env);
3179
3180 switch (ri->opc2 & 6) {
3181 case 0:
3182 switch (ri->opc1) {
3183 case 0:
3184 mmu_idx = secure ? ARMMMUIdx_S1SE1 : ARMMMUIdx_S1NSE1;
3185 break;
3186 case 4:
3187 mmu_idx = ARMMMUIdx_S1E2;
3188 break;
3189 case 6:
3190 mmu_idx = ARMMMUIdx_S1E3;
3191 break;
3192 default:
3193 g_assert_not_reached();
3194 }
3195 break;
3196 case 2:
3197 mmu_idx = secure ? ARMMMUIdx_S1SE0 : ARMMMUIdx_S1NSE0;
3198 break;
3199 case 4:
3200 mmu_idx = secure ? ARMMMUIdx_S1SE1 : ARMMMUIdx_S12NSE1;
3201 break;
3202 case 6:
3203 mmu_idx = secure ? ARMMMUIdx_S1SE0 : ARMMMUIdx_S12NSE0;
3204 break;
3205 default:
3206 g_assert_not_reached();
3207 }
3208
3209 env->cp15.par_el[1] = do_ats_write(env, value, access_type, mmu_idx);
3210}
3211#endif
3212
3213static const ARMCPRegInfo vapa_cp_reginfo[] = {
3214 { .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0,
3215 .access = PL1_RW, .resetvalue = 0,
3216 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.par_s),
3217 offsetoflow32(CPUARMState, cp15.par_ns) },
3218 .writefn = par_write },
3219#ifndef CONFIG_USER_ONLY
3220
3221 { .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY,
3222 .access = PL1_W, .accessfn = ats_access,
3223 .writefn = ats_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
3224#endif
3225 REGINFO_SENTINEL
3226};
3227
3228
3229static uint32_t simple_mpu_ap_bits(uint32_t val)
3230{
3231 uint32_t ret;
3232 uint32_t mask;
3233 int i;
3234 ret = 0;
3235 mask = 3;
3236 for (i = 0; i < 16; i += 2) {
3237 ret |= (val >> i) & mask;
3238 mask <<= 2;
3239 }
3240 return ret;
3241}
3242
3243
3244static uint32_t extended_mpu_ap_bits(uint32_t val)
3245{
3246 uint32_t ret;
3247 uint32_t mask;
3248 int i;
3249 ret = 0;
3250 mask = 3;
3251 for (i = 0; i < 16; i += 2) {
3252 ret |= (val & mask) << i;
3253 mask <<= 2;
3254 }
3255 return ret;
3256}
3257
3258static void pmsav5_data_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
3259 uint64_t value)
3260{
3261 env->cp15.pmsav5_data_ap = extended_mpu_ap_bits(value);
3262}
3263
3264static uint64_t pmsav5_data_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
3265{
3266 return simple_mpu_ap_bits(env->cp15.pmsav5_data_ap);
3267}
3268
3269static void pmsav5_insn_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
3270 uint64_t value)
3271{
3272 env->cp15.pmsav5_insn_ap = extended_mpu_ap_bits(value);
3273}
3274
3275static uint64_t pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
3276{
3277 return simple_mpu_ap_bits(env->cp15.pmsav5_insn_ap);
3278}
3279
3280static uint64_t pmsav7_read(CPUARMState *env, const ARMCPRegInfo *ri)
3281{
3282 uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri);
3283
3284 if (!u32p) {
3285 return 0;
3286 }
3287
3288 u32p += env->pmsav7.rnr[M_REG_NS];
3289 return *u32p;
3290}
3291
3292static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri,
3293 uint64_t value)
3294{
3295 ARMCPU *cpu = env_archcpu(env);
3296 uint32_t *u32p = *(uint32_t **)raw_ptr(env, ri);
3297
3298 if (!u32p) {
3299 return;
3300 }
3301
3302 u32p += env->pmsav7.rnr[M_REG_NS];
3303 tlb_flush(CPU(cpu));
3304 *u32p = value;
3305}
3306
3307static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri,
3308 uint64_t value)
3309{
3310 ARMCPU *cpu = env_archcpu(env);
3311 uint32_t nrgs = cpu->pmsav7_dregion;
3312
3313 if (value >= nrgs) {
3314 qemu_log_mask(LOG_GUEST_ERROR,
3315 "PMSAv7 RGNR write >= # supported regions, %" PRIu32
3316 " > %" PRIu32 "\n", (uint32_t)value, nrgs);
3317 return;
3318 }
3319
3320 raw_write(env, ri, value);
3321}
3322
3323static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
3324
3325
3326
3327
3328 { .name = "DRBAR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 0,
3329 .access = PL1_RW, .type = ARM_CP_NO_RAW,
3330 .fieldoffset = offsetof(CPUARMState, pmsav7.drbar),
3331 .readfn = pmsav7_read, .writefn = pmsav7_write,
3332 .resetfn = arm_cp_reset_ignore },
3333 { .name = "DRSR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 2,
3334 .access = PL1_RW, .type = ARM_CP_NO_RAW,
3335 .fieldoffset = offsetof(CPUARMState, pmsav7.drsr),
3336 .readfn = pmsav7_read, .writefn = pmsav7_write,
3337 .resetfn = arm_cp_reset_ignore },
3338 { .name = "DRACR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 4,
3339 .access = PL1_RW, .type = ARM_CP_NO_RAW,
3340 .fieldoffset = offsetof(CPUARMState, pmsav7.dracr),
3341 .readfn = pmsav7_read, .writefn = pmsav7_write,
3342 .resetfn = arm_cp_reset_ignore },
3343 { .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0,
3344 .access = PL1_RW,
3345 .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]),
3346 .writefn = pmsav7_rgnr_write,
3347 .resetfn = arm_cp_reset_ignore },
3348 REGINFO_SENTINEL
3349};
3350
3351static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
3352 { .name = "DATA_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
3353 .access = PL1_RW, .type = ARM_CP_ALIAS,
3354 .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap),
3355 .readfn = pmsav5_data_ap_read, .writefn = pmsav5_data_ap_write, },
3356 { .name = "INSN_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
3357 .access = PL1_RW, .type = ARM_CP_ALIAS,
3358 .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap),
3359 .readfn = pmsav5_insn_ap_read, .writefn = pmsav5_insn_ap_write, },
3360 { .name = "DATA_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 2,
3361 .access = PL1_RW,
3362 .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_data_ap),
3363 .resetvalue = 0, },
3364 { .name = "INSN_EXT_AP", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 3,
3365 .access = PL1_RW,
3366 .fieldoffset = offsetof(CPUARMState, cp15.pmsav5_insn_ap),
3367 .resetvalue = 0, },
3368 { .name = "DCACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
3369 .access = PL1_RW,
3370 .fieldoffset = offsetof(CPUARMState, cp15.c2_data), .resetvalue = 0, },
3371 { .name = "ICACHE_CFG", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 1,
3372 .access = PL1_RW,
3373 .fieldoffset = offsetof(CPUARMState, cp15.c2_insn), .resetvalue = 0, },
3374
3375 { .name = "946_PRBS0", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0,
3376 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3377 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[0]) },
3378 { .name = "946_PRBS1", .cp = 15, .crn = 6, .crm = 1, .opc1 = 0,
3379 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3380 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[1]) },
3381 { .name = "946_PRBS2", .cp = 15, .crn = 6, .crm = 2, .opc1 = 0,
3382 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3383 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[2]) },
3384 { .name = "946_PRBS3", .cp = 15, .crn = 6, .crm = 3, .opc1 = 0,
3385 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3386 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[3]) },
3387 { .name = "946_PRBS4", .cp = 15, .crn = 6, .crm = 4, .opc1 = 0,
3388 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3389 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[4]) },
3390 { .name = "946_PRBS5", .cp = 15, .crn = 6, .crm = 5, .opc1 = 0,
3391 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3392 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[5]) },
3393 { .name = "946_PRBS6", .cp = 15, .crn = 6, .crm = 6, .opc1 = 0,
3394 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3395 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[6]) },
3396 { .name = "946_PRBS7", .cp = 15, .crn = 6, .crm = 7, .opc1 = 0,
3397 .opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
3398 .fieldoffset = offsetof(CPUARMState, cp15.c6_region[7]) },
3399 REGINFO_SENTINEL
3400};
3401
3402static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
3403 uint64_t value)
3404{
3405 TCR *tcr = raw_ptr(env, ri);
3406 int maskshift = extract32(value, 0, 3);
3407
3408 if (!arm_feature(env, ARM_FEATURE_V8)) {
3409 if (arm_feature(env, ARM_FEATURE_LPAE) && (value & TTBCR_EAE)) {
3410
3411
3412 value &= ~((7 << 19) | (3 << 14) | (0xf << 3));
3413 } else if (arm_feature(env, ARM_FEATURE_EL3)) {
3414
3415
3416
3417
3418 value &= TTBCR_PD1 | TTBCR_PD0 | TTBCR_N;
3419 } else {
3420 value &= TTBCR_N;
3421 }
3422 }
3423
3424
3425
3426
3427
3428
3429
3430 tcr->raw_tcr = value;
3431 tcr->mask = ~(((uint32_t)0xffffffffu) >> maskshift);
3432 tcr->base_mask = ~((uint32_t)0x3fffu >> maskshift);
3433}
3434
3435static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
3436 uint64_t value)
3437{
3438 ARMCPU *cpu = env_archcpu(env);
3439 TCR *tcr = raw_ptr(env, ri);
3440
3441 if (arm_feature(env, ARM_FEATURE_LPAE)) {
3442
3443
3444
3445 tlb_flush(CPU(cpu));
3446 }
3447
3448 value = deposit64(tcr->raw_tcr, 0, 32, value);
3449 vmsa_ttbcr_raw_write(env, ri, value);
3450}
3451
3452static void vmsa_ttbcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
3453{
3454 TCR *tcr = raw_ptr(env, ri);
3455
3456
3457
3458
3459 tcr->raw_tcr = 0;
3460 tcr->mask = 0;
3461 tcr->base_mask = 0xffffc000u;
3462}
3463
3464static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
3465 uint64_t value)
3466{
3467 ARMCPU *cpu = env_archcpu(env);
3468 TCR *tcr = raw_ptr(env, ri);
3469
3470
3471 tlb_flush(CPU(cpu));
3472 tcr->raw_tcr = value;
3473}
3474
3475static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
3476 uint64_t value)
3477{
3478
3479 if (cpreg_field_is_64bit(ri) &&
3480 extract64(raw_read(env, ri) ^ value, 48, 16) != 0) {
3481 ARMCPU *cpu = env_archcpu(env);
3482 tlb_flush(CPU(cpu));
3483 }
3484 raw_write(env, ri, value);
3485}
3486
3487static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
3488 uint64_t value)
3489{
3490 ARMCPU *cpu = env_archcpu(env);
3491 CPUState *cs = CPU(cpu);
3492
3493
3494 if (raw_read(env, ri) != value) {
3495 tlb_flush_by_mmuidx(cs,
3496 ARMMMUIdxBit_S12NSE1 |
3497 ARMMMUIdxBit_S12NSE0 |
3498 ARMMMUIdxBit_S2NS);
3499 raw_write(env, ri, value);
3500 }
3501}
3502
3503static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
3504 { .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
3505 .access = PL1_RW, .type = ARM_CP_ALIAS,
3506 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s),
3507 offsetoflow32(CPUARMState, cp15.dfsr_ns) }, },
3508 { .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
3509 .access = PL1_RW, .resetvalue = 0,
3510 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ifsr_s),
3511 offsetoflow32(CPUARMState, cp15.ifsr_ns) } },
3512 { .name = "DFAR", .cp = 15, .opc1 = 0, .crn = 6, .crm = 0, .opc2 = 0,
3513 .access = PL1_RW, .resetvalue = 0,
3514 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.dfar_s),
3515 offsetof(CPUARMState, cp15.dfar_ns) } },
3516 { .name = "FAR_EL1", .state = ARM_CP_STATE_AA64,
3517 .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
3518 .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
3519 .resetvalue = 0, },
3520 REGINFO_SENTINEL
3521};
3522
3523static const ARMCPRegInfo vmsa_cp_reginfo[] = {
3524 { .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
3525 .opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
3526 .access = PL1_RW,
3527 .fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
3528 { .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
3529 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
3530 .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
3531 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
3532 offsetof(CPUARMState, cp15.ttbr0_ns) } },
3533 { .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
3534 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
3535 .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
3536 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
3537 offsetof(CPUARMState, cp15.ttbr1_ns) } },
3538 { .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
3539 .opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
3540 .access = PL1_RW, .writefn = vmsa_tcr_el1_write,
3541 .resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
3542 .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[1]) },
3543 { .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
3544 .access = PL1_RW, .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write,
3545 .raw_writefn = vmsa_ttbcr_raw_write,
3546 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tcr_el[3]),
3547 offsetoflow32(CPUARMState, cp15.tcr_el[1])} },
3548 REGINFO_SENTINEL
3549};
3550
3551
3552
3553
3554static const ARMCPRegInfo ttbcr2_reginfo = {
3555 .name = "TTBCR2", .cp = 15, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 3,
3556 .access = PL1_RW, .type = ARM_CP_ALIAS,
3557 .bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]),
3558 offsetofhigh32(CPUARMState, cp15.tcr_el[1]) },
3559};
3560
3561static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
3562 uint64_t value)
3563{
3564 env->cp15.c15_ticonfig = value & 0xe7;
3565
3566 env->cp15.c0_cpuid = (value & (1 << 5)) ?
3567 ARM_CPUID_TI915T : ARM_CPUID_TI925T;
3568}
3569
3570static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
3571 uint64_t value)
3572{
3573 env->cp15.c15_threadid = value & 0xffff;
3574}
3575
3576static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
3577 uint64_t value)
3578{
3579
3580 cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HALT);
3581}
3582
3583static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
3584 uint64_t value)
3585{
3586
3587
3588
3589 env->cp15.c15_i_max = 0x000;
3590 env->cp15.c15_i_min = 0xff0;
3591}
3592
3593static const ARMCPRegInfo omap_cp_reginfo[] = {
3594 { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
3595 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE,
3596 .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
3597 .resetvalue = 0, },
3598 { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
3599 .access = PL1_RW, .type = ARM_CP_NOP },
3600 { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
3601 .access = PL1_RW,
3602 .fieldoffset = offsetof(CPUARMState, cp15.c15_ticonfig), .resetvalue = 0,
3603 .writefn = omap_ticonfig_write },
3604 { .name = "IMAX", .cp = 15, .crn = 15, .crm = 2, .opc1 = 0, .opc2 = 0,
3605 .access = PL1_RW,
3606 .fieldoffset = offsetof(CPUARMState, cp15.c15_i_max), .resetvalue = 0, },
3607 { .name = "IMIN", .cp = 15, .crn = 15, .crm = 3, .opc1 = 0, .opc2 = 0,
3608 .access = PL1_RW, .resetvalue = 0xff0,
3609 .fieldoffset = offsetof(CPUARMState, cp15.c15_i_min) },
3610 { .name = "THREADID", .cp = 15, .crn = 15, .crm = 4, .opc1 = 0, .opc2 = 0,
3611 .access = PL1_RW,
3612 .fieldoffset = offsetof(CPUARMState, cp15.c15_threadid), .resetvalue = 0,
3613 .writefn = omap_threadid_write },
3614 { .name = "TI925T_STATUS", .cp = 15, .crn = 15,
3615 .crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
3616 .type = ARM_CP_NO_RAW,
3617 .readfn = arm_cp_read_zero, .writefn = omap_wfi_write, },
3618
3619
3620
3621
3622
3623 { .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
3624 .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
3625 .type = ARM_CP_OVERRIDE | ARM_CP_NO_RAW,
3626 .writefn = omap_cachemaint_write },
3627 { .name = "C9", .cp = 15, .crn = 9,
3628 .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
3629 .type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 },
3630 REGINFO_SENTINEL
3631};
3632
3633static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
3634 uint64_t value)
3635{
3636 env->cp15.c15_cpar = value & 0x3fff;
3637}
3638
3639static const ARMCPRegInfo xscale_cp_reginfo[] = {
3640 { .name = "XSCALE_CPAR",
3641 .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
3642 .fieldoffset = offsetof(CPUARMState, cp15.c15_cpar), .resetvalue = 0,
3643 .writefn = xscale_cpar_write, },
3644 { .name = "XSCALE_AUXCR",
3645 .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW,
3646 .fieldoffset = offsetof(CPUARMState, cp15.c1_xscaleauxcr),
3647 .resetvalue = 0, },
3648
3649
3650
3651 { .name = "XSCALE_LOCK_ICACHE_LINE",
3652 .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
3653 .access = PL1_W, .type = ARM_CP_NOP },
3654 { .name = "XSCALE_UNLOCK_ICACHE",
3655 .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
3656 .access = PL1_W, .type = ARM_CP_NOP },
3657 { .name = "XSCALE_DCACHE_LOCK",
3658 .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 0,
3659 .access = PL1_RW, .type = ARM_CP_NOP },
3660 { .name = "XSCALE_UNLOCK_DCACHE",
3661 .cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 1,
3662 .access = PL1_W, .type = ARM_CP_NOP },
3663 REGINFO_SENTINEL
3664};
3665
3666static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
3667
3668
3669
3670
3671
3672 { .name = "C15_IMPDEF", .cp = 15, .crn = 15,
3673 .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
3674 .access = PL1_RW,
3675 .type = ARM_CP_CONST | ARM_CP_NO_RAW | ARM_CP_OVERRIDE,
3676 .resetvalue = 0 },
3677 REGINFO_SENTINEL
3678};
3679
3680static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = {
3681
3682 { .name = "CDSR", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 6,
3683 .access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
3684 .resetvalue = 0 },
3685 REGINFO_SENTINEL
3686};
3687
3688static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
3689
3690 { .name = "BXSR", .cp = 15, .crn = 7, .crm = 12, .opc1 = 0, .opc2 = 4,
3691 .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
3692 .resetvalue = 0 },
3693
3694 { .name = "IICR", .cp = 15, .crm = 5, .opc1 = 0,
3695 .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
3696 { .name = "IDCR", .cp = 15, .crm = 6, .opc1 = 0,
3697 .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
3698 { .name = "CDCR", .cp = 15, .crm = 12, .opc1 = 0,
3699 .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
3700 { .name = "PIR", .cp = 15, .crm = 12, .opc1 = 1,
3701 .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
3702 { .name = "PDR", .cp = 15, .crm = 12, .opc1 = 2,
3703 .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
3704 { .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0,
3705 .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
3706 REGINFO_SENTINEL
3707};
3708
3709static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
3710
3711
3712
3713 { .name = "TC_DCACHE", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 3,
3714 .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
3715 .resetvalue = (1 << 30) },
3716 { .name = "TCI_DCACHE", .cp = 15, .crn = 7, .crm = 14, .opc1 = 0, .opc2 = 3,
3717 .access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
3718 .resetvalue = (1 << 30) },
3719 REGINFO_SENTINEL
3720};
3721
3722static const ARMCPRegInfo strongarm_cp_reginfo[] = {
3723
3724 { .name = "C9_READBUFFER", .cp = 15, .crn = 9,
3725 .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
3726 .access = PL1_RW, .resetvalue = 0,
3727 .type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_RAW },
3728 REGINFO_SENTINEL
3729};
3730
3731static uint64_t midr_read(CPUARMState *env, const ARMCPRegInfo *ri)
3732{
3733 ARMCPU *cpu = env_archcpu(env);
3734 unsigned int cur_el = arm_current_el(env);
3735 bool secure = arm_is_secure(env);
3736
3737 if (arm_feature(&cpu->env, ARM_FEATURE_EL2) && !secure && cur_el == 1) {
3738 return env->cp15.vpidr_el2;
3739 }
3740 return raw_read(env, ri);
3741}
3742
3743static uint64_t mpidr_read_val(CPUARMState *env)
3744{
3745 ARMCPU *cpu = env_archcpu(env);
3746 uint64_t mpidr = cpu->mp_affinity;
3747
3748 if (arm_feature(env, ARM_FEATURE_V7MP)) {
3749 mpidr |= (1U << 31);
3750
3751
3752
3753
3754 if (cpu->mp_is_up) {
3755 mpidr |= (1u << 30);
3756 }
3757 }
3758 return mpidr;
3759}
3760
3761static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
3762{
3763 unsigned int cur_el = arm_current_el(env);
3764 bool secure = arm_is_secure(env);
3765
3766 if (arm_feature(env, ARM_FEATURE_EL2) && !secure && cur_el == 1) {
3767 return env->cp15.vmpidr_el2;
3768 }
3769 return mpidr_read_val(env);
3770}
3771
3772static const ARMCPRegInfo lpae_cp_reginfo[] = {
3773
3774 { .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
3775 .opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
3776 .access = PL1_RW, .type = ARM_CP_CONST,
3777 .resetvalue = 0 },
3778
3779 { .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
3780 .access = PL1_RW, .type = ARM_CP_CONST,
3781 .resetvalue = 0 },
3782 { .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
3783 .access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
3784 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s),
3785 offsetof(CPUARMState, cp15.par_ns)} },
3786 { .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
3787 .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
3788 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
3789 offsetof(CPUARMState, cp15.ttbr0_ns) },
3790 .writefn = vmsa_ttbr_write, },
3791 { .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
3792 .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
3793 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
3794 offsetof(CPUARMState, cp15.ttbr1_ns) },
3795 .writefn = vmsa_ttbr_write, },
3796 REGINFO_SENTINEL
3797};
3798
3799static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
3800{
3801 return vfp_get_fpcr(env);
3802}
3803
3804static void aa64_fpcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
3805 uint64_t value)
3806{
3807 vfp_set_fpcr(env, value);
3808}
3809
3810static uint64_t aa64_fpsr_read(CPUARMState *env, const ARMCPRegInfo *ri)
3811{
3812 return vfp_get_fpsr(env);
3813}
3814
3815static void aa64_fpsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
3816 uint64_t value)
3817{
3818 vfp_set_fpsr(env, value);
3819}
3820
3821static CPAccessResult aa64_daif_access(CPUARMState *env, const ARMCPRegInfo *ri,
3822 bool isread)
3823{
3824 if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
3825 return CP_ACCESS_TRAP;
3826 }
3827 return CP_ACCESS_OK;
3828}
3829
3830static void aa64_daif_write(CPUARMState *env, const ARMCPRegInfo *ri,
3831 uint64_t value)
3832{
3833 env->daif = value & PSTATE_DAIF;
3834}
3835
3836static CPAccessResult aa64_cacheop_access(CPUARMState *env,
3837 const ARMCPRegInfo *ri,
3838 bool isread)
3839{
3840
3841
3842
3843 if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCI)) {
3844 return CP_ACCESS_TRAP;
3845 }
3846 return CP_ACCESS_OK;
3847}
3848
3849
3850
3851
3852
3853static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
3854 uint64_t value)
3855{
3856 CPUState *cs = env_cpu(env);
3857 bool sec = arm_is_secure_below_el3(env);
3858
3859 if (sec) {
3860 tlb_flush_by_mmuidx_all_cpus_synced(cs,
3861 ARMMMUIdxBit_S1SE1 |
3862 ARMMMUIdxBit_S1SE0);
3863 } else {
3864 tlb_flush_by_mmuidx_all_cpus_synced(cs,
3865 ARMMMUIdxBit_S12NSE1 |
3866 ARMMMUIdxBit_S12NSE0);
3867 }
3868}
3869
3870static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
3871 uint64_t value)
3872{
3873 CPUState *cs = env_cpu(env);
3874
3875 if (tlb_force_broadcast(env)) {
3876 tlbi_aa64_vmalle1is_write(env, NULL, value);
3877 return;
3878 }
3879
3880 if (arm_is_secure_below_el3(env)) {
3881 tlb_flush_by_mmuidx(cs,
3882 ARMMMUIdxBit_S1SE1 |
3883 ARMMMUIdxBit_S1SE0);
3884 } else {
3885 tlb_flush_by_mmuidx(cs,
3886 ARMMMUIdxBit_S12NSE1 |
3887 ARMMMUIdxBit_S12NSE0);
3888 }
3889}
3890
3891static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
3892 uint64_t value)
3893{
3894
3895
3896
3897
3898 ARMCPU *cpu = env_archcpu(env);
3899 CPUState *cs = CPU(cpu);
3900
3901 if (arm_is_secure_below_el3(env)) {
3902 tlb_flush_by_mmuidx(cs,
3903 ARMMMUIdxBit_S1SE1 |
3904 ARMMMUIdxBit_S1SE0);
3905 } else {
3906 if (arm_feature(env, ARM_FEATURE_EL2)) {
3907 tlb_flush_by_mmuidx(cs,
3908 ARMMMUIdxBit_S12NSE1 |
3909 ARMMMUIdxBit_S12NSE0 |
3910 ARMMMUIdxBit_S2NS);
3911 } else {
3912 tlb_flush_by_mmuidx(cs,
3913 ARMMMUIdxBit_S12NSE1 |
3914 ARMMMUIdxBit_S12NSE0);
3915 }
3916 }
3917}
3918
3919static void tlbi_aa64_alle2_write(CPUARMState *env, const ARMCPRegInfo *ri,
3920 uint64_t value)
3921{
3922 ARMCPU *cpu = env_archcpu(env);
3923 CPUState *cs = CPU(cpu);
3924
3925 tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_S1E2);
3926}
3927
3928static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri,
3929 uint64_t value)
3930{
3931 ARMCPU *cpu = env_archcpu(env);
3932 CPUState *cs = CPU(cpu);
3933
3934 tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_S1E3);
3935}
3936
3937static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
3938 uint64_t value)
3939{
3940
3941
3942
3943
3944 CPUState *cs = env_cpu(env);
3945 bool sec = arm_is_secure_below_el3(env);
3946 bool has_el2 = arm_feature(env, ARM_FEATURE_EL2);
3947
3948 if (sec) {
3949 tlb_flush_by_mmuidx_all_cpus_synced(cs,
3950 ARMMMUIdxBit_S1SE1 |
3951 ARMMMUIdxBit_S1SE0);
3952 } else if (has_el2) {
3953 tlb_flush_by_mmuidx_all_cpus_synced(cs,
3954 ARMMMUIdxBit_S12NSE1 |
3955 ARMMMUIdxBit_S12NSE0 |
3956 ARMMMUIdxBit_S2NS);
3957 } else {
3958 tlb_flush_by_mmuidx_all_cpus_synced(cs,
3959 ARMMMUIdxBit_S12NSE1 |
3960 ARMMMUIdxBit_S12NSE0);
3961 }
3962}
3963
3964static void tlbi_aa64_alle2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
3965 uint64_t value)
3966{
3967 CPUState *cs = env_cpu(env);
3968
3969 tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E2);
3970}
3971
3972static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
3973 uint64_t value)
3974{
3975 CPUState *cs = env_cpu(env);
3976
3977 tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E3);
3978}
3979
3980static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
3981 uint64_t value)
3982{
3983
3984
3985
3986
3987 ARMCPU *cpu = env_archcpu(env);
3988 CPUState *cs = CPU(cpu);
3989 uint64_t pageaddr = sextract64(value << 12, 0, 56);
3990
3991 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S1E2);
3992}
3993
3994static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
3995 uint64_t value)
3996{
3997
3998
3999
4000
4001 ARMCPU *cpu = env_archcpu(env);
4002 CPUState *cs = CPU(cpu);
4003 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4004
4005 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S1E3);
4006}
4007
4008static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4009 uint64_t value)
4010{
4011 ARMCPU *cpu = env_archcpu(env);
4012 CPUState *cs = CPU(cpu);
4013 bool sec = arm_is_secure_below_el3(env);
4014 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4015
4016 if (sec) {
4017 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
4018 ARMMMUIdxBit_S1SE1 |
4019 ARMMMUIdxBit_S1SE0);
4020 } else {
4021 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
4022 ARMMMUIdxBit_S12NSE1 |
4023 ARMMMUIdxBit_S12NSE0);
4024 }
4025}
4026
4027static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
4028 uint64_t value)
4029{
4030
4031
4032
4033
4034
4035 ARMCPU *cpu = env_archcpu(env);
4036 CPUState *cs = CPU(cpu);
4037 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4038
4039 if (tlb_force_broadcast(env)) {
4040 tlbi_aa64_vae1is_write(env, NULL, value);
4041 return;
4042 }
4043
4044 if (arm_is_secure_below_el3(env)) {
4045 tlb_flush_page_by_mmuidx(cs, pageaddr,
4046 ARMMMUIdxBit_S1SE1 |
4047 ARMMMUIdxBit_S1SE0);
4048 } else {
4049 tlb_flush_page_by_mmuidx(cs, pageaddr,
4050 ARMMMUIdxBit_S12NSE1 |
4051 ARMMMUIdxBit_S12NSE0);
4052 }
4053}
4054
4055static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4056 uint64_t value)
4057{
4058 CPUState *cs = env_cpu(env);
4059 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4060
4061 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
4062 ARMMMUIdxBit_S1E2);
4063}
4064
4065static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4066 uint64_t value)
4067{
4068 CPUState *cs = env_cpu(env);
4069 uint64_t pageaddr = sextract64(value << 12, 0, 56);
4070
4071 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
4072 ARMMMUIdxBit_S1E3);
4073}
4074
4075static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
4076 uint64_t value)
4077{
4078
4079
4080
4081
4082
4083
4084 ARMCPU *cpu = env_archcpu(env);
4085 CPUState *cs = CPU(cpu);
4086 uint64_t pageaddr;
4087
4088 if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
4089 return;
4090 }
4091
4092 pageaddr = sextract64(value << 12, 0, 48);
4093
4094 tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S2NS);
4095}
4096
4097static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
4098 uint64_t value)
4099{
4100 CPUState *cs = env_cpu(env);
4101 uint64_t pageaddr;
4102
4103 if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
4104 return;
4105 }
4106
4107 pageaddr = sextract64(value << 12, 0, 48);
4108
4109 tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
4110 ARMMMUIdxBit_S2NS);
4111}
4112
4113static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
4114 bool isread)
4115{
4116
4117
4118
4119 if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_DZE)) {
4120 return CP_ACCESS_TRAP;
4121 }
4122 return CP_ACCESS_OK;
4123}
4124
4125static uint64_t aa64_dczid_read(CPUARMState *env, const ARMCPRegInfo *ri)
4126{
4127 ARMCPU *cpu = env_archcpu(env);
4128 int dzp_bit = 1 << 4;
4129
4130
4131 if (aa64_zva_access(env, NULL, false) == CP_ACCESS_OK) {
4132 dzp_bit = 0;
4133 }
4134 return cpu->dcz_blocksize | dzp_bit;
4135}
4136
4137static CPAccessResult sp_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
4138 bool isread)
4139{
4140 if (!(env->pstate & PSTATE_SP)) {
4141
4142
4143
4144 return CP_ACCESS_TRAP_UNCATEGORIZED;
4145 }
4146 return CP_ACCESS_OK;
4147}
4148
4149static uint64_t spsel_read(CPUARMState *env, const ARMCPRegInfo *ri)
4150{
4151 return env->pstate & PSTATE_SP;
4152}
4153
4154static void spsel_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
4155{
4156 update_spsel(env, val);
4157}
4158
4159static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
4160 uint64_t value)
4161{
4162 ARMCPU *cpu = env_archcpu(env);
4163
4164 if (raw_read(env, ri) == value) {
4165
4166
4167
4168 return;
4169 }
4170
4171 if (arm_feature(env, ARM_FEATURE_PMSA) && !cpu->has_mpu) {
4172
4173 value &= ~SCTLR_M;
4174 }
4175
4176 raw_write(env, ri, value);
4177
4178
4179 tlb_flush(CPU(cpu));
4180
4181 if (ri->type & ARM_CP_SUPPRESS_TB_END) {
4182
4183
4184
4185
4186
4187
4188 arm_rebuild_hflags(env);
4189 }
4190}
4191
4192static CPAccessResult fpexc32_access(CPUARMState *env, const ARMCPRegInfo *ri,
4193 bool isread)
4194{
4195 if ((env->cp15.cptr_el[2] & CPTR_TFP) && arm_current_el(env) == 2) {
4196 return CP_ACCESS_TRAP_FP_EL2;
4197 }
4198 if (env->cp15.cptr_el[3] & CPTR_TFP) {
4199 return CP_ACCESS_TRAP_FP_EL3;
4200 }
4201 return CP_ACCESS_OK;
4202}
4203
4204static void sdcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
4205 uint64_t value)
4206{
4207 env->cp15.mdcr_el3 = value & SDCR_VALID_MASK;
4208}
4209
4210static const ARMCPRegInfo v8_cp_reginfo[] = {
4211
4212
4213
4214 { .name = "NZCV", .state = ARM_CP_STATE_AA64,
4215 .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 2,
4216 .access = PL0_RW, .type = ARM_CP_NZCV },
4217 { .name = "DAIF", .state = ARM_CP_STATE_AA64,
4218 .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 2,
4219 .type = ARM_CP_NO_RAW,
4220 .access = PL0_RW, .accessfn = aa64_daif_access,
4221 .fieldoffset = offsetof(CPUARMState, daif),
4222 .writefn = aa64_daif_write, .resetfn = arm_cp_reset_ignore },
4223 { .name = "FPCR", .state = ARM_CP_STATE_AA64,
4224 .opc0 = 3, .opc1 = 3, .opc2 = 0, .crn = 4, .crm = 4,
4225 .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
4226 .readfn = aa64_fpcr_read, .writefn = aa64_fpcr_write },
4227 { .name = "FPSR", .state = ARM_CP_STATE_AA64,
4228 .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 4, .crm = 4,
4229 .access = PL0_RW, .type = ARM_CP_FPU | ARM_CP_SUPPRESS_TB_END,
4230 .readfn = aa64_fpsr_read, .writefn = aa64_fpsr_write },
4231 { .name = "DCZID_EL0", .state = ARM_CP_STATE_AA64,
4232 .opc0 = 3, .opc1 = 3, .opc2 = 7, .crn = 0, .crm = 0,
4233 .access = PL0_R, .type = ARM_CP_NO_RAW,
4234 .readfn = aa64_dczid_read },
4235 { .name = "DC_ZVA", .state = ARM_CP_STATE_AA64,
4236 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 4, .opc2 = 1,
4237 .access = PL0_W, .type = ARM_CP_DC_ZVA,
4238#ifndef CONFIG_USER_ONLY
4239
4240 .accessfn = aa64_zva_access,
4241#endif
4242 },
4243 { .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
4244 .opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2,
4245 .access = PL1_R, .type = ARM_CP_CURRENTEL },
4246
4247 { .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
4248 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
4249 .access = PL1_W, .type = ARM_CP_NOP },
4250 { .name = "IC_IALLU", .state = ARM_CP_STATE_AA64,
4251 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
4252 .access = PL1_W, .type = ARM_CP_NOP },
4253 { .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
4254 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
4255 .access = PL0_W, .type = ARM_CP_NOP,
4256 .accessfn = aa64_cacheop_access },
4257 { .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
4258 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
4259 .access = PL1_W, .type = ARM_CP_NOP },
4260 { .name = "DC_ISW", .state = ARM_CP_STATE_AA64,
4261 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
4262 .access = PL1_W, .type = ARM_CP_NOP },
4263 { .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
4264 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
4265 .access = PL0_W, .type = ARM_CP_NOP,
4266 .accessfn = aa64_cacheop_access },
4267 { .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
4268 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
4269 .access = PL1_W, .type = ARM_CP_NOP },
4270 { .name = "DC_CVAU", .state = ARM_CP_STATE_AA64,
4271 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1,
4272 .access = PL0_W, .type = ARM_CP_NOP,
4273 .accessfn = aa64_cacheop_access },
4274 { .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64,
4275 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1,
4276 .access = PL0_W, .type = ARM_CP_NOP,
4277 .accessfn = aa64_cacheop_access },
4278 { .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
4279 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
4280 .access = PL1_W, .type = ARM_CP_NOP },
4281
4282 { .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
4283 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
4284 .access = PL1_W, .type = ARM_CP_NO_RAW,
4285 .writefn = tlbi_aa64_vmalle1is_write },
4286 { .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64,
4287 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
4288 .access = PL1_W, .type = ARM_CP_NO_RAW,
4289 .writefn = tlbi_aa64_vae1is_write },
4290 { .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64,
4291 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
4292 .access = PL1_W, .type = ARM_CP_NO_RAW,
4293 .writefn = tlbi_aa64_vmalle1is_write },
4294 { .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64,
4295 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
4296 .access = PL1_W, .type = ARM_CP_NO_RAW,
4297 .writefn = tlbi_aa64_vae1is_write },
4298 { .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64,
4299 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
4300 .access = PL1_W, .type = ARM_CP_NO_RAW,
4301 .writefn = tlbi_aa64_vae1is_write },
4302 { .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64,
4303 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
4304 .access = PL1_W, .type = ARM_CP_NO_RAW,
4305 .writefn = tlbi_aa64_vae1is_write },
4306 { .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64,
4307 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
4308 .access = PL1_W, .type = ARM_CP_NO_RAW,
4309 .writefn = tlbi_aa64_vmalle1_write },
4310 { .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64,
4311 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
4312 .access = PL1_W, .type = ARM_CP_NO_RAW,
4313 .writefn = tlbi_aa64_vae1_write },
4314 { .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64,
4315 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
4316 .access = PL1_W, .type = ARM_CP_NO_RAW,
4317 .writefn = tlbi_aa64_vmalle1_write },
4318 { .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64,
4319 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
4320 .access = PL1_W, .type = ARM_CP_NO_RAW,
4321 .writefn = tlbi_aa64_vae1_write },
4322 { .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64,
4323 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
4324 .access = PL1_W, .type = ARM_CP_NO_RAW,
4325 .writefn = tlbi_aa64_vae1_write },
4326 { .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64,
4327 .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
4328 .access = PL1_W, .type = ARM_CP_NO_RAW,
4329 .writefn = tlbi_aa64_vae1_write },
4330 { .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
4331 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
4332 .access = PL2_W, .type = ARM_CP_NO_RAW,
4333 .writefn = tlbi_aa64_ipas2e1is_write },
4334 { .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
4335 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
4336 .access = PL2_W, .type = ARM_CP_NO_RAW,
4337 .writefn = tlbi_aa64_ipas2e1is_write },
4338 { .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
4339 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
4340 .access = PL2_W, .type = ARM_CP_NO_RAW,
4341 .writefn = tlbi_aa64_alle1is_write },
4342 { .name = "TLBI_VMALLS12E1IS", .state = ARM_CP_STATE_AA64,
4343 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 6,
4344 .access = PL2_W, .type = ARM_CP_NO_RAW,
4345 .writefn = tlbi_aa64_alle1is_write },
4346 { .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
4347 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
4348 .access = PL2_W, .type = ARM_CP_NO_RAW,
4349 .writefn = tlbi_aa64_ipas2e1_write },
4350 { .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
4351 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
4352 .access = PL2_W, .type = ARM_CP_NO_RAW,
4353 .writefn = tlbi_aa64_ipas2e1_write },
4354 { .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
4355 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
4356 .access = PL2_W, .type = ARM_CP_NO_RAW,
4357 .writefn = tlbi_aa64_alle1_write },
4358 { .name = "TLBI_VMALLS12E1", .state = ARM_CP_STATE_AA64,
4359 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 6,
4360 .access = PL2_W, .type = ARM_CP_NO_RAW,
4361 .writefn = tlbi_aa64_alle1is_write },
4362#ifndef CONFIG_USER_ONLY
4363
4364 { .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64,
4365 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0,
4366 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
4367 .writefn = ats_write64 },
4368 { .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
4369 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1,
4370 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
4371 .writefn = ats_write64 },
4372 { .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64,
4373 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2,
4374 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
4375 .writefn = ats_write64 },
4376 { .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64,
4377 .opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3,
4378 .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
4379 .writefn = ats_write64 },
4380 { .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64,
4381 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4,
4382 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
4383 .writefn = ats_write64 },
4384 { .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64,
4385 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5,
4386 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
4387 .writefn = ats_write64 },
4388 { .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64,
4389 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6,
4390 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
4391 .writefn = ats_write64 },
4392 { .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64,
4393 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7,
4394 .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
4395 .writefn = ats_write64 },
4396
4397 { .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64,
4398 .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0,
4399 .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
4400 .writefn = ats_write64 },
4401 { .name = "AT_S1E3W", .state = ARM_CP_STATE_AA64,
4402 .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 1,
4403 .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
4404 .writefn = ats_write64 },
4405 { .name = "PAR_EL1", .state = ARM_CP_STATE_AA64,
4406 .type = ARM_CP_ALIAS,
4407 .opc0 = 3, .opc1 = 0, .crn = 7, .crm = 4, .opc2 = 0,
4408 .access = PL1_RW, .resetvalue = 0,
4409 .fieldoffset = offsetof(CPUARMState, cp15.par_el[1]),
4410 .writefn = par_write },
4411#endif
4412
4413 { .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
4414 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write },
4415 { .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
4416 .type = ARM_CP_NO_RAW, .access = PL1_W,
4417 .writefn = tlbimvaa_is_write },
4418 { .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
4419 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
4420 { .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
4421 .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write },
4422 { .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
4423 .type = ARM_CP_NO_RAW, .access = PL2_W,
4424 .writefn = tlbimva_hyp_write },
4425 { .name = "TLBIMVALHIS",
4426 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
4427 .type = ARM_CP_NO_RAW, .access = PL2_W,
4428 .writefn = tlbimva_hyp_is_write },
4429 { .name = "TLBIIPAS2",
4430 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
4431 .type = ARM_CP_NO_RAW, .access = PL2_W,
4432 .writefn = tlbiipas2_write },
4433 { .name = "TLBIIPAS2IS",
4434 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
4435 .type = ARM_CP_NO_RAW, .access = PL2_W,
4436 .writefn = tlbiipas2_is_write },
4437 { .name = "TLBIIPAS2L",
4438 .cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
4439 .type = ARM_CP_NO_RAW, .access = PL2_W,
4440 .writefn = tlbiipas2_write },
4441 { .name = "TLBIIPAS2LIS",
4442 .cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
4443 .type = ARM_CP_NO_RAW, .access = PL2_W,
4444 .writefn = tlbiipas2_is_write },
4445
4446 { .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
4447 .type = ARM_CP_NOP, .access = PL1_W },
4448 { .name = "BPIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 6,
4449 .type = ARM_CP_NOP, .access = PL1_W },
4450 { .name = "ICIALLU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
4451 .type = ARM_CP_NOP, .access = PL1_W },
4452 { .name = "ICIMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 1,
4453 .type = ARM_CP_NOP, .access = PL1_W },
4454 { .name = "BPIALL", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 6,
4455 .type = ARM_CP_NOP, .access = PL1_W },
4456 { .name = "BPIMVA", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 7,
4457 .type = ARM_CP_NOP, .access = PL1_W },
4458 { .name = "DCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
4459 .type = ARM_CP_NOP, .access = PL1_W },
4460 { .name = "DCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
4461 .type = ARM_CP_NOP, .access = PL1_W },
4462 { .name = "DCCMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 1,
4463 .type = ARM_CP_NOP, .access = PL1_W },
4464 { .name = "DCCSW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
4465 .type = ARM_CP_NOP, .access = PL1_W },
4466 { .name = "DCCMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 11, .opc2 = 1,
4467 .type = ARM_CP_NOP, .access = PL1_W },
4468 { .name = "DCCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 1,
4469 .type = ARM_CP_NOP, .access = PL1_W },
4470 { .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
4471 .type = ARM_CP_NOP, .access = PL1_W },
4472
4473 { .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0,
4474 .access = PL1_RW, .resetvalue = 0,
4475 .writefn = dacr_write, .raw_writefn = raw_write,
4476 .bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
4477 offsetoflow32(CPUARMState, cp15.dacr_ns) } },
4478 { .name = "ELR_EL1", .state = ARM_CP_STATE_AA64,
4479 .type = ARM_CP_ALIAS,
4480 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 1,
4481 .access = PL1_RW,
4482 .fieldoffset = offsetof(CPUARMState, elr_el[1]) },
4483 { .name = "SPSR_EL1", .state = ARM_CP_STATE_AA64,
4484 .type = ARM_CP_ALIAS,
4485 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
4486 .access = PL1_RW,
4487 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
4488
4489
4490
4491
4492 { .name = "SP_EL0", .state = ARM_CP_STATE_AA64,
4493 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 1, .opc2 = 0,
4494 .access = PL1_RW, .accessfn = sp_el0_access,
4495 .type = ARM_CP_ALIAS,
4496 .fieldoffset = offsetof(CPUARMState, sp_el[0]) },
4497 { .name = "SP_EL1", .state = ARM_CP_STATE_AA64,
4498 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 1, .opc2 = 0,
4499 .access = PL2_RW, .type = ARM_CP_ALIAS,
4500 .fieldoffset = offsetof(CPUARMState, sp_el[1]) },
4501 { .name = "SPSel", .state = ARM_CP_STATE_AA64,
4502 .opc0 = 3, .opc1 = 0, .crn = 4, .crm = 2, .opc2 = 0,
4503 .type = ARM_CP_NO_RAW,
4504 .access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
4505 { .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64,
4506 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0,
4507 .type = ARM_CP_ALIAS,
4508 .fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]),
4509 .access = PL2_RW, .accessfn = fpexc32_access },
4510 { .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
4511 .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
4512 .access = PL2_RW, .resetvalue = 0,
4513 .writefn = dacr_write, .raw_writefn = raw_write,
4514 .fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
4515 { .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
4516 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
4517 .access = PL2_RW, .resetvalue = 0,
4518 .fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
4519 { .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
4520 .type = ARM_CP_ALIAS,
4521 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0,
4522 .access = PL2_RW,
4523 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_IRQ]) },
4524 { .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64,
4525 .type = ARM_CP_ALIAS,
4526 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1,
4527 .access = PL2_RW,
4528 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_ABT]) },
4529 { .name = "SPSR_UND", .state = ARM_CP_STATE_AA64,
4530 .type = ARM_CP_ALIAS,
4531 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2,
4532 .access = PL2_RW,
4533 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_UND]) },
4534 { .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64,
4535 .type = ARM_CP_ALIAS,
4536 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3,
4537 .access = PL2_RW,
4538 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) },
4539 { .name = "MDCR_EL3", .state = ARM_CP_STATE_AA64,
4540 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 3, .opc2 = 1,
4541 .resetvalue = 0,
4542 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el3) },
4543 { .name = "SDCR", .type = ARM_CP_ALIAS,
4544 .cp = 15, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 1,
4545 .access = PL1_RW, .accessfn = access_trap_aa32s_el1,
4546 .writefn = sdcr_write,
4547 .fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) },
4548 REGINFO_SENTINEL
4549};
4550
4551
4552static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
4553 { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
4554 .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
4555 .access = PL2_RW,
4556 .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
4557 { .name = "HCR_EL2", .state = ARM_CP_STATE_BOTH,
4558 .type = ARM_CP_NO_RAW,
4559 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
4560 .access = PL2_RW,
4561 .type = ARM_CP_CONST, .resetvalue = 0 },
4562 { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
4563 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
4564 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4565 { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
4566 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
4567 .access = PL2_RW,
4568 .type = ARM_CP_CONST, .resetvalue = 0 },
4569 { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
4570 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
4571 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4572 { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH,
4573 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0,
4574 .access = PL2_RW, .type = ARM_CP_CONST,
4575 .resetvalue = 0 },
4576 { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
4577 .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
4578 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4579 { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
4580 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
4581 .access = PL2_RW, .type = ARM_CP_CONST,
4582 .resetvalue = 0 },
4583 { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
4584 .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
4585 .access = PL2_RW, .type = ARM_CP_CONST,
4586 .resetvalue = 0 },
4587 { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
4588 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0,
4589 .access = PL2_RW, .type = ARM_CP_CONST,
4590 .resetvalue = 0 },
4591 { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH,
4592 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1,
4593 .access = PL2_RW, .type = ARM_CP_CONST,
4594 .resetvalue = 0 },
4595 { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
4596 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
4597 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4598 { .name = "VTCR_EL2", .state = ARM_CP_STATE_BOTH,
4599 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
4600 .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any,
4601 .type = ARM_CP_CONST, .resetvalue = 0 },
4602 { .name = "VTTBR", .state = ARM_CP_STATE_AA32,
4603 .cp = 15, .opc1 = 6, .crm = 2,
4604 .access = PL2_RW, .accessfn = access_el3_aa32ns,
4605 .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
4606 { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
4607 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
4608 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4609 { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
4610 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
4611 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4612 { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
4613 .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
4614 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4615 { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
4616 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
4617 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4618 { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
4619 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
4620 .resetvalue = 0 },
4621 { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
4622 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
4623 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4624 { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64,
4625 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
4626 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4627 { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14,
4628 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
4629 .resetvalue = 0 },
4630 { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64,
4631 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2,
4632 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4633 { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14,
4634 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
4635 .resetvalue = 0 },
4636 { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH,
4637 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0,
4638 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4639 { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH,
4640 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1,
4641 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4642 { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
4643 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
4644 .access = PL2_RW, .accessfn = access_tda,
4645 .type = ARM_CP_CONST, .resetvalue = 0 },
4646 { .name = "HPFAR_EL2", .state = ARM_CP_STATE_BOTH,
4647 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
4648 .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any,
4649 .type = ARM_CP_CONST, .resetvalue = 0 },
4650 { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
4651 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
4652 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4653 { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
4654 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
4655 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4656 { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
4657 .type = ARM_CP_CONST,
4658 .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
4659 .access = PL2_RW, .resetvalue = 0 },
4660 REGINFO_SENTINEL
4661};
4662
4663
4664static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
4665 { .name = "HCR2", .state = ARM_CP_STATE_AA32,
4666 .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
4667 .access = PL2_RW,
4668 .type = ARM_CP_CONST, .resetvalue = 0 },
4669 REGINFO_SENTINEL
4670};
4671
4672static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
4673{
4674 ARMCPU *cpu = env_archcpu(env);
4675 uint64_t valid_mask = HCR_MASK;
4676
4677 if (arm_feature(env, ARM_FEATURE_EL3)) {
4678 valid_mask &= ~HCR_HCD;
4679 } else if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
4680
4681
4682
4683
4684
4685
4686
4687 valid_mask &= ~HCR_TSC;
4688 }
4689 if (cpu_isar_feature(aa64_lor, cpu)) {
4690 valid_mask |= HCR_TLOR;
4691 }
4692 if (cpu_isar_feature(aa64_pauth, cpu)) {
4693 valid_mask |= HCR_API | HCR_APK;
4694 }
4695
4696
4697 value &= valid_mask;
4698
4699
4700
4701
4702
4703
4704 if ((env->cp15.hcr_el2 ^ value) & (HCR_VM | HCR_PTW | HCR_DC)) {
4705 tlb_flush(CPU(cpu));
4706 }
4707 env->cp15.hcr_el2 = value;
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720 g_assert(qemu_mutex_iothread_locked());
4721 arm_cpu_update_virq(cpu);
4722 arm_cpu_update_vfiq(cpu);
4723}
4724
4725static void hcr_writehigh(CPUARMState *env, const ARMCPRegInfo *ri,
4726 uint64_t value)
4727{
4728
4729 value = deposit64(env->cp15.hcr_el2, 32, 32, value);
4730 hcr_write(env, NULL, value);
4731}
4732
4733static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
4734 uint64_t value)
4735{
4736
4737 value = deposit64(env->cp15.hcr_el2, 0, 32, value);
4738 hcr_write(env, NULL, value);
4739}
4740
4741
4742
4743
4744
4745
4746uint64_t arm_hcr_el2_eff(CPUARMState *env)
4747{
4748 uint64_t ret = env->cp15.hcr_el2;
4749
4750 if (arm_is_secure_below_el3(env)) {
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766 ret = 0;
4767 } else if (ret & HCR_TGE) {
4768
4769 if (ret & HCR_E2H) {
4770 ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO |
4771 HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE |
4772 HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU |
4773 HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE);
4774 } else {
4775 ret |= HCR_FMO | HCR_IMO | HCR_AMO;
4776 }
4777 ret &= ~(HCR_SWIO | HCR_PTW | HCR_VF | HCR_VI | HCR_VSE |
4778 HCR_FB | HCR_TID1 | HCR_TID3 | HCR_TSC | HCR_TACR |
4779 HCR_TSW | HCR_TTLB | HCR_TVM | HCR_HCD | HCR_TRVM |
4780 HCR_TLOR);
4781 }
4782
4783 return ret;
4784}
4785
4786static void cptr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
4787 uint64_t value)
4788{
4789
4790
4791
4792
4793 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
4794 !arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
4795 value &= ~(0x3 << 10);
4796 value |= env->cp15.cptr_el[2] & (0x3 << 10);
4797 }
4798 env->cp15.cptr_el[2] = value;
4799}
4800
4801static uint64_t cptr_el2_read(CPUARMState *env, const ARMCPRegInfo *ri)
4802{
4803
4804
4805
4806
4807 uint64_t value = env->cp15.cptr_el[2];
4808
4809 if (arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
4810 !arm_is_secure(env) && !extract32(env->cp15.nsacr, 10, 1)) {
4811 value |= 0x3 << 10;
4812 }
4813 return value;
4814}
4815
4816static const ARMCPRegInfo el2_cp_reginfo[] = {
4817 { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
4818 .type = ARM_CP_IO,
4819 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
4820 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
4821 .writefn = hcr_write },
4822 { .name = "HCR", .state = ARM_CP_STATE_AA32,
4823 .type = ARM_CP_ALIAS | ARM_CP_IO,
4824 .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
4825 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
4826 .writefn = hcr_writelow },
4827 { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
4828 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
4829 .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
4830 { .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
4831 .type = ARM_CP_ALIAS,
4832 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
4833 .access = PL2_RW,
4834 .fieldoffset = offsetof(CPUARMState, elr_el[2]) },
4835 { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
4836 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
4837 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
4838 { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
4839 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
4840 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) },
4841 { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
4842 .type = ARM_CP_ALIAS,
4843 .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
4844 .access = PL2_RW,
4845 .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[2]) },
4846 { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
4847 .type = ARM_CP_ALIAS,
4848 .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
4849 .access = PL2_RW,
4850 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
4851 { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
4852 .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
4853 .access = PL2_RW, .writefn = vbar_write,
4854 .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]),
4855 .resetvalue = 0 },
4856 { .name = "SP_EL2", .state = ARM_CP_STATE_AA64,
4857 .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 1, .opc2 = 0,
4858 .access = PL3_RW, .type = ARM_CP_ALIAS,
4859 .fieldoffset = offsetof(CPUARMState, sp_el[2]) },
4860 { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
4861 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
4862 .access = PL2_RW, .accessfn = cptr_access, .resetvalue = 0,
4863 .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[2]),
4864 .readfn = cptr_el2_read, .writefn = cptr_el2_write },
4865 { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH,
4866 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0,
4867 .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[2]),
4868 .resetvalue = 0 },
4869 { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
4870 .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
4871 .access = PL2_RW, .type = ARM_CP_ALIAS,
4872 .fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el[2]) },
4873 { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
4874 .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
4875 .access = PL2_RW, .type = ARM_CP_CONST,
4876 .resetvalue = 0 },
4877
4878 { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
4879 .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
4880 .access = PL2_RW, .type = ARM_CP_CONST,
4881 .resetvalue = 0 },
4882 { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
4883 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0,
4884 .access = PL2_RW, .type = ARM_CP_CONST,
4885 .resetvalue = 0 },
4886 { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH,
4887 .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1,
4888 .access = PL2_RW, .type = ARM_CP_CONST,
4889 .resetvalue = 0 },
4890 { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
4891 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
4892 .access = PL2_RW,
4893
4894
4895
4896 .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) },
4897 { .name = "VTCR", .state = ARM_CP_STATE_AA32,
4898 .cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
4899 .type = ARM_CP_ALIAS,
4900 .access = PL2_RW, .accessfn = access_el3_aa32ns,
4901 .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) },
4902 { .name = "VTCR_EL2", .state = ARM_CP_STATE_AA64,
4903 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
4904 .access = PL2_RW,
4905
4906
4907
4908 .fieldoffset = offsetof(CPUARMState, cp15.vtcr_el2) },
4909 { .name = "VTTBR", .state = ARM_CP_STATE_AA32,
4910 .cp = 15, .opc1 = 6, .crm = 2,
4911 .type = ARM_CP_64BIT | ARM_CP_ALIAS,
4912 .access = PL2_RW, .accessfn = access_el3_aa32ns,
4913 .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2),
4914 .writefn = vttbr_write },
4915 { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
4916 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
4917 .access = PL2_RW, .writefn = vttbr_write,
4918 .fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) },
4919 { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
4920 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
4921 .access = PL2_RW, .raw_writefn = raw_write, .writefn = sctlr_write,
4922 .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[2]) },
4923 { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
4924 .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
4925 .access = PL2_RW, .resetvalue = 0,
4926 .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) },
4927 { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
4928 .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
4929 .access = PL2_RW, .resetvalue = 0,
4930 .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
4931 { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
4932 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
4933 .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
4934 { .name = "TLBIALLNSNH",
4935 .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
4936 .type = ARM_CP_NO_RAW, .access = PL2_W,
4937 .writefn = tlbiall_nsnh_write },
4938 { .name = "TLBIALLNSNHIS",
4939 .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
4940 .type = ARM_CP_NO_RAW, .access = PL2_W,
4941 .writefn = tlbiall_nsnh_is_write },
4942 { .name = "TLBIALLH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
4943 .type = ARM_CP_NO_RAW, .access = PL2_W,
4944 .writefn = tlbiall_hyp_write },
4945 { .name = "TLBIALLHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0,
4946 .type = ARM_CP_NO_RAW, .access = PL2_W,
4947 .writefn = tlbiall_hyp_is_write },
4948 { .name = "TLBIMVAH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
4949 .type = ARM_CP_NO_RAW, .access = PL2_W,
4950 .writefn = tlbimva_hyp_write },
4951 { .name = "TLBIMVAHIS", .cp = 15, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
4952 .type = ARM_CP_NO_RAW, .access = PL2_W,
4953 .writefn = tlbimva_hyp_is_write },
4954 { .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
4955 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
4956 .type = ARM_CP_NO_RAW, .access = PL2_W,
4957 .writefn = tlbi_aa64_alle2_write },
4958 { .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64,
4959 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
4960 .type = ARM_CP_NO_RAW, .access = PL2_W,
4961 .writefn = tlbi_aa64_vae2_write },
4962 { .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64,
4963 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
4964 .access = PL2_W, .type = ARM_CP_NO_RAW,
4965 .writefn = tlbi_aa64_vae2_write },
4966 { .name = "TLBI_ALLE2IS", .state = ARM_CP_STATE_AA64,
4967 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0,
4968 .access = PL2_W, .type = ARM_CP_NO_RAW,
4969 .writefn = tlbi_aa64_alle2is_write },
4970 { .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64,
4971 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
4972 .type = ARM_CP_NO_RAW, .access = PL2_W,
4973 .writefn = tlbi_aa64_vae2is_write },
4974 { .name = "TLBI_VALE2IS", .state = ARM_CP_STATE_AA64,
4975 .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
4976 .access = PL2_W, .type = ARM_CP_NO_RAW,
4977 .writefn = tlbi_aa64_vae2is_write },
4978#ifndef CONFIG_USER_ONLY
4979
4980
4981
4982
4983 { .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64,
4984 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
4985 .access = PL2_W, .accessfn = at_s1e2_access,
4986 .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
4987 { .name = "AT_S1E2W", .state = ARM_CP_STATE_AA64,
4988 .opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
4989 .access = PL2_W, .accessfn = at_s1e2_access,
4990 .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
4991
4992
4993
4994
4995
4996 { .name = "ATS1HR", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
4997 .access = PL2_W,
4998 .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
4999 { .name = "ATS1HW", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
5000 .access = PL2_W,
5001 .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
5002 { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
5003 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
5004
5005
5006
5007
5008 .access = PL2_RW, .resetvalue = 3,
5009 .fieldoffset = offsetof(CPUARMState, cp15.cnthctl_el2) },
5010 { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64,
5011 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
5012 .access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 0,
5013 .writefn = gt_cntvoff_write,
5014 .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) },
5015 { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14,
5016 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS | ARM_CP_IO,
5017 .writefn = gt_cntvoff_write,
5018 .fieldoffset = offsetof(CPUARMState, cp15.cntvoff_el2) },
5019 { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64,
5020 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2,
5021 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval),
5022 .type = ARM_CP_IO, .access = PL2_RW,
5023 .writefn = gt_hyp_cval_write, .raw_writefn = raw_write },
5024 { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14,
5025 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].cval),
5026 .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_IO,
5027 .writefn = gt_hyp_cval_write, .raw_writefn = raw_write },
5028 { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH,
5029 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0,
5030 .type = ARM_CP_NO_RAW | ARM_CP_IO, .access = PL2_RW,
5031 .resetfn = gt_hyp_timer_reset,
5032 .readfn = gt_hyp_tval_read, .writefn = gt_hyp_tval_write },
5033 { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH,
5034 .type = ARM_CP_IO,
5035 .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1,
5036 .access = PL2_RW,
5037 .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_HYP].ctl),
5038 .resetvalue = 0,
5039 .writefn = gt_hyp_ctl_write, .raw_writefn = raw_write },
5040#endif
5041
5042
5043
5044
5045
5046 { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
5047 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
5048 .access = PL2_RW, .resetvalue = 0,
5049 .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2), },
5050 { .name = "HPFAR", .state = ARM_CP_STATE_AA32,
5051 .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
5052 .access = PL2_RW, .accessfn = access_el3_aa32ns,
5053 .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) },
5054 { .name = "HPFAR_EL2", .state = ARM_CP_STATE_AA64,
5055 .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
5056 .access = PL2_RW,
5057 .fieldoffset = offsetof(CPUARMState, cp15.hpfar_el2) },
5058 { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
5059 .cp = 15, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
5060 .access = PL2_RW,
5061 .fieldoffset = offsetof(CPUARMState, cp15.hstr_el2) },
5062 REGINFO_SENTINEL
5063};
5064
5065static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
5066 { .name = "HCR2", .state = ARM_CP_STATE_AA32,
5067 .type = ARM_CP_ALIAS | ARM_CP_IO,
5068 .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
5069 .access = PL2_RW,
5070 .fieldoffset = offsetofhigh32(CPUARMState, cp15.hcr_el2),
5071 .writefn = hcr_writehigh },
5072 REGINFO_SENTINEL
5073};
5074
5075static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
5076 bool isread)
5077{
5078
5079
5080
5081 if (arm_current_el(env) == 3) {
5082 return CP_ACCESS_OK;
5083 }
5084 if (arm_is_secure_below_el3(env)) {
5085 return CP_ACCESS_TRAP_EL3;
5086 }
5087
5088 if (isread) {
5089 return CP_ACCESS_OK;
5090 }
5091 return CP_ACCESS_TRAP_UNCATEGORIZED;
5092}
5093
5094static const ARMCPRegInfo el3_cp_reginfo[] = {
5095 { .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
5096 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
5097 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
5098 .resetvalue = 0, .writefn = scr_write },
5099 { .name = "SCR", .type = ARM_CP_ALIAS,
5100 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
5101 .access = PL1_RW, .accessfn = access_trap_aa32s_el1,
5102 .fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
5103 .writefn = scr_write },
5104 { .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64,
5105 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1,
5106 .access = PL3_RW, .resetvalue = 0,
5107 .fieldoffset = offsetof(CPUARMState, cp15.sder) },
5108 { .name = "SDER",
5109 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 1,
5110 .access = PL3_RW, .resetvalue = 0,
5111 .fieldoffset = offsetoflow32(CPUARMState, cp15.sder) },
5112 { .name = "MVBAR", .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
5113 .access = PL1_RW, .accessfn = access_trap_aa32s_el1,
5114 .writefn = vbar_write, .resetvalue = 0,
5115 .fieldoffset = offsetof(CPUARMState, cp15.mvbar) },
5116 { .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64,
5117 .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 0,
5118 .access = PL3_RW, .resetvalue = 0,
5119 .fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[3]) },
5120 { .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
5121 .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 2,
5122 .access = PL3_RW,
5123
5124
5125
5126
5127
5128 .resetfn = vmsa_ttbcr_reset, .raw_writefn = vmsa_ttbcr_raw_write,
5129 .fieldoffset = offsetof(CPUARMState, cp15.tcr_el[3]) },
5130 { .name = "ELR_EL3", .state = ARM_CP_STATE_AA64,
5131 .type = ARM_CP_ALIAS,
5132 .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1,
5133 .access = PL3_RW,
5134 .fieldoffset = offsetof(CPUARMState, elr_el[3]) },
5135 { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64,
5136 .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0,
5137 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[3]) },
5138 { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64,
5139 .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0,
5140 .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[3]) },
5141 { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64,
5142 .type = ARM_CP_ALIAS,
5143 .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0,
5144 .access = PL3_RW,
5145 .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_MON]) },
5146 { .name = "VBAR_EL3", .state = ARM_CP_STATE_AA64,
5147 .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 0,
5148 .access = PL3_RW, .writefn = vbar_write,
5149 .fieldoffset = offsetof(CPUARMState, cp15.vbar_el[3]),
5150 .resetvalue = 0 },
5151 { .name = "CPTR_EL3", .state = ARM_CP_STATE_AA64,
5152 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 2,
5153 .access = PL3_RW, .accessfn = cptr_access, .resetvalue = 0,
5154 .fieldoffset = offsetof(CPUARMState, cp15.cptr_el[3]) },
5155 { .name = "TPIDR_EL3", .state = ARM_CP_STATE_AA64,
5156 .opc0 = 3, .opc1 = 6, .crn = 13, .crm = 0, .opc2 = 2,
5157 .access = PL3_RW, .resetvalue = 0,
5158 .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[3]) },
5159 { .name = "AMAIR_EL3", .state = ARM_CP_STATE_AA64,
5160 .opc0 = 3, .opc1 = 6, .crn = 10, .crm = 3, .opc2 = 0,
5161 .access = PL3_RW, .type = ARM_CP_CONST,
5162 .resetvalue = 0 },
5163 { .name = "AFSR0_EL3", .state = ARM_CP_STATE_BOTH,
5164 .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 0,
5165 .access = PL3_RW, .type = ARM_CP_CONST,
5166 .resetvalue = 0 },
5167 { .name = "AFSR1_EL3", .state = ARM_CP_STATE_BOTH,
5168 .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 1, .opc2 = 1,
5169 .access = PL3_RW, .type = ARM_CP_CONST,
5170 .resetvalue = 0 },
5171 { .name = "TLBI_ALLE3IS", .state = ARM_CP_STATE_AA64,
5172 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 0,
5173 .access = PL3_W, .type = ARM_CP_NO_RAW,
5174 .writefn = tlbi_aa64_alle3is_write },
5175 { .name = "TLBI_VAE3IS", .state = ARM_CP_STATE_AA64,
5176 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 1,
5177 .access = PL3_W, .type = ARM_CP_NO_RAW,
5178 .writefn = tlbi_aa64_vae3is_write },
5179 { .name = "TLBI_VALE3IS", .state = ARM_CP_STATE_AA64,
5180 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 3, .opc2 = 5,
5181 .access = PL3_W, .type = ARM_CP_NO_RAW,
5182 .writefn = tlbi_aa64_vae3is_write },
5183 { .name = "TLBI_ALLE3", .state = ARM_CP_STATE_AA64,
5184 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 0,
5185 .access = PL3_W, .type = ARM_CP_NO_RAW,
5186 .writefn = tlbi_aa64_alle3_write },
5187 { .name = "TLBI_VAE3", .state = ARM_CP_STATE_AA64,
5188 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 1,
5189 .access = PL3_W, .type = ARM_CP_NO_RAW,
5190 .writefn = tlbi_aa64_vae3_write },
5191 { .name = "TLBI_VALE3", .state = ARM_CP_STATE_AA64,
5192 .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 5,
5193 .access = PL3_W, .type = ARM_CP_NO_RAW,
5194 .writefn = tlbi_aa64_vae3_write },
5195 REGINFO_SENTINEL
5196};
5197
5198static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
5199 bool isread)
5200{
5201
5202
5203
5204 if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCT)) {
5205 return CP_ACCESS_TRAP;
5206 }
5207 return CP_ACCESS_OK;
5208}
5209
5210static void oslar_write(CPUARMState *env, const ARMCPRegInfo *ri,
5211 uint64_t value)
5212{
5213
5214
5215
5216 int oslock;
5217
5218 if (ri->state == ARM_CP_STATE_AA32) {
5219 oslock = (value == 0xC5ACCE55);
5220 } else {
5221 oslock = value & 1;
5222 }
5223
5224 env->cp15.oslsr_el1 = deposit32(env->cp15.oslsr_el1, 1, 1, oslock);
5225}
5226
5227static const ARMCPRegInfo debug_cp_reginfo[] = {
5228
5229
5230
5231
5232
5233
5234 { .name = "DBGDRAR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 0,
5235 .access = PL0_R, .accessfn = access_tdra,
5236 .type = ARM_CP_CONST, .resetvalue = 0 },
5237 { .name = "MDRAR_EL1", .state = ARM_CP_STATE_AA64,
5238 .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
5239 .access = PL1_R, .accessfn = access_tdra,
5240 .type = ARM_CP_CONST, .resetvalue = 0 },
5241 { .name = "DBGDSAR", .cp = 14, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 0,
5242 .access = PL0_R, .accessfn = access_tdra,
5243 .type = ARM_CP_CONST, .resetvalue = 0 },
5244
5245 { .name = "MDSCR_EL1", .state = ARM_CP_STATE_BOTH,
5246 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
5247 .access = PL1_RW, .accessfn = access_tda,
5248 .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1),
5249 .resetvalue = 0 },
5250
5251
5252
5253 { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_BOTH,
5254 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
5255 .type = ARM_CP_ALIAS,
5256 .access = PL1_R, .accessfn = access_tda,
5257 .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1), },
5258 { .name = "OSLAR_EL1", .state = ARM_CP_STATE_BOTH,
5259 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 4,
5260 .access = PL1_W, .type = ARM_CP_NO_RAW,
5261 .accessfn = access_tdosa,
5262 .writefn = oslar_write },
5263 { .name = "OSLSR_EL1", .state = ARM_CP_STATE_BOTH,
5264 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 4,
5265 .access = PL1_R, .resetvalue = 10,
5266 .accessfn = access_tdosa,
5267 .fieldoffset = offsetof(CPUARMState, cp15.oslsr_el1) },
5268
5269 { .name = "OSDLR_EL1", .state = ARM_CP_STATE_BOTH,
5270 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 1, .crm = 3, .opc2 = 4,
5271 .access = PL1_RW, .accessfn = access_tdosa,
5272 .type = ARM_CP_NOP },
5273
5274
5275
5276 { .name = "DBGVCR",
5277 .cp = 14, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
5278 .access = PL1_RW, .accessfn = access_tda,
5279 .type = ARM_CP_NOP },
5280
5281
5282
5283 { .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
5284 .opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
5285 .access = PL2_RW, .accessfn = access_tda,
5286 .type = ARM_CP_NOP },
5287
5288
5289
5290
5291 { .name = "MDCCINT_EL1", .state = ARM_CP_STATE_BOTH,
5292 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
5293 .access = PL1_RW, .accessfn = access_tda,
5294 .type = ARM_CP_NOP },
5295 REGINFO_SENTINEL
5296};
5297
5298static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
5299
5300 { .name = "DBGDRAR", .cp = 14, .crm = 1, .opc1 = 0,
5301 .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
5302 { .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
5303 .access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
5304 REGINFO_SENTINEL
5305};
5306
5307
5308
5309
5310
5311
5312
5313int sve_exception_el(CPUARMState *env, int el)
5314{
5315#ifndef CONFIG_USER_ONLY
5316 if (el <= 1) {
5317 bool disabled = false;
5318
5319
5320
5321
5322
5323
5324 if (!extract32(env->cp15.cpacr_el1, 16, 1)) {
5325 disabled = true;
5326 } else if (!extract32(env->cp15.cpacr_el1, 17, 1)) {
5327 disabled = el == 0;
5328 }
5329 if (disabled) {
5330
5331 return (arm_feature(env, ARM_FEATURE_EL2)
5332 && (arm_hcr_el2_eff(env) & HCR_TGE) ? 2 : 1);
5333 }
5334
5335
5336 if (!extract32(env->cp15.cpacr_el1, 20, 1)) {
5337 disabled = true;
5338 } else if (!extract32(env->cp15.cpacr_el1, 21, 1)) {
5339 disabled = el == 0;
5340 }
5341 if (disabled) {
5342 return 0;
5343 }
5344 }
5345
5346
5347
5348
5349 if (el <= 2 && !arm_is_secure_below_el3(env)) {
5350 if (env->cp15.cptr_el[2] & CPTR_TZ) {
5351 return 2;
5352 }
5353 if (env->cp15.cptr_el[2] & CPTR_TFP) {
5354 return 0;
5355 }
5356 }
5357
5358
5359 if (arm_feature(env, ARM_FEATURE_EL3)
5360 && !(env->cp15.cptr_el[3] & CPTR_EZ)) {
5361 return 3;
5362 }
5363#endif
5364 return 0;
5365}
5366
5367static uint32_t sve_zcr_get_valid_len(ARMCPU *cpu, uint32_t start_len)
5368{
5369 uint32_t end_len;
5370
5371 end_len = start_len &= 0xf;
5372 if (!test_bit(start_len, cpu->sve_vq_map)) {
5373 end_len = find_last_bit(cpu->sve_vq_map, start_len);
5374 assert(end_len < start_len);
5375 }
5376 return end_len;
5377}
5378
5379
5380
5381
5382uint32_t sve_zcr_len_for_el(CPUARMState *env, int el)
5383{
5384 ARMCPU *cpu = env_archcpu(env);
5385 uint32_t zcr_len = cpu->sve_max_vq - 1;
5386
5387 if (el <= 1) {
5388 zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
5389 }
5390 if (el <= 2 && arm_feature(env, ARM_FEATURE_EL2)) {
5391 zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
5392 }
5393 if (arm_feature(env, ARM_FEATURE_EL3)) {
5394 zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
5395 }
5396
5397 return sve_zcr_get_valid_len(cpu, zcr_len);
5398}
5399
5400static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
5401 uint64_t value)
5402{
5403 int cur_el = arm_current_el(env);
5404 int old_len = sve_zcr_len_for_el(env, cur_el);
5405 int new_len;
5406
5407
5408 QEMU_BUILD_BUG_ON(ARM_MAX_VQ > 16);
5409 raw_write(env, ri, value & 0xf);
5410
5411
5412
5413
5414
5415 new_len = sve_zcr_len_for_el(env, cur_el);
5416 if (new_len < old_len) {
5417 aarch64_sve_narrow_vq(env, new_len + 1);
5418 }
5419}
5420
5421static const ARMCPRegInfo zcr_el1_reginfo = {
5422 .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
5423 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
5424 .access = PL1_RW, .type = ARM_CP_SVE,
5425 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
5426 .writefn = zcr_write, .raw_writefn = raw_write
5427};
5428
5429static const ARMCPRegInfo zcr_el2_reginfo = {
5430 .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
5431 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
5432 .access = PL2_RW, .type = ARM_CP_SVE,
5433 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
5434 .writefn = zcr_write, .raw_writefn = raw_write
5435};
5436
5437static const ARMCPRegInfo zcr_no_el2_reginfo = {
5438 .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
5439 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
5440 .access = PL2_RW, .type = ARM_CP_SVE,
5441 .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
5442};
5443
5444static const ARMCPRegInfo zcr_el3_reginfo = {
5445 .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
5446 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
5447 .access = PL3_RW, .type = ARM_CP_SVE,
5448 .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
5449 .writefn = zcr_write, .raw_writefn = raw_write
5450};
5451
5452void hw_watchpoint_update(ARMCPU *cpu, int n)
5453{
5454 CPUARMState *env = &cpu->env;
5455 vaddr len = 0;
5456 vaddr wvr = env->cp15.dbgwvr[n];
5457 uint64_t wcr = env->cp15.dbgwcr[n];
5458 int mask;
5459 int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
5460
5461 if (env->cpu_watchpoint[n]) {
5462 cpu_watchpoint_remove_by_ref(CPU(cpu), env->cpu_watchpoint[n]);
5463 env->cpu_watchpoint[n] = NULL;
5464 }
5465
5466 if (!extract64(wcr, 0, 1)) {
5467
5468 return;
5469 }
5470
5471 switch (extract64(wcr, 3, 2)) {
5472 case 0:
5473
5474 return;
5475 case 1:
5476 flags |= BP_MEM_READ;
5477 break;
5478 case 2:
5479 flags |= BP_MEM_WRITE;
5480 break;
5481 case 3:
5482 flags |= BP_MEM_ACCESS;
5483 break;
5484 }
5485
5486
5487
5488
5489
5490 mask = extract64(wcr, 24, 4);
5491 if (mask == 1 || mask == 2) {
5492
5493
5494
5495
5496 return;
5497 } else if (mask) {
5498
5499 len = 1ULL << mask;
5500
5501
5502
5503
5504 wvr &= ~(len - 1);
5505 } else {
5506
5507 int bas = extract64(wcr, 5, 8);
5508 int basstart;
5509
5510 if (bas == 0) {
5511
5512 return;
5513 }
5514
5515 if (extract64(wvr, 2, 1)) {
5516
5517
5518
5519 bas &= 0xf;
5520 }
5521
5522
5523
5524
5525
5526 basstart = ctz32(bas);
5527 len = cto32(bas >> basstart);
5528 wvr += basstart;
5529 }
5530
5531 cpu_watchpoint_insert(CPU(cpu), wvr, len, flags,
5532 &env->cpu_watchpoint[n]);
5533}
5534
5535void hw_watchpoint_update_all(ARMCPU *cpu)
5536{
5537 int i;
5538 CPUARMState *env = &cpu->env;
5539
5540
5541
5542
5543 cpu_watchpoint_remove_all(CPU(cpu), BP_CPU);
5544 memset(env->cpu_watchpoint, 0, sizeof(env->cpu_watchpoint));
5545
5546 for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_watchpoint); i++) {
5547 hw_watchpoint_update(cpu, i);
5548 }
5549}
5550
5551static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
5552 uint64_t value)
5553{
5554 ARMCPU *cpu = env_archcpu(env);
5555 int i = ri->crm;
5556
5557
5558
5559
5560
5561 value = sextract64(value, 0, 49) & ~3ULL;
5562
5563 raw_write(env, ri, value);
5564 hw_watchpoint_update(cpu, i);
5565}
5566
5567static void dbgwcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
5568 uint64_t value)
5569{
5570 ARMCPU *cpu = env_archcpu(env);
5571 int i = ri->crm;
5572
5573 raw_write(env, ri, value);
5574 hw_watchpoint_update(cpu, i);
5575}
5576
5577void hw_breakpoint_update(ARMCPU *cpu, int n)
5578{
5579 CPUARMState *env = &cpu->env;
5580 uint64_t bvr = env->cp15.dbgbvr[n];
5581 uint64_t bcr = env->cp15.dbgbcr[n];
5582 vaddr addr;
5583 int bt;
5584 int flags = BP_CPU;
5585
5586 if (env->cpu_breakpoint[n]) {
5587 cpu_breakpoint_remove_by_ref(CPU(cpu), env->cpu_breakpoint[n]);
5588 env->cpu_breakpoint[n] = NULL;
5589 }
5590
5591 if (!extract64(bcr, 0, 1)) {
5592
5593 return;
5594 }
5595
5596 bt = extract64(bcr, 20, 4);
5597
5598 switch (bt) {
5599 case 4:
5600 case 5:
5601 qemu_log_mask(LOG_UNIMP,
5602 "arm: address mismatch breakpoint types not implemented\n");
5603 return;
5604 case 0:
5605 case 1:
5606 {
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622 int bas = extract64(bcr, 5, 4);
5623 addr = sextract64(bvr, 0, 49) & ~3ULL;
5624 if (bas == 0) {
5625 return;
5626 }
5627 if (bas == 0xc) {
5628 addr += 2;
5629 }
5630 break;
5631 }
5632 case 2:
5633 case 8:
5634 case 10:
5635 qemu_log_mask(LOG_UNIMP,
5636 "arm: unlinked context breakpoint types not implemented\n");
5637 return;
5638 case 9:
5639 case 11:
5640 case 3:
5641 default:
5642
5643
5644
5645
5646
5647 return;
5648 }
5649
5650 cpu_breakpoint_insert(CPU(cpu), addr, flags, &env->cpu_breakpoint[n]);
5651}
5652
5653void hw_breakpoint_update_all(ARMCPU *cpu)
5654{
5655 int i;
5656 CPUARMState *env = &cpu->env;
5657
5658
5659
5660
5661 cpu_breakpoint_remove_all(CPU(cpu), BP_CPU);
5662 memset(env->cpu_breakpoint, 0, sizeof(env->cpu_breakpoint));
5663
5664 for (i = 0; i < ARRAY_SIZE(cpu->env.cpu_breakpoint); i++) {
5665 hw_breakpoint_update(cpu, i);
5666 }
5667}
5668
5669static void dbgbvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
5670 uint64_t value)
5671{
5672 ARMCPU *cpu = env_archcpu(env);
5673 int i = ri->crm;
5674
5675 raw_write(env, ri, value);
5676 hw_breakpoint_update(cpu, i);
5677}
5678
5679static void dbgbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
5680 uint64_t value)
5681{
5682 ARMCPU *cpu = env_archcpu(env);
5683 int i = ri->crm;
5684
5685
5686
5687
5688 value = deposit64(value, 6, 1, extract64(value, 5, 1));
5689 value = deposit64(value, 8, 1, extract64(value, 7, 1));
5690
5691 raw_write(env, ri, value);
5692 hw_breakpoint_update(cpu, i);
5693}
5694
5695static void define_debug_regs(ARMCPU *cpu)
5696{
5697
5698
5699
5700 int i;
5701 int wrps, brps, ctx_cmps;
5702 ARMCPRegInfo dbgdidr = {
5703 .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
5704 .access = PL0_R, .accessfn = access_tda,
5705 .type = ARM_CP_CONST, .resetvalue = cpu->dbgdidr,
5706 };
5707
5708
5709 brps = extract32(cpu->dbgdidr, 24, 4);
5710 wrps = extract32(cpu->dbgdidr, 28, 4);
5711 ctx_cmps = extract32(cpu->dbgdidr, 20, 4);
5712
5713 assert(ctx_cmps <= brps);
5714
5715
5716
5717
5718
5719 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
5720 assert(extract32(cpu->id_aa64dfr0, 12, 4) == brps);
5721 assert(extract32(cpu->id_aa64dfr0, 20, 4) == wrps);
5722 assert(extract32(cpu->id_aa64dfr0, 28, 4) == ctx_cmps);
5723 }
5724
5725 define_one_arm_cp_reg(cpu, &dbgdidr);
5726 define_arm_cp_regs(cpu, debug_cp_reginfo);
5727
5728 if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {
5729 define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);
5730 }
5731
5732 for (i = 0; i < brps + 1; i++) {
5733 ARMCPRegInfo dbgregs[] = {
5734 { .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,
5735 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,
5736 .access = PL1_RW, .accessfn = access_tda,
5737 .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]),
5738 .writefn = dbgbvr_write, .raw_writefn = raw_write
5739 },
5740 { .name = "DBGBCR", .state = ARM_CP_STATE_BOTH,
5741 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,
5742 .access = PL1_RW, .accessfn = access_tda,
5743 .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
5744 .writefn = dbgbcr_write, .raw_writefn = raw_write
5745 },
5746 REGINFO_SENTINEL
5747 };
5748 define_arm_cp_regs(cpu, dbgregs);
5749 }
5750
5751 for (i = 0; i < wrps + 1; i++) {
5752 ARMCPRegInfo dbgregs[] = {
5753 { .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,
5754 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,
5755 .access = PL1_RW, .accessfn = access_tda,
5756 .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]),
5757 .writefn = dbgwvr_write, .raw_writefn = raw_write
5758 },
5759 { .name = "DBGWCR", .state = ARM_CP_STATE_BOTH,
5760 .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,
5761 .access = PL1_RW, .accessfn = access_tda,
5762 .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
5763 .writefn = dbgwcr_write, .raw_writefn = raw_write
5764 },
5765 REGINFO_SENTINEL
5766 };
5767 define_arm_cp_regs(cpu, dbgregs);
5768 }
5769}
5770
5771
5772
5773
5774
5775
5776static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
5777{
5778 ARMCPU *cpu = env_archcpu(env);
5779 uint64_t pfr1 = cpu->id_pfr1;
5780
5781 if (env->gicv3state) {
5782 pfr1 |= 1 << 28;
5783 }
5784 return pfr1;
5785}
5786
5787static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
5788{
5789 ARMCPU *cpu = env_archcpu(env);
5790 uint64_t pfr0 = cpu->isar.id_aa64pfr0;
5791
5792 if (env->gicv3state) {
5793 pfr0 |= 1 << 24;
5794 }
5795 return pfr0;
5796}
5797
5798
5799
5800
5801static CPAccessResult access_lor_ns(CPUARMState *env)
5802{
5803 int el = arm_current_el(env);
5804
5805 if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TLOR)) {
5806 return CP_ACCESS_TRAP_EL2;
5807 }
5808 if (el < 3 && (env->cp15.scr_el3 & SCR_TLOR)) {
5809 return CP_ACCESS_TRAP_EL3;
5810 }
5811 return CP_ACCESS_OK;
5812}
5813
5814static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri,
5815 bool isread)
5816{
5817 if (arm_is_secure_below_el3(env)) {
5818
5819 return CP_ACCESS_OK;
5820 }
5821 return access_lor_ns(env);
5822}
5823
5824static CPAccessResult access_lor_other(CPUARMState *env,
5825 const ARMCPRegInfo *ri, bool isread)
5826{
5827 if (arm_is_secure_below_el3(env)) {
5828
5829 return CP_ACCESS_TRAP;
5830 }
5831 return access_lor_ns(env);
5832}
5833
5834#ifdef TARGET_AARCH64
5835static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri,
5836 bool isread)
5837{
5838 int el = arm_current_el(env);
5839
5840 if (el < 2 &&
5841 arm_feature(env, ARM_FEATURE_EL2) &&
5842 !(arm_hcr_el2_eff(env) & HCR_APK)) {
5843 return CP_ACCESS_TRAP_EL2;
5844 }
5845 if (el < 3 &&
5846 arm_feature(env, ARM_FEATURE_EL3) &&
5847 !(env->cp15.scr_el3 & SCR_APK)) {
5848 return CP_ACCESS_TRAP_EL3;
5849 }
5850 return CP_ACCESS_OK;
5851}
5852
5853static const ARMCPRegInfo pauth_reginfo[] = {
5854 { .name = "APDAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
5855 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
5856 .access = PL1_RW, .accessfn = access_pauth,
5857 .fieldoffset = offsetof(CPUARMState, keys.apda.lo) },
5858 { .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
5859 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
5860 .access = PL1_RW, .accessfn = access_pauth,
5861 .fieldoffset = offsetof(CPUARMState, keys.apda.hi) },
5862 { .name = "APDBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
5863 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
5864 .access = PL1_RW, .accessfn = access_pauth,
5865 .fieldoffset = offsetof(CPUARMState, keys.apdb.lo) },
5866 { .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
5867 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
5868 .access = PL1_RW, .accessfn = access_pauth,
5869 .fieldoffset = offsetof(CPUARMState, keys.apdb.hi) },
5870 { .name = "APGAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
5871 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 0,
5872 .access = PL1_RW, .accessfn = access_pauth,
5873 .fieldoffset = offsetof(CPUARMState, keys.apga.lo) },
5874 { .name = "APGAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
5875 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 1,
5876 .access = PL1_RW, .accessfn = access_pauth,
5877 .fieldoffset = offsetof(CPUARMState, keys.apga.hi) },
5878 { .name = "APIAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
5879 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 0,
5880 .access = PL1_RW, .accessfn = access_pauth,
5881 .fieldoffset = offsetof(CPUARMState, keys.apia.lo) },
5882 { .name = "APIAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
5883 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 1,
5884 .access = PL1_RW, .accessfn = access_pauth,
5885 .fieldoffset = offsetof(CPUARMState, keys.apia.hi) },
5886 { .name = "APIBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
5887 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 2,
5888 .access = PL1_RW, .accessfn = access_pauth,
5889 .fieldoffset = offsetof(CPUARMState, keys.apib.lo) },
5890 { .name = "APIBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
5891 .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
5892 .access = PL1_RW, .accessfn = access_pauth,
5893 .fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
5894 REGINFO_SENTINEL
5895};
5896
5897static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
5898{
5899 Error *err = NULL;
5900 uint64_t ret;
5901
5902
5903 env->NF = env->CF = env->VF = 0, env->ZF = 1;
5904
5905 if (qemu_guest_getrandom(&ret, sizeof(ret), &err) < 0) {
5906
5907
5908
5909
5910
5911
5912
5913 qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s",
5914 ri->name, error_get_pretty(err));
5915 error_free(err);
5916
5917 env->ZF = 0;
5918 return 0;
5919 }
5920 return ret;
5921}
5922
5923
5924static const ARMCPRegInfo rndr_reginfo[] = {
5925 { .name = "RNDR", .state = ARM_CP_STATE_AA64,
5926 .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
5927 .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 0,
5928 .access = PL0_R, .readfn = rndr_readfn },
5929 { .name = "RNDRRS", .state = ARM_CP_STATE_AA64,
5930 .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
5931 .opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
5932 .access = PL0_R, .readfn = rndr_readfn },
5933 REGINFO_SENTINEL
5934};
5935#endif
5936
5937static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
5938 bool isread)
5939{
5940 int el = arm_current_el(env);
5941
5942 if (el == 0) {
5943 uint64_t sctlr = arm_sctlr(env, el);
5944 if (!(sctlr & SCTLR_EnRCTX)) {
5945 return CP_ACCESS_TRAP;
5946 }
5947 } else if (el == 1) {
5948 uint64_t hcr = arm_hcr_el2_eff(env);
5949 if (hcr & HCR_NV) {
5950 return CP_ACCESS_TRAP_EL2;
5951 }
5952 }
5953 return CP_ACCESS_OK;
5954}
5955
5956static const ARMCPRegInfo predinv_reginfo[] = {
5957 { .name = "CFP_RCTX", .state = ARM_CP_STATE_AA64,
5958 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 4,
5959 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
5960 { .name = "DVP_RCTX", .state = ARM_CP_STATE_AA64,
5961 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 5,
5962 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
5963 { .name = "CPP_RCTX", .state = ARM_CP_STATE_AA64,
5964 .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 7,
5965 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
5966
5967
5968
5969 { .name = "CFPRCTX", .state = ARM_CP_STATE_AA32,
5970 .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 4,
5971 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
5972 { .name = "DVPRCTX", .state = ARM_CP_STATE_AA32,
5973 .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 5,
5974 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
5975 { .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
5976 .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
5977 .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
5978 REGINFO_SENTINEL
5979};
5980
5981static CPAccessResult access_aa64_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
5982 bool isread)
5983{
5984 if ((arm_current_el(env) < 2) && (arm_hcr_el2_eff(env) & HCR_TID3)) {
5985 return CP_ACCESS_TRAP_EL2;
5986 }
5987
5988 return CP_ACCESS_OK;
5989}
5990
5991static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
5992 bool isread)
5993{
5994 if (arm_feature(env, ARM_FEATURE_V8)) {
5995 return access_aa64_tid3(env, ri, isread);
5996 }
5997
5998 return CP_ACCESS_OK;
5999}
6000
6001void register_cp_regs_for_features(ARMCPU *cpu)
6002{
6003
6004 CPUARMState *env = &cpu->env;
6005 if (arm_feature(env, ARM_FEATURE_M)) {
6006
6007 return;
6008 }
6009
6010 define_arm_cp_regs(cpu, cp_reginfo);
6011 if (!arm_feature(env, ARM_FEATURE_V8)) {
6012
6013
6014
6015 define_arm_cp_regs(cpu, not_v8_cp_reginfo);
6016 }
6017
6018 if (arm_feature(env, ARM_FEATURE_V6)) {
6019
6020 ARMCPRegInfo v6_idregs[] = {
6021 { .name = "ID_PFR0", .state = ARM_CP_STATE_BOTH,
6022 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
6023 .access = PL1_R, .type = ARM_CP_CONST,
6024 .accessfn = access_aa32_tid3,
6025 .resetvalue = cpu->id_pfr0 },
6026
6027
6028
6029 { .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH,
6030 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1,
6031 .access = PL1_R, .type = ARM_CP_NO_RAW,
6032 .accessfn = access_aa32_tid3,
6033 .readfn = id_pfr1_read,
6034 .writefn = arm_cp_write_ignore },
6035 { .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH,
6036 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
6037 .access = PL1_R, .type = ARM_CP_CONST,
6038 .accessfn = access_aa32_tid3,
6039 .resetvalue = cpu->id_dfr0 },
6040 { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
6041 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
6042 .access = PL1_R, .type = ARM_CP_CONST,
6043 .accessfn = access_aa32_tid3,
6044 .resetvalue = cpu->id_afr0 },
6045 { .name = "ID_MMFR0", .state = ARM_CP_STATE_BOTH,
6046 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4,
6047 .access = PL1_R, .type = ARM_CP_CONST,
6048 .accessfn = access_aa32_tid3,
6049 .resetvalue = cpu->id_mmfr0 },
6050 { .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,
6051 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,
6052 .access = PL1_R, .type = ARM_CP_CONST,
6053 .accessfn = access_aa32_tid3,
6054 .resetvalue = cpu->id_mmfr1 },
6055 { .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,
6056 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,
6057 .access = PL1_R, .type = ARM_CP_CONST,
6058 .accessfn = access_aa32_tid3,
6059 .resetvalue = cpu->id_mmfr2 },
6060 { .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,
6061 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,
6062 .access = PL1_R, .type = ARM_CP_CONST,
6063 .accessfn = access_aa32_tid3,
6064 .resetvalue = cpu->id_mmfr3 },
6065 { .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
6066 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
6067 .access = PL1_R, .type = ARM_CP_CONST,
6068 .accessfn = access_aa32_tid3,
6069 .resetvalue = cpu->isar.id_isar0 },
6070 { .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH,
6071 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1,
6072 .access = PL1_R, .type = ARM_CP_CONST,
6073 .accessfn = access_aa32_tid3,
6074 .resetvalue = cpu->isar.id_isar1 },
6075 { .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH,
6076 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
6077 .access = PL1_R, .type = ARM_CP_CONST,
6078 .accessfn = access_aa32_tid3,
6079 .resetvalue = cpu->isar.id_isar2 },
6080 { .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH,
6081 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3,
6082 .access = PL1_R, .type = ARM_CP_CONST,
6083 .accessfn = access_aa32_tid3,
6084 .resetvalue = cpu->isar.id_isar3 },
6085 { .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH,
6086 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4,
6087 .access = PL1_R, .type = ARM_CP_CONST,
6088 .accessfn = access_aa32_tid3,
6089 .resetvalue = cpu->isar.id_isar4 },
6090 { .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH,
6091 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,
6092 .access = PL1_R, .type = ARM_CP_CONST,
6093 .accessfn = access_aa32_tid3,
6094 .resetvalue = cpu->isar.id_isar5 },
6095 { .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
6096 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
6097 .access = PL1_R, .type = ARM_CP_CONST,
6098 .accessfn = access_aa32_tid3,
6099 .resetvalue = cpu->id_mmfr4 },
6100 { .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
6101 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
6102 .access = PL1_R, .type = ARM_CP_CONST,
6103 .accessfn = access_aa32_tid3,
6104 .resetvalue = cpu->isar.id_isar6 },
6105 REGINFO_SENTINEL
6106 };
6107 define_arm_cp_regs(cpu, v6_idregs);
6108 define_arm_cp_regs(cpu, v6_cp_reginfo);
6109 } else {
6110 define_arm_cp_regs(cpu, not_v6_cp_reginfo);
6111 }
6112 if (arm_feature(env, ARM_FEATURE_V6K)) {
6113 define_arm_cp_regs(cpu, v6k_cp_reginfo);
6114 }
6115 if (arm_feature(env, ARM_FEATURE_V7MP) &&
6116 !arm_feature(env, ARM_FEATURE_PMSA)) {
6117 define_arm_cp_regs(cpu, v7mp_cp_reginfo);
6118 }
6119 if (arm_feature(env, ARM_FEATURE_V7VE)) {
6120 define_arm_cp_regs(cpu, pmovsset_cp_reginfo);
6121 }
6122 if (arm_feature(env, ARM_FEATURE_V7)) {
6123
6124
6125
6126
6127 unsigned int i, pmcrn = 4;
6128 ARMCPRegInfo pmcr = {
6129 .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
6130 .access = PL0_RW,
6131 .type = ARM_CP_IO | ARM_CP_ALIAS,
6132 .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
6133 .accessfn = pmreg_access, .writefn = pmcr_write,
6134 .raw_writefn = raw_write,
6135 };
6136 ARMCPRegInfo pmcr64 = {
6137 .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
6138 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
6139 .access = PL0_RW, .accessfn = pmreg_access,
6140 .type = ARM_CP_IO,
6141 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
6142 .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
6143 .writefn = pmcr_write, .raw_writefn = raw_write,
6144 };
6145 define_one_arm_cp_reg(cpu, &pmcr);
6146 define_one_arm_cp_reg(cpu, &pmcr64);
6147 for (i = 0; i < pmcrn; i++) {
6148 char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
6149 char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
6150 char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
6151 char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
6152 ARMCPRegInfo pmev_regs[] = {
6153 { .name = pmevcntr_name, .cp = 15, .crn = 14,
6154 .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
6155 .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
6156 .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
6157 .accessfn = pmreg_access },
6158 { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
6159 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
6160 .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
6161 .type = ARM_CP_IO,
6162 .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
6163 .raw_readfn = pmevcntr_rawread,
6164 .raw_writefn = pmevcntr_rawwrite },
6165 { .name = pmevtyper_name, .cp = 15, .crn = 14,
6166 .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
6167 .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
6168 .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
6169 .accessfn = pmreg_access },
6170 { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
6171 .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
6172 .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
6173 .type = ARM_CP_IO,
6174 .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
6175 .raw_writefn = pmevtyper_rawwrite },
6176 REGINFO_SENTINEL
6177 };
6178 define_arm_cp_regs(cpu, pmev_regs);
6179 g_free(pmevcntr_name);
6180 g_free(pmevcntr_el0_name);
6181 g_free(pmevtyper_name);
6182 g_free(pmevtyper_el0_name);
6183 }
6184 ARMCPRegInfo clidr = {
6185 .name = "CLIDR", .state = ARM_CP_STATE_BOTH,
6186 .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
6187 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr
6188 };
6189 define_one_arm_cp_reg(cpu, &clidr);
6190 define_arm_cp_regs(cpu, v7_cp_reginfo);
6191 define_debug_regs(cpu);
6192 } else {
6193 define_arm_cp_regs(cpu, not_v7_cp_reginfo);
6194 }
6195 if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
6196 FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
6197 ARMCPRegInfo v81_pmu_regs[] = {
6198 { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
6199 .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
6200 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6201 .resetvalue = extract64(cpu->pmceid0, 32, 32) },
6202 { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
6203 .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
6204 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6205 .resetvalue = extract64(cpu->pmceid1, 32, 32) },
6206 REGINFO_SENTINEL
6207 };
6208 define_arm_cp_regs(cpu, v81_pmu_regs);
6209 }
6210 if (arm_feature(env, ARM_FEATURE_V8)) {
6211
6212
6213
6214
6215
6216 ARMCPRegInfo v8_idregs[] = {
6217
6218
6219
6220
6221 { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64,
6222 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0,
6223 .access = PL1_R, .type = ARM_CP_NO_RAW,
6224 .accessfn = access_aa64_tid3,
6225 .readfn = id_aa64pfr0_read,
6226 .writefn = arm_cp_write_ignore },
6227 { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64,
6228 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
6229 .access = PL1_R, .type = ARM_CP_CONST,
6230 .accessfn = access_aa64_tid3,
6231 .resetvalue = cpu->isar.id_aa64pfr1},
6232 { .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6233 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,
6234 .access = PL1_R, .type = ARM_CP_CONST,
6235 .accessfn = access_aa64_tid3,
6236 .resetvalue = 0 },
6237 { .name = "ID_AA64PFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6238 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 3,
6239 .access = PL1_R, .type = ARM_CP_CONST,
6240 .accessfn = access_aa64_tid3,
6241 .resetvalue = 0 },
6242 { .name = "ID_AA64ZFR0_EL1", .state = ARM_CP_STATE_AA64,
6243 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4,
6244 .access = PL1_R, .type = ARM_CP_CONST,
6245 .accessfn = access_aa64_tid3,
6246
6247 .resetvalue = 0 },
6248 { .name = "ID_AA64PFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6249 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,
6250 .access = PL1_R, .type = ARM_CP_CONST,
6251 .accessfn = access_aa64_tid3,
6252 .resetvalue = 0 },
6253 { .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6254 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6,
6255 .access = PL1_R, .type = ARM_CP_CONST,
6256 .accessfn = access_aa64_tid3,
6257 .resetvalue = 0 },
6258 { .name = "ID_AA64PFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6259 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 7,
6260 .access = PL1_R, .type = ARM_CP_CONST,
6261 .accessfn = access_aa64_tid3,
6262 .resetvalue = 0 },
6263 { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64,
6264 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
6265 .access = PL1_R, .type = ARM_CP_CONST,
6266 .accessfn = access_aa64_tid3,
6267 .resetvalue = cpu->id_aa64dfr0 },
6268 { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
6269 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
6270 .access = PL1_R, .type = ARM_CP_CONST,
6271 .accessfn = access_aa64_tid3,
6272 .resetvalue = cpu->id_aa64dfr1 },
6273 { .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6274 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
6275 .access = PL1_R, .type = ARM_CP_CONST,
6276 .accessfn = access_aa64_tid3,
6277 .resetvalue = 0 },
6278 { .name = "ID_AA64DFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6279 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 3,
6280 .access = PL1_R, .type = ARM_CP_CONST,
6281 .accessfn = access_aa64_tid3,
6282 .resetvalue = 0 },
6283 { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64,
6284 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4,
6285 .access = PL1_R, .type = ARM_CP_CONST,
6286 .accessfn = access_aa64_tid3,
6287 .resetvalue = cpu->id_aa64afr0 },
6288 { .name = "ID_AA64AFR1_EL1", .state = ARM_CP_STATE_AA64,
6289 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5,
6290 .access = PL1_R, .type = ARM_CP_CONST,
6291 .accessfn = access_aa64_tid3,
6292 .resetvalue = cpu->id_aa64afr1 },
6293 { .name = "ID_AA64AFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6294 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 6,
6295 .access = PL1_R, .type = ARM_CP_CONST,
6296 .accessfn = access_aa64_tid3,
6297 .resetvalue = 0 },
6298 { .name = "ID_AA64AFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6299 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 7,
6300 .access = PL1_R, .type = ARM_CP_CONST,
6301 .accessfn = access_aa64_tid3,
6302 .resetvalue = 0 },
6303 { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,
6304 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
6305 .access = PL1_R, .type = ARM_CP_CONST,
6306 .accessfn = access_aa64_tid3,
6307 .resetvalue = cpu->isar.id_aa64isar0 },
6308 { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
6309 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
6310 .access = PL1_R, .type = ARM_CP_CONST,
6311 .accessfn = access_aa64_tid3,
6312 .resetvalue = cpu->isar.id_aa64isar1 },
6313 { .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6314 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
6315 .access = PL1_R, .type = ARM_CP_CONST,
6316 .accessfn = access_aa64_tid3,
6317 .resetvalue = 0 },
6318 { .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6319 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3,
6320 .access = PL1_R, .type = ARM_CP_CONST,
6321 .accessfn = access_aa64_tid3,
6322 .resetvalue = 0 },
6323 { .name = "ID_AA64ISAR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6324 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 4,
6325 .access = PL1_R, .type = ARM_CP_CONST,
6326 .accessfn = access_aa64_tid3,
6327 .resetvalue = 0 },
6328 { .name = "ID_AA64ISAR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6329 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 5,
6330 .access = PL1_R, .type = ARM_CP_CONST,
6331 .accessfn = access_aa64_tid3,
6332 .resetvalue = 0 },
6333 { .name = "ID_AA64ISAR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6334 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 6,
6335 .access = PL1_R, .type = ARM_CP_CONST,
6336 .accessfn = access_aa64_tid3,
6337 .resetvalue = 0 },
6338 { .name = "ID_AA64ISAR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6339 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 7,
6340 .access = PL1_R, .type = ARM_CP_CONST,
6341 .accessfn = access_aa64_tid3,
6342 .resetvalue = 0 },
6343 { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,
6344 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
6345 .access = PL1_R, .type = ARM_CP_CONST,
6346 .accessfn = access_aa64_tid3,
6347 .resetvalue = cpu->isar.id_aa64mmfr0 },
6348 { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
6349 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
6350 .access = PL1_R, .type = ARM_CP_CONST,
6351 .accessfn = access_aa64_tid3,
6352 .resetvalue = cpu->isar.id_aa64mmfr1 },
6353 { .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6354 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
6355 .access = PL1_R, .type = ARM_CP_CONST,
6356 .accessfn = access_aa64_tid3,
6357 .resetvalue = 0 },
6358 { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6359 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
6360 .access = PL1_R, .type = ARM_CP_CONST,
6361 .accessfn = access_aa64_tid3,
6362 .resetvalue = 0 },
6363 { .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6364 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
6365 .access = PL1_R, .type = ARM_CP_CONST,
6366 .accessfn = access_aa64_tid3,
6367 .resetvalue = 0 },
6368 { .name = "ID_AA64MMFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6369 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 5,
6370 .access = PL1_R, .type = ARM_CP_CONST,
6371 .accessfn = access_aa64_tid3,
6372 .resetvalue = 0 },
6373 { .name = "ID_AA64MMFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6374 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 6,
6375 .access = PL1_R, .type = ARM_CP_CONST,
6376 .accessfn = access_aa64_tid3,
6377 .resetvalue = 0 },
6378 { .name = "ID_AA64MMFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6379 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 7,
6380 .access = PL1_R, .type = ARM_CP_CONST,
6381 .accessfn = access_aa64_tid3,
6382 .resetvalue = 0 },
6383 { .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64,
6384 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0,
6385 .access = PL1_R, .type = ARM_CP_CONST,
6386 .accessfn = access_aa64_tid3,
6387 .resetvalue = cpu->isar.mvfr0 },
6388 { .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64,
6389 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1,
6390 .access = PL1_R, .type = ARM_CP_CONST,
6391 .accessfn = access_aa64_tid3,
6392 .resetvalue = cpu->isar.mvfr1 },
6393 { .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64,
6394 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
6395 .access = PL1_R, .type = ARM_CP_CONST,
6396 .accessfn = access_aa64_tid3,
6397 .resetvalue = cpu->isar.mvfr2 },
6398 { .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6399 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3,
6400 .access = PL1_R, .type = ARM_CP_CONST,
6401 .accessfn = access_aa64_tid3,
6402 .resetvalue = 0 },
6403 { .name = "MVFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6404 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
6405 .access = PL1_R, .type = ARM_CP_CONST,
6406 .accessfn = access_aa64_tid3,
6407 .resetvalue = 0 },
6408 { .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6409 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
6410 .access = PL1_R, .type = ARM_CP_CONST,
6411 .accessfn = access_aa64_tid3,
6412 .resetvalue = 0 },
6413 { .name = "MVFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6414 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
6415 .access = PL1_R, .type = ARM_CP_CONST,
6416 .accessfn = access_aa64_tid3,
6417 .resetvalue = 0 },
6418 { .name = "MVFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
6419 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,
6420 .access = PL1_R, .type = ARM_CP_CONST,
6421 .accessfn = access_aa64_tid3,
6422 .resetvalue = 0 },
6423 { .name = "PMCEID0", .state = ARM_CP_STATE_AA32,
6424 .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6,
6425 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6426 .resetvalue = extract64(cpu->pmceid0, 0, 32) },
6427 { .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64,
6428 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6,
6429 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6430 .resetvalue = cpu->pmceid0 },
6431 { .name = "PMCEID1", .state = ARM_CP_STATE_AA32,
6432 .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 7,
6433 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6434 .resetvalue = extract64(cpu->pmceid1, 0, 32) },
6435 { .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64,
6436 .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,
6437 .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
6438 .resetvalue = cpu->pmceid1 },
6439 REGINFO_SENTINEL
6440 };
6441#ifdef CONFIG_USER_ONLY
6442 ARMCPRegUserSpaceInfo v8_user_idregs[] = {
6443 { .name = "ID_AA64PFR0_EL1",
6444 .exported_bits = 0x000f000f00ff0000,
6445 .fixed_bits = 0x0000000000000011 },
6446 { .name = "ID_AA64PFR1_EL1",
6447 .exported_bits = 0x00000000000000f0 },
6448 { .name = "ID_AA64PFR*_EL1_RESERVED",
6449 .is_glob = true },
6450 { .name = "ID_AA64ZFR0_EL1" },
6451 { .name = "ID_AA64MMFR0_EL1",
6452 .fixed_bits = 0x00000000ff000000 },
6453 { .name = "ID_AA64MMFR1_EL1" },
6454 { .name = "ID_AA64MMFR*_EL1_RESERVED",
6455 .is_glob = true },
6456 { .name = "ID_AA64DFR0_EL1",
6457 .fixed_bits = 0x0000000000000006 },
6458 { .name = "ID_AA64DFR1_EL1" },
6459 { .name = "ID_AA64DFR*_EL1_RESERVED",
6460 .is_glob = true },
6461 { .name = "ID_AA64AFR*",
6462 .is_glob = true },
6463 { .name = "ID_AA64ISAR0_EL1",
6464 .exported_bits = 0x00fffffff0fffff0 },
6465 { .name = "ID_AA64ISAR1_EL1",
6466 .exported_bits = 0x000000f0ffffffff },
6467 { .name = "ID_AA64ISAR*_EL1_RESERVED",
6468 .is_glob = true },
6469 REGUSERINFO_SENTINEL
6470 };
6471 modify_arm_cp_regs(v8_idregs, v8_user_idregs);
6472#endif
6473
6474 if (!arm_feature(env, ARM_FEATURE_EL3) &&
6475 !arm_feature(env, ARM_FEATURE_EL2)) {
6476 ARMCPRegInfo rvbar = {
6477 .name = "RVBAR_EL1", .state = ARM_CP_STATE_AA64,
6478 .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
6479 .type = ARM_CP_CONST, .access = PL1_R, .resetvalue = cpu->rvbar
6480 };
6481 define_one_arm_cp_reg(cpu, &rvbar);
6482 }
6483 define_arm_cp_regs(cpu, v8_idregs);
6484 define_arm_cp_regs(cpu, v8_cp_reginfo);
6485 }
6486 if (arm_feature(env, ARM_FEATURE_EL2)) {
6487 uint64_t vmpidr_def = mpidr_read_val(env);
6488 ARMCPRegInfo vpidr_regs[] = {
6489 { .name = "VPIDR", .state = ARM_CP_STATE_AA32,
6490 .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
6491 .access = PL2_RW, .accessfn = access_el3_aa32ns,
6492 .resetvalue = cpu->midr, .type = ARM_CP_ALIAS,
6493 .fieldoffset = offsetoflow32(CPUARMState, cp15.vpidr_el2) },
6494 { .name = "VPIDR_EL2", .state = ARM_CP_STATE_AA64,
6495 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
6496 .access = PL2_RW, .resetvalue = cpu->midr,
6497 .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
6498 { .name = "VMPIDR", .state = ARM_CP_STATE_AA32,
6499 .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
6500 .access = PL2_RW, .accessfn = access_el3_aa32ns,
6501 .resetvalue = vmpidr_def, .type = ARM_CP_ALIAS,
6502 .fieldoffset = offsetoflow32(CPUARMState, cp15.vmpidr_el2) },
6503 { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_AA64,
6504 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
6505 .access = PL2_RW,
6506 .resetvalue = vmpidr_def,
6507 .fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
6508 REGINFO_SENTINEL
6509 };
6510 define_arm_cp_regs(cpu, vpidr_regs);
6511 define_arm_cp_regs(cpu, el2_cp_reginfo);
6512 if (arm_feature(env, ARM_FEATURE_V8)) {
6513 define_arm_cp_regs(cpu, el2_v8_cp_reginfo);
6514 }
6515
6516 if (!arm_feature(env, ARM_FEATURE_EL3)) {
6517 ARMCPRegInfo rvbar = {
6518 .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
6519 .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
6520 .type = ARM_CP_CONST, .access = PL2_R, .resetvalue = cpu->rvbar
6521 };
6522 define_one_arm_cp_reg(cpu, &rvbar);
6523 }
6524 } else {
6525
6526
6527
6528 if (arm_feature(env, ARM_FEATURE_EL3)) {
6529
6530
6531
6532 ARMCPRegInfo vpidr_regs[] = {
6533 { .name = "VPIDR_EL2", .state = ARM_CP_STATE_BOTH,
6534 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
6535 .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any,
6536 .type = ARM_CP_CONST, .resetvalue = cpu->midr,
6537 .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
6538 { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_BOTH,
6539 .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
6540 .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any,
6541 .type = ARM_CP_NO_RAW,
6542 .writefn = arm_cp_write_ignore, .readfn = mpidr_read },
6543 REGINFO_SENTINEL
6544 };
6545 define_arm_cp_regs(cpu, vpidr_regs);
6546 define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);
6547 if (arm_feature(env, ARM_FEATURE_V8)) {
6548 define_arm_cp_regs(cpu, el3_no_el2_v8_cp_reginfo);
6549 }
6550 }
6551 }
6552 if (arm_feature(env, ARM_FEATURE_EL3)) {
6553 define_arm_cp_regs(cpu, el3_cp_reginfo);
6554 ARMCPRegInfo el3_regs[] = {
6555 { .name = "RVBAR_EL3", .state = ARM_CP_STATE_AA64,
6556 .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 1,
6557 .type = ARM_CP_CONST, .access = PL3_R, .resetvalue = cpu->rvbar },
6558 { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64,
6559 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 0,
6560 .access = PL3_RW,
6561 .raw_writefn = raw_write, .writefn = sctlr_write,
6562 .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]),
6563 .resetvalue = cpu->reset_sctlr },
6564 REGINFO_SENTINEL
6565 };
6566
6567 define_arm_cp_regs(cpu, el3_regs);
6568 }
6569
6570
6571
6572
6573
6574
6575
6576
6577 if (arm_feature(env, ARM_FEATURE_EL3)) {
6578 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
6579 ARMCPRegInfo nsacr = {
6580 .name = "NSACR", .type = ARM_CP_CONST,
6581 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
6582 .access = PL1_RW, .accessfn = nsacr_access,
6583 .resetvalue = 0xc00
6584 };
6585 define_one_arm_cp_reg(cpu, &nsacr);
6586 } else {
6587 ARMCPRegInfo nsacr = {
6588 .name = "NSACR",
6589 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
6590 .access = PL3_RW | PL1_R,
6591 .resetvalue = 0,
6592 .fieldoffset = offsetof(CPUARMState, cp15.nsacr)
6593 };
6594 define_one_arm_cp_reg(cpu, &nsacr);
6595 }
6596 } else {
6597 if (arm_feature(env, ARM_FEATURE_V8)) {
6598 ARMCPRegInfo nsacr = {
6599 .name = "NSACR", .type = ARM_CP_CONST,
6600 .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
6601 .access = PL1_R,
6602 .resetvalue = 0xc00
6603 };
6604 define_one_arm_cp_reg(cpu, &nsacr);
6605 }
6606 }
6607
6608 if (arm_feature(env, ARM_FEATURE_PMSA)) {
6609 if (arm_feature(env, ARM_FEATURE_V6)) {
6610
6611 assert(arm_feature(env, ARM_FEATURE_V7));
6612 define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
6613 define_arm_cp_regs(cpu, pmsav7_cp_reginfo);
6614 } else {
6615 define_arm_cp_regs(cpu, pmsav5_cp_reginfo);
6616 }
6617 } else {
6618 define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
6619 define_arm_cp_regs(cpu, vmsa_cp_reginfo);
6620
6621 if (FIELD_EX32(cpu->id_mmfr4, ID_MMFR4, HPDS) != 0) {
6622 define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
6623 }
6624 }
6625 if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
6626 define_arm_cp_regs(cpu, t2ee_cp_reginfo);
6627 }
6628 if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
6629 define_arm_cp_regs(cpu, generic_timer_cp_reginfo);
6630 }
6631 if (arm_feature(env, ARM_FEATURE_VAPA)) {
6632 define_arm_cp_regs(cpu, vapa_cp_reginfo);
6633 }
6634 if (arm_feature(env, ARM_FEATURE_CACHE_TEST_CLEAN)) {
6635 define_arm_cp_regs(cpu, cache_test_clean_cp_reginfo);
6636 }
6637 if (arm_feature(env, ARM_FEATURE_CACHE_DIRTY_REG)) {
6638 define_arm_cp_regs(cpu, cache_dirty_status_cp_reginfo);
6639 }
6640 if (arm_feature(env, ARM_FEATURE_CACHE_BLOCK_OPS)) {
6641 define_arm_cp_regs(cpu, cache_block_ops_cp_reginfo);
6642 }
6643 if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
6644 define_arm_cp_regs(cpu, omap_cp_reginfo);
6645 }
6646 if (arm_feature(env, ARM_FEATURE_STRONGARM)) {
6647 define_arm_cp_regs(cpu, strongarm_cp_reginfo);
6648 }
6649 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6650 define_arm_cp_regs(cpu, xscale_cp_reginfo);
6651 }
6652 if (arm_feature(env, ARM_FEATURE_DUMMY_C15_REGS)) {
6653 define_arm_cp_regs(cpu, dummy_c15_cp_reginfo);
6654 }
6655 if (arm_feature(env, ARM_FEATURE_LPAE)) {
6656 define_arm_cp_regs(cpu, lpae_cp_reginfo);
6657 }
6658
6659
6660
6661
6662 {
6663 ARMCPRegInfo id_pre_v8_midr_cp_reginfo[] = {
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673 { .name = "MIDR",
6674 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = CP_ANY,
6675 .access = PL1_R, .resetvalue = cpu->midr,
6676 .writefn = arm_cp_write_ignore, .raw_writefn = raw_write,
6677 .readfn = midr_read,
6678 .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
6679 .type = ARM_CP_OVERRIDE },
6680
6681 { .name = "DUMMY",
6682 .cp = 15, .crn = 0, .crm = 3, .opc1 = 0, .opc2 = CP_ANY,
6683 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
6684 { .name = "DUMMY",
6685 .cp = 15, .crn = 0, .crm = 4, .opc1 = 0, .opc2 = CP_ANY,
6686 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
6687 { .name = "DUMMY",
6688 .cp = 15, .crn = 0, .crm = 5, .opc1 = 0, .opc2 = CP_ANY,
6689 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
6690 { .name = "DUMMY",
6691 .cp = 15, .crn = 0, .crm = 6, .opc1 = 0, .opc2 = CP_ANY,
6692 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
6693 { .name = "DUMMY",
6694 .cp = 15, .crn = 0, .crm = 7, .opc1 = 0, .opc2 = CP_ANY,
6695 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
6696 REGINFO_SENTINEL
6697 };
6698 ARMCPRegInfo id_v8_midr_cp_reginfo[] = {
6699 { .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH,
6700 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 0,
6701 .access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr,
6702 .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
6703 .readfn = midr_read },
6704
6705 { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
6706 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
6707 .access = PL1_R, .resetvalue = cpu->midr },
6708 { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
6709 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7,
6710 .access = PL1_R, .resetvalue = cpu->midr },
6711 { .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,
6712 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
6713 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
6714 REGINFO_SENTINEL
6715 };
6716 ARMCPRegInfo id_cp_reginfo[] = {
6717
6718 { .name = "CTR",
6719 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
6720 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
6721 { .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
6722 .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
6723 .access = PL0_R, .accessfn = ctr_el0_access,
6724 .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
6725
6726 { .name = "TCMTR",
6727 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2,
6728 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
6729 REGINFO_SENTINEL
6730 };
6731
6732 ARMCPRegInfo id_tlbtr_reginfo = {
6733 .name = "TLBTR",
6734 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3,
6735 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0,
6736 };
6737
6738 ARMCPRegInfo id_mpuir_reginfo = {
6739 .name = "MPUIR",
6740 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
6741 .access = PL1_R, .type = ARM_CP_CONST,
6742 .resetvalue = cpu->pmsav7_dregion << 8
6743 };
6744 ARMCPRegInfo crn0_wi_reginfo = {
6745 .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
6746 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
6747 .type = ARM_CP_NOP | ARM_CP_OVERRIDE
6748 };
6749#ifdef CONFIG_USER_ONLY
6750 ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
6751 { .name = "MIDR_EL1",
6752 .exported_bits = 0x00000000ffffffff },
6753 { .name = "REVIDR_EL1" },
6754 REGUSERINFO_SENTINEL
6755 };
6756 modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo);
6757#endif
6758 if (arm_feature(env, ARM_FEATURE_OMAPCP) ||
6759 arm_feature(env, ARM_FEATURE_STRONGARM)) {
6760 ARMCPRegInfo *r;
6761
6762
6763
6764
6765
6766 define_one_arm_cp_reg(cpu, &crn0_wi_reginfo);
6767 for (r = id_pre_v8_midr_cp_reginfo;
6768 r->type != ARM_CP_SENTINEL; r++) {
6769 r->access = PL1_RW;
6770 }
6771 for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) {
6772 r->access = PL1_RW;
6773 }
6774 id_mpuir_reginfo.access = PL1_RW;
6775 id_tlbtr_reginfo.access = PL1_RW;
6776 }
6777 if (arm_feature(env, ARM_FEATURE_V8)) {
6778 define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo);
6779 } else {
6780 define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo);
6781 }
6782 define_arm_cp_regs(cpu, id_cp_reginfo);
6783 if (!arm_feature(env, ARM_FEATURE_PMSA)) {
6784 define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);
6785 } else if (arm_feature(env, ARM_FEATURE_V7)) {
6786 define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
6787 }
6788 }
6789
6790 if (arm_feature(env, ARM_FEATURE_MPIDR)) {
6791 ARMCPRegInfo mpidr_cp_reginfo[] = {
6792 { .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH,
6793 .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
6794 .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
6795 REGINFO_SENTINEL
6796 };
6797#ifdef CONFIG_USER_ONLY
6798 ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
6799 { .name = "MPIDR_EL1",
6800 .fixed_bits = 0x0000000080000000 },
6801 REGUSERINFO_SENTINEL
6802 };
6803 modify_arm_cp_regs(mpidr_cp_reginfo, mpidr_user_cp_reginfo);
6804#endif
6805 define_arm_cp_regs(cpu, mpidr_cp_reginfo);
6806 }
6807
6808 if (arm_feature(env, ARM_FEATURE_AUXCR)) {
6809 ARMCPRegInfo auxcr_reginfo[] = {
6810 { .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH,
6811 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1,
6812 .access = PL1_RW, .type = ARM_CP_CONST,
6813 .resetvalue = cpu->reset_auxcr },
6814 { .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH,
6815 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1,
6816 .access = PL2_RW, .type = ARM_CP_CONST,
6817 .resetvalue = 0 },
6818 { .name = "ACTLR_EL3", .state = ARM_CP_STATE_AA64,
6819 .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 1,
6820 .access = PL3_RW, .type = ARM_CP_CONST,
6821 .resetvalue = 0 },
6822 REGINFO_SENTINEL
6823 };
6824 define_arm_cp_regs(cpu, auxcr_reginfo);
6825 if (arm_feature(env, ARM_FEATURE_V8)) {
6826
6827 ARMCPRegInfo hactlr2_reginfo = {
6828 .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
6829 .cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
6830 .access = PL2_RW, .type = ARM_CP_CONST,
6831 .resetvalue = 0
6832 };
6833 define_one_arm_cp_reg(cpu, &hactlr2_reginfo);
6834 }
6835 }
6836
6837 if (arm_feature(env, ARM_FEATURE_CBAR)) {
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
6852
6853 uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
6854 | extract64(cpu->reset_cbar, 32, 12);
6855 ARMCPRegInfo cbar_reginfo[] = {
6856 { .name = "CBAR",
6857 .type = ARM_CP_CONST,
6858 .cp = 15, .crn = 15, .crm = 3, .opc1 = 1, .opc2 = 0,
6859 .access = PL1_R, .resetvalue = cbar32 },
6860 { .name = "CBAR_EL1", .state = ARM_CP_STATE_AA64,
6861 .type = ARM_CP_CONST,
6862 .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 0,
6863 .access = PL1_R, .resetvalue = cpu->reset_cbar },
6864 REGINFO_SENTINEL
6865 };
6866
6867 assert(arm_feature(env, ARM_FEATURE_CBAR_RO));
6868 define_arm_cp_regs(cpu, cbar_reginfo);
6869 } else {
6870 ARMCPRegInfo cbar = {
6871 .name = "CBAR",
6872 .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0,
6873 .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar,
6874 .fieldoffset = offsetof(CPUARMState,
6875 cp15.c15_config_base_address)
6876 };
6877 if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
6878 cbar.access = PL1_R;
6879 cbar.fieldoffset = 0;
6880 cbar.type = ARM_CP_CONST;
6881 }
6882 define_one_arm_cp_reg(cpu, &cbar);
6883 }
6884 }
6885
6886 if (arm_feature(env, ARM_FEATURE_VBAR)) {
6887 ARMCPRegInfo vbar_cp_reginfo[] = {
6888 { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
6889 .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
6890 .access = PL1_RW, .writefn = vbar_write,
6891 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
6892 offsetof(CPUARMState, cp15.vbar_ns) },
6893 .resetvalue = 0 },
6894 REGINFO_SENTINEL
6895 };
6896 define_arm_cp_regs(cpu, vbar_cp_reginfo);
6897 }
6898
6899
6900 {
6901 ARMCPRegInfo sctlr = {
6902 .name = "SCTLR", .state = ARM_CP_STATE_BOTH,
6903 .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
6904 .access = PL1_RW,
6905 .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
6906 offsetof(CPUARMState, cp15.sctlr_ns) },
6907 .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
6908 .raw_writefn = raw_write,
6909 };
6910 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6911
6912
6913
6914
6915 sctlr.type |= ARM_CP_SUPPRESS_TB_END;
6916 }
6917 define_one_arm_cp_reg(cpu, &sctlr);
6918 }
6919
6920 if (cpu_isar_feature(aa64_lor, cpu)) {
6921
6922
6923
6924
6925
6926 static const ARMCPRegInfo lor_reginfo[] = {
6927 { .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64,
6928 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0,
6929 .access = PL1_RW, .accessfn = access_lor_other,
6930 .type = ARM_CP_CONST, .resetvalue = 0 },
6931 { .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64,
6932 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1,
6933 .access = PL1_RW, .accessfn = access_lor_other,
6934 .type = ARM_CP_CONST, .resetvalue = 0 },
6935 { .name = "LORN_EL1", .state = ARM_CP_STATE_AA64,
6936 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2,
6937 .access = PL1_RW, .accessfn = access_lor_other,
6938 .type = ARM_CP_CONST, .resetvalue = 0 },
6939 { .name = "LORC_EL1", .state = ARM_CP_STATE_AA64,
6940 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3,
6941 .access = PL1_RW, .accessfn = access_lor_other,
6942 .type = ARM_CP_CONST, .resetvalue = 0 },
6943 { .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
6944 .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
6945 .access = PL1_R, .accessfn = access_lorid,
6946 .type = ARM_CP_CONST, .resetvalue = 0 },
6947 REGINFO_SENTINEL
6948 };
6949 define_arm_cp_regs(cpu, lor_reginfo);
6950 }
6951
6952 if (cpu_isar_feature(aa64_sve, cpu)) {
6953 define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
6954 if (arm_feature(env, ARM_FEATURE_EL2)) {
6955 define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
6956 } else {
6957 define_one_arm_cp_reg(cpu, &zcr_no_el2_reginfo);
6958 }
6959 if (arm_feature(env, ARM_FEATURE_EL3)) {
6960 define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
6961 }
6962 }
6963
6964#ifdef TARGET_AARCH64
6965 if (cpu_isar_feature(aa64_pauth, cpu)) {
6966 define_arm_cp_regs(cpu, pauth_reginfo);
6967 }
6968 if (cpu_isar_feature(aa64_rndr, cpu)) {
6969 define_arm_cp_regs(cpu, rndr_reginfo);
6970 }
6971#endif
6972
6973
6974
6975
6976
6977
6978 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
6979 ? cpu_isar_feature(aa64_predinv, cpu)
6980 : cpu_isar_feature(aa32_predinv, cpu)) {
6981 define_arm_cp_regs(cpu, predinv_reginfo);
6982 }
6983}
6984
6985void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
6986{
6987 CPUState *cs = CPU(cpu);
6988 CPUARMState *env = &cpu->env;
6989
6990 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
6991 gdb_register_coprocessor(cs, aarch64_fpu_gdb_get_reg,
6992 aarch64_fpu_gdb_set_reg,
6993 34, "aarch64-fpu.xml", 0);
6994 } else if (arm_feature(env, ARM_FEATURE_NEON)) {
6995 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
6996 51, "arm-neon.xml", 0);
6997 } else if (arm_feature(env, ARM_FEATURE_VFP3)) {
6998 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
6999 35, "arm-vfp3.xml", 0);
7000 } else if (arm_feature(env, ARM_FEATURE_VFP)) {
7001 gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
7002 19, "arm-vfp.xml", 0);
7003 }
7004 gdb_register_coprocessor(cs, arm_gdb_get_sysreg, arm_gdb_set_sysreg,
7005 arm_gen_dynamic_xml(cs),
7006 "system-registers.xml", 0);
7007}
7008
7009
7010static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b)
7011{
7012 ObjectClass *class_a = (ObjectClass *)a;
7013 ObjectClass *class_b = (ObjectClass *)b;
7014 const char *name_a, *name_b;
7015
7016 name_a = object_class_get_name(class_a);
7017 name_b = object_class_get_name(class_b);
7018 if (strcmp(name_a, "any-" TYPE_ARM_CPU) == 0) {
7019 return 1;
7020 } else if (strcmp(name_b, "any-" TYPE_ARM_CPU) == 0) {
7021 return -1;
7022 } else {
7023 return strcmp(name_a, name_b);
7024 }
7025}
7026
7027static void arm_cpu_list_entry(gpointer data, gpointer user_data)
7028{
7029 ObjectClass *oc = data;
7030 const char *typename;
7031 char *name;
7032
7033 typename = object_class_get_name(oc);
7034 name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_ARM_CPU));
7035 qemu_printf(" %s\n", name);
7036 g_free(name);
7037}
7038
7039void arm_cpu_list(void)
7040{
7041 GSList *list;
7042
7043 list = object_class_get_list(TYPE_ARM_CPU, false);
7044 list = g_slist_sort(list, arm_cpu_list_compare);
7045 qemu_printf("Available CPUs:\n");
7046 g_slist_foreach(list, arm_cpu_list_entry, NULL);
7047 g_slist_free(list);
7048}
7049
7050static void arm_cpu_add_definition(gpointer data, gpointer user_data)
7051{
7052 ObjectClass *oc = data;
7053 CpuDefinitionInfoList **cpu_list = user_data;
7054 CpuDefinitionInfoList *entry;
7055 CpuDefinitionInfo *info;
7056 const char *typename;
7057
7058 typename = object_class_get_name(oc);
7059 info = g_malloc0(sizeof(*info));
7060 info->name = g_strndup(typename,
7061 strlen(typename) - strlen("-" TYPE_ARM_CPU));
7062 info->q_typename = g_strdup(typename);
7063
7064 entry = g_malloc0(sizeof(*entry));
7065 entry->value = info;
7066 entry->next = *cpu_list;
7067 *cpu_list = entry;
7068}
7069
7070CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
7071{
7072 CpuDefinitionInfoList *cpu_list = NULL;
7073 GSList *list;
7074
7075 list = object_class_get_list(TYPE_ARM_CPU, false);
7076 g_slist_foreach(list, arm_cpu_add_definition, &cpu_list);
7077 g_slist_free(list);
7078
7079 return cpu_list;
7080}
7081
7082static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
7083 void *opaque, int state, int secstate,
7084 int crm, int opc1, int opc2,
7085 const char *name)
7086{
7087
7088
7089
7090 uint32_t *key = g_new(uint32_t, 1);
7091 ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
7092 int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
7093 int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
7094
7095 r2->name = g_strdup(name);
7096
7097
7098
7099 r2->secure = secstate;
7100
7101 if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
7102
7103
7104
7105
7106 r2->fieldoffset = r->bank_fieldoffsets[ns];
7107 }
7108
7109 if (state == ARM_CP_STATE_AA32) {
7110 if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121 if ((r->state == ARM_CP_STATE_BOTH && ns) ||
7122 (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
7123 r2->type |= ARM_CP_ALIAS;
7124 }
7125 } else if ((secstate != r->secure) && !ns) {
7126
7127
7128
7129 r2->type |= ARM_CP_ALIAS;
7130 }
7131
7132 if (r->state == ARM_CP_STATE_BOTH) {
7133
7134
7135 if (r2->cp == 0) {
7136 r2->cp = 15;
7137 }
7138
7139#ifdef HOST_WORDS_BIGENDIAN
7140 if (r2->fieldoffset) {
7141 r2->fieldoffset += sizeof(uint32_t);
7142 }
7143#endif
7144 }
7145 }
7146 if (state == ARM_CP_STATE_AA64) {
7147
7148
7149
7150
7151
7152
7153
7154 if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
7155 r2->cp = CP_REG_ARM64_SYSREG_CP;
7156 }
7157 *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
7158 r2->opc0, opc1, opc2);
7159 } else {
7160 *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
7161 }
7162 if (opaque) {
7163 r2->opaque = opaque;
7164 }
7165
7166
7167
7168 r2->state = state;
7169
7170
7171
7172 r2->crm = crm;
7173 r2->opc1 = opc1;
7174 r2->opc2 = opc2;
7175
7176
7177
7178
7179
7180
7181 if ((r->type & ARM_CP_SPECIAL)) {
7182 r2->type |= ARM_CP_NO_RAW;
7183 }
7184 if (((r->crm == CP_ANY) && crm != 0) ||
7185 ((r->opc1 == CP_ANY) && opc1 != 0) ||
7186 ((r->opc2 == CP_ANY) && opc2 != 0)) {
7187 r2->type |= ARM_CP_ALIAS | ARM_CP_NO_GDB;
7188 }
7189
7190
7191
7192
7193
7194 if (!(r2->type & ARM_CP_NO_RAW)) {
7195 assert(!raw_accessors_invalid(r2));
7196 }
7197
7198
7199
7200
7201 if (!(r->type & ARM_CP_OVERRIDE)) {
7202 ARMCPRegInfo *oldreg;
7203 oldreg = g_hash_table_lookup(cpu->cp_regs, key);
7204 if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
7205 fprintf(stderr, "Register redefined: cp=%d %d bit "
7206 "crn=%d crm=%d opc1=%d opc2=%d, "
7207 "was %s, now %s\n", r2->cp, 32 + 32 * is64,
7208 r2->crn, r2->crm, r2->opc1, r2->opc2,
7209 oldreg->name, r2->name);
7210 g_assert_not_reached();
7211 }
7212 }
7213 g_hash_table_insert(cpu->cp_regs, key, r2);
7214}
7215
7216
7217void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
7218 const ARMCPRegInfo *r, void *opaque)
7219{
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243 int crm, opc1, opc2, state;
7244 int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
7245 int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
7246 int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
7247 int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
7248 int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
7249 int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
7250
7251 assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
7252
7253 assert((r->state != ARM_CP_STATE_AA32) || (r->opc0 == 0));
7254
7255 assert((r->state != ARM_CP_STATE_AA64) || !(r->type & ARM_CP_64BIT));
7256
7257
7258
7259
7260
7261
7262 if (r->state != ARM_CP_STATE_AA32) {
7263 int mask = 0;
7264 switch (r->opc1) {
7265 case 0:
7266
7267 mask = PL0U_R | PL1_RW;
7268 break;
7269 case 1: case 2:
7270
7271 mask = PL1_RW;
7272 break;
7273 case 3:
7274
7275 mask = PL0_RW;
7276 break;
7277 case 4:
7278
7279 mask = PL2_RW;
7280 break;
7281 case 5:
7282
7283 assert(false);
7284 break;
7285 case 6:
7286
7287 mask = PL3_RW;
7288 break;
7289 case 7:
7290
7291 mask = PL1_RW;
7292 break;
7293 default:
7294
7295 assert(false);
7296 break;
7297 }
7298
7299 assert((r->access & ~mask) == 0);
7300 }
7301
7302
7303
7304
7305 if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
7306 if (r->access & PL3_R) {
7307 assert((r->fieldoffset ||
7308 (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
7309 r->readfn);
7310 }
7311 if (r->access & PL3_W) {
7312 assert((r->fieldoffset ||
7313 (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
7314 r->writefn);
7315 }
7316 }
7317
7318 assert(cptype_valid(r->type));
7319 for (crm = crmmin; crm <= crmmax; crm++) {
7320 for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
7321 for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
7322 for (state = ARM_CP_STATE_AA32;
7323 state <= ARM_CP_STATE_AA64; state++) {
7324 if (r->state != state && r->state != ARM_CP_STATE_BOTH) {
7325 continue;
7326 }
7327 if (state == ARM_CP_STATE_AA32) {
7328
7329
7330
7331 char *name;
7332
7333 switch (r->secure) {
7334 case ARM_CP_SECSTATE_S:
7335 case ARM_CP_SECSTATE_NS:
7336 add_cpreg_to_hashtable(cpu, r, opaque, state,
7337 r->secure, crm, opc1, opc2,
7338 r->name);
7339 break;
7340 default:
7341 name = g_strdup_printf("%s_S", r->name);
7342 add_cpreg_to_hashtable(cpu, r, opaque, state,
7343 ARM_CP_SECSTATE_S,
7344 crm, opc1, opc2, name);
7345 g_free(name);
7346 add_cpreg_to_hashtable(cpu, r, opaque, state,
7347 ARM_CP_SECSTATE_NS,
7348 crm, opc1, opc2, r->name);
7349 break;
7350 }
7351 } else {
7352
7353
7354 add_cpreg_to_hashtable(cpu, r, opaque, state,
7355 ARM_CP_SECSTATE_NS,
7356 crm, opc1, opc2, r->name);
7357 }
7358 }
7359 }
7360 }
7361 }
7362}
7363
7364void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
7365 const ARMCPRegInfo *regs, void *opaque)
7366{
7367
7368 const ARMCPRegInfo *r;
7369 for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
7370 define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
7371 }
7372}
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
7383{
7384 const ARMCPRegUserSpaceInfo *m;
7385 ARMCPRegInfo *r;
7386
7387 for (m = mods; m->name; m++) {
7388 GPatternSpec *pat = NULL;
7389 if (m->is_glob) {
7390 pat = g_pattern_spec_new(m->name);
7391 }
7392 for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
7393 if (pat && g_pattern_match_string(pat, r->name)) {
7394 r->type = ARM_CP_CONST;
7395 r->access = PL0U_R;
7396 r->resetvalue = 0;
7397
7398 } else if (strcmp(r->name, m->name) == 0) {
7399 r->type = ARM_CP_CONST;
7400 r->access = PL0U_R;
7401 r->resetvalue &= m->exported_bits;
7402 r->resetvalue |= m->fixed_bits;
7403 break;
7404 }
7405 }
7406 if (pat) {
7407 g_pattern_spec_free(pat);
7408 }
7409 }
7410}
7411
7412const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
7413{
7414 return g_hash_table_lookup(cpregs, &encoded_cp);
7415}
7416
7417void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
7418 uint64_t value)
7419{
7420
7421}
7422
7423uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri)
7424{
7425
7426 return 0;
7427}
7428
7429void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
7430{
7431
7432}
7433
7434static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
7435{
7436
7437
7438
7439
7440
7441
7442 if (write_type == CPSRWriteByInstr &&
7443 ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_HYP ||
7444 mode == ARM_CPU_MODE_HYP)) {
7445 return 1;
7446 }
7447
7448 switch (mode) {
7449 case ARM_CPU_MODE_USR:
7450 return 0;
7451 case ARM_CPU_MODE_SYS:
7452 case ARM_CPU_MODE_SVC:
7453 case ARM_CPU_MODE_ABT:
7454 case ARM_CPU_MODE_UND:
7455 case ARM_CPU_MODE_IRQ:
7456 case ARM_CPU_MODE_FIQ:
7457
7458
7459
7460
7461
7462
7463 if (write_type == CPSRWriteByInstr &&
7464 (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON &&
7465 (arm_hcr_el2_eff(env) & HCR_TGE)) {
7466 return 1;
7467 }
7468 return 0;
7469 case ARM_CPU_MODE_HYP:
7470 return !arm_feature(env, ARM_FEATURE_EL2)
7471 || arm_current_el(env) < 2 || arm_is_secure_below_el3(env);
7472 case ARM_CPU_MODE_MON:
7473 return arm_current_el(env) < 3;
7474 default:
7475 return 1;
7476 }
7477}
7478
7479uint32_t cpsr_read(CPUARMState *env)
7480{
7481 int ZF;
7482 ZF = (env->ZF == 0);
7483 return env->uncached_cpsr | (env->NF & 0x80000000) | (ZF << 30) |
7484 (env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27)
7485 | (env->thumb << 5) | ((env->condexec_bits & 3) << 25)
7486 | ((env->condexec_bits & 0xfc) << 8)
7487 | (env->GE << 16) | (env->daif & CPSR_AIF);
7488}
7489
7490void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
7491 CPSRWriteType write_type)
7492{
7493 uint32_t changed_daif;
7494
7495 if (mask & CPSR_NZCV) {
7496 env->ZF = (~val) & CPSR_Z;
7497 env->NF = val;
7498 env->CF = (val >> 29) & 1;
7499 env->VF = (val << 3) & 0x80000000;
7500 }
7501 if (mask & CPSR_Q)
7502 env->QF = ((val & CPSR_Q) != 0);
7503 if (mask & CPSR_T)
7504 env->thumb = ((val & CPSR_T) != 0);
7505 if (mask & CPSR_IT_0_1) {
7506 env->condexec_bits &= ~3;
7507 env->condexec_bits |= (val >> 25) & 3;
7508 }
7509 if (mask & CPSR_IT_2_7) {
7510 env->condexec_bits &= 3;
7511 env->condexec_bits |= (val >> 8) & 0xfc;
7512 }
7513 if (mask & CPSR_GE) {
7514 env->GE = (val >> 16) & 0xf;
7515 }
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525 if (write_type != CPSRWriteRaw && !arm_feature(env, ARM_FEATURE_V8) &&
7526 arm_feature(env, ARM_FEATURE_EL3) &&
7527 !arm_feature(env, ARM_FEATURE_EL2) &&
7528 !arm_is_secure(env)) {
7529
7530 changed_daif = (env->daif ^ val) & mask;
7531
7532 if (changed_daif & CPSR_A) {
7533
7534
7535
7536 if (!(env->cp15.scr_el3 & SCR_AW)) {
7537 qemu_log_mask(LOG_GUEST_ERROR,
7538 "Ignoring attempt to switch CPSR_A flag from "
7539 "non-secure world with SCR.AW bit clear\n");
7540 mask &= ~CPSR_A;
7541 }
7542 }
7543
7544 if (changed_daif & CPSR_F) {
7545
7546
7547
7548 if (!(env->cp15.scr_el3 & SCR_FW)) {
7549 qemu_log_mask(LOG_GUEST_ERROR,
7550 "Ignoring attempt to switch CPSR_F flag from "
7551 "non-secure world with SCR.FW bit clear\n");
7552 mask &= ~CPSR_F;
7553 }
7554
7555
7556
7557
7558
7559 if ((A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_NMFI) &&
7560 (val & CPSR_F)) {
7561 qemu_log_mask(LOG_GUEST_ERROR,
7562 "Ignoring attempt to enable CPSR_F flag "
7563 "(non-maskable FIQ [NMFI] support enabled)\n");
7564 mask &= ~CPSR_F;
7565 }
7566 }
7567 }
7568
7569 env->daif &= ~(CPSR_AIF & mask);
7570 env->daif |= val & CPSR_AIF & mask;
7571
7572 if (write_type != CPSRWriteRaw &&
7573 ((env->uncached_cpsr ^ val) & mask & CPSR_M)) {
7574 if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) {
7575
7576
7577
7578
7579
7580
7581 mask &= ~CPSR_M;
7582 } else if (bad_mode_switch(env, val & CPSR_M, write_type)) {
7583
7584
7585
7586
7587
7588
7589
7590
7591 mask &= ~CPSR_M;
7592 if (write_type != CPSRWriteByGDBStub &&
7593 arm_feature(env, ARM_FEATURE_V8)) {
7594 mask |= CPSR_IL;
7595 val |= CPSR_IL;
7596 }
7597 qemu_log_mask(LOG_GUEST_ERROR,
7598 "Illegal AArch32 mode switch attempt from %s to %s\n",
7599 aarch32_mode_name(env->uncached_cpsr),
7600 aarch32_mode_name(val));
7601 } else {
7602 qemu_log_mask(CPU_LOG_INT, "%s %s to %s PC 0x%" PRIx32 "\n",
7603 write_type == CPSRWriteExceptionReturn ?
7604 "Exception return from AArch32" :
7605 "AArch32 mode switch from",
7606 aarch32_mode_name(env->uncached_cpsr),
7607 aarch32_mode_name(val), env->regs[15]);
7608 switch_mode(env, val & CPSR_M);
7609 }
7610 }
7611 mask &= ~CACHED_CPSR_BITS;
7612 env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
7613}
7614
7615
7616uint32_t HELPER(sxtb16)(uint32_t x)
7617{
7618 uint32_t res;
7619 res = (uint16_t)(int8_t)x;
7620 res |= (uint32_t)(int8_t)(x >> 16) << 16;
7621 return res;
7622}
7623
7624uint32_t HELPER(uxtb16)(uint32_t x)
7625{
7626 uint32_t res;
7627 res = (uint16_t)(uint8_t)x;
7628 res |= (uint32_t)(uint8_t)(x >> 16) << 16;
7629 return res;
7630}
7631
7632int32_t HELPER(sdiv)(int32_t num, int32_t den)
7633{
7634 if (den == 0)
7635 return 0;
7636 if (num == INT_MIN && den == -1)
7637 return INT_MIN;
7638 return num / den;
7639}
7640
7641uint32_t HELPER(udiv)(uint32_t num, uint32_t den)
7642{
7643 if (den == 0)
7644 return 0;
7645 return num / den;
7646}
7647
7648uint32_t HELPER(rbit)(uint32_t x)
7649{
7650 return revbit32(x);
7651}
7652
7653#ifdef CONFIG_USER_ONLY
7654
7655static void switch_mode(CPUARMState *env, int mode)
7656{
7657 ARMCPU *cpu = env_archcpu(env);
7658
7659 if (mode != ARM_CPU_MODE_USR) {
7660 cpu_abort(CPU(cpu), "Tried to switch out of user mode\n");
7661 }
7662}
7663
7664uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
7665 uint32_t cur_el, bool secure)
7666{
7667 return 1;
7668}
7669
7670void aarch64_sync_64_to_32(CPUARMState *env)
7671{
7672 g_assert_not_reached();
7673}
7674
7675#else
7676
7677static void switch_mode(CPUARMState *env, int mode)
7678{
7679 int old_mode;
7680 int i;
7681
7682 old_mode = env->uncached_cpsr & CPSR_M;
7683 if (mode == old_mode)
7684 return;
7685
7686 if (old_mode == ARM_CPU_MODE_FIQ) {
7687 memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
7688 memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
7689 } else if (mode == ARM_CPU_MODE_FIQ) {
7690 memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
7691 memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
7692 }
7693
7694 i = bank_number(old_mode);
7695 env->banked_r13[i] = env->regs[13];
7696 env->banked_spsr[i] = env->spsr;
7697
7698 i = bank_number(mode);
7699 env->regs[13] = env->banked_r13[i];
7700 env->spsr = env->banked_spsr[i];
7701
7702 env->banked_r14[r14_bank_number(old_mode)] = env->regs[14];
7703 env->regs[14] = env->banked_r14[r14_bank_number(mode)];
7704}
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743static const int8_t target_el_table[2][2][2][2][2][4] = {
7744 {{{{{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },},
7745 {{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},},
7746 {{{ 1, 1, 2, -1 },{ 3, -1, -1, 3 },},
7747 {{ 2, 2, 2, -1 },{ 3, -1, -1, 3 },},},},
7748 {{{{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},
7749 {{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},},
7750 {{{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},
7751 {{ 3, 3, 3, -1 },{ 3, -1, -1, 3 },},},},},
7752 {{{{{ 1, 1, 2, -1 },{ 1, 1, -1, 1 },},
7753 {{ 2, 2, 2, -1 },{ 1, 1, -1, 1 },},},
7754 {{{ 1, 1, 1, -1 },{ 1, 1, -1, 1 },},
7755 {{ 2, 2, 2, -1 },{ 1, 1, -1, 1 },},},},
7756 {{{{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},
7757 {{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},},
7758 {{{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},
7759 {{ 3, 3, 3, -1 },{ 3, 3, -1, 3 },},},},},
7760};
7761
7762
7763
7764
7765uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
7766 uint32_t cur_el, bool secure)
7767{
7768 CPUARMState *env = cs->env_ptr;
7769 bool rw;
7770 bool scr;
7771 bool hcr;
7772 int target_el;
7773
7774 bool is64 = arm_feature(env, ARM_FEATURE_AARCH64);
7775 uint64_t hcr_el2;
7776
7777 if (arm_feature(env, ARM_FEATURE_EL3)) {
7778 rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
7779 } else {
7780
7781
7782
7783
7784 rw = is64;
7785 }
7786
7787 hcr_el2 = arm_hcr_el2_eff(env);
7788 switch (excp_idx) {
7789 case EXCP_IRQ:
7790 scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
7791 hcr = hcr_el2 & HCR_IMO;
7792 break;
7793 case EXCP_FIQ:
7794 scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
7795 hcr = hcr_el2 & HCR_FMO;
7796 break;
7797 default:
7798 scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA);
7799 hcr = hcr_el2 & HCR_AMO;
7800 break;
7801 };
7802
7803
7804 target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el];
7805
7806 assert(target_el > 0);
7807
7808 return target_el;
7809}
7810
7811void arm_log_exception(int idx)
7812{
7813 if (qemu_loglevel_mask(CPU_LOG_INT)) {
7814 const char *exc = NULL;
7815 static const char * const excnames[] = {
7816 [EXCP_UDEF] = "Undefined Instruction",
7817 [EXCP_SWI] = "SVC",
7818 [EXCP_PREFETCH_ABORT] = "Prefetch Abort",
7819 [EXCP_DATA_ABORT] = "Data Abort",
7820 [EXCP_IRQ] = "IRQ",
7821 [EXCP_FIQ] = "FIQ",
7822 [EXCP_BKPT] = "Breakpoint",
7823 [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
7824 [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
7825 [EXCP_HVC] = "Hypervisor Call",
7826 [EXCP_HYP_TRAP] = "Hypervisor Trap",
7827 [EXCP_SMC] = "Secure Monitor Call",
7828 [EXCP_VIRQ] = "Virtual IRQ",
7829 [EXCP_VFIQ] = "Virtual FIQ",
7830 [EXCP_SEMIHOST] = "Semihosting call",
7831 [EXCP_NOCP] = "v7M NOCP UsageFault",
7832 [EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
7833 [EXCP_STKOF] = "v8M STKOF UsageFault",
7834 [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
7835 [EXCP_LSERR] = "v8M LSERR UsageFault",
7836 [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
7837 };
7838
7839 if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
7840 exc = excnames[idx];
7841 }
7842 if (!exc) {
7843 exc = "unknown";
7844 }
7845 qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
7846 }
7847}
7848
7849
7850
7851
7852
7853
7854void aarch64_sync_32_to_64(CPUARMState *env)
7855{
7856 int i;
7857 uint32_t mode = env->uncached_cpsr & CPSR_M;
7858
7859
7860 for (i = 0; i < 8; i++) {
7861 env->xregs[i] = env->regs[i];
7862 }
7863
7864
7865
7866
7867
7868 if (mode == ARM_CPU_MODE_FIQ) {
7869 for (i = 8; i < 13; i++) {
7870 env->xregs[i] = env->usr_regs[i - 8];
7871 }
7872 } else {
7873 for (i = 8; i < 13; i++) {
7874 env->xregs[i] = env->regs[i];
7875 }
7876 }
7877
7878
7879
7880
7881
7882
7883 if (mode == ARM_CPU_MODE_USR || mode == ARM_CPU_MODE_SYS) {
7884 env->xregs[13] = env->regs[13];
7885 env->xregs[14] = env->regs[14];
7886 } else {
7887 env->xregs[13] = env->banked_r13[bank_number(ARM_CPU_MODE_USR)];
7888
7889 if (mode == ARM_CPU_MODE_HYP) {
7890 env->xregs[14] = env->regs[14];
7891 } else {
7892 env->xregs[14] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_USR)];
7893 }
7894 }
7895
7896 if (mode == ARM_CPU_MODE_HYP) {
7897 env->xregs[15] = env->regs[13];
7898 } else {
7899 env->xregs[15] = env->banked_r13[bank_number(ARM_CPU_MODE_HYP)];
7900 }
7901
7902 if (mode == ARM_CPU_MODE_IRQ) {
7903 env->xregs[16] = env->regs[14];
7904 env->xregs[17] = env->regs[13];
7905 } else {
7906 env->xregs[16] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_IRQ)];
7907 env->xregs[17] = env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)];
7908 }
7909
7910 if (mode == ARM_CPU_MODE_SVC) {
7911 env->xregs[18] = env->regs[14];
7912 env->xregs[19] = env->regs[13];
7913 } else {
7914 env->xregs[18] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_SVC)];
7915 env->xregs[19] = env->banked_r13[bank_number(ARM_CPU_MODE_SVC)];
7916 }
7917
7918 if (mode == ARM_CPU_MODE_ABT) {
7919 env->xregs[20] = env->regs[14];
7920 env->xregs[21] = env->regs[13];
7921 } else {
7922 env->xregs[20] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_ABT)];
7923 env->xregs[21] = env->banked_r13[bank_number(ARM_CPU_MODE_ABT)];
7924 }
7925
7926 if (mode == ARM_CPU_MODE_UND) {
7927 env->xregs[22] = env->regs[14];
7928 env->xregs[23] = env->regs[13];
7929 } else {
7930 env->xregs[22] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_UND)];
7931 env->xregs[23] = env->banked_r13[bank_number(ARM_CPU_MODE_UND)];
7932 }
7933
7934
7935
7936
7937
7938
7939 if (mode == ARM_CPU_MODE_FIQ) {
7940 for (i = 24; i < 31; i++) {
7941 env->xregs[i] = env->regs[i - 16];
7942 }
7943 } else {
7944 for (i = 24; i < 29; i++) {
7945 env->xregs[i] = env->fiq_regs[i - 24];
7946 }
7947 env->xregs[29] = env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)];
7948 env->xregs[30] = env->banked_r14[r14_bank_number(ARM_CPU_MODE_FIQ)];
7949 }
7950
7951 env->pc = env->regs[15];
7952}
7953
7954
7955
7956
7957
7958
7959void aarch64_sync_64_to_32(CPUARMState *env)
7960{
7961 int i;
7962 uint32_t mode = env->uncached_cpsr & CPSR_M;
7963
7964
7965 for (i = 0; i < 8; i++) {
7966 env->regs[i] = env->xregs[i];
7967 }
7968
7969
7970
7971
7972
7973 if (mode == ARM_CPU_MODE_FIQ) {
7974 for (i = 8; i < 13; i++) {
7975 env->usr_regs[i - 8] = env->xregs[i];
7976 }
7977 } else {
7978 for (i = 8; i < 13; i++) {
7979 env->regs[i] = env->xregs[i];
7980 }
7981 }
7982
7983
7984
7985
7986
7987
7988
7989 if (mode == ARM_CPU_MODE_USR || mode == ARM_CPU_MODE_SYS) {
7990 env->regs[13] = env->xregs[13];
7991 env->regs[14] = env->xregs[14];
7992 } else {
7993 env->banked_r13[bank_number(ARM_CPU_MODE_USR)] = env->xregs[13];
7994
7995
7996
7997
7998
7999 if (mode == ARM_CPU_MODE_HYP) {
8000 env->regs[14] = env->xregs[14];
8001 } else {
8002 env->banked_r14[r14_bank_number(ARM_CPU_MODE_USR)] = env->xregs[14];
8003 }
8004 }
8005
8006 if (mode == ARM_CPU_MODE_HYP) {
8007 env->regs[13] = env->xregs[15];
8008 } else {
8009 env->banked_r13[bank_number(ARM_CPU_MODE_HYP)] = env->xregs[15];
8010 }
8011
8012 if (mode == ARM_CPU_MODE_IRQ) {
8013 env->regs[14] = env->xregs[16];
8014 env->regs[13] = env->xregs[17];
8015 } else {
8016 env->banked_r14[r14_bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[16];
8017 env->banked_r13[bank_number(ARM_CPU_MODE_IRQ)] = env->xregs[17];
8018 }
8019
8020 if (mode == ARM_CPU_MODE_SVC) {
8021 env->regs[14] = env->xregs[18];
8022 env->regs[13] = env->xregs[19];
8023 } else {
8024 env->banked_r14[r14_bank_number(ARM_CPU_MODE_SVC)] = env->xregs[18];
8025 env->banked_r13[bank_number(ARM_CPU_MODE_SVC)] = env->xregs[19];
8026 }
8027
8028 if (mode == ARM_CPU_MODE_ABT) {
8029 env->regs[14] = env->xregs[20];
8030 env->regs[13] = env->xregs[21];
8031 } else {
8032 env->banked_r14[r14_bank_number(ARM_CPU_MODE_ABT)] = env->xregs[20];
8033 env->banked_r13[bank_number(ARM_CPU_MODE_ABT)] = env->xregs[21];
8034 }
8035
8036 if (mode == ARM_CPU_MODE_UND) {
8037 env->regs[14] = env->xregs[22];
8038 env->regs[13] = env->xregs[23];
8039 } else {
8040 env->banked_r14[r14_bank_number(ARM_CPU_MODE_UND)] = env->xregs[22];
8041 env->banked_r13[bank_number(ARM_CPU_MODE_UND)] = env->xregs[23];
8042 }
8043
8044
8045
8046
8047
8048 if (mode == ARM_CPU_MODE_FIQ) {
8049 for (i = 24; i < 31; i++) {
8050 env->regs[i - 16] = env->xregs[i];
8051 }
8052 } else {
8053 for (i = 24; i < 29; i++) {
8054 env->fiq_regs[i - 24] = env->xregs[i];
8055 }
8056 env->banked_r13[bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[29];
8057 env->banked_r14[r14_bank_number(ARM_CPU_MODE_FIQ)] = env->xregs[30];
8058 }
8059
8060 env->regs[15] = env->pc;
8061}
8062
8063static void take_aarch32_exception(CPUARMState *env, int new_mode,
8064 uint32_t mask, uint32_t offset,
8065 uint32_t newpc)
8066{
8067
8068 switch_mode(env, new_mode);
8069
8070
8071
8072
8073 env->uncached_cpsr &= ~PSTATE_SS;
8074 env->spsr = cpsr_read(env);
8075
8076 env->condexec_bits = 0;
8077
8078 env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
8079
8080 env->uncached_cpsr &= ~CPSR_E;
8081 if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) {
8082 env->uncached_cpsr |= CPSR_E;
8083 }
8084
8085 env->uncached_cpsr &= ~(CPSR_IL | CPSR_J);
8086 env->daif |= mask;
8087
8088 if (new_mode == ARM_CPU_MODE_HYP) {
8089 env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
8090 env->elr_el[2] = env->regs[15];
8091 } else {
8092
8093
8094
8095
8096 if (arm_feature(env, ARM_FEATURE_V4T)) {
8097 env->thumb =
8098 (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) != 0;
8099 }
8100 env->regs[14] = env->regs[15] + offset;
8101 }
8102 env->regs[15] = newpc;
8103 arm_rebuild_hflags(env);
8104}
8105
8106static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
8107{
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119 uint32_t addr, mask;
8120 ARMCPU *cpu = ARM_CPU(cs);
8121 CPUARMState *env = &cpu->env;
8122
8123 switch (cs->exception_index) {
8124 case EXCP_UDEF:
8125 addr = 0x04;
8126 break;
8127 case EXCP_SWI:
8128 addr = 0x14;
8129 break;
8130 case EXCP_BKPT:
8131
8132 case EXCP_PREFETCH_ABORT:
8133 env->cp15.ifar_s = env->exception.vaddress;
8134 qemu_log_mask(CPU_LOG_INT, "...with HIFAR 0x%x\n",
8135 (uint32_t)env->exception.vaddress);
8136 addr = 0x0c;
8137 break;
8138 case EXCP_DATA_ABORT:
8139 env->cp15.dfar_s = env->exception.vaddress;
8140 qemu_log_mask(CPU_LOG_INT, "...with HDFAR 0x%x\n",
8141 (uint32_t)env->exception.vaddress);
8142 addr = 0x10;
8143 break;
8144 case EXCP_IRQ:
8145 addr = 0x18;
8146 break;
8147 case EXCP_FIQ:
8148 addr = 0x1c;
8149 break;
8150 case EXCP_HVC:
8151 addr = 0x08;
8152 break;
8153 case EXCP_HYP_TRAP:
8154 addr = 0x14;
8155 break;
8156 default:
8157 cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
8158 }
8159
8160 if (cs->exception_index != EXCP_IRQ && cs->exception_index != EXCP_FIQ) {
8161 if (!arm_feature(env, ARM_FEATURE_V8)) {
8162
8163
8164
8165
8166
8167 if (cs->exception_index == EXCP_PREFETCH_ABORT ||
8168 (cs->exception_index == EXCP_DATA_ABORT &&
8169 !(env->exception.syndrome & ARM_EL_ISV)) ||
8170 syn_get_ec(env->exception.syndrome) == EC_UNCATEGORIZED) {
8171 env->exception.syndrome &= ~ARM_EL_IL;
8172 }
8173 }
8174 env->cp15.esr_el[2] = env->exception.syndrome;
8175 }
8176
8177 if (arm_current_el(env) != 2 && addr < 0x14) {
8178 addr = 0x14;
8179 }
8180
8181 mask = 0;
8182 if (!(env->cp15.scr_el3 & SCR_EA)) {
8183 mask |= CPSR_A;
8184 }
8185 if (!(env->cp15.scr_el3 & SCR_IRQ)) {
8186 mask |= CPSR_I;
8187 }
8188 if (!(env->cp15.scr_el3 & SCR_FIQ)) {
8189 mask |= CPSR_F;
8190 }
8191
8192 addr += env->cp15.hvbar;
8193
8194 take_aarch32_exception(env, ARM_CPU_MODE_HYP, mask, 0, addr);
8195}
8196
8197static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
8198{
8199 ARMCPU *cpu = ARM_CPU(cs);
8200 CPUARMState *env = &cpu->env;
8201 uint32_t addr;
8202 uint32_t mask;
8203 int new_mode;
8204 uint32_t offset;
8205 uint32_t moe;
8206
8207
8208 switch (syn_get_ec(env->exception.syndrome)) {
8209 case EC_BREAKPOINT:
8210 case EC_BREAKPOINT_SAME_EL:
8211 moe = 1;
8212 break;
8213 case EC_WATCHPOINT:
8214 case EC_WATCHPOINT_SAME_EL:
8215 moe = 10;
8216 break;
8217 case EC_AA32_BKPT:
8218 moe = 3;
8219 break;
8220 case EC_VECTORCATCH:
8221 moe = 5;
8222 break;
8223 default:
8224 moe = 0;
8225 break;
8226 }
8227
8228 if (moe) {
8229 env->cp15.mdscr_el1 = deposit64(env->cp15.mdscr_el1, 2, 4, moe);
8230 }
8231
8232 if (env->exception.target_el == 2) {
8233 arm_cpu_do_interrupt_aarch32_hyp(cs);
8234 return;
8235 }
8236
8237 switch (cs->exception_index) {
8238 case EXCP_UDEF:
8239 new_mode = ARM_CPU_MODE_UND;
8240 addr = 0x04;
8241 mask = CPSR_I;
8242 if (env->thumb)
8243 offset = 2;
8244 else
8245 offset = 4;
8246 break;
8247 case EXCP_SWI:
8248 new_mode = ARM_CPU_MODE_SVC;
8249 addr = 0x08;
8250 mask = CPSR_I;
8251
8252 offset = 0;
8253 break;
8254 case EXCP_BKPT:
8255
8256 case EXCP_PREFETCH_ABORT:
8257 A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr);
8258 A32_BANKED_CURRENT_REG_SET(env, ifar, env->exception.vaddress);
8259 qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",
8260 env->exception.fsr, (uint32_t)env->exception.vaddress);
8261 new_mode = ARM_CPU_MODE_ABT;
8262 addr = 0x0c;
8263 mask = CPSR_A | CPSR_I;
8264 offset = 4;
8265 break;
8266 case EXCP_DATA_ABORT:
8267 A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr);
8268 A32_BANKED_CURRENT_REG_SET(env, dfar, env->exception.vaddress);
8269 qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",
8270 env->exception.fsr,
8271 (uint32_t)env->exception.vaddress);
8272 new_mode = ARM_CPU_MODE_ABT;
8273 addr = 0x10;
8274 mask = CPSR_A | CPSR_I;
8275 offset = 8;
8276 break;
8277 case EXCP_IRQ:
8278 new_mode = ARM_CPU_MODE_IRQ;
8279 addr = 0x18;
8280
8281 mask = CPSR_A | CPSR_I;
8282 offset = 4;
8283 if (env->cp15.scr_el3 & SCR_IRQ) {
8284
8285 new_mode = ARM_CPU_MODE_MON;
8286 mask |= CPSR_F;
8287 }
8288 break;
8289 case EXCP_FIQ:
8290 new_mode = ARM_CPU_MODE_FIQ;
8291 addr = 0x1c;
8292
8293 mask = CPSR_A | CPSR_I | CPSR_F;
8294 if (env->cp15.scr_el3 & SCR_FIQ) {
8295
8296 new_mode = ARM_CPU_MODE_MON;
8297 }
8298 offset = 4;
8299 break;
8300 case EXCP_VIRQ:
8301 new_mode = ARM_CPU_MODE_IRQ;
8302 addr = 0x18;
8303
8304 mask = CPSR_A | CPSR_I;
8305 offset = 4;
8306 break;
8307 case EXCP_VFIQ:
8308 new_mode = ARM_CPU_MODE_FIQ;
8309 addr = 0x1c;
8310
8311 mask = CPSR_A | CPSR_I | CPSR_F;
8312 offset = 4;
8313 break;
8314 case EXCP_SMC:
8315 new_mode = ARM_CPU_MODE_MON;
8316 addr = 0x08;
8317 mask = CPSR_A | CPSR_I | CPSR_F;
8318 offset = 0;
8319 break;
8320 default:
8321 cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
8322 return;
8323 }
8324
8325 if (new_mode == ARM_CPU_MODE_MON) {
8326 addr += env->cp15.mvbar;
8327 } else if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
8328
8329 addr += 0xffff0000;
8330 } else {
8331
8332
8333
8334
8335
8336 addr += A32_BANKED_CURRENT_REG_GET(env, vbar);
8337 }
8338
8339 if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
8340 env->cp15.scr_el3 &= ~SCR_NS;
8341 }
8342
8343 take_aarch32_exception(env, new_mode, mask, offset, addr);
8344}
8345
8346
8347static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
8348{
8349 ARMCPU *cpu = ARM_CPU(cs);
8350 CPUARMState *env = &cpu->env;
8351 unsigned int new_el = env->exception.target_el;
8352 target_ulong addr = env->cp15.vbar_el[new_el];
8353 unsigned int new_mode = aarch64_pstate_mode(new_el, true);
8354 unsigned int cur_el = arm_current_el(env);
8355
8356
8357
8358
8359
8360 aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
8361
8362 if (cur_el < new_el) {
8363
8364
8365
8366 bool is_aa64;
8367
8368 switch (new_el) {
8369 case 3:
8370 is_aa64 = (env->cp15.scr_el3 & SCR_RW) != 0;
8371 break;
8372 case 2:
8373 is_aa64 = (env->cp15.hcr_el2 & HCR_RW) != 0;
8374 break;
8375 case 1:
8376 is_aa64 = is_a64(env);
8377 break;
8378 default:
8379 g_assert_not_reached();
8380 }
8381
8382 if (is_aa64) {
8383 addr += 0x400;
8384 } else {
8385 addr += 0x600;
8386 }
8387 } else if (pstate_read(env) & PSTATE_SP) {
8388 addr += 0x200;
8389 }
8390
8391 switch (cs->exception_index) {
8392 case EXCP_PREFETCH_ABORT:
8393 case EXCP_DATA_ABORT:
8394 env->cp15.far_el[new_el] = env->exception.vaddress;
8395 qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n",
8396 env->cp15.far_el[new_el]);
8397
8398 case EXCP_BKPT:
8399 case EXCP_UDEF:
8400 case EXCP_SWI:
8401 case EXCP_HVC:
8402 case EXCP_HYP_TRAP:
8403 case EXCP_SMC:
8404 if (syn_get_ec(env->exception.syndrome) == EC_ADVSIMDFPACCESSTRAP) {
8405
8406
8407
8408
8409
8410
8411 env->exception.syndrome &= ~MAKE_64BIT_MASK(0, 20);
8412 }
8413 env->cp15.esr_el[new_el] = env->exception.syndrome;
8414 break;
8415 case EXCP_IRQ:
8416 case EXCP_VIRQ:
8417 addr += 0x80;
8418 break;
8419 case EXCP_FIQ:
8420 case EXCP_VFIQ:
8421 addr += 0x100;
8422 break;
8423 case EXCP_SEMIHOST:
8424 qemu_log_mask(CPU_LOG_INT,
8425 "...handling as semihosting call 0x%" PRIx64 "\n",
8426 env->xregs[0]);
8427 env->xregs[0] = do_arm_semihosting(env);
8428 return;
8429 default:
8430 cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
8431 }
8432
8433 if (is_a64(env)) {
8434 env->banked_spsr[aarch64_banked_spsr_index(new_el)] = pstate_read(env);
8435 aarch64_save_sp(env, arm_current_el(env));
8436 env->elr_el[new_el] = env->pc;
8437 } else {
8438 env->banked_spsr[aarch64_banked_spsr_index(new_el)] = cpsr_read(env);
8439 env->elr_el[new_el] = env->regs[15];
8440
8441 aarch64_sync_32_to_64(env);
8442
8443 env->condexec_bits = 0;
8444 }
8445 qemu_log_mask(CPU_LOG_INT, "...with ELR 0x%" PRIx64 "\n",
8446 env->elr_el[new_el]);
8447
8448 pstate_write(env, PSTATE_DAIF | new_mode);
8449 env->aarch64 = 1;
8450 aarch64_restore_sp(env, new_el);
8451 helper_rebuild_hflags_a64(env, new_el);
8452
8453 env->pc = addr;
8454
8455 qemu_log_mask(CPU_LOG_INT, "...to EL%d PC 0x%" PRIx64 " PSTATE 0x%x\n",
8456 new_el, env->pc, pstate_read(env));
8457}
8458
8459
8460
8461
8462
8463
8464
8465
8466#ifdef CONFIG_TCG
8467static void handle_semihosting(CPUState *cs)
8468{
8469 ARMCPU *cpu = ARM_CPU(cs);
8470 CPUARMState *env = &cpu->env;
8471
8472 if (is_a64(env)) {
8473 qemu_log_mask(CPU_LOG_INT,
8474 "...handling as semihosting call 0x%" PRIx64 "\n",
8475 env->xregs[0]);
8476 env->xregs[0] = do_arm_semihosting(env);
8477 } else {
8478 qemu_log_mask(CPU_LOG_INT,
8479 "...handling as semihosting call 0x%x\n",
8480 env->regs[0]);
8481 env->regs[0] = do_arm_semihosting(env);
8482 }
8483}
8484#endif
8485
8486
8487
8488
8489
8490
8491void arm_cpu_do_interrupt(CPUState *cs)
8492{
8493 ARMCPU *cpu = ARM_CPU(cs);
8494 CPUARMState *env = &cpu->env;
8495 unsigned int new_el = env->exception.target_el;
8496
8497 assert(!arm_feature(env, ARM_FEATURE_M));
8498
8499 arm_log_exception(cs->exception_index);
8500 qemu_log_mask(CPU_LOG_INT, "...from EL%d to EL%d\n", arm_current_el(env),
8501 new_el);
8502 if (qemu_loglevel_mask(CPU_LOG_INT)
8503 && !excp_is_internal(cs->exception_index)) {
8504 qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%x/0x%" PRIx32 "\n",
8505 syn_get_ec(env->exception.syndrome),
8506 env->exception.syndrome);
8507 }
8508
8509 if (arm_is_psci_call(cpu, cs->exception_index)) {
8510 arm_handle_psci_call(cpu);
8511 qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
8512 return;
8513 }
8514
8515
8516
8517
8518
8519
8520#ifdef CONFIG_TCG
8521 if (cs->exception_index == EXCP_SEMIHOST) {
8522 handle_semihosting(cs);
8523 return;
8524 }
8525#endif
8526
8527
8528
8529
8530
8531 g_assert(qemu_mutex_iothread_locked());
8532
8533 arm_call_pre_el_change_hook(cpu);
8534
8535 assert(!excp_is_internal(cs->exception_index));
8536 if (arm_el_is_aa64(env, new_el)) {
8537 arm_cpu_do_interrupt_aarch64(cs);
8538 } else {
8539 arm_cpu_do_interrupt_aarch32(cs);
8540 }
8541
8542 arm_call_el_change_hook(cpu);
8543
8544 if (!kvm_enabled()) {
8545 cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
8546 }
8547}
8548#endif
8549
8550
8551static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
8552{
8553 switch (mmu_idx) {
8554 case ARMMMUIdx_S2NS:
8555 case ARMMMUIdx_S1E2:
8556 return 2;
8557 case ARMMMUIdx_S1E3:
8558 return 3;
8559 case ARMMMUIdx_S1SE0:
8560 return arm_el_is_aa64(env, 3) ? 1 : 3;
8561 case ARMMMUIdx_S1SE1:
8562 case ARMMMUIdx_S1NSE0:
8563 case ARMMMUIdx_S1NSE1:
8564 case ARMMMUIdx_MPrivNegPri:
8565 case ARMMMUIdx_MUserNegPri:
8566 case ARMMMUIdx_MPriv:
8567 case ARMMMUIdx_MUser:
8568 case ARMMMUIdx_MSPrivNegPri:
8569 case ARMMMUIdx_MSUserNegPri:
8570 case ARMMMUIdx_MSPriv:
8571 case ARMMMUIdx_MSUser:
8572 return 1;
8573 default:
8574 g_assert_not_reached();
8575 }
8576}
8577
8578#ifndef CONFIG_USER_ONLY
8579
8580
8581static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
8582{
8583 return env->cp15.sctlr_el[regime_el(env, mmu_idx)];
8584}
8585
8586
8587static inline bool regime_translation_disabled(CPUARMState *env,
8588 ARMMMUIdx mmu_idx)
8589{
8590 if (arm_feature(env, ARM_FEATURE_M)) {
8591 switch (env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] &
8592 (R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
8593 case R_V7M_MPU_CTRL_ENABLE_MASK:
8594
8595 return mmu_idx & ARM_MMU_IDX_M_NEGPRI;
8596 case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK:
8597
8598 return false;
8599 case 0:
8600 default:
8601
8602
8603
8604 return true;
8605 }
8606 }
8607
8608 if (mmu_idx == ARMMMUIdx_S2NS) {
8609
8610 return (env->cp15.hcr_el2 & (HCR_DC | HCR_VM)) == 0;
8611 }
8612
8613 if (env->cp15.hcr_el2 & HCR_TGE) {
8614
8615 if (!regime_is_secure(env, mmu_idx) && regime_el(env, mmu_idx) == 1) {
8616 return true;
8617 }
8618 }
8619
8620 if ((env->cp15.hcr_el2 & HCR_DC) &&
8621 (mmu_idx == ARMMMUIdx_S1NSE0 || mmu_idx == ARMMMUIdx_S1NSE1)) {
8622
8623 return true;
8624 }
8625
8626 return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
8627}
8628
8629static inline bool regime_translation_big_endian(CPUARMState *env,
8630 ARMMMUIdx mmu_idx)
8631{
8632 return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0;
8633}
8634
8635
8636static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
8637 int ttbrn)
8638{
8639 if (mmu_idx == ARMMMUIdx_S2NS) {
8640 return env->cp15.vttbr_el2;
8641 }
8642 if (ttbrn == 0) {
8643 return env->cp15.ttbr0_el[regime_el(env, mmu_idx)];
8644 } else {
8645 return env->cp15.ttbr1_el[regime_el(env, mmu_idx)];
8646 }
8647}
8648
8649#endif
8650
8651
8652static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
8653{
8654 if (mmu_idx == ARMMMUIdx_S2NS) {
8655 return &env->cp15.vtcr_el2;
8656 }
8657 return &env->cp15.tcr_el[regime_el(env, mmu_idx)];
8658}
8659
8660
8661
8662
8663static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
8664{
8665 if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
8666 mmu_idx += (ARMMMUIdx_S1NSE0 - ARMMMUIdx_S12NSE0);
8667 }
8668 return mmu_idx;
8669}
8670
8671
8672static inline bool regime_using_lpae_format(CPUARMState *env,
8673 ARMMMUIdx mmu_idx)
8674{
8675 int el = regime_el(env, mmu_idx);
8676 if (el == 2 || arm_el_is_aa64(env, el)) {
8677 return true;
8678 }
8679 if (arm_feature(env, ARM_FEATURE_LPAE)
8680 && (regime_tcr(env, mmu_idx)->raw_tcr & TTBCR_EAE)) {
8681 return true;
8682 }
8683 return false;
8684}
8685
8686
8687
8688
8689bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
8690{
8691 mmu_idx = stage_1_mmu_idx(mmu_idx);
8692
8693 return regime_using_lpae_format(env, mmu_idx);
8694}
8695
8696#ifndef CONFIG_USER_ONLY
8697static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
8698{
8699 switch (mmu_idx) {
8700 case ARMMMUIdx_S1SE0:
8701 case ARMMMUIdx_S1NSE0:
8702 case ARMMMUIdx_MUser:
8703 case ARMMMUIdx_MSUser:
8704 case ARMMMUIdx_MUserNegPri:
8705 case ARMMMUIdx_MSUserNegPri:
8706 return true;
8707 default:
8708 return false;
8709 case ARMMMUIdx_S12NSE0:
8710 case ARMMMUIdx_S12NSE1:
8711 g_assert_not_reached();
8712 }
8713}
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723static inline int ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx,
8724 int ap, int domain_prot)
8725{
8726 bool is_user = regime_is_user(env, mmu_idx);
8727
8728 if (domain_prot == 3) {
8729 return PAGE_READ | PAGE_WRITE;
8730 }
8731
8732 switch (ap) {
8733 case 0:
8734 if (arm_feature(env, ARM_FEATURE_V7)) {
8735 return 0;
8736 }
8737 switch (regime_sctlr(env, mmu_idx) & (SCTLR_S | SCTLR_R)) {
8738 case SCTLR_S:
8739 return is_user ? 0 : PAGE_READ;
8740 case SCTLR_R:
8741 return PAGE_READ;
8742 default:
8743 return 0;
8744 }
8745 case 1:
8746 return is_user ? 0 : PAGE_READ | PAGE_WRITE;
8747 case 2:
8748 if (is_user) {
8749 return PAGE_READ;
8750 } else {
8751 return PAGE_READ | PAGE_WRITE;
8752 }
8753 case 3:
8754 return PAGE_READ | PAGE_WRITE;
8755 case 4:
8756 return 0;
8757 case 5:
8758 return is_user ? 0 : PAGE_READ;
8759 case 6:
8760 return PAGE_READ;
8761 case 7:
8762 if (!arm_feature(env, ARM_FEATURE_V6K)) {
8763 return 0;
8764 }
8765 return PAGE_READ;
8766 default:
8767 g_assert_not_reached();
8768 }
8769}
8770
8771
8772
8773
8774
8775
8776
8777static inline int simple_ap_to_rw_prot_is_user(int ap, bool is_user)
8778{
8779 switch (ap) {
8780 case 0:
8781 return is_user ? 0 : PAGE_READ | PAGE_WRITE;
8782 case 1:
8783 return PAGE_READ | PAGE_WRITE;
8784 case 2:
8785 return is_user ? 0 : PAGE_READ;
8786 case 3:
8787 return PAGE_READ;
8788 default:
8789 g_assert_not_reached();
8790 }
8791}
8792
8793static inline int
8794simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
8795{
8796 return simple_ap_to_rw_prot_is_user(ap, regime_is_user(env, mmu_idx));
8797}
8798
8799
8800
8801
8802
8803
8804
8805static int get_S2prot(CPUARMState *env, int s2ap, int xn)
8806{
8807 int prot = 0;
8808
8809 if (s2ap & 1) {
8810 prot |= PAGE_READ;
8811 }
8812 if (s2ap & 2) {
8813 prot |= PAGE_WRITE;
8814 }
8815 if (!xn) {
8816 if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
8817 prot |= PAGE_EXEC;
8818 }
8819 }
8820 return prot;
8821}
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
8834 int ap, int ns, int xn, int pxn)
8835{
8836 bool is_user = regime_is_user(env, mmu_idx);
8837 int prot_rw, user_rw;
8838 bool have_wxn;
8839 int wxn = 0;
8840
8841 assert(mmu_idx != ARMMMUIdx_S2NS);
8842
8843 user_rw = simple_ap_to_rw_prot_is_user(ap, true);
8844 if (is_user) {
8845 prot_rw = user_rw;
8846 } else {
8847 prot_rw = simple_ap_to_rw_prot_is_user(ap, false);
8848 }
8849
8850 if (ns && arm_is_secure(env) && (env->cp15.scr_el3 & SCR_SIF)) {
8851 return prot_rw;
8852 }
8853
8854
8855
8856
8857
8858
8859 have_wxn = arm_feature(env, ARM_FEATURE_LPAE);
8860
8861 if (have_wxn) {
8862 wxn = regime_sctlr(env, mmu_idx) & SCTLR_WXN;
8863 }
8864
8865 if (is_aa64) {
8866 switch (regime_el(env, mmu_idx)) {
8867 case 1:
8868 if (!is_user) {
8869 xn = pxn || (user_rw & PAGE_WRITE);
8870 }
8871 break;
8872 case 2:
8873 case 3:
8874 break;
8875 }
8876 } else if (arm_feature(env, ARM_FEATURE_V7)) {
8877 switch (regime_el(env, mmu_idx)) {
8878 case 1:
8879 case 3:
8880 if (is_user) {
8881 xn = xn || !(user_rw & PAGE_READ);
8882 } else {
8883 int uwxn = 0;
8884 if (have_wxn) {
8885 uwxn = regime_sctlr(env, mmu_idx) & SCTLR_UWXN;
8886 }
8887 xn = xn || !(prot_rw & PAGE_READ) || pxn ||
8888 (uwxn && (user_rw & PAGE_WRITE));
8889 }
8890 break;
8891 case 2:
8892 break;
8893 }
8894 } else {
8895 xn = wxn = 0;
8896 }
8897
8898 if (xn || (wxn && (prot_rw & PAGE_WRITE))) {
8899 return prot_rw;
8900 }
8901 return prot_rw | PAGE_EXEC;
8902}
8903
8904static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
8905 uint32_t *table, uint32_t address)
8906{
8907
8908 TCR *tcr = regime_tcr(env, mmu_idx);
8909
8910 if (address & tcr->mask) {
8911 if (tcr->raw_tcr & TTBCR_PD1) {
8912
8913 return false;
8914 }
8915 *table = regime_ttbr(env, mmu_idx, 1) & 0xffffc000;
8916 } else {
8917 if (tcr->raw_tcr & TTBCR_PD0) {
8918
8919 return false;
8920 }
8921 *table = regime_ttbr(env, mmu_idx, 0) & tcr->base_mask;
8922 }
8923 *table |= (address >> 18) & 0x3ffc;
8924 return true;
8925}
8926
8927
8928static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
8929 hwaddr addr, MemTxAttrs txattrs,
8930 ARMMMUFaultInfo *fi)
8931{
8932 if ((mmu_idx == ARMMMUIdx_S1NSE0 || mmu_idx == ARMMMUIdx_S1NSE1) &&
8933 !regime_translation_disabled(env, ARMMMUIdx_S2NS)) {
8934 target_ulong s2size;
8935 hwaddr s2pa;
8936 int s2prot;
8937 int ret;
8938 ARMCacheAttrs cacheattrs = {};
8939 ARMCacheAttrs *pcacheattrs = NULL;
8940
8941 if (env->cp15.hcr_el2 & HCR_PTW) {
8942
8943
8944
8945
8946
8947 pcacheattrs = &cacheattrs;
8948 }
8949
8950 ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
8951 &txattrs, &s2prot, &s2size, fi, pcacheattrs);
8952 if (ret) {
8953 assert(fi->type != ARMFault_None);
8954 fi->s2addr = addr;
8955 fi->stage2 = true;
8956 fi->s1ptw = true;
8957 return ~0;
8958 }
8959 if (pcacheattrs && (pcacheattrs->attrs & 0xf0) == 0) {
8960
8961 fi->type = ARMFault_Permission;
8962 fi->s2addr = addr;
8963 fi->stage2 = true;
8964 fi->s1ptw = true;
8965 return ~0;
8966 }
8967 addr = s2pa;
8968 }
8969 return addr;
8970}
8971
8972
8973static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
8974 ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
8975{
8976 ARMCPU *cpu = ARM_CPU(cs);
8977 CPUARMState *env = &cpu->env;
8978 MemTxAttrs attrs = {};
8979 MemTxResult result = MEMTX_OK;
8980 AddressSpace *as;
8981 uint32_t data;
8982
8983 attrs.secure = is_secure;
8984 as = arm_addressspace(cs, attrs);
8985 addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fi);
8986 if (fi->s1ptw) {
8987 return 0;
8988 }
8989 if (regime_translation_big_endian(env, mmu_idx)) {
8990 data = address_space_ldl_be(as, addr, attrs, &result);
8991 } else {
8992 data = address_space_ldl_le(as, addr, attrs, &result);
8993 }
8994 if (result == MEMTX_OK) {
8995 return data;
8996 }
8997 fi->type = ARMFault_SyncExternalOnWalk;
8998 fi->ea = arm_extabort_type(result);
8999 return 0;
9000}
9001
9002static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
9003 ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
9004{
9005 ARMCPU *cpu = ARM_CPU(cs);
9006 CPUARMState *env = &cpu->env;
9007 MemTxAttrs attrs = {};
9008 MemTxResult result = MEMTX_OK;
9009 AddressSpace *as;
9010 uint64_t data;
9011
9012 attrs.secure = is_secure;
9013 as = arm_addressspace(cs, attrs);
9014 addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fi);
9015 if (fi->s1ptw) {
9016 return 0;
9017 }
9018 if (regime_translation_big_endian(env, mmu_idx)) {
9019 data = address_space_ldq_be(as, addr, attrs, &result);
9020 } else {
9021 data = address_space_ldq_le(as, addr, attrs, &result);
9022 }
9023 if (result == MEMTX_OK) {
9024 return data;
9025 }
9026 fi->type = ARMFault_SyncExternalOnWalk;
9027 fi->ea = arm_extabort_type(result);
9028 return 0;
9029}
9030
9031static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
9032 MMUAccessType access_type, ARMMMUIdx mmu_idx,
9033 hwaddr *phys_ptr, int *prot,
9034 target_ulong *page_size,
9035 ARMMMUFaultInfo *fi)
9036{
9037 CPUState *cs = env_cpu(env);
9038 int level = 1;
9039 uint32_t table;
9040 uint32_t desc;
9041 int type;
9042 int ap;
9043 int domain = 0;
9044 int domain_prot;
9045 hwaddr phys_addr;
9046 uint32_t dacr;
9047
9048
9049
9050 if (!get_level1_table_address(env, mmu_idx, &table, address)) {
9051
9052 fi->type = ARMFault_Translation;
9053 goto do_fault;
9054 }
9055 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
9056 mmu_idx, fi);
9057 if (fi->type != ARMFault_None) {
9058 goto do_fault;
9059 }
9060 type = (desc & 3);
9061 domain = (desc >> 5) & 0x0f;
9062 if (regime_el(env, mmu_idx) == 1) {
9063 dacr = env->cp15.dacr_ns;
9064 } else {
9065 dacr = env->cp15.dacr_s;
9066 }
9067 domain_prot = (dacr >> (domain * 2)) & 3;
9068 if (type == 0) {
9069
9070 fi->type = ARMFault_Translation;
9071 goto do_fault;
9072 }
9073 if (type != 2) {
9074 level = 2;
9075 }
9076 if (domain_prot == 0 || domain_prot == 2) {
9077 fi->type = ARMFault_Domain;
9078 goto do_fault;
9079 }
9080 if (type == 2) {
9081
9082 phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
9083 ap = (desc >> 10) & 3;
9084 *page_size = 1024 * 1024;
9085 } else {
9086
9087 if (type == 1) {
9088
9089 table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
9090 } else {
9091
9092 table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
9093 }
9094 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
9095 mmu_idx, fi);
9096 if (fi->type != ARMFault_None) {
9097 goto do_fault;
9098 }
9099 switch (desc & 3) {
9100 case 0:
9101 fi->type = ARMFault_Translation;
9102 goto do_fault;
9103 case 1:
9104 phys_addr = (desc & 0xffff0000) | (address & 0xffff);
9105 ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
9106 *page_size = 0x10000;
9107 break;
9108 case 2:
9109 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
9110 ap = (desc >> (4 + ((address >> 9) & 6))) & 3;
9111 *page_size = 0x1000;
9112 break;
9113 case 3:
9114 if (type == 1) {
9115
9116 if (arm_feature(env, ARM_FEATURE_XSCALE)
9117 || arm_feature(env, ARM_FEATURE_V6)) {
9118 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
9119 *page_size = 0x1000;
9120 } else {
9121
9122
9123
9124 fi->type = ARMFault_Translation;
9125 goto do_fault;
9126 }
9127 } else {
9128 phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
9129 *page_size = 0x400;
9130 }
9131 ap = (desc >> 4) & 3;
9132 break;
9133 default:
9134
9135 abort();
9136 }
9137 }
9138 *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
9139 *prot |= *prot ? PAGE_EXEC : 0;
9140 if (!(*prot & (1 << access_type))) {
9141
9142 fi->type = ARMFault_Permission;
9143 goto do_fault;
9144 }
9145 *phys_ptr = phys_addr;
9146 return false;
9147do_fault:
9148 fi->domain = domain;
9149 fi->level = level;
9150 return true;
9151}
9152
9153static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
9154 MMUAccessType access_type, ARMMMUIdx mmu_idx,
9155 hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
9156 target_ulong *page_size, ARMMMUFaultInfo *fi)
9157{
9158 CPUState *cs = env_cpu(env);
9159 int level = 1;
9160 uint32_t table;
9161 uint32_t desc;
9162 uint32_t xn;
9163 uint32_t pxn = 0;
9164 int type;
9165 int ap;
9166 int domain = 0;
9167 int domain_prot;
9168 hwaddr phys_addr;
9169 uint32_t dacr;
9170 bool ns;
9171
9172
9173
9174 if (!get_level1_table_address(env, mmu_idx, &table, address)) {
9175
9176 fi->type = ARMFault_Translation;
9177 goto do_fault;
9178 }
9179 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
9180 mmu_idx, fi);
9181 if (fi->type != ARMFault_None) {
9182 goto do_fault;
9183 }
9184 type = (desc & 3);
9185 if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) {
9186
9187
9188
9189 fi->type = ARMFault_Translation;
9190 goto do_fault;
9191 }
9192 if ((type == 1) || !(desc & (1 << 18))) {
9193
9194 domain = (desc >> 5) & 0x0f;
9195 }
9196 if (regime_el(env, mmu_idx) == 1) {
9197 dacr = env->cp15.dacr_ns;
9198 } else {
9199 dacr = env->cp15.dacr_s;
9200 }
9201 if (type == 1) {
9202 level = 2;
9203 }
9204 domain_prot = (dacr >> (domain * 2)) & 3;
9205 if (domain_prot == 0 || domain_prot == 2) {
9206
9207 fi->type = ARMFault_Domain;
9208 goto do_fault;
9209 }
9210 if (type != 1) {
9211 if (desc & (1 << 18)) {
9212
9213 phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
9214 phys_addr |= (uint64_t)extract32(desc, 20, 4) << 32;
9215 phys_addr |= (uint64_t)extract32(desc, 5, 4) << 36;
9216 *page_size = 0x1000000;
9217 } else {
9218
9219 phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
9220 *page_size = 0x100000;
9221 }
9222 ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
9223 xn = desc & (1 << 4);
9224 pxn = desc & 1;
9225 ns = extract32(desc, 19, 1);
9226 } else {
9227 if (arm_feature(env, ARM_FEATURE_PXN)) {
9228 pxn = (desc >> 2) & 1;
9229 }
9230 ns = extract32(desc, 3, 1);
9231
9232 table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
9233 desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
9234 mmu_idx, fi);
9235 if (fi->type != ARMFault_None) {
9236 goto do_fault;
9237 }
9238 ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
9239 switch (desc & 3) {
9240 case 0:
9241 fi->type = ARMFault_Translation;
9242 goto do_fault;
9243 case 1:
9244 phys_addr = (desc & 0xffff0000) | (address & 0xffff);
9245 xn = desc & (1 << 15);
9246 *page_size = 0x10000;
9247 break;
9248 case 2: case 3:
9249 phys_addr = (desc & 0xfffff000) | (address & 0xfff);
9250 xn = desc & 1;
9251 *page_size = 0x1000;
9252 break;
9253 default:
9254
9255 abort();
9256 }
9257 }
9258 if (domain_prot == 3) {
9259 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
9260 } else {
9261 if (pxn && !regime_is_user(env, mmu_idx)) {
9262 xn = 1;
9263 }
9264 if (xn && access_type == MMU_INST_FETCH) {
9265 fi->type = ARMFault_Permission;
9266 goto do_fault;
9267 }
9268
9269 if (arm_feature(env, ARM_FEATURE_V6K) &&
9270 (regime_sctlr(env, mmu_idx) & SCTLR_AFE)) {
9271
9272 if ((ap & 1) == 0) {
9273
9274 fi->type = ARMFault_AccessFlag;
9275 goto do_fault;
9276 }
9277 *prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
9278 } else {
9279 *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
9280 }
9281 if (*prot && !xn) {
9282 *prot |= PAGE_EXEC;
9283 }
9284 if (!(*prot & (1 << access_type))) {
9285
9286 fi->type = ARMFault_Permission;
9287 goto do_fault;
9288 }
9289 }
9290 if (ns) {
9291
9292
9293
9294
9295 attrs->secure = false;
9296 }
9297 *phys_ptr = phys_addr;
9298 return false;
9299do_fault:
9300 fi->domain = domain;
9301 fi->level = level;
9302 return true;
9303}
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
9317 int inputsize, int stride)
9318{
9319 const int grainsize = stride + 3;
9320 int startsizecheck;
9321
9322
9323 if (level < 0) {
9324 return false;
9325 }
9326
9327 startsizecheck = inputsize - ((3 - level) * stride + grainsize);
9328 if (startsizecheck < 1 || startsizecheck > stride + 4) {
9329 return false;
9330 }
9331
9332 if (is_aa64) {
9333 CPUARMState *env = &cpu->env;
9334 unsigned int pamax = arm_pamax(cpu);
9335
9336 switch (stride) {
9337 case 13:
9338 if (level == 0 || (level == 1 && pamax <= 42)) {
9339 return false;
9340 }
9341 break;
9342 case 11:
9343 if (level == 0 || (level == 1 && pamax <= 40)) {
9344 return false;
9345 }
9346 break;
9347 case 9:
9348 if (level == 0 && pamax <= 42) {
9349 return false;
9350 }
9351 break;
9352 default:
9353 g_assert_not_reached();
9354 }
9355
9356
9357 if (inputsize > pamax &&
9358 (arm_el_is_aa64(env, 1) || inputsize > 40)) {
9359
9360 return false;
9361 }
9362 } else {
9363
9364 assert(stride == 9);
9365
9366 if (level == 0) {
9367 return false;
9368 }
9369 }
9370 return true;
9371}
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
9382{
9383 uint8_t hiattr = extract32(s2attrs, 2, 2);
9384 uint8_t loattr = extract32(s2attrs, 0, 2);
9385 uint8_t hihint = 0, lohint = 0;
9386
9387 if (hiattr != 0) {
9388 if ((env->cp15.hcr_el2 & HCR_CD) != 0) {
9389 hiattr = loattr = 1;
9390 } else {
9391 if (hiattr != 1) {
9392 hihint = 3;
9393 }
9394 if (loattr != 1) {
9395 lohint = 3;
9396 }
9397 }
9398 }
9399
9400 return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
9401}
9402#endif
9403
9404ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
9405 ARMMMUIdx mmu_idx)
9406{
9407 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
9408 uint32_t el = regime_el(env, mmu_idx);
9409 bool tbi, tbid, epd, hpd, using16k, using64k;
9410 int select, tsz;
9411
9412
9413
9414
9415
9416 select = extract64(va, 55, 1);
9417
9418 if (el > 1) {
9419 tsz = extract32(tcr, 0, 6);
9420 using64k = extract32(tcr, 14, 1);
9421 using16k = extract32(tcr, 15, 1);
9422 if (mmu_idx == ARMMMUIdx_S2NS) {
9423
9424 tbi = tbid = hpd = false;
9425 } else {
9426 tbi = extract32(tcr, 20, 1);
9427 hpd = extract32(tcr, 24, 1);
9428 tbid = extract32(tcr, 29, 1);
9429 }
9430 epd = false;
9431 } else if (!select) {
9432 tsz = extract32(tcr, 0, 6);
9433 epd = extract32(tcr, 7, 1);
9434 using64k = extract32(tcr, 14, 1);
9435 using16k = extract32(tcr, 15, 1);
9436 tbi = extract64(tcr, 37, 1);
9437 hpd = extract64(tcr, 41, 1);
9438 tbid = extract64(tcr, 51, 1);
9439 } else {
9440 int tg = extract32(tcr, 30, 2);
9441 using16k = tg == 1;
9442 using64k = tg == 3;
9443 tsz = extract32(tcr, 16, 6);
9444 epd = extract32(tcr, 23, 1);
9445 tbi = extract64(tcr, 38, 1);
9446 hpd = extract64(tcr, 42, 1);
9447 tbid = extract64(tcr, 52, 1);
9448 }
9449 tsz = MIN(tsz, 39);
9450 tsz = MAX(tsz, 16);
9451
9452 return (ARMVAParameters) {
9453 .tsz = tsz,
9454 .select = select,
9455 .tbi = tbi,
9456 .tbid = tbid,
9457 .epd = epd,
9458 .hpd = hpd,
9459 .using16k = using16k,
9460 .using64k = using64k,
9461 };
9462}
9463
9464ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
9465 ARMMMUIdx mmu_idx, bool data)
9466{
9467 ARMVAParameters ret = aa64_va_parameters_both(env, va, mmu_idx);
9468
9469
9470 ret.tbi &= (data || !ret.tbid);
9471 return ret;
9472}
9473
9474#ifndef CONFIG_USER_ONLY
9475static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
9476 ARMMMUIdx mmu_idx)
9477{
9478 uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
9479 uint32_t el = regime_el(env, mmu_idx);
9480 int select, tsz;
9481 bool epd, hpd;
9482
9483 if (mmu_idx == ARMMMUIdx_S2NS) {
9484
9485 bool sext = extract32(tcr, 4, 1);
9486 bool sign = extract32(tcr, 3, 1);
9487
9488
9489
9490
9491
9492 if (sign != sext) {
9493 qemu_log_mask(LOG_GUEST_ERROR,
9494 "AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
9495 }
9496 tsz = sextract32(tcr, 0, 4) + 8;
9497 select = 0;
9498 hpd = false;
9499 epd = false;
9500 } else if (el == 2) {
9501
9502 tsz = extract32(tcr, 0, 3);
9503 select = 0;
9504 hpd = extract64(tcr, 24, 1);
9505 epd = false;
9506 } else {
9507 int t0sz = extract32(tcr, 0, 3);
9508 int t1sz = extract32(tcr, 16, 3);
9509
9510 if (t1sz == 0) {
9511 select = va > (0xffffffffu >> t0sz);
9512 } else {
9513
9514 select = va >= ~(0xffffffffu >> t1sz);
9515 }
9516 if (!select) {
9517 tsz = t0sz;
9518 epd = extract32(tcr, 7, 1);
9519 hpd = extract64(tcr, 41, 1);
9520 } else {
9521 tsz = t1sz;
9522 epd = extract32(tcr, 23, 1);
9523 hpd = extract64(tcr, 42, 1);
9524 }
9525
9526 hpd &= extract32(tcr, 6, 1);
9527 }
9528
9529 return (ARMVAParameters) {
9530 .tsz = tsz,
9531 .select = select,
9532 .epd = epd,
9533 .hpd = hpd,
9534 };
9535}
9536
9537static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
9538 MMUAccessType access_type, ARMMMUIdx mmu_idx,
9539 hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
9540 target_ulong *page_size_ptr,
9541 ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
9542{
9543 ARMCPU *cpu = env_archcpu(env);
9544 CPUState *cs = CPU(cpu);
9545
9546 ARMFaultType fault_type = ARMFault_Translation;
9547 uint32_t level;
9548 ARMVAParameters param;
9549 uint64_t ttbr;
9550 hwaddr descaddr, indexmask, indexmask_grainsize;
9551 uint32_t tableattrs;
9552 target_ulong page_size;
9553 uint32_t attrs;
9554 int32_t stride;
9555 int addrsize, inputsize;
9556 TCR *tcr = regime_tcr(env, mmu_idx);
9557 int ap, ns, xn, pxn;
9558 uint32_t el = regime_el(env, mmu_idx);
9559 bool ttbr1_valid;
9560 uint64_t descaddrmask;
9561 bool aarch64 = arm_el_is_aa64(env, el);
9562 bool guarded = false;
9563
9564
9565
9566
9567
9568
9569
9570 if (aarch64) {
9571 param = aa64_va_parameters(env, address, mmu_idx,
9572 access_type != MMU_INST_FETCH);
9573 level = 0;
9574
9575
9576
9577 ttbr1_valid = (el < 2);
9578 addrsize = 64 - 8 * param.tbi;
9579 inputsize = 64 - param.tsz;
9580 } else {
9581 param = aa32_va_parameters(env, address, mmu_idx);
9582 level = 1;
9583
9584 ttbr1_valid = (el != 2);
9585 addrsize = (mmu_idx == ARMMMUIdx_S2NS ? 40 : 32);
9586 inputsize = addrsize - param.tsz;
9587 }
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598 if (inputsize < addrsize) {
9599 target_ulong top_bits = sextract64(address, inputsize,
9600 addrsize - inputsize);
9601 if (-top_bits != param.select || (param.select && !ttbr1_valid)) {
9602
9603 fault_type = ARMFault_Translation;
9604 goto do_fault;
9605 }
9606 }
9607
9608 if (param.using64k) {
9609 stride = 13;
9610 } else if (param.using16k) {
9611 stride = 11;
9612 } else {
9613 stride = 9;
9614 }
9615
9616
9617
9618
9619
9620
9621
9622
9623 ttbr = regime_ttbr(env, mmu_idx, param.select);
9624
9625
9626
9627
9628
9629 if (param.epd) {
9630
9631
9632
9633 goto do_fault;
9634 }
9635
9636 if (mmu_idx != ARMMMUIdx_S2NS) {
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648 level = 4 - (inputsize - 4) / stride;
9649 } else {
9650
9651
9652
9653 uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2);
9654 uint32_t startlevel;
9655 bool ok;
9656
9657 if (!aarch64 || stride == 9) {
9658
9659 startlevel = 2 - sl0;
9660 } else {
9661
9662 startlevel = 3 - sl0;
9663 }
9664
9665
9666 ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
9667 inputsize, stride);
9668 if (!ok) {
9669 fault_type = ARMFault_Translation;
9670 goto do_fault;
9671 }
9672 level = startlevel;
9673 }
9674
9675 indexmask_grainsize = (1ULL << (stride + 3)) - 1;
9676 indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
9677
9678
9679 descaddr = extract64(ttbr, 0, 48);
9680 descaddr &= ~indexmask;
9681
9682
9683
9684
9685
9686
9687 descaddrmask = ((1ull << (aarch64 ? 48 : 40)) - 1) &
9688 ~indexmask_grainsize;
9689
9690
9691
9692
9693
9694
9695 tableattrs = regime_is_secure(env, mmu_idx) ? 0 : (1 << 4);
9696 for (;;) {
9697 uint64_t descriptor;
9698 bool nstable;
9699
9700 descaddr |= (address >> (stride * (4 - level))) & indexmask;
9701 descaddr &= ~7ULL;
9702 nstable = extract32(tableattrs, 4, 1);
9703 descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fi);
9704 if (fi->type != ARMFault_None) {
9705 goto do_fault;
9706 }
9707
9708 if (!(descriptor & 1) ||
9709 (!(descriptor & 2) && (level == 3))) {
9710
9711 goto do_fault;
9712 }
9713 descaddr = descriptor & descaddrmask;
9714
9715 if ((descriptor & 2) && (level < 3)) {
9716
9717
9718
9719
9720
9721 tableattrs |= extract64(descriptor, 59, 5);
9722 level++;
9723 indexmask = indexmask_grainsize;
9724 continue;
9725 }
9726
9727
9728
9729
9730 page_size = (1ULL << ((stride * (4 - level)) + 3));
9731 descaddr |= (address & (page_size - 1));
9732
9733 attrs = extract64(descriptor, 2, 10)
9734 | (extract64(descriptor, 52, 12) << 10);
9735
9736 if (mmu_idx == ARMMMUIdx_S2NS) {
9737
9738 break;
9739 }
9740
9741 attrs |= nstable << 3;
9742 guarded = extract64(descriptor, 50, 1);
9743 if (param.hpd) {
9744
9745 break;
9746 }
9747 attrs |= extract32(tableattrs, 0, 2) << 11;
9748
9749
9750
9751 attrs &= ~(extract32(tableattrs, 2, 1) << 4);
9752 attrs |= extract32(tableattrs, 3, 1) << 5;
9753 break;
9754 }
9755
9756
9757
9758 fault_type = ARMFault_AccessFlag;
9759 if ((attrs & (1 << 8)) == 0) {
9760
9761 goto do_fault;
9762 }
9763
9764 ap = extract32(attrs, 4, 2);
9765 xn = extract32(attrs, 12, 1);
9766
9767 if (mmu_idx == ARMMMUIdx_S2NS) {
9768 ns = true;
9769 *prot = get_S2prot(env, ap, xn);
9770 } else {
9771 ns = extract32(attrs, 3, 1);
9772 pxn = extract32(attrs, 11, 1);
9773 *prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
9774 }
9775
9776 fault_type = ARMFault_Permission;
9777 if (!(*prot & (1 << access_type))) {
9778 goto do_fault;
9779 }
9780
9781 if (ns) {
9782
9783
9784
9785
9786 txattrs->secure = false;
9787 }
9788
9789 if (aarch64 && guarded && cpu_isar_feature(aa64_bti, cpu)) {
9790 txattrs->target_tlb_bit0 = true;
9791 }
9792
9793 if (cacheattrs != NULL) {
9794 if (mmu_idx == ARMMMUIdx_S2NS) {
9795 cacheattrs->attrs = convert_stage2_attrs(env,
9796 extract32(attrs, 0, 4));
9797 } else {
9798
9799 uint8_t attrindx = extract32(attrs, 0, 3);
9800 uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
9801 assert(attrindx <= 7);
9802 cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
9803 }
9804 cacheattrs->shareability = extract32(attrs, 6, 2);
9805 }
9806
9807 *phys_ptr = descaddr;
9808 *page_size_ptr = page_size;
9809 return false;
9810
9811do_fault:
9812 fi->type = fault_type;
9813 fi->level = level;
9814
9815 fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_S2NS);
9816 return true;
9817}
9818
9819static inline void get_phys_addr_pmsav7_default(CPUARMState *env,
9820 ARMMMUIdx mmu_idx,
9821 int32_t address, int *prot)
9822{
9823 if (!arm_feature(env, ARM_FEATURE_M)) {
9824 *prot = PAGE_READ | PAGE_WRITE;
9825 switch (address) {
9826 case 0xF0000000 ... 0xFFFFFFFF:
9827 if (regime_sctlr(env, mmu_idx) & SCTLR_V) {
9828
9829 *prot |= PAGE_EXEC;
9830 }
9831 break;
9832 case 0x00000000 ... 0x7FFFFFFF:
9833 *prot |= PAGE_EXEC;
9834 break;
9835 }
9836 } else {
9837
9838
9839
9840
9841 switch (address) {
9842 case 0x00000000 ... 0x1fffffff:
9843 case 0x20000000 ... 0x3fffffff:
9844 case 0x60000000 ... 0x7fffffff:
9845 case 0x80000000 ... 0x9fffffff:
9846 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
9847 break;
9848 case 0x40000000 ... 0x5fffffff:
9849 case 0xa0000000 ... 0xbfffffff:
9850 case 0xc0000000 ... 0xdfffffff:
9851 case 0xe0000000 ... 0xffffffff:
9852 *prot = PAGE_READ | PAGE_WRITE;
9853 break;
9854 default:
9855 g_assert_not_reached();
9856 }
9857 }
9858}
9859
9860static bool pmsav7_use_background_region(ARMCPU *cpu,
9861 ARMMMUIdx mmu_idx, bool is_user)
9862{
9863
9864
9865
9866 CPUARMState *env = &cpu->env;
9867
9868 if (is_user) {
9869 return false;
9870 }
9871
9872 if (arm_feature(env, ARM_FEATURE_M)) {
9873 return env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)]
9874 & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
9875 } else {
9876 return regime_sctlr(env, mmu_idx) & SCTLR_BR;
9877 }
9878}
9879
9880static inline bool m_is_ppb_region(CPUARMState *env, uint32_t address)
9881{
9882
9883 return arm_feature(env, ARM_FEATURE_M) &&
9884 extract32(address, 20, 12) == 0xe00;
9885}
9886
9887static inline bool m_is_system_region(CPUARMState *env, uint32_t address)
9888{
9889
9890
9891
9892 return arm_feature(env, ARM_FEATURE_M) && extract32(address, 29, 3) == 0x7;
9893}
9894
9895static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
9896 MMUAccessType access_type, ARMMMUIdx mmu_idx,
9897 hwaddr *phys_ptr, int *prot,
9898 target_ulong *page_size,
9899 ARMMMUFaultInfo *fi)
9900{
9901 ARMCPU *cpu = env_archcpu(env);
9902 int n;
9903 bool is_user = regime_is_user(env, mmu_idx);
9904
9905 *phys_ptr = address;
9906 *page_size = TARGET_PAGE_SIZE;
9907 *prot = 0;
9908
9909 if (regime_translation_disabled(env, mmu_idx) ||
9910 m_is_ppb_region(env, address)) {
9911
9912
9913
9914
9915
9916
9917
9918 get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
9919 } else {
9920 for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
9921
9922 uint32_t base = env->pmsav7.drbar[n];
9923 uint32_t rsize = extract32(env->pmsav7.drsr[n], 1, 5);
9924 uint32_t rmask;
9925 bool srdis = false;
9926
9927 if (!(env->pmsav7.drsr[n] & 0x1)) {
9928 continue;
9929 }
9930
9931 if (!rsize) {
9932 qemu_log_mask(LOG_GUEST_ERROR,
9933 "DRSR[%d]: Rsize field cannot be 0\n", n);
9934 continue;
9935 }
9936 rsize++;
9937 rmask = (1ull << rsize) - 1;
9938
9939 if (base & rmask) {
9940 qemu_log_mask(LOG_GUEST_ERROR,
9941 "DRBAR[%d]: 0x%" PRIx32 " misaligned "
9942 "to DRSR region size, mask = 0x%" PRIx32 "\n",
9943 n, base, rmask);
9944 continue;
9945 }
9946
9947 if (address < base || address > base + rmask) {
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957 if (ranges_overlap(base, rmask,
9958 address & TARGET_PAGE_MASK,
9959 TARGET_PAGE_SIZE)) {
9960 *page_size = 1;
9961 }
9962 continue;
9963 }
9964
9965
9966
9967 if (rsize >= 8) {
9968 int i, snd;
9969 uint32_t srdis_mask;
9970
9971 rsize -= 3;
9972 snd = ((address - base) >> rsize) & 0x7;
9973 srdis = extract32(env->pmsav7.drsr[n], snd + 8, 1);
9974
9975 srdis_mask = srdis ? 0x3 : 0x0;
9976 for (i = 2; i <= 8 && rsize < TARGET_PAGE_BITS; i *= 2) {
9977
9978
9979
9980
9981
9982
9983 int snd_rounded = snd & ~(i - 1);
9984 uint32_t srdis_multi = extract32(env->pmsav7.drsr[n],
9985 snd_rounded + 8, i);
9986 if (srdis_mask ^ srdis_multi) {
9987 break;
9988 }
9989 srdis_mask = (srdis_mask << i) | srdis_mask;
9990 rsize++;
9991 }
9992 }
9993 if (srdis) {
9994 continue;
9995 }
9996 if (rsize < TARGET_PAGE_BITS) {
9997 *page_size = 1 << rsize;
9998 }
9999 break;
10000 }
10001
10002 if (n == -1) {
10003 if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
10004
10005 fi->type = ARMFault_Background;
10006 return true;
10007 }
10008 get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
10009 } else {
10010 uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3);
10011 uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1);
10012
10013 if (m_is_system_region(env, address)) {
10014
10015 xn = 1;
10016 }
10017
10018 if (is_user) {
10019 switch (ap) {
10020 case 0:
10021 case 1:
10022 case 5:
10023 break;
10024 case 3:
10025 *prot |= PAGE_WRITE;
10026
10027 case 2:
10028 case 6:
10029 *prot |= PAGE_READ | PAGE_EXEC;
10030 break;
10031 case 7:
10032
10033 if (arm_feature(env, ARM_FEATURE_M)) {
10034 *prot |= PAGE_READ | PAGE_EXEC;
10035 break;
10036 }
10037
10038 default:
10039 qemu_log_mask(LOG_GUEST_ERROR,
10040 "DRACR[%d]: Bad value for AP bits: 0x%"
10041 PRIx32 "\n", n, ap);
10042 }
10043 } else {
10044 switch (ap) {
10045 case 0:
10046 break;
10047 case 1:
10048 case 2:
10049 case 3:
10050 *prot |= PAGE_WRITE;
10051
10052 case 5:
10053 case 6:
10054 *prot |= PAGE_READ | PAGE_EXEC;
10055 break;
10056 case 7:
10057
10058 if (arm_feature(env, ARM_FEATURE_M)) {
10059 *prot |= PAGE_READ | PAGE_EXEC;
10060 break;
10061 }
10062
10063 default:
10064 qemu_log_mask(LOG_GUEST_ERROR,
10065 "DRACR[%d]: Bad value for AP bits: 0x%"
10066 PRIx32 "\n", n, ap);
10067 }
10068 }
10069
10070
10071 if (xn) {
10072 *prot &= ~PAGE_EXEC;
10073 }
10074 }
10075 }
10076
10077 fi->type = ARMFault_Permission;
10078 fi->level = 1;
10079 return !(*prot & (1 << access_type));
10080}
10081
10082static bool v8m_is_sau_exempt(CPUARMState *env,
10083 uint32_t address, MMUAccessType access_type)
10084{
10085
10086
10087
10088 return
10089 (access_type == MMU_INST_FETCH && m_is_system_region(env, address)) ||
10090 (address >= 0xe0000000 && address <= 0xe0002fff) ||
10091 (address >= 0xe000e000 && address <= 0xe000efff) ||
10092 (address >= 0xe002e000 && address <= 0xe002efff) ||
10093 (address >= 0xe0040000 && address <= 0xe0041fff) ||
10094 (address >= 0xe00ff000 && address <= 0xe00fffff);
10095}
10096
10097void v8m_security_lookup(CPUARMState *env, uint32_t address,
10098 MMUAccessType access_type, ARMMMUIdx mmu_idx,
10099 V8M_SAttributes *sattrs)
10100{
10101
10102
10103
10104
10105 ARMCPU *cpu = env_archcpu(env);
10106 int r;
10107 bool idau_exempt = false, idau_ns = true, idau_nsc = true;
10108 int idau_region = IREGION_NOTVALID;
10109 uint32_t addr_page_base = address & TARGET_PAGE_MASK;
10110 uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
10111
10112 if (cpu->idau) {
10113 IDAUInterfaceClass *iic = IDAU_INTERFACE_GET_CLASS(cpu->idau);
10114 IDAUInterface *ii = IDAU_INTERFACE(cpu->idau);
10115
10116 iic->check(ii, address, &idau_region, &idau_exempt, &idau_ns,
10117 &idau_nsc);
10118 }
10119
10120 if (access_type == MMU_INST_FETCH && extract32(address, 28, 4) == 0xf) {
10121
10122 return;
10123 }
10124
10125 if (idau_exempt || v8m_is_sau_exempt(env, address, access_type)) {
10126 sattrs->ns = !regime_is_secure(env, mmu_idx);
10127 return;
10128 }
10129
10130 if (idau_region != IREGION_NOTVALID) {
10131 sattrs->irvalid = true;
10132 sattrs->iregion = idau_region;
10133 }
10134
10135 switch (env->sau.ctrl & 3) {
10136 case 0:
10137 break;
10138 case 2:
10139 sattrs->ns = true;
10140 break;
10141 default:
10142 for (r = 0; r < cpu->sau_sregion; r++) {
10143 if (env->sau.rlar[r] & 1) {
10144 uint32_t base = env->sau.rbar[r] & ~0x1f;
10145 uint32_t limit = env->sau.rlar[r] | 0x1f;
10146
10147 if (base <= address && limit >= address) {
10148 if (base > addr_page_base || limit < addr_page_limit) {
10149 sattrs->subpage = true;
10150 }
10151 if (sattrs->srvalid) {
10152
10153
10154
10155
10156 sattrs->ns = false;
10157 sattrs->nsc = false;
10158 sattrs->sregion = 0;
10159 sattrs->srvalid = false;
10160 break;
10161 } else {
10162 if (env->sau.rlar[r] & 2) {
10163 sattrs->nsc = true;
10164 } else {
10165 sattrs->ns = true;
10166 }
10167 sattrs->srvalid = true;
10168 sattrs->sregion = r;
10169 }
10170 } else {
10171
10172
10173
10174
10175
10176
10177
10178
10179
10180 if (limit >= base &&
10181 ranges_overlap(base, limit - base + 1,
10182 addr_page_base,
10183 TARGET_PAGE_SIZE)) {
10184 sattrs->subpage = true;
10185 }
10186 }
10187 }
10188 }
10189 break;
10190 }
10191
10192
10193
10194
10195
10196 if (!idau_ns) {
10197 if (sattrs->ns || (!idau_nsc && sattrs->nsc)) {
10198 sattrs->ns = false;
10199 sattrs->nsc = idau_nsc;
10200 }
10201 }
10202}
10203
10204bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
10205 MMUAccessType access_type, ARMMMUIdx mmu_idx,
10206 hwaddr *phys_ptr, MemTxAttrs *txattrs,
10207 int *prot, bool *is_subpage,
10208 ARMMMUFaultInfo *fi, uint32_t *mregion)
10209{
10210
10211
10212
10213
10214
10215
10216
10217
10218 ARMCPU *cpu = env_archcpu(env);
10219 bool is_user = regime_is_user(env, mmu_idx);
10220 uint32_t secure = regime_is_secure(env, mmu_idx);
10221 int n;
10222 int matchregion = -1;
10223 bool hit = false;
10224 uint32_t addr_page_base = address & TARGET_PAGE_MASK;
10225 uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
10226
10227 *is_subpage = false;
10228 *phys_ptr = address;
10229 *prot = 0;
10230 if (mregion) {
10231 *mregion = -1;
10232 }
10233
10234
10235
10236
10237
10238
10239
10240 if (regime_translation_disabled(env, mmu_idx)) {
10241 hit = true;
10242 } else if (m_is_ppb_region(env, address)) {
10243 hit = true;
10244 } else {
10245 if (pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
10246 hit = true;
10247 }
10248
10249 for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
10250
10251
10252
10253
10254
10255 uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
10256 uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
10257
10258 if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
10259
10260 continue;
10261 }
10262
10263 if (address < base || address > limit) {
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273 if (limit >= base &&
10274 ranges_overlap(base, limit - base + 1,
10275 addr_page_base,
10276 TARGET_PAGE_SIZE)) {
10277 *is_subpage = true;
10278 }
10279 continue;
10280 }
10281
10282 if (base > addr_page_base || limit < addr_page_limit) {
10283 *is_subpage = true;
10284 }
10285
10286 if (matchregion != -1) {
10287
10288
10289
10290 fi->type = ARMFault_Permission;
10291 fi->level = 1;
10292 return true;
10293 }
10294
10295 matchregion = n;
10296 hit = true;
10297 }
10298 }
10299
10300 if (!hit) {
10301
10302 fi->type = ARMFault_Background;
10303 return true;
10304 }
10305
10306 if (matchregion == -1) {
10307
10308 get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
10309 } else {
10310 uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
10311 uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
10312
10313 if (m_is_system_region(env, address)) {
10314
10315 xn = 1;
10316 }
10317
10318 *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
10319 if (*prot && !xn) {
10320 *prot |= PAGE_EXEC;
10321 }
10322
10323
10324
10325 if (mregion) {
10326 *mregion = matchregion;
10327 }
10328 }
10329
10330 fi->type = ARMFault_Permission;
10331 fi->level = 1;
10332 return !(*prot & (1 << access_type));
10333}
10334
10335
10336static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
10337 MMUAccessType access_type, ARMMMUIdx mmu_idx,
10338 hwaddr *phys_ptr, MemTxAttrs *txattrs,
10339 int *prot, target_ulong *page_size,
10340 ARMMMUFaultInfo *fi)
10341{
10342 uint32_t secure = regime_is_secure(env, mmu_idx);
10343 V8M_SAttributes sattrs = {};
10344 bool ret;
10345 bool mpu_is_subpage;
10346
10347 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
10348 v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
10349 if (access_type == MMU_INST_FETCH) {
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367 if (sattrs.ns != !secure) {
10368 if (sattrs.nsc) {
10369 fi->type = ARMFault_QEMU_NSCExec;
10370 } else {
10371 fi->type = ARMFault_QEMU_SFault;
10372 }
10373 *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
10374 *phys_ptr = address;
10375 *prot = 0;
10376 return true;
10377 }
10378 } else {
10379
10380
10381
10382
10383 if (sattrs.ns) {
10384 txattrs->secure = false;
10385 } else if (!secure) {
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395 fi->type = ARMFault_QEMU_SFault;
10396 *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
10397 *phys_ptr = address;
10398 *prot = 0;
10399 return true;
10400 }
10401 }
10402 }
10403
10404 ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
10405 txattrs, prot, &mpu_is_subpage, fi, NULL);
10406 *page_size = sattrs.subpage || mpu_is_subpage ? 1 : TARGET_PAGE_SIZE;
10407 return ret;
10408}
10409
10410static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
10411 MMUAccessType access_type, ARMMMUIdx mmu_idx,
10412 hwaddr *phys_ptr, int *prot,
10413 ARMMMUFaultInfo *fi)
10414{
10415 int n;
10416 uint32_t mask;
10417 uint32_t base;
10418 bool is_user = regime_is_user(env, mmu_idx);
10419
10420 if (regime_translation_disabled(env, mmu_idx)) {
10421
10422 *phys_ptr = address;
10423 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
10424 return false;
10425 }
10426
10427 *phys_ptr = address;
10428 for (n = 7; n >= 0; n--) {
10429 base = env->cp15.c6_region[n];
10430 if ((base & 1) == 0) {
10431 continue;
10432 }
10433 mask = 1 << ((base >> 1) & 0x1f);
10434
10435
10436 mask = (mask << 1) - 1;
10437 if (((base ^ address) & ~mask) == 0) {
10438 break;
10439 }
10440 }
10441 if (n < 0) {
10442 fi->type = ARMFault_Background;
10443 return true;
10444 }
10445
10446 if (access_type == MMU_INST_FETCH) {
10447 mask = env->cp15.pmsav5_insn_ap;
10448 } else {
10449 mask = env->cp15.pmsav5_data_ap;
10450 }
10451 mask = (mask >> (n * 4)) & 0xf;
10452 switch (mask) {
10453 case 0:
10454 fi->type = ARMFault_Permission;
10455 fi->level = 1;
10456 return true;
10457 case 1:
10458 if (is_user) {
10459 fi->type = ARMFault_Permission;
10460 fi->level = 1;
10461 return true;
10462 }
10463 *prot = PAGE_READ | PAGE_WRITE;
10464 break;
10465 case 2:
10466 *prot = PAGE_READ;
10467 if (!is_user) {
10468 *prot |= PAGE_WRITE;
10469 }
10470 break;
10471 case 3:
10472 *prot = PAGE_READ | PAGE_WRITE;
10473 break;
10474 case 5:
10475 if (is_user) {
10476 fi->type = ARMFault_Permission;
10477 fi->level = 1;
10478 return true;
10479 }
10480 *prot = PAGE_READ;
10481 break;
10482 case 6:
10483 *prot = PAGE_READ;
10484 break;
10485 default:
10486
10487 fi->type = ARMFault_Permission;
10488 fi->level = 1;
10489 return true;
10490 }
10491 *prot |= PAGE_EXEC;
10492 return false;
10493}
10494
10495
10496
10497
10498
10499
10500
10501
10502static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2)
10503{
10504 if (s1 == 4 || s2 == 4) {
10505
10506 return 4;
10507 } else if (extract32(s1, 2, 2) == 0 || extract32(s1, 2, 2) == 2) {
10508
10509 return s1;
10510 } else if (extract32(s2, 2, 2) == 2) {
10511
10512
10513
10514 return (2 << 2) | extract32(s1, 0, 2);
10515 } else {
10516 return s1;
10517 }
10518}
10519
10520
10521
10522
10523
10524
10525
10526static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2)
10527{
10528 uint8_t s1lo = extract32(s1.attrs, 0, 4), s2lo = extract32(s2.attrs, 0, 4);
10529 uint8_t s1hi = extract32(s1.attrs, 4, 4), s2hi = extract32(s2.attrs, 4, 4);
10530 ARMCacheAttrs ret;
10531
10532
10533 if (s1.shareability == 2 || s2.shareability == 2) {
10534
10535 ret.shareability = 2;
10536 } else if (s1.shareability == 3 || s2.shareability == 3) {
10537
10538 ret.shareability = 3;
10539 } else {
10540
10541 ret.shareability = 0;
10542 }
10543
10544
10545 if (s1hi == 0 || s2hi == 0) {
10546
10547 if (s1lo == 0 || s2lo == 0) {
10548
10549 ret.attrs = 0;
10550 } else if (s1lo == 4 || s2lo == 4) {
10551
10552 ret.attrs = 4;
10553 } else if (s1lo == 8 || s2lo == 8) {
10554
10555 ret.attrs = 8;
10556 } else {
10557 ret.attrs = 0xc;
10558 }
10559
10560
10561
10562
10563 ret.shareability = 2;
10564 } else {
10565
10566 ret.attrs = combine_cacheattr_nibble(s1hi, s2hi) << 4
10567 | combine_cacheattr_nibble(s1lo, s2lo);
10568
10569 if (ret.attrs == 0x44) {
10570
10571
10572
10573
10574 ret.shareability = 2;
10575 }
10576 }
10577
10578 return ret;
10579}
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608bool get_phys_addr(CPUARMState *env, target_ulong address,
10609 MMUAccessType access_type, ARMMMUIdx mmu_idx,
10610 hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
10611 target_ulong *page_size,
10612 ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
10613{
10614 if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
10615
10616
10617
10618 if (arm_feature(env, ARM_FEATURE_EL2)) {
10619 hwaddr ipa;
10620 int s2_prot;
10621 int ret;
10622 ARMCacheAttrs cacheattrs2 = {};
10623
10624 ret = get_phys_addr(env, address, access_type,
10625 stage_1_mmu_idx(mmu_idx), &ipa, attrs,
10626 prot, page_size, fi, cacheattrs);
10627
10628
10629 if (ret || regime_translation_disabled(env, ARMMMUIdx_S2NS)) {
10630 *phys_ptr = ipa;
10631 return ret;
10632 }
10633
10634
10635 ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_S2NS,
10636 phys_ptr, attrs, &s2_prot,
10637 page_size, fi,
10638 cacheattrs != NULL ? &cacheattrs2 : NULL);
10639 fi->s2addr = ipa;
10640
10641 *prot &= s2_prot;
10642
10643
10644 if (!ret && cacheattrs != NULL) {
10645 if (env->cp15.hcr_el2 & HCR_DC) {
10646
10647
10648
10649
10650
10651
10652 cacheattrs->attrs = 0xff;
10653 cacheattrs->shareability = 0;
10654 }
10655 *cacheattrs = combine_cacheattrs(*cacheattrs, cacheattrs2);
10656 }
10657
10658 return ret;
10659 } else {
10660
10661
10662
10663 mmu_idx = stage_1_mmu_idx(mmu_idx);
10664 }
10665 }
10666
10667
10668
10669
10670
10671 attrs->secure = regime_is_secure(env, mmu_idx);
10672 attrs->user = regime_is_user(env, mmu_idx);
10673
10674
10675
10676
10677 if (address < 0x02000000 && mmu_idx != ARMMMUIdx_S2NS
10678 && !arm_feature(env, ARM_FEATURE_V8)) {
10679 if (regime_el(env, mmu_idx) == 3) {
10680 address += env->cp15.fcseidr_s;
10681 } else {
10682 address += env->cp15.fcseidr_ns;
10683 }
10684 }
10685
10686 if (arm_feature(env, ARM_FEATURE_PMSA)) {
10687 bool ret;
10688 *page_size = TARGET_PAGE_SIZE;
10689
10690 if (arm_feature(env, ARM_FEATURE_V8)) {
10691
10692 ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
10693 phys_ptr, attrs, prot, page_size, fi);
10694 } else if (arm_feature(env, ARM_FEATURE_V7)) {
10695
10696 ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
10697 phys_ptr, prot, page_size, fi);
10698 } else {
10699
10700 ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
10701 phys_ptr, prot, fi);
10702 }
10703 qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
10704 " mmu_idx %u -> %s (prot %c%c%c)\n",
10705 access_type == MMU_DATA_LOAD ? "reading" :
10706 (access_type == MMU_DATA_STORE ? "writing" : "execute"),
10707 (uint32_t)address, mmu_idx,
10708 ret ? "Miss" : "Hit",
10709 *prot & PAGE_READ ? 'r' : '-',
10710 *prot & PAGE_WRITE ? 'w' : '-',
10711 *prot & PAGE_EXEC ? 'x' : '-');
10712
10713 return ret;
10714 }
10715
10716
10717
10718 if (regime_translation_disabled(env, mmu_idx)) {
10719
10720 *phys_ptr = address;
10721 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
10722 *page_size = TARGET_PAGE_SIZE;
10723 return 0;
10724 }
10725
10726 if (regime_using_lpae_format(env, mmu_idx)) {
10727 return get_phys_addr_lpae(env, address, access_type, mmu_idx,
10728 phys_ptr, attrs, prot, page_size,
10729 fi, cacheattrs);
10730 } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
10731 return get_phys_addr_v6(env, address, access_type, mmu_idx,
10732 phys_ptr, attrs, prot, page_size, fi);
10733 } else {
10734 return get_phys_addr_v5(env, address, access_type, mmu_idx,
10735 phys_ptr, prot, page_size, fi);
10736 }
10737}
10738
10739hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
10740 MemTxAttrs *attrs)
10741{
10742 ARMCPU *cpu = ARM_CPU(cs);
10743 CPUARMState *env = &cpu->env;
10744 hwaddr phys_addr;
10745 target_ulong page_size;
10746 int prot;
10747 bool ret;
10748 ARMMMUFaultInfo fi = {};
10749 ARMMMUIdx mmu_idx = arm_mmu_idx(env);
10750
10751 *attrs = (MemTxAttrs) {};
10752
10753 ret = get_phys_addr(env, addr, 0, mmu_idx, &phys_addr,
10754 attrs, &prot, &page_size, &fi, NULL);
10755
10756 if (ret) {
10757 return -1;
10758 }
10759 return phys_addr;
10760}
10761
10762#endif
10763
10764
10765
10766
10767
10768
10769
10770
10771static inline uint16_t add16_sat(uint16_t a, uint16_t b)
10772{
10773 uint16_t res;
10774
10775 res = a + b;
10776 if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
10777 if (a & 0x8000)
10778 res = 0x8000;
10779 else
10780 res = 0x7fff;
10781 }
10782 return res;
10783}
10784
10785
10786static inline uint8_t add8_sat(uint8_t a, uint8_t b)
10787{
10788 uint8_t res;
10789
10790 res = a + b;
10791 if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
10792 if (a & 0x80)
10793 res = 0x80;
10794 else
10795 res = 0x7f;
10796 }
10797 return res;
10798}
10799
10800
10801static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
10802{
10803 uint16_t res;
10804
10805 res = a - b;
10806 if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
10807 if (a & 0x8000)
10808 res = 0x8000;
10809 else
10810 res = 0x7fff;
10811 }
10812 return res;
10813}
10814
10815
10816static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
10817{
10818 uint8_t res;
10819
10820 res = a - b;
10821 if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
10822 if (a & 0x80)
10823 res = 0x80;
10824 else
10825 res = 0x7f;
10826 }
10827 return res;
10828}
10829
10830#define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
10831#define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
10832#define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
10833#define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
10834#define PFX q
10835
10836#include "op_addsub.h"
10837
10838
10839static inline uint16_t add16_usat(uint16_t a, uint16_t b)
10840{
10841 uint16_t res;
10842 res = a + b;
10843 if (res < a)
10844 res = 0xffff;
10845 return res;
10846}
10847
10848static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
10849{
10850 if (a > b)
10851 return a - b;
10852 else
10853 return 0;
10854}
10855
10856static inline uint8_t add8_usat(uint8_t a, uint8_t b)
10857{
10858 uint8_t res;
10859 res = a + b;
10860 if (res < a)
10861 res = 0xff;
10862 return res;
10863}
10864
10865static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
10866{
10867 if (a > b)
10868 return a - b;
10869 else
10870 return 0;
10871}
10872
10873#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
10874#define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
10875#define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
10876#define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
10877#define PFX uq
10878
10879#include "op_addsub.h"
10880
10881
10882#define SARITH16(a, b, n, op) do { \
10883 int32_t sum; \
10884 sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \
10885 RESULT(sum, n, 16); \
10886 if (sum >= 0) \
10887 ge |= 3 << (n * 2); \
10888 } while(0)
10889
10890#define SARITH8(a, b, n, op) do { \
10891 int32_t sum; \
10892 sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \
10893 RESULT(sum, n, 8); \
10894 if (sum >= 0) \
10895 ge |= 1 << n; \
10896 } while(0)
10897
10898
10899#define ADD16(a, b, n) SARITH16(a, b, n, +)
10900#define SUB16(a, b, n) SARITH16(a, b, n, -)
10901#define ADD8(a, b, n) SARITH8(a, b, n, +)
10902#define SUB8(a, b, n) SARITH8(a, b, n, -)
10903#define PFX s
10904#define ARITH_GE
10905
10906#include "op_addsub.h"
10907
10908
10909#define ADD16(a, b, n) do { \
10910 uint32_t sum; \
10911 sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
10912 RESULT(sum, n, 16); \
10913 if ((sum >> 16) == 1) \
10914 ge |= 3 << (n * 2); \
10915 } while(0)
10916
10917#define ADD8(a, b, n) do { \
10918 uint32_t sum; \
10919 sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
10920 RESULT(sum, n, 8); \
10921 if ((sum >> 8) == 1) \
10922 ge |= 1 << n; \
10923 } while(0)
10924
10925#define SUB16(a, b, n) do { \
10926 uint32_t sum; \
10927 sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
10928 RESULT(sum, n, 16); \
10929 if ((sum >> 16) == 0) \
10930 ge |= 3 << (n * 2); \
10931 } while(0)
10932
10933#define SUB8(a, b, n) do { \
10934 uint32_t sum; \
10935 sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
10936 RESULT(sum, n, 8); \
10937 if ((sum >> 8) == 0) \
10938 ge |= 1 << n; \
10939 } while(0)
10940
10941#define PFX u
10942#define ARITH_GE
10943
10944#include "op_addsub.h"
10945
10946
10947#define ADD16(a, b, n) \
10948 RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
10949#define SUB16(a, b, n) \
10950 RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
10951#define ADD8(a, b, n) \
10952 RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
10953#define SUB8(a, b, n) \
10954 RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
10955#define PFX sh
10956
10957#include "op_addsub.h"
10958
10959
10960#define ADD16(a, b, n) \
10961 RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
10962#define SUB16(a, b, n) \
10963 RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
10964#define ADD8(a, b, n) \
10965 RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
10966#define SUB8(a, b, n) \
10967 RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
10968#define PFX uh
10969
10970#include "op_addsub.h"
10971
10972static inline uint8_t do_usad(uint8_t a, uint8_t b)
10973{
10974 if (a > b)
10975 return a - b;
10976 else
10977 return b - a;
10978}
10979
10980
10981uint32_t HELPER(usad8)(uint32_t a, uint32_t b)
10982{
10983 uint32_t sum;
10984 sum = do_usad(a, b);
10985 sum += do_usad(a >> 8, b >> 8);
10986 sum += do_usad(a >> 16, b >>16);
10987 sum += do_usad(a >> 24, b >> 24);
10988 return sum;
10989}
10990
10991
10992uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
10993{
10994 uint32_t mask;
10995
10996 mask = 0;
10997 if (flags & 1)
10998 mask |= 0xff;
10999 if (flags & 2)
11000 mask |= 0xff00;
11001 if (flags & 4)
11002 mask |= 0xff0000;
11003 if (flags & 8)
11004 mask |= 0xff000000;
11005 return (a & mask) | (b & ~mask);
11006}
11007
11008
11009
11010
11011
11012uint32_t HELPER(crc32)(uint32_t acc, uint32_t val, uint32_t bytes)
11013{
11014 uint8_t buf[4];
11015
11016 stl_le_p(buf, val);
11017
11018
11019 return crc32(acc ^ 0xffffffff, buf, bytes) ^ 0xffffffff;
11020}
11021
11022uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
11023{
11024 uint8_t buf[4];
11025
11026 stl_le_p(buf, val);
11027
11028
11029 return crc32c(acc, buf, bytes) ^ 0xffffffff;
11030}
11031
11032
11033
11034
11035int fp_exception_el(CPUARMState *env, int cur_el)
11036{
11037#ifndef CONFIG_USER_ONLY
11038 int fpen;
11039
11040
11041
11042
11043 if (!arm_feature(env, ARM_FEATURE_V6)) {
11044 return 0;
11045 }
11046
11047 if (arm_feature(env, ARM_FEATURE_M)) {
11048
11049 if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
11050 return 1;
11051 }
11052
11053 if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
11054 if (!extract32(env->v7m.nsacr, 10, 1)) {
11055
11056 return 3;
11057 }
11058 }
11059
11060 return 0;
11061 }
11062
11063
11064
11065
11066
11067
11068 fpen = extract32(env->cp15.cpacr_el1, 20, 2);
11069 switch (fpen) {
11070 case 0:
11071 case 2:
11072 if (cur_el == 0 || cur_el == 1) {
11073
11074 if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
11075 return 3;
11076 }
11077 return 1;
11078 }
11079 if (cur_el == 3 && !is_a64(env)) {
11080
11081 return 3;
11082 }
11083 break;
11084 case 1:
11085 if (cur_el == 0) {
11086 return 1;
11087 }
11088 break;
11089 case 3:
11090 break;
11091 }
11092
11093
11094
11095
11096
11097
11098 if ((arm_feature(env, ARM_FEATURE_EL3) && !arm_el_is_aa64(env, 3) &&
11099 cur_el <= 2 && !arm_is_secure_below_el3(env))) {
11100 if (!extract32(env->cp15.nsacr, 10, 1)) {
11101
11102 return cur_el == 2 ? 2 : 1;
11103 }
11104 }
11105
11106
11107
11108
11109
11110
11111 if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1)
11112 && !arm_is_secure_below_el3(env)) {
11113
11114 return 2;
11115 }
11116
11117
11118 if (extract32(env->cp15.cptr_el[3], 10, 1)) {
11119
11120 return 3;
11121 }
11122#endif
11123 return 0;
11124}
11125
11126#ifndef CONFIG_TCG
11127ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
11128{
11129 g_assert_not_reached();
11130}
11131#endif
11132
11133ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
11134{
11135 if (arm_feature(env, ARM_FEATURE_M)) {
11136 return arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
11137 }
11138
11139 if (el < 2 && arm_is_secure_below_el3(env)) {
11140 return ARMMMUIdx_S1SE0 + el;
11141 } else {
11142 return ARMMMUIdx_S12NSE0 + el;
11143 }
11144}
11145
11146ARMMMUIdx arm_mmu_idx(CPUARMState *env)
11147{
11148 return arm_mmu_idx_el(env, arm_current_el(env));
11149}
11150
11151int cpu_mmu_index(CPUARMState *env, bool ifetch)
11152{
11153 return arm_to_core_mmu_idx(arm_mmu_idx(env));
11154}
11155
11156#ifndef CONFIG_USER_ONLY
11157ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
11158{
11159 return stage_1_mmu_idx(arm_mmu_idx(env));
11160}
11161#endif
11162
11163static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
11164 ARMMMUIdx mmu_idx, uint32_t flags)
11165{
11166 flags = FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el);
11167 flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX,
11168 arm_to_core_mmu_idx(mmu_idx));
11169
11170 if (arm_singlestep_active(env)) {
11171 flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
11172 }
11173 return flags;
11174}
11175
11176static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
11177 ARMMMUIdx mmu_idx, uint32_t flags)
11178{
11179 bool sctlr_b = arm_sctlr_b(env);
11180
11181 if (sctlr_b) {
11182 flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, 1);
11183 }
11184 if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
11185 flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
11186 }
11187 flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
11188
11189 return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
11190}
11191
11192static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
11193 ARMMMUIdx mmu_idx)
11194{
11195 uint32_t flags = 0;
11196
11197
11198 flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
11199
11200 if (arm_v7m_is_handler_mode(env)) {
11201 flags = FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1);
11202 }
11203
11204
11205
11206
11207
11208
11209 if (arm_feature(env, ARM_FEATURE_V8) &&
11210 !((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
11211 (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
11212 flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
11213 }
11214
11215 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
11216}
11217
11218static uint32_t rebuild_hflags_aprofile(CPUARMState *env)
11219{
11220 int flags = 0;
11221
11222 flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL,
11223 arm_debug_target_el(env));
11224 return flags;
11225}
11226
11227static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
11228 ARMMMUIdx mmu_idx)
11229{
11230 uint32_t flags = rebuild_hflags_aprofile(env);
11231
11232 if (arm_el_is_aa64(env, 1)) {
11233 flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
11234 }
11235 return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
11236}
11237
11238static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
11239 ARMMMUIdx mmu_idx)
11240{
11241 uint32_t flags = rebuild_hflags_aprofile(env);
11242 ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
11243 ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
11244 uint64_t sctlr;
11245 int tbii, tbid;
11246
11247 flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
11248
11249
11250 if (regime_el(env, stage1) < 2) {
11251 ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
11252 tbid = (p1.tbi << 1) | p0.tbi;
11253 tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
11254 } else {
11255 tbid = p0.tbi;
11256 tbii = tbid & !p0.tbid;
11257 }
11258
11259 flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
11260 flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
11261
11262 if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
11263 int sve_el = sve_exception_el(env, el);
11264 uint32_t zcr_len;
11265
11266
11267
11268
11269
11270 if (sve_el != 0 && fp_el == 0) {
11271 zcr_len = 0;
11272 } else {
11273 zcr_len = sve_zcr_len_for_el(env, el);
11274 }
11275 flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
11276 flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
11277 }
11278
11279 sctlr = arm_sctlr(env, el);
11280
11281 if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
11282 flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
11283 }
11284
11285 if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
11286
11287
11288
11289
11290
11291
11292 if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
11293 flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
11294 }
11295 }
11296
11297 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
11298
11299 if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
11300 flags = FIELD_DP32(flags, TBFLAG_A64, BT, 1);
11301 }
11302 }
11303
11304 return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
11305}
11306
11307static uint32_t rebuild_hflags_internal(CPUARMState *env)
11308{
11309 int el = arm_current_el(env);
11310 int fp_el = fp_exception_el(env, el);
11311 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
11312
11313 if (is_a64(env)) {
11314 return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
11315 } else if (arm_feature(env, ARM_FEATURE_M)) {
11316 return rebuild_hflags_m32(env, fp_el, mmu_idx);
11317 } else {
11318 return rebuild_hflags_a32(env, fp_el, mmu_idx);
11319 }
11320}
11321
11322void arm_rebuild_hflags(CPUARMState *env)
11323{
11324 env->hflags = rebuild_hflags_internal(env);
11325}
11326
11327void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
11328{
11329 int fp_el = fp_exception_el(env, el);
11330 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
11331
11332 env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
11333}
11334
11335void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
11336{
11337 int fp_el = fp_exception_el(env, el);
11338 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
11339
11340 env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
11341}
11342
11343void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
11344{
11345 int fp_el = fp_exception_el(env, el);
11346 ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
11347
11348 env->hflags = rebuild_hflags_a64(env, el, fp_el, mmu_idx);
11349}
11350
11351void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
11352 target_ulong *cs_base, uint32_t *pflags)
11353{
11354 uint32_t flags = env->hflags;
11355 uint32_t pstate_for_ss;
11356
11357 *cs_base = 0;
11358#ifdef CONFIG_DEBUG_TCG
11359 assert(flags == rebuild_hflags_internal(env));
11360#endif
11361
11362 if (FIELD_EX32(flags, TBFLAG_ANY, AARCH64_STATE)) {
11363 *pc = env->pc;
11364 if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
11365 flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
11366 }
11367 pstate_for_ss = env->pstate;
11368 } else {
11369 *pc = env->regs[15];
11370
11371 if (arm_feature(env, ARM_FEATURE_M)) {
11372 if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11373 FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S)
11374 != env->v7m.secure) {
11375 flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
11376 }
11377
11378 if ((env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
11379 (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
11380 (env->v7m.secure &&
11381 !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
11382
11383
11384
11385
11386
11387 flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
11388 }
11389
11390 bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
11391 if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
11392 flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
11393 }
11394 } else {
11395
11396
11397
11398
11399 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
11400 flags = FIELD_DP32(flags, TBFLAG_A32,
11401 XSCALE_CPAR, env->cp15.c15_cpar);
11402 } else {
11403 flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN,
11404 env->vfp.vec_len);
11405 flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE,
11406 env->vfp.vec_stride);
11407 }
11408 if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
11409 flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
11410 }
11411 }
11412
11413 flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
11414 flags = FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bits);
11415 pstate_for_ss = env->uncached_cpsr;
11416 }
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427 if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) &&
11428 (pstate_for_ss & PSTATE_SS)) {
11429 flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
11430 }
11431
11432 *pflags = flags;
11433}
11434
11435#ifdef TARGET_AARCH64
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
11451{
11452 int i, j;
11453 uint64_t pmask;
11454
11455 assert(vq >= 1 && vq <= ARM_MAX_VQ);
11456 assert(vq <= env_archcpu(env)->sve_max_vq);
11457
11458
11459 for (i = 0; i < 32; i++) {
11460 memset(&env->vfp.zregs[i].d[2 * vq], 0, 16 * (ARM_MAX_VQ - vq));
11461 }
11462
11463
11464 pmask = 0;
11465 if (vq & 3) {
11466 pmask = ~(-1ULL << (16 * (vq & 3)));
11467 }
11468 for (j = vq / 4; j < ARM_MAX_VQ / 4; j++) {
11469 for (i = 0; i < 17; ++i) {
11470 env->vfp.pregs[i].p[j] &= pmask;
11471 }
11472 pmask = 0;
11473 }
11474}
11475
11476
11477
11478
11479void aarch64_sve_change_el(CPUARMState *env, int old_el,
11480 int new_el, bool el0_a64)
11481{
11482 ARMCPU *cpu = env_archcpu(env);
11483 int old_len, new_len;
11484 bool old_a64, new_a64;
11485
11486
11487 if (!cpu_isar_feature(aa64_sve, cpu)) {
11488 return;
11489 }
11490
11491
11492 if (fp_exception_el(env, old_el) || fp_exception_el(env, new_el)) {
11493 return;
11494 }
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508 old_a64 = old_el ? arm_el_is_aa64(env, old_el) : el0_a64;
11509 old_len = (old_a64 && !sve_exception_el(env, old_el)
11510 ? sve_zcr_len_for_el(env, old_el) : 0);
11511 new_a64 = new_el ? arm_el_is_aa64(env, new_el) : el0_a64;
11512 new_len = (new_a64 && !sve_exception_el(env, new_el)
11513 ? sve_zcr_len_for_el(env, new_el) : 0);
11514
11515
11516 if (new_len < old_len) {
11517 aarch64_sve_narrow_vq(env, new_len + 1);
11518 }
11519}
11520#endif
11521