1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include "qemu/osdep.h"
20#include "cpu.h"
21#include "exec/helper-proto.h"
22#include "internals.h"
23#include "exec/cpu_ldst.h"
24
25#define SIGNBIT (uint32_t)0x80000000
26#define SIGNBIT64 ((uint64_t)1 << 63)
27
28static void raise_exception(CPUARMState *env, uint32_t excp,
29 uint32_t syndrome, uint32_t target_el)
30{
31 CPUState *cs = CPU(arm_env_get_cpu(env));
32
33 assert(!excp_is_internal(excp));
34 cs->exception_index = excp;
35 env->exception.syndrome = syndrome;
36 env->exception.target_el = target_el;
37 cpu_loop_exit(cs);
38}
39
40static int exception_target_el(CPUARMState *env)
41{
42 int target_el = MAX(1, arm_current_el(env));
43
44
45
46
47 if (arm_is_secure(env) && !arm_el_is_aa64(env, 3) && target_el == 1) {
48 target_el = 3;
49 }
50
51 return target_el;
52}
53
54uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
55 uint32_t rn, uint32_t maxindex)
56{
57 uint32_t val;
58 uint32_t tmp;
59 int index;
60 int shift;
61 uint64_t *table;
62 table = (uint64_t *)&env->vfp.regs[rn];
63 val = 0;
64 for (shift = 0; shift < 32; shift += 8) {
65 index = (ireg >> shift) & 0xff;
66 if (index < maxindex) {
67 tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff;
68 val |= tmp << shift;
69 } else {
70 val |= def & (0xff << shift);
71 }
72 }
73 return val;
74}
75
76#if !defined(CONFIG_USER_ONLY)
77
78#include "hw/remote-port.h"
79
80static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
81 unsigned int target_el,
82 bool same_el,
83 bool s1ptw, int is_write,
84 int fsc)
85{
86 uint32_t syn;
87
88
89
90
91
92
93
94
95
96
97
98
99 if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
100 syn = syn_data_abort_no_iss(same_el,
101 0, 0, s1ptw, is_write == 1, fsc);
102 } else {
103
104
105
106
107 syn = syn_data_abort_with_iss(same_el,
108 0, 0, 0, 0, 0,
109 0, 0, s1ptw, is_write == 1, fsc,
110 false);
111
112 syn |= template_syn;
113 }
114 return syn;
115}
116
117
118
119
120
121void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
122 uintptr_t retaddr)
123{
124 bool ret;
125 uint32_t fsr = 0;
126 ARMMMUFaultInfo fi = {};
127
128 ret = arm_tlb_fill(cs, addr, is_write, mmu_idx, &fsr, &fi);
129 if (unlikely(ret)) {
130 ARMCPU *cpu = ARM_CPU(cs);
131 CPUARMState *env = &cpu->env;
132 uint32_t syn, exc;
133 unsigned int target_el;
134 bool same_el;
135
136 if (retaddr) {
137
138 cpu_restore_state(cs, retaddr);
139 }
140
141 target_el = exception_target_el(env);
142 if (fi.stage2) {
143 target_el = 2;
144 env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4;
145 }
146 same_el = arm_current_el(env) == target_el;
147
148 syn = fsr & ~(1 << 9);
149
150
151
152
153 if (is_write == 2) {
154 syn = syn_insn_abort(same_el, 0, fi.s1ptw, syn);
155 exc = EXCP_PREFETCH_ABORT;
156 } else {
157 syn = merge_syn_data_abort(env->exception.syndrome, target_el,
158 same_el, fi.s1ptw, is_write, syn);
159 if (is_write == 1 && arm_feature(env, ARM_FEATURE_V6)) {
160 fsr |= (1 << 11);
161 }
162 exc = EXCP_DATA_ABORT;
163 }
164
165 env->exception.vaddress = addr;
166 env->exception.fsr = fsr;
167 raise_exception(env, exc, syn, target_el);
168 }
169}
170
171
172void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, int is_write,
173 int is_user, uintptr_t retaddr)
174{
175 ARMCPU *cpu = ARM_CPU(cs);
176 CPUARMState *env = &cpu->env;
177 int target_el;
178 bool same_el;
179 uint32_t syn;
180
181 if (retaddr) {
182
183 cpu_restore_state(cs, retaddr);
184 }
185
186 target_el = exception_target_el(env);
187 same_el = (arm_current_el(env) == target_el);
188
189 env->exception.vaddress = vaddr;
190
191
192
193
194 if (arm_s1_regime_using_lpae_format(env, cpu_mmu_index(env, false))) {
195 env->exception.fsr = 0x21;
196 } else {
197 env->exception.fsr = 0x1;
198 }
199
200 if (is_write == 1 && arm_feature(env, ARM_FEATURE_V6)) {
201 env->exception.fsr |= (1 << 11);
202 }
203
204 syn = merge_syn_data_abort(env->exception.syndrome, target_el,
205 same_el, 0, is_write, 0x21);
206 raise_exception(env, EXCP_DATA_ABORT, syn, target_el);
207}
208
209#endif
210
211uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
212{
213 uint32_t res = a + b;
214 if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT))
215 env->QF = 1;
216 return res;
217}
218
219uint32_t HELPER(add_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
220{
221 uint32_t res = a + b;
222 if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) {
223 env->QF = 1;
224 res = ~(((int32_t)a >> 31) ^ SIGNBIT);
225 }
226 return res;
227}
228
229uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
230{
231 uint32_t res = a - b;
232 if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) {
233 env->QF = 1;
234 res = ~(((int32_t)a >> 31) ^ SIGNBIT);
235 }
236 return res;
237}
238
239uint32_t HELPER(double_saturate)(CPUARMState *env, int32_t val)
240{
241 uint32_t res;
242 if (val >= 0x40000000) {
243 res = ~SIGNBIT;
244 env->QF = 1;
245 } else if (val <= (int32_t)0xc0000000) {
246 res = SIGNBIT;
247 env->QF = 1;
248 } else {
249 res = val << 1;
250 }
251 return res;
252}
253
254uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
255{
256 uint32_t res = a + b;
257 if (res < a) {
258 env->QF = 1;
259 res = ~0;
260 }
261 return res;
262}
263
264uint32_t HELPER(sub_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
265{
266 uint32_t res = a - b;
267 if (res > a) {
268 env->QF = 1;
269 res = 0;
270 }
271 return res;
272}
273
274
275static inline uint32_t do_ssat(CPUARMState *env, int32_t val, int shift)
276{
277 int32_t top;
278 uint32_t mask;
279
280 top = val >> shift;
281 mask = (1u << shift) - 1;
282 if (top > 0) {
283 env->QF = 1;
284 return mask;
285 } else if (top < -1) {
286 env->QF = 1;
287 return ~mask;
288 }
289 return val;
290}
291
292
293static inline uint32_t do_usat(CPUARMState *env, int32_t val, int shift)
294{
295 uint32_t max;
296
297 max = (1u << shift) - 1;
298 if (val < 0) {
299 env->QF = 1;
300 return 0;
301 } else if (val > max) {
302 env->QF = 1;
303 return max;
304 }
305 return val;
306}
307
308
309uint32_t HELPER(ssat)(CPUARMState *env, uint32_t x, uint32_t shift)
310{
311 return do_ssat(env, x, shift);
312}
313
314
315uint32_t HELPER(ssat16)(CPUARMState *env, uint32_t x, uint32_t shift)
316{
317 uint32_t res;
318
319 res = (uint16_t)do_ssat(env, (int16_t)x, shift);
320 res |= do_ssat(env, ((int32_t)x) >> 16, shift) << 16;
321 return res;
322}
323
324
325uint32_t HELPER(usat)(CPUARMState *env, uint32_t x, uint32_t shift)
326{
327 return do_usat(env, x, shift);
328}
329
330
331uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift)
332{
333 uint32_t res;
334
335 res = (uint16_t)do_usat(env, (int16_t)x, shift);
336 res |= do_usat(env, ((int32_t)x) >> 16, shift) << 16;
337 return res;
338}
339
340void HELPER(setend)(CPUARMState *env)
341{
342 env->uncached_cpsr ^= CPSR_E;
343}
344
345
346
347
348
349static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
350{
351 int cur_el = arm_current_el(env);
352 uint64_t mask;
353
354
355
356
357 if (cur_el < 1 && arm_feature(env, ARM_FEATURE_V8)) {
358 int target_el;
359
360 mask = is_wfe ? SCTLR_nTWE : SCTLR_nTWI;
361 if (arm_is_secure_below_el3(env) && !arm_el_is_aa64(env, 3)) {
362
363 target_el = 3;
364 } else {
365 target_el = 1;
366 }
367
368 if (!(env->cp15.sctlr_el[target_el] & mask)) {
369 return target_el;
370 }
371 }
372
373
374
375
376
377 if (cur_el < 2 && !arm_is_secure(env)) {
378 mask = (is_wfe) ? HCR_TWE : HCR_TWI;
379 if (env->cp15.hcr_el2 & mask) {
380 return 2;
381 }
382 }
383
384
385 if (cur_el < 3) {
386 mask = (is_wfe) ? SCR_TWE : SCR_TWI;
387 if (env->cp15.scr_el3 & mask) {
388 return 3;
389 }
390 }
391
392 return 0;
393}
394
395void HELPER(wfi)(CPUARMState *env)
396{
397 CPUState *cs = CPU(arm_env_get_cpu(env));
398 ARMCPU *cpu = arm_env_get_cpu(env);
399 int target_el = check_wfx_trap(env, false);
400
401 if (cpu_has_work(cs)) {
402 cs->exception_index = -1;
403 cpu_loop_exit(cs);
404 return;
405 }
406
407 if (target_el) {
408 env->pc -= 4;
409 raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0), target_el);
410 }
411
412 if (use_icount) {
413 cs->exception_index = EXCP_YIELD;
414 } else {
415 cs->exception_index = EXCP_HLT;
416 cs->halted = 1;
417 }
418
419 cpu->is_in_wfi = true;
420 qemu_set_irq(cpu->wfi, 1);
421
422 cpu_loop_exit(cs);
423}
424
425void HELPER(wfe)(CPUARMState *env)
426{
427 ARMCPU *ac = ARM_CPU(arm_env_get_cpu(env));
428 CPUState *cs = CPU(ac);
429
430 switch (ac->pe) {
431 case 1:
432 ac->pe = 0;
433 return;
434 case 0:
435 cs->exception_index = EXCP_YIELD;
436 cpu_loop_exit(cs);
437 return;
438 default:
439 g_assert_not_reached();
440 }
441}
442
443void HELPER(sev)(CPUARMState *env)
444{
445 CPUState *cs = CPU(arm_env_get_cpu(env));
446 CPUState *i;
447
448 for (i = first_cpu; i; i = CPU_NEXT(i)) {
449 ARMCPU *ac = ARM_CPU(i);
450 ac->pe = 1;
451 if (i == cs || i->halt_pin || i->reset_pin || i->arch_halt_pin) {
452 continue;
453 }
454 cpu_reset_interrupt(i, CPU_INTERRUPT_HALT);
455 cpu_interrupt(i, CPU_INTERRUPT_EXITTB);
456 i->halted = 0;
457 }
458}
459
460void HELPER(sevl)(CPUARMState *env)
461{
462 ARMCPU *ac = arm_env_get_cpu(env);
463
464 ac->pe = 1;
465}
466
467void HELPER(yield)(CPUARMState *env)
468{
469 ARMCPU *cpu = arm_env_get_cpu(env);
470 CPUState *cs = CPU(cpu);
471
472
473
474
475
476 cs->exception_index = EXCP_YIELD;
477 cpu_loop_exit(cs);
478}
479
480
481
482
483
484
485
486void HELPER(exception_internal)(CPUARMState *env, uint32_t excp)
487{
488 CPUState *cs = CPU(arm_env_get_cpu(env));
489
490 assert(excp_is_internal(excp));
491 cs->exception_index = excp;
492 cpu_loop_exit(cs);
493}
494
495
496void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp,
497 uint32_t syndrome, uint32_t target_el)
498{
499 raise_exception(env, excp, syndrome, target_el);
500}
501
502uint32_t HELPER(cpsr_read)(CPUARMState *env)
503{
504 return cpsr_read(env) & ~(CPSR_EXEC | CPSR_RESERVED);
505}
506
507void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
508{
509 cpsr_write(env, val, mask, CPSRWriteByInstr);
510}
511
512
513void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
514{
515 cpsr_write(env, val, CPSR_ERET_MASK, CPSRWriteExceptionReturn);
516}
517
518
519uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
520{
521 uint32_t val;
522
523 if (regno == 13) {
524 val = env->banked_r13[BANK_USRSYS];
525 } else if (regno == 14) {
526 val = env->banked_r14[BANK_USRSYS];
527 } else if (regno >= 8
528 && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
529 val = env->usr_regs[regno - 8];
530 } else {
531 val = env->regs[regno];
532 }
533 return val;
534}
535
536void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
537{
538 if (regno == 13) {
539 env->banked_r13[BANK_USRSYS] = val;
540 } else if (regno == 14) {
541 env->banked_r14[BANK_USRSYS] = val;
542 } else if (regno >= 8
543 && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
544 env->usr_regs[regno - 8] = val;
545 } else {
546 env->regs[regno] = val;
547 }
548}
549
550void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
551{
552 if ((env->uncached_cpsr & CPSR_M) == mode) {
553 env->regs[13] = val;
554 } else {
555 env->banked_r13[bank_number(mode)] = val;
556 }
557}
558
559uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
560{
561 if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_SYS) {
562
563
564
565 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
566 exception_target_el(env));
567 }
568
569 if ((env->uncached_cpsr & CPSR_M) == mode) {
570 return env->regs[13];
571 } else {
572 return env->banked_r13[bank_number(mode)];
573 }
574}
575
576static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
577 uint32_t regno)
578{
579
580
581
582
583
584 int curmode = env->uncached_cpsr & CPSR_M;
585
586 if (curmode == tgtmode) {
587 goto undef;
588 }
589
590 if (tgtmode == ARM_CPU_MODE_USR) {
591 switch (regno) {
592 case 8 ... 12:
593 if (curmode != ARM_CPU_MODE_FIQ) {
594 goto undef;
595 }
596 break;
597 case 13:
598 if (curmode == ARM_CPU_MODE_SYS) {
599 goto undef;
600 }
601 break;
602 case 14:
603 if (curmode == ARM_CPU_MODE_HYP || curmode == ARM_CPU_MODE_SYS) {
604 goto undef;
605 }
606 break;
607 default:
608 break;
609 }
610 }
611
612 if (tgtmode == ARM_CPU_MODE_HYP) {
613 switch (regno) {
614 case 17:
615 if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
616 goto undef;
617 }
618 break;
619 default:
620 if (curmode != ARM_CPU_MODE_MON) {
621 goto undef;
622 }
623 break;
624 }
625 }
626
627 return;
628
629undef:
630 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
631 exception_target_el(env));
632}
633
634void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
635 uint32_t regno)
636{
637 msr_mrs_banked_exc_checks(env, tgtmode, regno);
638
639 switch (regno) {
640 case 16:
641 env->banked_spsr[bank_number(tgtmode)] = value;
642 break;
643 case 17:
644 env->elr_el[2] = value;
645 break;
646 case 13:
647 env->banked_r13[bank_number(tgtmode)] = value;
648 break;
649 case 14:
650 env->banked_r14[bank_number(tgtmode)] = value;
651 break;
652 case 8 ... 12:
653 switch (tgtmode) {
654 case ARM_CPU_MODE_USR:
655 env->usr_regs[regno - 8] = value;
656 break;
657 case ARM_CPU_MODE_FIQ:
658 env->fiq_regs[regno - 8] = value;
659 break;
660 default:
661 g_assert_not_reached();
662 }
663 break;
664 default:
665 g_assert_not_reached();
666 }
667}
668
669uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
670{
671 msr_mrs_banked_exc_checks(env, tgtmode, regno);
672
673 switch (regno) {
674 case 16:
675 return env->banked_spsr[bank_number(tgtmode)];
676 case 17:
677 return env->elr_el[2];
678 case 13:
679 return env->banked_r13[bank_number(tgtmode)];
680 case 14:
681 return env->banked_r14[bank_number(tgtmode)];
682 case 8 ... 12:
683 switch (tgtmode) {
684 case ARM_CPU_MODE_USR:
685 return env->usr_regs[regno - 8];
686 case ARM_CPU_MODE_FIQ:
687 return env->fiq_regs[regno - 8];
688 default:
689 g_assert_not_reached();
690 }
691 default:
692 g_assert_not_reached();
693 }
694}
695
696void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
697 uint32_t isread)
698{
699 const ARMCPRegInfo *ri = rip;
700 int target_el;
701
702 if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14
703 && extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {
704 raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
705 }
706
707 if (!ri->accessfn) {
708 return;
709 }
710
711 switch (ri->accessfn(env, ri, isread)) {
712 case CP_ACCESS_OK:
713 return;
714 case CP_ACCESS_TRAP:
715 target_el = exception_target_el(env);
716 break;
717 case CP_ACCESS_TRAP_EL2:
718
719
720
721 assert(!arm_is_secure(env) && arm_current_el(env) != 3);
722 target_el = 2;
723 break;
724 case CP_ACCESS_TRAP_EL3:
725 target_el = 3;
726 break;
727 case CP_ACCESS_TRAP_UNCATEGORIZED:
728 target_el = exception_target_el(env);
729 syndrome = syn_uncategorized();
730 break;
731 case CP_ACCESS_TRAP_UNCATEGORIZED_EL2:
732 target_el = 2;
733 syndrome = syn_uncategorized();
734 break;
735 case CP_ACCESS_TRAP_UNCATEGORIZED_EL3:
736 target_el = 3;
737 syndrome = syn_uncategorized();
738 break;
739 case CP_ACCESS_TRAP_FP_EL2:
740 target_el = 2;
741
742
743
744
745
746 syndrome = syn_fp_access_trap(1, 0xe, false);
747 break;
748 case CP_ACCESS_TRAP_FP_EL3:
749 target_el = 3;
750 syndrome = syn_fp_access_trap(1, 0xe, false);
751 break;
752 default:
753 g_assert_not_reached();
754 }
755
756 raise_exception(env, EXCP_UDEF, syndrome, target_el);
757}
758
759void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
760{
761 const ARMCPRegInfo *ri = rip;
762
763 ri->writefn(env, ri, value);
764}
765
766uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)
767{
768 const ARMCPRegInfo *ri = rip;
769
770 return ri->readfn(env, ri);
771}
772
773void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value)
774{
775 const ARMCPRegInfo *ri = rip;
776
777 ri->writefn(env, ri, value);
778}
779
780uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
781{
782 const ARMCPRegInfo *ri = rip;
783
784 return ri->readfn(env, ri);
785}
786
787void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
788{
789
790
791
792
793 if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
794 uint32_t syndrome = syn_aa64_sysregtrap(0, extract32(op, 0, 3),
795 extract32(op, 3, 3), 4,
796 imm, 0x1f, 0);
797 raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
798 }
799
800 switch (op) {
801 case 0x05:
802 update_spsel(env, imm);
803 break;
804 case 0x1e:
805 env->daif |= (imm << 6) & PSTATE_DAIF;
806 break;
807 case 0x1f:
808 env->daif &= ~((imm << 6) & PSTATE_DAIF);
809 break;
810 default:
811 g_assert_not_reached();
812 }
813}
814
815void HELPER(clear_pstate_ss)(CPUARMState *env)
816{
817 env->pstate &= ~PSTATE_SS;
818}
819
820void HELPER(pre_hvc)(CPUARMState *env)
821{
822 ARMCPU *cpu = arm_env_get_cpu(env);
823 int cur_el = arm_current_el(env);
824
825 bool secure = false;
826 bool undef;
827
828 if (arm_is_psci_call(cpu, EXCP_HVC)) {
829
830
831
832 return;
833 }
834
835 if (!arm_feature(env, ARM_FEATURE_EL2)) {
836
837 undef = true;
838 } else if (arm_feature(env, ARM_FEATURE_EL3)) {
839
840 undef = !(env->cp15.scr_el3 & SCR_HCE);
841 } else {
842 undef = env->cp15.hcr_el2 & HCR_HCD;
843 }
844
845
846
847
848
849
850 if (secure && (!is_a64(env) || cur_el == 1)) {
851 undef = true;
852 }
853
854 if (undef) {
855 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
856 exception_target_el(env));
857 }
858}
859
860void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
861{
862 ARMCPU *cpu = arm_env_get_cpu(env);
863 int cur_el = arm_current_el(env);
864 bool secure = arm_is_secure(env);
865 bool smd = env->cp15.scr_el3 & SCR_SMD;
866
867
868
869
870
871
872
873 bool undef = arm_feature(env, ARM_FEATURE_AARCH64) ? smd : smd && !secure;
874
875 if (arm_is_psci_call(cpu, EXCP_SMC)) {
876
877
878
879 return;
880 }
881
882 if (!arm_feature(env, ARM_FEATURE_EL3)) {
883
884 undef = true;
885 } else if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) {
886
887 raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
888 }
889
890 if (undef) {
891 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
892 exception_target_el(env));
893 }
894}
895
896static int el_from_spsr(uint32_t spsr)
897{
898
899
900
901 if (spsr & PSTATE_nRW) {
902 switch (spsr & CPSR_M) {
903 case ARM_CPU_MODE_USR:
904 return 0;
905 case ARM_CPU_MODE_HYP:
906 return 2;
907 case ARM_CPU_MODE_FIQ:
908 case ARM_CPU_MODE_IRQ:
909 case ARM_CPU_MODE_SVC:
910 case ARM_CPU_MODE_ABT:
911 case ARM_CPU_MODE_UND:
912 case ARM_CPU_MODE_SYS:
913 return 1;
914 case ARM_CPU_MODE_MON:
915
916
917
918 default:
919 return -1;
920 }
921 } else {
922 if (extract32(spsr, 1, 1)) {
923
924 return -1;
925 }
926 if (extract32(spsr, 0, 4) == 1) {
927
928 return -1;
929 }
930 return extract32(spsr, 2, 2);
931 }
932}
933
934void HELPER(exception_return)(CPUARMState *env)
935{
936 int cur_el = arm_current_el(env);
937 unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
938 uint32_t spsr = env->banked_spsr[spsr_idx];
939 int new_el;
940 bool return_to_aa64 = (spsr & PSTATE_nRW) == 0;
941
942 aarch64_save_sp(env, cur_el);
943
944 env->exclusive_addr = -1;
945
946
947
948
949
950
951
952
953 if (arm_generate_debug_exceptions(env)) {
954 spsr &= ~PSTATE_SS;
955 }
956
957 new_el = el_from_spsr(spsr);
958 if (new_el == -1) {
959 goto illegal_return;
960 }
961 if (new_el > cur_el
962 || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) {
963
964
965
966 goto illegal_return;
967 }
968
969 if (new_el != 0 && arm_el_is_aa64(env, new_el) != return_to_aa64) {
970
971 goto illegal_return;
972 }
973
974 if (new_el == 2 && arm_is_secure_below_el3(env)) {
975
976 goto illegal_return;
977 }
978
979 if (new_el == 1 && (env->cp15.hcr_el2 & HCR_TGE)
980 && !arm_is_secure_below_el3(env)) {
981 goto illegal_return;
982 }
983
984 if (!return_to_aa64) {
985 env->aarch64 = 0;
986
987
988
989
990 cpsr_write(env, spsr, ~0, CPSRWriteRaw);
991 if (!arm_singlestep_active(env)) {
992 env->uncached_cpsr &= ~PSTATE_SS;
993 }
994 aarch64_sync_64_to_32(env);
995
996 if (spsr & CPSR_T) {
997 env->regs[15] = env->elr_el[cur_el] & ~0x1;
998 } else {
999 env->regs[15] = env->elr_el[cur_el] & ~0x3;
1000 }
1001 } else {
1002 env->aarch64 = 1;
1003 pstate_write(env, spsr);
1004 if (!arm_singlestep_active(env)) {
1005 env->pstate &= ~PSTATE_SS;
1006 }
1007 aarch64_restore_sp(env, new_el);
1008 env->pc = env->elr_el[cur_el];
1009 }
1010
1011 return;
1012
1013illegal_return:
1014
1015
1016
1017
1018
1019
1020
1021 env->pstate |= PSTATE_IL;
1022 env->pc = env->elr_el[cur_el];
1023 spsr &= PSTATE_NZCV | PSTATE_DAIF;
1024 spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
1025 pstate_write(env, spsr);
1026 if (!arm_singlestep_active(env)) {
1027 env->pstate &= ~PSTATE_SS;
1028 }
1029}
1030
1031
1032static bool linked_bp_matches(ARMCPU *cpu, int lbn)
1033{
1034 CPUARMState *env = &cpu->env;
1035 uint64_t bcr = env->cp15.dbgbcr[lbn];
1036 int brps = extract32(cpu->dbgdidr, 24, 4);
1037 int ctx_cmps = extract32(cpu->dbgdidr, 20, 4);
1038 int bt;
1039 uint32_t contextidr;
1040
1041
1042
1043
1044
1045
1046
1047 if (lbn > brps || lbn < (brps - ctx_cmps)) {
1048 return false;
1049 }
1050
1051 bcr = env->cp15.dbgbcr[lbn];
1052
1053 if (extract64(bcr, 0, 1) == 0) {
1054
1055 return false;
1056 }
1057
1058 bt = extract64(bcr, 20, 4);
1059
1060
1061
1062
1063
1064 contextidr = extract64(env->cp15.contextidr_el[1], 0, 32);
1065
1066 switch (bt) {
1067 case 3:
1068 if (arm_current_el(env) > 1) {
1069
1070 return false;
1071 }
1072 return (contextidr == extract64(env->cp15.dbgbvr[lbn], 0, 32));
1073 case 5:
1074 case 9:
1075 case 11:
1076 default:
1077
1078
1079
1080 return false;
1081 }
1082
1083 return false;
1084}
1085
1086static bool bp_wp_matches(ARMCPU *cpu, int n, bool is_wp)
1087{
1088 CPUARMState *env = &cpu->env;
1089 uint64_t cr;
1090 int pac, hmc, ssc, wt, lbn;
1091
1092
1093
1094 bool is_secure = arm_is_secure(env);
1095 int access_el = arm_current_el(env);
1096
1097 if (is_wp) {
1098 CPUWatchpoint *wp = env->cpu_watchpoint[n];
1099
1100 if (!wp || !(wp->flags & BP_WATCHPOINT_HIT)) {
1101 return false;
1102 }
1103 cr = env->cp15.dbgwcr[n];
1104 if (wp->hitattrs.user) {
1105
1106
1107
1108
1109 access_el = 0;
1110 }
1111 } else {
1112 uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
1113
1114 if (!env->cpu_breakpoint[n] || env->cpu_breakpoint[n]->pc != pc) {
1115 return false;
1116 }
1117 cr = env->cp15.dbgbcr[n];
1118 }
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131 pac = extract64(cr, 1, 2);
1132 hmc = extract64(cr, 13, 1);
1133 ssc = extract64(cr, 14, 2);
1134
1135 switch (ssc) {
1136 case 0:
1137 break;
1138 case 1:
1139 case 3:
1140 if (is_secure) {
1141 return false;
1142 }
1143 break;
1144 case 2:
1145 if (!is_secure) {
1146 return false;
1147 }
1148 break;
1149 }
1150
1151 switch (access_el) {
1152 case 3:
1153 case 2:
1154 if (!hmc) {
1155 return false;
1156 }
1157 break;
1158 case 1:
1159 if (extract32(pac, 0, 1) == 0) {
1160 return false;
1161 }
1162 break;
1163 case 0:
1164 if (extract32(pac, 1, 1) == 0) {
1165 return false;
1166 }
1167 break;
1168 default:
1169 g_assert_not_reached();
1170 }
1171
1172 wt = extract64(cr, 20, 1);
1173 lbn = extract64(cr, 16, 4);
1174
1175 if (wt && !linked_bp_matches(cpu, lbn)) {
1176 return false;
1177 }
1178
1179 return true;
1180}
1181
1182static bool check_watchpoints(ARMCPU *cpu)
1183{
1184 CPUARMState *env = &cpu->env;
1185 int n;
1186
1187
1188
1189
1190 if (extract32(env->cp15.mdscr_el1, 15, 1) == 0
1191 || !arm_generate_debug_exceptions(env)) {
1192 return false;
1193 }
1194
1195 for (n = 0; n < ARRAY_SIZE(env->cpu_watchpoint); n++) {
1196 if (bp_wp_matches(cpu, n, true)) {
1197 return true;
1198 }
1199 }
1200 return false;
1201}
1202
1203static bool check_breakpoints(ARMCPU *cpu)
1204{
1205 CPUARMState *env = &cpu->env;
1206 int n;
1207
1208
1209
1210
1211 if (extract32(env->cp15.mdscr_el1, 15, 1) == 0
1212 || !arm_generate_debug_exceptions(env)) {
1213 return false;
1214 }
1215
1216 for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {
1217 if (bp_wp_matches(cpu, n, false)) {
1218 return true;
1219 }
1220 }
1221 return false;
1222}
1223
1224void HELPER(check_breakpoints)(CPUARMState *env)
1225{
1226 ARMCPU *cpu = arm_env_get_cpu(env);
1227
1228 if (check_breakpoints(cpu)) {
1229 HELPER(exception_internal(env, EXCP_DEBUG));
1230 }
1231}
1232
1233bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
1234{
1235
1236
1237
1238 ARMCPU *cpu = ARM_CPU(cs);
1239
1240 return check_watchpoints(cpu);
1241}
1242
1243void arm_debug_excp_handler(CPUState *cs)
1244{
1245
1246
1247
1248 ARMCPU *cpu = ARM_CPU(cs);
1249 CPUARMState *env = &cpu->env;
1250 CPUWatchpoint *wp_hit = cs->watchpoint_hit;
1251
1252 if (wp_hit) {
1253 if (wp_hit->flags & BP_CPU) {
1254 bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;
1255 bool same_el = arm_debug_target_el(env) == arm_current_el(env);
1256
1257 cs->watchpoint_hit = NULL;
1258
1259 if (extended_addresses_enabled(env)) {
1260 env->exception.fsr = (1 << 9) | 0x22;
1261 } else {
1262 env->exception.fsr = 0x2;
1263 }
1264 env->exception.vaddress = wp_hit->hitaddr;
1265 raise_exception(env, EXCP_DATA_ABORT,
1266 syn_watchpoint(same_el, 0, wnr),
1267 arm_debug_target_el(env));
1268 }
1269 } else {
1270 uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
1271 bool same_el = (arm_debug_target_el(env) == arm_current_el(env));
1272
1273
1274
1275
1276
1277
1278 if (cpu_breakpoint_test(cs, pc, BP_GDB)
1279 || !cpu_breakpoint_test(cs, pc, BP_CPU)) {
1280 return;
1281 }
1282
1283 if (extended_addresses_enabled(env)) {
1284 env->exception.fsr = (1 << 9) | 0x22;
1285 } else {
1286 env->exception.fsr = 0x2;
1287 }
1288
1289 raise_exception(env, EXCP_PREFETCH_ABORT,
1290 syn_breakpoint(same_el),
1291 arm_debug_target_el(env));
1292 }
1293}
1294
1295
1296
1297
1298
1299
1300
1301uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i)
1302{
1303 int shift = i & 0xff;
1304 if (shift >= 32) {
1305 if (shift == 32)
1306 env->CF = x & 1;
1307 else
1308 env->CF = 0;
1309 return 0;
1310 } else if (shift != 0) {
1311 env->CF = (x >> (32 - shift)) & 1;
1312 return x << shift;
1313 }
1314 return x;
1315}
1316
1317uint32_t HELPER(shr_cc)(CPUARMState *env, uint32_t x, uint32_t i)
1318{
1319 int shift = i & 0xff;
1320 if (shift >= 32) {
1321 if (shift == 32)
1322 env->CF = (x >> 31) & 1;
1323 else
1324 env->CF = 0;
1325 return 0;
1326 } else if (shift != 0) {
1327 env->CF = (x >> (shift - 1)) & 1;
1328 return x >> shift;
1329 }
1330 return x;
1331}
1332
1333uint32_t HELPER(sar_cc)(CPUARMState *env, uint32_t x, uint32_t i)
1334{
1335 int shift = i & 0xff;
1336 if (shift >= 32) {
1337 env->CF = (x >> 31) & 1;
1338 return (int32_t)x >> 31;
1339 } else if (shift != 0) {
1340 env->CF = (x >> (shift - 1)) & 1;
1341 return (int32_t)x >> shift;
1342 }
1343 return x;
1344}
1345
1346uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i)
1347{
1348 int shift1, shift;
1349 shift1 = i & 0xff;
1350 shift = shift1 & 0x1f;
1351 if (shift == 0) {
1352 if (shift1 != 0)
1353 env->CF = (x >> 31) & 1;
1354 return x;
1355 } else {
1356 env->CF = (x >> (shift - 1)) & 1;
1357 return ((uint32_t)x >> shift) | (x << (32 - shift));
1358 }
1359}
1360