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