1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#ifndef TARGET_ARM_INTERNALS_H
26#define TARGET_ARM_INTERNALS_H
27
28#include "hw/registerfields.h"
29
30
31#define BANK_USRSYS 0
32#define BANK_SVC 1
33#define BANK_ABT 2
34#define BANK_UND 3
35#define BANK_IRQ 4
36#define BANK_FIQ 5
37#define BANK_HYP 6
38#define BANK_MON 7
39
40static inline bool excp_is_internal(int excp)
41{
42
43
44
45 return excp == EXCP_INTERRUPT
46 || excp == EXCP_HLT
47 || excp == EXCP_DEBUG
48 || excp == EXCP_HALTED
49 || excp == EXCP_EXCEPTION_EXIT
50 || excp == EXCP_KERNEL_TRAP
51 || excp == EXCP_SEMIHOST;
52}
53
54
55
56
57#define GTIMER_SCALE 16
58
59
60FIELD(V7M_CONTROL, NPRIV, 0, 1)
61FIELD(V7M_CONTROL, SPSEL, 1, 1)
62FIELD(V7M_CONTROL, FPCA, 2, 1)
63FIELD(V7M_CONTROL, SFPA, 3, 1)
64
65
66FIELD(V7M_EXCRET, ES, 0, 1)
67FIELD(V7M_EXCRET, RES0, 1, 1)
68FIELD(V7M_EXCRET, SPSEL, 2, 1)
69FIELD(V7M_EXCRET, MODE, 3, 1)
70FIELD(V7M_EXCRET, FTYPE, 4, 1)
71FIELD(V7M_EXCRET, DCRS, 5, 1)
72FIELD(V7M_EXCRET, S, 6, 1)
73FIELD(V7M_EXCRET, RES1, 7, 25)
74
75
76#define EXC_RETURN_MIN_MAGIC 0xff000000
77
78
79
80#define FNC_RETURN_MIN_MAGIC 0xfefffffe
81
82
83
84
85
86
87
88
89
90
91
92
93
94#define M_FAKE_FSR_NSC_EXEC 0xf
95#define M_FAKE_FSR_SFAULT 0xe
96
97
98
99
100
101
102
103void QEMU_NORETURN raise_exception(CPUARMState *env, uint32_t excp,
104 uint32_t syndrome, uint32_t target_el);
105
106
107
108
109void QEMU_NORETURN raise_exception_ra(CPUARMState *env, uint32_t excp,
110 uint32_t syndrome, uint32_t target_el,
111 uintptr_t ra);
112
113
114
115
116
117
118
119static inline unsigned int aarch64_banked_spsr_index(unsigned int el)
120{
121 static const unsigned int map[4] = {
122 [1] = BANK_SVC,
123 [2] = BANK_HYP,
124 [3] = BANK_MON,
125 };
126 assert(el >= 1 && el <= 3);
127 return map[el];
128}
129
130
131static inline int bank_number(int mode)
132{
133 switch (mode) {
134 case ARM_CPU_MODE_USR:
135 case ARM_CPU_MODE_SYS:
136 return BANK_USRSYS;
137 case ARM_CPU_MODE_SVC:
138 return BANK_SVC;
139 case ARM_CPU_MODE_ABT:
140 return BANK_ABT;
141 case ARM_CPU_MODE_UND:
142 return BANK_UND;
143 case ARM_CPU_MODE_IRQ:
144 return BANK_IRQ;
145 case ARM_CPU_MODE_FIQ:
146 return BANK_FIQ;
147 case ARM_CPU_MODE_HYP:
148 return BANK_HYP;
149 case ARM_CPU_MODE_MON:
150 return BANK_MON;
151 }
152 g_assert_not_reached();
153}
154
155
156
157
158
159
160
161
162
163
164
165
166static inline int r14_bank_number(int mode)
167{
168 return (mode == ARM_CPU_MODE_HYP) ? BANK_USRSYS : bank_number(mode);
169}
170
171void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
172void arm_translate_init(void);
173
174enum arm_fprounding {
175 FPROUNDING_TIEEVEN,
176 FPROUNDING_POSINF,
177 FPROUNDING_NEGINF,
178 FPROUNDING_ZERO,
179 FPROUNDING_TIEAWAY,
180 FPROUNDING_ODD
181};
182
183int arm_rmode_to_sf(int rmode);
184
185static inline void aarch64_save_sp(CPUARMState *env, int el)
186{
187 if (env->pstate & PSTATE_SP) {
188 env->sp_el[el] = env->xregs[31];
189 } else {
190 env->sp_el[0] = env->xregs[31];
191 }
192}
193
194static inline void aarch64_restore_sp(CPUARMState *env, int el)
195{
196 if (env->pstate & PSTATE_SP) {
197 env->xregs[31] = env->sp_el[el];
198 } else {
199 env->xregs[31] = env->sp_el[0];
200 }
201}
202
203static inline void update_spsel(CPUARMState *env, uint32_t imm)
204{
205 unsigned int cur_el = arm_current_el(env);
206
207
208
209 if (!((imm ^ env->pstate) & PSTATE_SP)) {
210 return;
211 }
212 aarch64_save_sp(env, cur_el);
213 env->pstate = deposit32(env->pstate, 0, 1, imm);
214
215
216
217
218 assert(cur_el >= 1 && cur_el <= 3);
219 aarch64_restore_sp(env, cur_el);
220}
221
222
223
224
225
226
227
228
229static inline unsigned int arm_pamax(ARMCPU *cpu)
230{
231 static const unsigned int pamax_map[] = {
232 [0] = 32,
233 [1] = 36,
234 [2] = 40,
235 [3] = 42,
236 [4] = 44,
237 [5] = 48,
238 };
239 unsigned int parange =
240 FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
241
242
243
244 assert(parange < ARRAY_SIZE(pamax_map));
245 return pamax_map[parange];
246}
247
248
249
250
251
252static inline bool extended_addresses_enabled(CPUARMState *env)
253{
254 TCR *tcr = &env->cp15.tcr_el[arm_is_secure(env) ? 3 : 1];
255 return arm_el_is_aa64(env, 1) ||
256 (arm_feature(env, ARM_FEATURE_LPAE) && (tcr->raw_tcr & TTBCR_EAE));
257}
258
259
260enum arm_exception_class {
261 EC_UNCATEGORIZED = 0x00,
262 EC_WFX_TRAP = 0x01,
263 EC_CP15RTTRAP = 0x03,
264 EC_CP15RRTTRAP = 0x04,
265 EC_CP14RTTRAP = 0x05,
266 EC_CP14DTTRAP = 0x06,
267 EC_ADVSIMDFPACCESSTRAP = 0x07,
268 EC_FPIDTRAP = 0x08,
269 EC_PACTRAP = 0x09,
270 EC_CP14RRTTRAP = 0x0c,
271 EC_BTITRAP = 0x0d,
272 EC_ILLEGALSTATE = 0x0e,
273 EC_AA32_SVC = 0x11,
274 EC_AA32_HVC = 0x12,
275 EC_AA32_SMC = 0x13,
276 EC_AA64_SVC = 0x15,
277 EC_AA64_HVC = 0x16,
278 EC_AA64_SMC = 0x17,
279 EC_SYSTEMREGISTERTRAP = 0x18,
280 EC_SVEACCESSTRAP = 0x19,
281 EC_INSNABORT = 0x20,
282 EC_INSNABORT_SAME_EL = 0x21,
283 EC_PCALIGNMENT = 0x22,
284 EC_DATAABORT = 0x24,
285 EC_DATAABORT_SAME_EL = 0x25,
286 EC_SPALIGNMENT = 0x26,
287 EC_AA32_FPTRAP = 0x28,
288 EC_AA64_FPTRAP = 0x2c,
289 EC_SERROR = 0x2f,
290 EC_BREAKPOINT = 0x30,
291 EC_BREAKPOINT_SAME_EL = 0x31,
292 EC_SOFTWARESTEP = 0x32,
293 EC_SOFTWARESTEP_SAME_EL = 0x33,
294 EC_WATCHPOINT = 0x34,
295 EC_WATCHPOINT_SAME_EL = 0x35,
296 EC_AA32_BKPT = 0x38,
297 EC_VECTORCATCH = 0x3a,
298 EC_AA64_BKPT = 0x3c,
299};
300
301#define ARM_EL_EC_SHIFT 26
302#define ARM_EL_IL_SHIFT 25
303#define ARM_EL_ISV_SHIFT 24
304#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
305#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
306
307static inline uint32_t syn_get_ec(uint32_t syn)
308{
309 return syn >> ARM_EL_EC_SHIFT;
310}
311
312
313
314
315
316
317
318
319
320
321static inline uint32_t syn_uncategorized(void)
322{
323 return (EC_UNCATEGORIZED << ARM_EL_EC_SHIFT) | ARM_EL_IL;
324}
325
326static inline uint32_t syn_aa64_svc(uint32_t imm16)
327{
328 return (EC_AA64_SVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
329}
330
331static inline uint32_t syn_aa64_hvc(uint32_t imm16)
332{
333 return (EC_AA64_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
334}
335
336static inline uint32_t syn_aa64_smc(uint32_t imm16)
337{
338 return (EC_AA64_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
339}
340
341static inline uint32_t syn_aa32_svc(uint32_t imm16, bool is_16bit)
342{
343 return (EC_AA32_SVC << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
344 | (is_16bit ? 0 : ARM_EL_IL);
345}
346
347static inline uint32_t syn_aa32_hvc(uint32_t imm16)
348{
349 return (EC_AA32_HVC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
350}
351
352static inline uint32_t syn_aa32_smc(void)
353{
354 return (EC_AA32_SMC << ARM_EL_EC_SHIFT) | ARM_EL_IL;
355}
356
357static inline uint32_t syn_aa64_bkpt(uint32_t imm16)
358{
359 return (EC_AA64_BKPT << ARM_EL_EC_SHIFT) | ARM_EL_IL | (imm16 & 0xffff);
360}
361
362static inline uint32_t syn_aa32_bkpt(uint32_t imm16, bool is_16bit)
363{
364 return (EC_AA32_BKPT << ARM_EL_EC_SHIFT) | (imm16 & 0xffff)
365 | (is_16bit ? 0 : ARM_EL_IL);
366}
367
368static inline uint32_t syn_aa64_sysregtrap(int op0, int op1, int op2,
369 int crn, int crm, int rt,
370 int isread)
371{
372 return (EC_SYSTEMREGISTERTRAP << ARM_EL_EC_SHIFT) | ARM_EL_IL
373 | (op0 << 20) | (op2 << 17) | (op1 << 14) | (crn << 10) | (rt << 5)
374 | (crm << 1) | isread;
375}
376
377static inline uint32_t syn_cp14_rt_trap(int cv, int cond, int opc1, int opc2,
378 int crn, int crm, int rt, int isread,
379 bool is_16bit)
380{
381 return (EC_CP14RTTRAP << ARM_EL_EC_SHIFT)
382 | (is_16bit ? 0 : ARM_EL_IL)
383 | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
384 | (crn << 10) | (rt << 5) | (crm << 1) | isread;
385}
386
387static inline uint32_t syn_cp15_rt_trap(int cv, int cond, int opc1, int opc2,
388 int crn, int crm, int rt, int isread,
389 bool is_16bit)
390{
391 return (EC_CP15RTTRAP << ARM_EL_EC_SHIFT)
392 | (is_16bit ? 0 : ARM_EL_IL)
393 | (cv << 24) | (cond << 20) | (opc2 << 17) | (opc1 << 14)
394 | (crn << 10) | (rt << 5) | (crm << 1) | isread;
395}
396
397static inline uint32_t syn_cp14_rrt_trap(int cv, int cond, int opc1, int crm,
398 int rt, int rt2, int isread,
399 bool is_16bit)
400{
401 return (EC_CP14RRTTRAP << ARM_EL_EC_SHIFT)
402 | (is_16bit ? 0 : ARM_EL_IL)
403 | (cv << 24) | (cond << 20) | (opc1 << 16)
404 | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
405}
406
407static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
408 int rt, int rt2, int isread,
409 bool is_16bit)
410{
411 return (EC_CP15RRTTRAP << ARM_EL_EC_SHIFT)
412 | (is_16bit ? 0 : ARM_EL_IL)
413 | (cv << 24) | (cond << 20) | (opc1 << 16)
414 | (rt2 << 10) | (rt << 5) | (crm << 1) | isread;
415}
416
417static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit)
418{
419
420 return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
421 | (is_16bit ? 0 : ARM_EL_IL)
422 | (cv << 24) | (cond << 20) | 0xa;
423}
424
425static inline uint32_t syn_simd_access_trap(int cv, int cond, bool is_16bit)
426{
427
428 return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
429 | (is_16bit ? 0 : ARM_EL_IL)
430 | (cv << 24) | (cond << 20) | (1 << 5);
431}
432
433static inline uint32_t syn_sve_access_trap(void)
434{
435 return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
436}
437
438static inline uint32_t syn_pactrap(void)
439{
440 return EC_PACTRAP << ARM_EL_EC_SHIFT;
441}
442
443static inline uint32_t syn_btitrap(int btype)
444{
445 return (EC_BTITRAP << ARM_EL_EC_SHIFT) | btype;
446}
447
448static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
449{
450 return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
451 | ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc;
452}
453
454static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv,
455 int ea, int cm, int s1ptw,
456 int wnr, int fsc)
457{
458 return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
459 | ARM_EL_IL
460 | (fnv << 10) | (ea << 9) | (cm << 8) | (s1ptw << 7)
461 | (wnr << 6) | fsc;
462}
463
464static inline uint32_t syn_data_abort_with_iss(int same_el,
465 int sas, int sse, int srt,
466 int sf, int ar,
467 int ea, int cm, int s1ptw,
468 int wnr, int fsc,
469 bool is_16bit)
470{
471 return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
472 | (is_16bit ? 0 : ARM_EL_IL)
473 | ARM_EL_ISV | (sas << 22) | (sse << 21) | (srt << 16)
474 | (sf << 15) | (ar << 14)
475 | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
476}
477
478static inline uint32_t syn_swstep(int same_el, int isv, int ex)
479{
480 return (EC_SOFTWARESTEP << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
481 | ARM_EL_IL | (isv << 24) | (ex << 6) | 0x22;
482}
483
484static inline uint32_t syn_watchpoint(int same_el, int cm, int wnr)
485{
486 return (EC_WATCHPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
487 | ARM_EL_IL | (cm << 8) | (wnr << 6) | 0x22;
488}
489
490static inline uint32_t syn_breakpoint(int same_el)
491{
492 return (EC_BREAKPOINT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
493 | ARM_EL_IL | 0x22;
494}
495
496static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
497{
498 return (EC_WFX_TRAP << ARM_EL_EC_SHIFT) |
499 (is_16bit ? 0 : (1 << ARM_EL_IL_SHIFT)) |
500 (cv << 24) | (cond << 20) | ti;
501}
502
503
504
505
506void hw_watchpoint_update(ARMCPU *cpu, int n);
507
508
509
510
511void hw_watchpoint_update_all(ARMCPU *cpu);
512
513
514
515void hw_breakpoint_update(ARMCPU *cpu, int n);
516
517
518
519
520void hw_breakpoint_update_all(ARMCPU *cpu);
521
522
523bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
524
525
526
527
528vaddr arm_adjust_watchpoint_address(CPUState *cs, vaddr addr, int len);
529
530
531void arm_debug_excp_handler(CPUState *cs);
532
533#if defined(CONFIG_USER_ONLY) || !defined(CONFIG_TCG)
534static inline bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
535{
536 return false;
537}
538static inline void arm_handle_psci_call(ARMCPU *cpu)
539{
540 g_assert_not_reached();
541}
542#else
543
544bool arm_is_psci_call(ARMCPU *cpu, int excp_type);
545
546void arm_handle_psci_call(ARMCPU *cpu);
547#endif
548
549
550
551
552
553
554static inline void arm_clear_exclusive(CPUARMState *env)
555{
556 env->exclusive_addr = -1;
557}
558
559
560
561
562
563
564typedef enum ARMFaultType {
565 ARMFault_None,
566 ARMFault_AccessFlag,
567 ARMFault_Alignment,
568 ARMFault_Background,
569 ARMFault_Domain,
570 ARMFault_Permission,
571 ARMFault_Translation,
572 ARMFault_AddressSize,
573 ARMFault_SyncExternal,
574 ARMFault_SyncExternalOnWalk,
575 ARMFault_SyncParity,
576 ARMFault_SyncParityOnWalk,
577 ARMFault_AsyncParity,
578 ARMFault_AsyncExternal,
579 ARMFault_Debug,
580 ARMFault_TLBConflict,
581 ARMFault_Lockdown,
582 ARMFault_Exclusive,
583 ARMFault_ICacheMaint,
584 ARMFault_QEMU_NSCExec,
585 ARMFault_QEMU_SFault,
586} ARMFaultType;
587
588
589
590
591
592
593
594
595
596
597
598typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
599struct ARMMMUFaultInfo {
600 ARMFaultType type;
601 target_ulong s2addr;
602 int level;
603 int domain;
604 bool stage2;
605 bool s1ptw;
606 bool ea;
607};
608
609
610
611
612
613
614
615static inline uint32_t arm_fi_to_sfsc(ARMMMUFaultInfo *fi)
616{
617 uint32_t fsc;
618
619 switch (fi->type) {
620 case ARMFault_None:
621 return 0;
622 case ARMFault_AccessFlag:
623 fsc = fi->level == 1 ? 0x3 : 0x6;
624 break;
625 case ARMFault_Alignment:
626 fsc = 0x1;
627 break;
628 case ARMFault_Permission:
629 fsc = fi->level == 1 ? 0xd : 0xf;
630 break;
631 case ARMFault_Domain:
632 fsc = fi->level == 1 ? 0x9 : 0xb;
633 break;
634 case ARMFault_Translation:
635 fsc = fi->level == 1 ? 0x5 : 0x7;
636 break;
637 case ARMFault_SyncExternal:
638 fsc = 0x8 | (fi->ea << 12);
639 break;
640 case ARMFault_SyncExternalOnWalk:
641 fsc = fi->level == 1 ? 0xc : 0xe;
642 fsc |= (fi->ea << 12);
643 break;
644 case ARMFault_SyncParity:
645 fsc = 0x409;
646 break;
647 case ARMFault_SyncParityOnWalk:
648 fsc = fi->level == 1 ? 0x40c : 0x40e;
649 break;
650 case ARMFault_AsyncParity:
651 fsc = 0x408;
652 break;
653 case ARMFault_AsyncExternal:
654 fsc = 0x406 | (fi->ea << 12);
655 break;
656 case ARMFault_Debug:
657 fsc = 0x2;
658 break;
659 case ARMFault_TLBConflict:
660 fsc = 0x400;
661 break;
662 case ARMFault_Lockdown:
663 fsc = 0x404;
664 break;
665 case ARMFault_Exclusive:
666 fsc = 0x405;
667 break;
668 case ARMFault_ICacheMaint:
669 fsc = 0x4;
670 break;
671 case ARMFault_Background:
672 fsc = 0x0;
673 break;
674 case ARMFault_QEMU_NSCExec:
675 fsc = M_FAKE_FSR_NSC_EXEC;
676 break;
677 case ARMFault_QEMU_SFault:
678 fsc = M_FAKE_FSR_SFAULT;
679 break;
680 default:
681
682
683
684 g_assert_not_reached();
685 }
686
687 fsc |= (fi->domain << 4);
688 return fsc;
689}
690
691
692
693
694
695
696static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
697{
698 uint32_t fsc;
699
700 switch (fi->type) {
701 case ARMFault_None:
702 return 0;
703 case ARMFault_AddressSize:
704 fsc = fi->level & 3;
705 break;
706 case ARMFault_AccessFlag:
707 fsc = (fi->level & 3) | (0x2 << 2);
708 break;
709 case ARMFault_Permission:
710 fsc = (fi->level & 3) | (0x3 << 2);
711 break;
712 case ARMFault_Translation:
713 fsc = (fi->level & 3) | (0x1 << 2);
714 break;
715 case ARMFault_SyncExternal:
716 fsc = 0x10 | (fi->ea << 12);
717 break;
718 case ARMFault_SyncExternalOnWalk:
719 fsc = (fi->level & 3) | (0x5 << 2) | (fi->ea << 12);
720 break;
721 case ARMFault_SyncParity:
722 fsc = 0x18;
723 break;
724 case ARMFault_SyncParityOnWalk:
725 fsc = (fi->level & 3) | (0x7 << 2);
726 break;
727 case ARMFault_AsyncParity:
728 fsc = 0x19;
729 break;
730 case ARMFault_AsyncExternal:
731 fsc = 0x11 | (fi->ea << 12);
732 break;
733 case ARMFault_Alignment:
734 fsc = 0x21;
735 break;
736 case ARMFault_Debug:
737 fsc = 0x22;
738 break;
739 case ARMFault_TLBConflict:
740 fsc = 0x30;
741 break;
742 case ARMFault_Lockdown:
743 fsc = 0x34;
744 break;
745 case ARMFault_Exclusive:
746 fsc = 0x35;
747 break;
748 default:
749
750
751
752 g_assert_not_reached();
753 }
754
755 fsc |= 1 << 9;
756 return fsc;
757}
758
759static inline bool arm_extabort_type(MemTxResult result)
760{
761
762
763
764
765
766 return result != MEMTX_DECODE_ERROR;
767}
768
769bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
770 MMUAccessType access_type, int mmu_idx,
771 bool probe, uintptr_t retaddr);
772
773static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx)
774{
775 return mmu_idx & ARM_MMU_IDX_COREIDX_MASK;
776}
777
778static inline ARMMMUIdx core_to_arm_mmu_idx(CPUARMState *env, int mmu_idx)
779{
780 if (arm_feature(env, ARM_FEATURE_M)) {
781 return mmu_idx | ARM_MMU_IDX_M;
782 } else {
783 return mmu_idx | ARM_MMU_IDX_A;
784 }
785}
786
787static inline ARMMMUIdx core_to_aa64_mmu_idx(int mmu_idx)
788{
789
790 return mmu_idx | ARM_MMU_IDX_A;
791}
792
793int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
794
795
796
797
798
799ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
800 bool secstate, bool priv, bool negpri);
801
802
803
804
805
806ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
807 bool secstate, bool priv);
808
809
810ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
811
812
813
814bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx);
815
816
817void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
818 MMUAccessType access_type,
819 int mmu_idx, uintptr_t retaddr);
820
821
822
823
824
825void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
826 vaddr addr, unsigned size,
827 MMUAccessType access_type,
828 int mmu_idx, MemTxAttrs attrs,
829 MemTxResult response, uintptr_t retaddr);
830
831
832static inline void arm_call_pre_el_change_hook(ARMCPU *cpu)
833{
834 ARMELChangeHook *hook, *next;
835 QLIST_FOREACH_SAFE(hook, &cpu->pre_el_change_hooks, node, next) {
836 hook->hook(cpu, hook->opaque);
837 }
838}
839static inline void arm_call_el_change_hook(ARMCPU *cpu)
840{
841 ARMELChangeHook *hook, *next;
842 QLIST_FOREACH_SAFE(hook, &cpu->el_change_hooks, node, next) {
843 hook->hook(cpu, hook->opaque);
844 }
845}
846
847
848static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
849{
850 switch (mmu_idx) {
851 case ARMMMUIdx_Stage1_E0:
852 case ARMMMUIdx_Stage1_E1:
853 case ARMMMUIdx_Stage1_E1_PAN:
854 case ARMMMUIdx_E10_0:
855 case ARMMMUIdx_E10_1:
856 case ARMMMUIdx_E10_1_PAN:
857 case ARMMMUIdx_E20_0:
858 case ARMMMUIdx_E20_2:
859 case ARMMMUIdx_E20_2_PAN:
860 case ARMMMUIdx_SE10_0:
861 case ARMMMUIdx_SE10_1:
862 case ARMMMUIdx_SE10_1_PAN:
863 return true;
864 default:
865 return false;
866 }
867}
868
869
870static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
871{
872 switch (mmu_idx) {
873 case ARMMMUIdx_E10_0:
874 case ARMMMUIdx_E10_1:
875 case ARMMMUIdx_E10_1_PAN:
876 case ARMMMUIdx_E20_0:
877 case ARMMMUIdx_E20_2:
878 case ARMMMUIdx_E20_2_PAN:
879 case ARMMMUIdx_Stage1_E0:
880 case ARMMMUIdx_Stage1_E1:
881 case ARMMMUIdx_Stage1_E1_PAN:
882 case ARMMMUIdx_E2:
883 case ARMMMUIdx_Stage2:
884 case ARMMMUIdx_MPrivNegPri:
885 case ARMMMUIdx_MUserNegPri:
886 case ARMMMUIdx_MPriv:
887 case ARMMMUIdx_MUser:
888 return false;
889 case ARMMMUIdx_SE3:
890 case ARMMMUIdx_SE10_0:
891 case ARMMMUIdx_SE10_1:
892 case ARMMMUIdx_SE10_1_PAN:
893 case ARMMMUIdx_MSPrivNegPri:
894 case ARMMMUIdx_MSUserNegPri:
895 case ARMMMUIdx_MSPriv:
896 case ARMMMUIdx_MSUser:
897 return true;
898 default:
899 g_assert_not_reached();
900 }
901}
902
903static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
904{
905 switch (mmu_idx) {
906 case ARMMMUIdx_Stage1_E1_PAN:
907 case ARMMMUIdx_E10_1_PAN:
908 case ARMMMUIdx_E20_2_PAN:
909 case ARMMMUIdx_SE10_1_PAN:
910 return true;
911 default:
912 return false;
913 }
914}
915
916
917static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
918{
919 switch (mmu_idx) {
920 case ARMMMUIdx_E20_0:
921 case ARMMMUIdx_E20_2:
922 case ARMMMUIdx_E20_2_PAN:
923 case ARMMMUIdx_Stage2:
924 case ARMMMUIdx_E2:
925 return 2;
926 case ARMMMUIdx_SE3:
927 return 3;
928 case ARMMMUIdx_SE10_0:
929 return arm_el_is_aa64(env, 3) ? 1 : 3;
930 case ARMMMUIdx_SE10_1:
931 case ARMMMUIdx_SE10_1_PAN:
932 case ARMMMUIdx_Stage1_E0:
933 case ARMMMUIdx_Stage1_E1:
934 case ARMMMUIdx_Stage1_E1_PAN:
935 case ARMMMUIdx_E10_0:
936 case ARMMMUIdx_E10_1:
937 case ARMMMUIdx_E10_1_PAN:
938 case ARMMMUIdx_MPrivNegPri:
939 case ARMMMUIdx_MUserNegPri:
940 case ARMMMUIdx_MPriv:
941 case ARMMMUIdx_MUser:
942 case ARMMMUIdx_MSPrivNegPri:
943 case ARMMMUIdx_MSUserNegPri:
944 case ARMMMUIdx_MSPriv:
945 case ARMMMUIdx_MSUser:
946 return 1;
947 default:
948 g_assert_not_reached();
949 }
950}
951
952
953static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
954{
955 if (mmu_idx == ARMMMUIdx_Stage2) {
956 return &env->cp15.vtcr_el2;
957 }
958 return &env->cp15.tcr_el[regime_el(env, mmu_idx)];
959}
960
961
962
963
964static inline uint32_t arm_debug_exception_fsr(CPUARMState *env)
965{
966 ARMMMUFaultInfo fi = { .type = ARMFault_Debug };
967 int target_el = arm_debug_target_el(env);
968 bool using_lpae = false;
969
970 if (target_el == 2 || arm_el_is_aa64(env, target_el)) {
971 using_lpae = true;
972 } else {
973 if (arm_feature(env, ARM_FEATURE_LPAE) &&
974 (env->cp15.tcr_el[target_el].raw_tcr & TTBCR_EAE)) {
975 using_lpae = true;
976 }
977 }
978
979 if (using_lpae) {
980 return arm_fi_to_lfsc(&fi);
981 } else {
982 return arm_fi_to_sfsc(&fi);
983 }
984}
985
986
987
988
989
990
991static inline int arm_num_brps(ARMCPU *cpu)
992{
993 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
994 return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1;
995 } else {
996 return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, BRPS) + 1;
997 }
998}
999
1000
1001
1002
1003
1004
1005static inline int arm_num_wrps(ARMCPU *cpu)
1006{
1007 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
1008 return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1;
1009 } else {
1010 return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, WRPS) + 1;
1011 }
1012}
1013
1014
1015
1016
1017
1018
1019static inline int arm_num_ctx_cmps(ARMCPU *cpu)
1020{
1021 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
1022 return FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) + 1;
1023 } else {
1024 return FIELD_EX32(cpu->isar.dbgdidr, DBGDIDR, CTX_CMPS) + 1;
1025 }
1026}
1027
1028
1029
1030
1031
1032
1033static inline bool v7m_using_psp(CPUARMState *env)
1034{
1035
1036
1037
1038
1039
1040 return !arm_v7m_is_handler_mode(env) &&
1041 env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK;
1042}
1043
1044
1045
1046
1047
1048
1049static inline uint32_t v7m_sp_limit(CPUARMState *env)
1050{
1051 if (v7m_using_psp(env)) {
1052 return env->v7m.psplim[env->v7m.secure];
1053 } else {
1054 return env->v7m.msplim[env->v7m.secure];
1055 }
1056}
1057
1058
1059
1060
1061
1062
1063static inline bool v7m_cpacr_pass(CPUARMState *env,
1064 bool is_secure, bool is_priv)
1065{
1066 switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
1067 case 0:
1068 case 2:
1069 return false;
1070 case 1:
1071 return is_priv;
1072 case 3:
1073 return true;
1074 default:
1075 g_assert_not_reached();
1076 }
1077}
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087static inline const char *aarch32_mode_name(uint32_t psr)
1088{
1089 static const char cpu_mode_names[16][4] = {
1090 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
1091 "???", "???", "hyp", "und", "???", "???", "???", "sys"
1092 };
1093
1094 return cpu_mode_names[psr & 0xf];
1095}
1096
1097
1098
1099
1100
1101
1102
1103
1104void arm_cpu_update_virq(ARMCPU *cpu);
1105
1106
1107
1108
1109
1110
1111
1112
1113void arm_cpu_update_vfiq(ARMCPU *cpu);
1114
1115
1116
1117
1118
1119
1120
1121
1122ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el);
1123
1124
1125
1126
1127
1128
1129
1130ARMMMUIdx arm_mmu_idx(CPUARMState *env);
1131
1132
1133
1134
1135
1136
1137
1138#ifdef CONFIG_USER_ONLY
1139static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
1140{
1141 return ARMMMUIdx_Stage1_E0;
1142}
1143#else
1144ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
1145#endif
1146
1147
1148
1149
1150
1151
1152
1153
1154static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
1155{
1156 switch (mmu_idx) {
1157 case ARMMMUIdx_Stage1_E0:
1158 case ARMMMUIdx_Stage1_E1:
1159 case ARMMMUIdx_Stage1_E1_PAN:
1160 return true;
1161 default:
1162 return false;
1163 }
1164}
1165
1166static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
1167 const ARMISARegisters *id)
1168{
1169 uint32_t valid = CPSR_M | CPSR_AIF | CPSR_IL | CPSR_NZCV;
1170
1171 if ((features >> ARM_FEATURE_V4T) & 1) {
1172 valid |= CPSR_T;
1173 }
1174 if ((features >> ARM_FEATURE_V5) & 1) {
1175 valid |= CPSR_Q;
1176 }
1177 if ((features >> ARM_FEATURE_V6) & 1) {
1178 valid |= CPSR_E | CPSR_GE;
1179 }
1180 if ((features >> ARM_FEATURE_THUMB2) & 1) {
1181 valid |= CPSR_IT;
1182 }
1183 if (isar_feature_aa32_jazelle(id)) {
1184 valid |= CPSR_J;
1185 }
1186 if (isar_feature_aa32_pan(id)) {
1187 valid |= CPSR_PAN;
1188 }
1189
1190 return valid;
1191}
1192
1193static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
1194{
1195 uint32_t valid;
1196
1197 valid = PSTATE_M | PSTATE_DAIF | PSTATE_IL | PSTATE_SS | PSTATE_NZCV;
1198 if (isar_feature_aa64_bti(id)) {
1199 valid |= PSTATE_BTYPE;
1200 }
1201 if (isar_feature_aa64_pan(id)) {
1202 valid |= PSTATE_PAN;
1203 }
1204 if (isar_feature_aa64_uao(id)) {
1205 valid |= PSTATE_UAO;
1206 }
1207 if (isar_feature_aa64_mte(id)) {
1208 valid |= PSTATE_TCO;
1209 }
1210
1211 return valid;
1212}
1213
1214
1215
1216
1217
1218typedef struct ARMVAParameters {
1219 unsigned tsz : 8;
1220 unsigned select : 1;
1221 bool tbi : 1;
1222 bool epd : 1;
1223 bool hpd : 1;
1224 bool using16k : 1;
1225 bool using64k : 1;
1226} ARMVAParameters;
1227
1228ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
1229 ARMMMUIdx mmu_idx, bool data);
1230
1231static inline int exception_target_el(CPUARMState *env)
1232{
1233 int target_el = MAX(1, arm_current_el(env));
1234
1235
1236
1237
1238
1239 if (arm_is_secure(env) && !arm_el_is_aa64(env, 3) && target_el == 1) {
1240 target_el = 3;
1241 }
1242
1243 return target_el;
1244}
1245
1246
1247static inline bool allocation_tag_access_enabled(CPUARMState *env, int el,
1248 uint64_t sctlr)
1249{
1250 if (el < 3
1251 && arm_feature(env, ARM_FEATURE_EL3)
1252 && !(env->cp15.scr_el3 & SCR_ATA)) {
1253 return false;
1254 }
1255 if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
1256 uint64_t hcr = arm_hcr_el2_eff(env);
1257 if (!(hcr & HCR_ATA) && (!(hcr & HCR_E2H) || !(hcr & HCR_TGE))) {
1258 return false;
1259 }
1260 }
1261 sctlr &= (el == 0 ? SCTLR_ATA0 : SCTLR_ATA);
1262 return sctlr != 0;
1263}
1264
1265#ifndef CONFIG_USER_ONLY
1266
1267
1268typedef struct V8M_SAttributes {
1269 bool subpage;
1270 bool ns;
1271 bool nsc;
1272 uint8_t sregion;
1273 bool srvalid;
1274 uint8_t iregion;
1275 bool irvalid;
1276} V8M_SAttributes;
1277
1278void v8m_security_lookup(CPUARMState *env, uint32_t address,
1279 MMUAccessType access_type, ARMMMUIdx mmu_idx,
1280 V8M_SAttributes *sattrs);
1281
1282bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
1283 MMUAccessType access_type, ARMMMUIdx mmu_idx,
1284 hwaddr *phys_ptr, MemTxAttrs *txattrs,
1285 int *prot, bool *is_subpage,
1286 ARMMMUFaultInfo *fi, uint32_t *mregion);
1287
1288
1289typedef struct ARMCacheAttrs {
1290 unsigned int attrs:8;
1291 unsigned int shareability:2;
1292} ARMCacheAttrs;
1293
1294bool get_phys_addr(CPUARMState *env, target_ulong address,
1295 MMUAccessType access_type, ARMMMUIdx mmu_idx,
1296 hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
1297 target_ulong *page_size,
1298 ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
1299 __attribute__((nonnull));
1300
1301void arm_log_exception(int idx);
1302
1303#endif
1304
1305
1306
1307
1308
1309#define GMID_EL1_BS 6
1310
1311
1312#define LOG2_TAG_GRANULE 4
1313#define TAG_GRANULE (1 << LOG2_TAG_GRANULE)
1314
1315
1316
1317
1318
1319#define SVE_MTEDESC_SHIFT 5
1320
1321
1322FIELD(MTEDESC, MIDX, 0, 4)
1323FIELD(MTEDESC, TBI, 4, 2)
1324FIELD(MTEDESC, TCMA, 6, 2)
1325FIELD(MTEDESC, WRITE, 8, 1)
1326FIELD(MTEDESC, ESIZE, 9, 5)
1327FIELD(MTEDESC, TSIZE, 14, 10)
1328
1329bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr);
1330uint64_t mte_check1(CPUARMState *env, uint32_t desc,
1331 uint64_t ptr, uintptr_t ra);
1332uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
1333 uint64_t ptr, uintptr_t ra);
1334
1335static inline int allocation_tag_from_addr(uint64_t ptr)
1336{
1337 return extract64(ptr, 56, 4);
1338}
1339
1340static inline uint64_t address_with_allocation_tag(uint64_t ptr, int rtag)
1341{
1342 return deposit64(ptr, 56, 4, rtag);
1343}
1344
1345
1346static inline bool tbi_check(uint32_t desc, int bit55)
1347{
1348 return (desc >> (R_MTEDESC_TBI_SHIFT + bit55)) & 1;
1349}
1350
1351
1352static inline bool tcma_check(uint32_t desc, int bit55, int ptr_tag)
1353{
1354
1355
1356
1357
1358 bool match = ((ptr_tag + bit55) & 0xf) == 0;
1359 bool tcma = (desc >> (R_MTEDESC_TCMA_SHIFT + bit55)) & 1;
1360 return tcma && match;
1361}
1362
1363
1364
1365
1366
1367
1368
1369static inline uint64_t useronly_clean_ptr(uint64_t ptr)
1370{
1371
1372#ifdef CONFIG_USER_ONLY
1373 ptr = sextract64(ptr, 0, 56);
1374#endif
1375 return ptr;
1376}
1377
1378static inline uint64_t useronly_maybe_clean_ptr(uint32_t desc, uint64_t ptr)
1379{
1380#ifdef CONFIG_USER_ONLY
1381 int64_t clean_ptr = sextract64(ptr, 0, 56);
1382 if (tbi_check(desc, clean_ptr < 0)) {
1383 ptr = clean_ptr;
1384 }
1385#endif
1386 return ptr;
1387}
1388
1389#endif
1390