]> Git Repo - qemu.git/blob - target/arm/op_helper.c
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
[qemu.git] / target / arm / op_helper.c
1 /*
2  *  ARM helper routines
3  *
4  *  Copyright (c) 2005-2007 CodeSourcery, LLC
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 #include "qemu/osdep.h"
20 #include "qemu/log.h"
21 #include "qemu/main-loop.h"
22 #include "cpu.h"
23 #include "exec/helper-proto.h"
24 #include "internals.h"
25 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
27
28 #define SIGNBIT (uint32_t)0x80000000
29 #define SIGNBIT64 ((uint64_t)1 << 63)
30
31 static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
32                                     uint32_t syndrome, uint32_t target_el)
33 {
34     CPUState *cs = env_cpu(env);
35
36     if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
37         /*
38          * Redirect NS EL1 exceptions to NS EL2. These are reported with
39          * their original syndrome register value, with the exception of
40          * SIMD/FP access traps, which are reported as uncategorized
41          * (see DDI0478C.a D1.10.4)
42          */
43         target_el = 2;
44         if (syn_get_ec(syndrome) == EC_ADVSIMDFPACCESSTRAP) {
45             syndrome = syn_uncategorized();
46         }
47     }
48
49     assert(!excp_is_internal(excp));
50     cs->exception_index = excp;
51     env->exception.syndrome = syndrome;
52     env->exception.target_el = target_el;
53
54     return cs;
55 }
56
57 void raise_exception(CPUARMState *env, uint32_t excp,
58                      uint32_t syndrome, uint32_t target_el)
59 {
60     CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
61     cpu_loop_exit(cs);
62 }
63
64 void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
65                         uint32_t target_el, uintptr_t ra)
66 {
67     CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
68     cpu_loop_exit_restore(cs, ra);
69 }
70
71 uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, void *vn,
72                           uint32_t maxindex)
73 {
74     uint32_t val, shift;
75     uint64_t *table = vn;
76
77     val = 0;
78     for (shift = 0; shift < 32; shift += 8) {
79         uint32_t index = (ireg >> shift) & 0xff;
80         if (index < maxindex) {
81             uint32_t tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff;
82             val |= tmp << shift;
83         } else {
84             val |= def & (0xff << shift);
85         }
86     }
87     return val;
88 }
89
90 void HELPER(v8m_stackcheck)(CPUARMState *env, uint32_t newvalue)
91 {
92     /*
93      * Perform the v8M stack limit check for SP updates from translated code,
94      * raising an exception if the limit is breached.
95      */
96     if (newvalue < v7m_sp_limit(env)) {
97         CPUState *cs = env_cpu(env);
98
99         /*
100          * Stack limit exceptions are a rare case, so rather than syncing
101          * PC/condbits before the call, we use cpu_restore_state() to
102          * get them right before raising the exception.
103          */
104         cpu_restore_state(cs, GETPC(), true);
105         raise_exception(env, EXCP_STKOF, 0, 1);
106     }
107 }
108
109 uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
110 {
111     uint32_t res = a + b;
112     if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT))
113         env->QF = 1;
114     return res;
115 }
116
117 uint32_t HELPER(add_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
118 {
119     uint32_t res = a + b;
120     if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) {
121         env->QF = 1;
122         res = ~(((int32_t)a >> 31) ^ SIGNBIT);
123     }
124     return res;
125 }
126
127 uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
128 {
129     uint32_t res = a - b;
130     if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) {
131         env->QF = 1;
132         res = ~(((int32_t)a >> 31) ^ SIGNBIT);
133     }
134     return res;
135 }
136
137 uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
138 {
139     uint32_t res = a + b;
140     if (res < a) {
141         env->QF = 1;
142         res = ~0;
143     }
144     return res;
145 }
146
147 uint32_t HELPER(sub_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
148 {
149     uint32_t res = a - b;
150     if (res > a) {
151         env->QF = 1;
152         res = 0;
153     }
154     return res;
155 }
156
157 /* Signed saturation.  */
158 static inline uint32_t do_ssat(CPUARMState *env, int32_t val, int shift)
159 {
160     int32_t top;
161     uint32_t mask;
162
163     top = val >> shift;
164     mask = (1u << shift) - 1;
165     if (top > 0) {
166         env->QF = 1;
167         return mask;
168     } else if (top < -1) {
169         env->QF = 1;
170         return ~mask;
171     }
172     return val;
173 }
174
175 /* Unsigned saturation.  */
176 static inline uint32_t do_usat(CPUARMState *env, int32_t val, int shift)
177 {
178     uint32_t max;
179
180     max = (1u << shift) - 1;
181     if (val < 0) {
182         env->QF = 1;
183         return 0;
184     } else if (val > max) {
185         env->QF = 1;
186         return max;
187     }
188     return val;
189 }
190
191 /* Signed saturate.  */
192 uint32_t HELPER(ssat)(CPUARMState *env, uint32_t x, uint32_t shift)
193 {
194     return do_ssat(env, x, shift);
195 }
196
197 /* Dual halfword signed saturate.  */
198 uint32_t HELPER(ssat16)(CPUARMState *env, uint32_t x, uint32_t shift)
199 {
200     uint32_t res;
201
202     res = (uint16_t)do_ssat(env, (int16_t)x, shift);
203     res |= do_ssat(env, ((int32_t)x) >> 16, shift) << 16;
204     return res;
205 }
206
207 /* Unsigned saturate.  */
208 uint32_t HELPER(usat)(CPUARMState *env, uint32_t x, uint32_t shift)
209 {
210     return do_usat(env, x, shift);
211 }
212
213 /* Dual halfword unsigned saturate.  */
214 uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift)
215 {
216     uint32_t res;
217
218     res = (uint16_t)do_usat(env, (int16_t)x, shift);
219     res |= do_usat(env, ((int32_t)x) >> 16, shift) << 16;
220     return res;
221 }
222
223 void HELPER(setend)(CPUARMState *env)
224 {
225     env->uncached_cpsr ^= CPSR_E;
226     arm_rebuild_hflags(env);
227 }
228
229 /* Function checks whether WFx (WFI/WFE) instructions are set up to be trapped.
230  * The function returns the target EL (1-3) if the instruction is to be trapped;
231  * otherwise it returns 0 indicating it is not trapped.
232  */
233 static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
234 {
235     int cur_el = arm_current_el(env);
236     uint64_t mask;
237
238     if (arm_feature(env, ARM_FEATURE_M)) {
239         /* M profile cores can never trap WFI/WFE. */
240         return 0;
241     }
242
243     /* If we are currently in EL0 then we need to check if SCTLR is set up for
244      * WFx instructions being trapped to EL1. These trap bits don't exist in v7.
245      */
246     if (cur_el < 1 && arm_feature(env, ARM_FEATURE_V8)) {
247         int target_el;
248
249         mask = is_wfe ? SCTLR_nTWE : SCTLR_nTWI;
250         if (arm_is_secure_below_el3(env) && !arm_el_is_aa64(env, 3)) {
251             /* Secure EL0 and Secure PL1 is at EL3 */
252             target_el = 3;
253         } else {
254             target_el = 1;
255         }
256
257         if (!(env->cp15.sctlr_el[target_el] & mask)) {
258             return target_el;
259         }
260     }
261
262     /* We are not trapping to EL1; trap to EL2 if HCR_EL2 requires it
263      * No need for ARM_FEATURE check as if HCR_EL2 doesn't exist the
264      * bits will be zero indicating no trap.
265      */
266     if (cur_el < 2) {
267         mask = is_wfe ? HCR_TWE : HCR_TWI;
268         if (arm_hcr_el2_eff(env) & mask) {
269             return 2;
270         }
271     }
272
273     /* We are not trapping to EL1 or EL2; trap to EL3 if SCR_EL3 requires it */
274     if (cur_el < 3) {
275         mask = (is_wfe) ? SCR_TWE : SCR_TWI;
276         if (env->cp15.scr_el3 & mask) {
277             return 3;
278         }
279     }
280
281     return 0;
282 }
283
284 void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
285 {
286     CPUState *cs = env_cpu(env);
287     int target_el = check_wfx_trap(env, false);
288
289     if (cpu_has_work(cs)) {
290         /* Don't bother to go into our "low power state" if
291          * we would just wake up immediately.
292          */
293         return;
294     }
295
296     if (target_el) {
297         if (env->aarch64) {
298             env->pc -= insn_len;
299         } else {
300             env->regs[15] -= insn_len;
301         }
302
303         raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2),
304                         target_el);
305     }
306
307     cs->exception_index = EXCP_HLT;
308     cs->halted = 1;
309     cpu_loop_exit(cs);
310 }
311
312 void HELPER(wfe)(CPUARMState *env)
313 {
314     /* This is a hint instruction that is semantically different
315      * from YIELD even though we currently implement it identically.
316      * Don't actually halt the CPU, just yield back to top
317      * level loop. This is not going into a "low power state"
318      * (ie halting until some event occurs), so we never take
319      * a configurable trap to a different exception level.
320      */
321     HELPER(yield)(env);
322 }
323
324 void HELPER(yield)(CPUARMState *env)
325 {
326     CPUState *cs = env_cpu(env);
327
328     /* This is a non-trappable hint instruction that generally indicates
329      * that the guest is currently busy-looping. Yield control back to the
330      * top level loop so that a more deserving VCPU has a chance to run.
331      */
332     cs->exception_index = EXCP_YIELD;
333     cpu_loop_exit(cs);
334 }
335
336 /* Raise an internal-to-QEMU exception. This is limited to only
337  * those EXCP values which are special cases for QEMU to interrupt
338  * execution and not to be used for exceptions which are passed to
339  * the guest (those must all have syndrome information and thus should
340  * use exception_with_syndrome).
341  */
342 void HELPER(exception_internal)(CPUARMState *env, uint32_t excp)
343 {
344     CPUState *cs = env_cpu(env);
345
346     assert(excp_is_internal(excp));
347     cs->exception_index = excp;
348     cpu_loop_exit(cs);
349 }
350
351 /* Raise an exception with the specified syndrome register value */
352 void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp,
353                                      uint32_t syndrome, uint32_t target_el)
354 {
355     raise_exception(env, excp, syndrome, target_el);
356 }
357
358 /* Raise an EXCP_BKPT with the specified syndrome register value,
359  * targeting the correct exception level for debug exceptions.
360  */
361 void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
362 {
363     int debug_el = arm_debug_target_el(env);
364     int cur_el = arm_current_el(env);
365
366     /* FSR will only be used if the debug target EL is AArch32. */
367     env->exception.fsr = arm_debug_exception_fsr(env);
368     /* FAR is UNKNOWN: clear vaddress to avoid potentially exposing
369      * values to the guest that it shouldn't be able to see at its
370      * exception/security level.
371      */
372     env->exception.vaddress = 0;
373     /*
374      * Other kinds of architectural debug exception are ignored if
375      * they target an exception level below the current one (in QEMU
376      * this is checked by arm_generate_debug_exceptions()). Breakpoint
377      * instructions are special because they always generate an exception
378      * to somewhere: if they can't go to the configured debug exception
379      * level they are taken to the current exception level.
380      */
381     if (debug_el < cur_el) {
382         debug_el = cur_el;
383     }
384     raise_exception(env, EXCP_BKPT, syndrome, debug_el);
385 }
386
387 uint32_t HELPER(cpsr_read)(CPUARMState *env)
388 {
389     /*
390      * We store the ARMv8 PSTATE.SS bit in env->uncached_cpsr.
391      * This is convenient for populating SPSR_ELx, but must be
392      * hidden from aarch32 mode, where it is not visible.
393      *
394      * TODO: ARMv8.4-DIT -- need to move SS somewhere else.
395      */
396     return cpsr_read(env) & ~(CPSR_EXEC | PSTATE_SS);
397 }
398
399 void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
400 {
401     cpsr_write(env, val, mask, CPSRWriteByInstr);
402     /* TODO: Not all cpsr bits are relevant to hflags.  */
403     arm_rebuild_hflags(env);
404 }
405
406 /* Write the CPSR for a 32-bit exception return */
407 void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
408 {
409     uint32_t mask;
410
411     qemu_mutex_lock_iothread();
412     arm_call_pre_el_change_hook(env_archcpu(env));
413     qemu_mutex_unlock_iothread();
414
415     mask = aarch32_cpsr_valid_mask(env->features, &env_archcpu(env)->isar);
416     cpsr_write(env, val, mask, CPSRWriteExceptionReturn);
417
418     /* Generated code has already stored the new PC value, but
419      * without masking out its low bits, because which bits need
420      * masking depends on whether we're returning to Thumb or ARM
421      * state. Do the masking now.
422      */
423     env->regs[15] &= (env->thumb ? ~1 : ~3);
424     arm_rebuild_hflags(env);
425
426     qemu_mutex_lock_iothread();
427     arm_call_el_change_hook(env_archcpu(env));
428     qemu_mutex_unlock_iothread();
429 }
430
431 /* Access to user mode registers from privileged modes.  */
432 uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
433 {
434     uint32_t val;
435
436     if (regno == 13) {
437         val = env->banked_r13[BANK_USRSYS];
438     } else if (regno == 14) {
439         val = env->banked_r14[BANK_USRSYS];
440     } else if (regno >= 8
441                && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
442         val = env->usr_regs[regno - 8];
443     } else {
444         val = env->regs[regno];
445     }
446     return val;
447 }
448
449 void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
450 {
451     if (regno == 13) {
452         env->banked_r13[BANK_USRSYS] = val;
453     } else if (regno == 14) {
454         env->banked_r14[BANK_USRSYS] = val;
455     } else if (regno >= 8
456                && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
457         env->usr_regs[regno - 8] = val;
458     } else {
459         env->regs[regno] = val;
460     }
461 }
462
463 void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
464 {
465     if ((env->uncached_cpsr & CPSR_M) == mode) {
466         env->regs[13] = val;
467     } else {
468         env->banked_r13[bank_number(mode)] = val;
469     }
470 }
471
472 uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
473 {
474     if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_SYS) {
475         /* SRS instruction is UNPREDICTABLE from System mode; we UNDEF.
476          * Other UNPREDICTABLE and UNDEF cases were caught at translate time.
477          */
478         raise_exception(env, EXCP_UDEF, syn_uncategorized(),
479                         exception_target_el(env));
480     }
481
482     if ((env->uncached_cpsr & CPSR_M) == mode) {
483         return env->regs[13];
484     } else {
485         return env->banked_r13[bank_number(mode)];
486     }
487 }
488
489 static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
490                                       uint32_t regno)
491 {
492     /* Raise an exception if the requested access is one of the UNPREDICTABLE
493      * cases; otherwise return. This broadly corresponds to the pseudocode
494      * BankedRegisterAccessValid() and SPSRAccessValid(),
495      * except that we have already handled some cases at translate time.
496      */
497     int curmode = env->uncached_cpsr & CPSR_M;
498
499     if (regno == 17) {
500         /* ELR_Hyp: a special case because access from tgtmode is OK */
501         if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
502             goto undef;
503         }
504         return;
505     }
506
507     if (curmode == tgtmode) {
508         goto undef;
509     }
510
511     if (tgtmode == ARM_CPU_MODE_USR) {
512         switch (regno) {
513         case 8 ... 12:
514             if (curmode != ARM_CPU_MODE_FIQ) {
515                 goto undef;
516             }
517             break;
518         case 13:
519             if (curmode == ARM_CPU_MODE_SYS) {
520                 goto undef;
521             }
522             break;
523         case 14:
524             if (curmode == ARM_CPU_MODE_HYP || curmode == ARM_CPU_MODE_SYS) {
525                 goto undef;
526             }
527             break;
528         default:
529             break;
530         }
531     }
532
533     if (tgtmode == ARM_CPU_MODE_HYP) {
534         /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
535         if (curmode != ARM_CPU_MODE_MON) {
536             goto undef;
537         }
538     }
539
540     return;
541
542 undef:
543     raise_exception(env, EXCP_UDEF, syn_uncategorized(),
544                     exception_target_el(env));
545 }
546
547 void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
548                         uint32_t regno)
549 {
550     msr_mrs_banked_exc_checks(env, tgtmode, regno);
551
552     switch (regno) {
553     case 16: /* SPSRs */
554         env->banked_spsr[bank_number(tgtmode)] = value;
555         break;
556     case 17: /* ELR_Hyp */
557         env->elr_el[2] = value;
558         break;
559     case 13:
560         env->banked_r13[bank_number(tgtmode)] = value;
561         break;
562     case 14:
563         env->banked_r14[r14_bank_number(tgtmode)] = value;
564         break;
565     case 8 ... 12:
566         switch (tgtmode) {
567         case ARM_CPU_MODE_USR:
568             env->usr_regs[regno - 8] = value;
569             break;
570         case ARM_CPU_MODE_FIQ:
571             env->fiq_regs[regno - 8] = value;
572             break;
573         default:
574             g_assert_not_reached();
575         }
576         break;
577     default:
578         g_assert_not_reached();
579     }
580 }
581
582 uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
583 {
584     msr_mrs_banked_exc_checks(env, tgtmode, regno);
585
586     switch (regno) {
587     case 16: /* SPSRs */
588         return env->banked_spsr[bank_number(tgtmode)];
589     case 17: /* ELR_Hyp */
590         return env->elr_el[2];
591     case 13:
592         return env->banked_r13[bank_number(tgtmode)];
593     case 14:
594         return env->banked_r14[r14_bank_number(tgtmode)];
595     case 8 ... 12:
596         switch (tgtmode) {
597         case ARM_CPU_MODE_USR:
598             return env->usr_regs[regno - 8];
599         case ARM_CPU_MODE_FIQ:
600             return env->fiq_regs[regno - 8];
601         default:
602             g_assert_not_reached();
603         }
604     default:
605         g_assert_not_reached();
606     }
607 }
608
609 void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
610                                  uint32_t isread)
611 {
612     const ARMCPRegInfo *ri = rip;
613     int target_el;
614
615     if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14
616         && extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {
617         raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
618     }
619
620     /*
621      * Check for an EL2 trap due to HSTR_EL2. We expect EL0 accesses
622      * to sysregs non accessible at EL0 to have UNDEF-ed already.
623      */
624     if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
625         (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
626         uint32_t mask = 1 << ri->crn;
627
628         if (ri->type & ARM_CP_64BIT) {
629             mask = 1 << ri->crm;
630         }
631
632         /* T4 and T14 are RES0 */
633         mask &= ~((1 << 4) | (1 << 14));
634
635         if (env->cp15.hstr_el2 & mask) {
636             target_el = 2;
637             goto exept;
638         }
639     }
640
641     if (!ri->accessfn) {
642         return;
643     }
644
645     switch (ri->accessfn(env, ri, isread)) {
646     case CP_ACCESS_OK:
647         return;
648     case CP_ACCESS_TRAP:
649         target_el = exception_target_el(env);
650         break;
651     case CP_ACCESS_TRAP_EL2:
652         /* Requesting a trap to EL2 when we're in EL3 or S-EL0/1 is
653          * a bug in the access function.
654          */
655         assert(!arm_is_secure(env) && arm_current_el(env) != 3);
656         target_el = 2;
657         break;
658     case CP_ACCESS_TRAP_EL3:
659         target_el = 3;
660         break;
661     case CP_ACCESS_TRAP_UNCATEGORIZED:
662         target_el = exception_target_el(env);
663         syndrome = syn_uncategorized();
664         break;
665     case CP_ACCESS_TRAP_UNCATEGORIZED_EL2:
666         target_el = 2;
667         syndrome = syn_uncategorized();
668         break;
669     case CP_ACCESS_TRAP_UNCATEGORIZED_EL3:
670         target_el = 3;
671         syndrome = syn_uncategorized();
672         break;
673     case CP_ACCESS_TRAP_FP_EL2:
674         target_el = 2;
675         /* Since we are an implementation that takes exceptions on a trapped
676          * conditional insn only if the insn has passed its condition code
677          * check, we take the IMPDEF choice to always report CV=1 COND=0xe
678          * (which is also the required value for AArch64 traps).
679          */
680         syndrome = syn_fp_access_trap(1, 0xe, false);
681         break;
682     case CP_ACCESS_TRAP_FP_EL3:
683         target_el = 3;
684         syndrome = syn_fp_access_trap(1, 0xe, false);
685         break;
686     default:
687         g_assert_not_reached();
688     }
689
690 exept:
691     raise_exception(env, EXCP_UDEF, syndrome, target_el);
692 }
693
694 void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
695 {
696     const ARMCPRegInfo *ri = rip;
697
698     if (ri->type & ARM_CP_IO) {
699         qemu_mutex_lock_iothread();
700         ri->writefn(env, ri, value);
701         qemu_mutex_unlock_iothread();
702     } else {
703         ri->writefn(env, ri, value);
704     }
705 }
706
707 uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)
708 {
709     const ARMCPRegInfo *ri = rip;
710     uint32_t res;
711
712     if (ri->type & ARM_CP_IO) {
713         qemu_mutex_lock_iothread();
714         res = ri->readfn(env, ri);
715         qemu_mutex_unlock_iothread();
716     } else {
717         res = ri->readfn(env, ri);
718     }
719
720     return res;
721 }
722
723 void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value)
724 {
725     const ARMCPRegInfo *ri = rip;
726
727     if (ri->type & ARM_CP_IO) {
728         qemu_mutex_lock_iothread();
729         ri->writefn(env, ri, value);
730         qemu_mutex_unlock_iothread();
731     } else {
732         ri->writefn(env, ri, value);
733     }
734 }
735
736 uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
737 {
738     const ARMCPRegInfo *ri = rip;
739     uint64_t res;
740
741     if (ri->type & ARM_CP_IO) {
742         qemu_mutex_lock_iothread();
743         res = ri->readfn(env, ri);
744         qemu_mutex_unlock_iothread();
745     } else {
746         res = ri->readfn(env, ri);
747     }
748
749     return res;
750 }
751
752 void HELPER(pre_hvc)(CPUARMState *env)
753 {
754     ARMCPU *cpu = env_archcpu(env);
755     int cur_el = arm_current_el(env);
756     /* FIXME: Use actual secure state.  */
757     bool secure = false;
758     bool undef;
759
760     if (arm_is_psci_call(cpu, EXCP_HVC)) {
761         /* If PSCI is enabled and this looks like a valid PSCI call then
762          * that overrides the architecturally mandated HVC behaviour.
763          */
764         return;
765     }
766
767     if (!arm_feature(env, ARM_FEATURE_EL2)) {
768         /* If EL2 doesn't exist, HVC always UNDEFs */
769         undef = true;
770     } else if (arm_feature(env, ARM_FEATURE_EL3)) {
771         /* EL3.HCE has priority over EL2.HCD. */
772         undef = !(env->cp15.scr_el3 & SCR_HCE);
773     } else {
774         undef = env->cp15.hcr_el2 & HCR_HCD;
775     }
776
777     /* In ARMv7 and ARMv8/AArch32, HVC is undef in secure state.
778      * For ARMv8/AArch64, HVC is allowed in EL3.
779      * Note that we've already trapped HVC from EL0 at translation
780      * time.
781      */
782     if (secure && (!is_a64(env) || cur_el == 1)) {
783         undef = true;
784     }
785
786     if (undef) {
787         raise_exception(env, EXCP_UDEF, syn_uncategorized(),
788                         exception_target_el(env));
789     }
790 }
791
792 void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
793 {
794     ARMCPU *cpu = env_archcpu(env);
795     int cur_el = arm_current_el(env);
796     bool secure = arm_is_secure(env);
797     bool smd_flag = env->cp15.scr_el3 & SCR_SMD;
798
799     /*
800      * SMC behaviour is summarized in the following table.
801      * This helper handles the "Trap to EL2" and "Undef insn" cases.
802      * The "Trap to EL3" and "PSCI call" cases are handled in the exception
803      * helper.
804      *
805      *  -> ARM_FEATURE_EL3 and !SMD
806      *                           HCR_TSC && NS EL1   !HCR_TSC || !NS EL1
807      *
808      *  Conduit SMC, valid call  Trap to EL2         PSCI Call
809      *  Conduit SMC, inval call  Trap to EL2         Trap to EL3
810      *  Conduit not SMC          Trap to EL2         Trap to EL3
811      *
812      *
813      *  -> ARM_FEATURE_EL3 and SMD
814      *                           HCR_TSC && NS EL1   !HCR_TSC || !NS EL1
815      *
816      *  Conduit SMC, valid call  Trap to EL2         PSCI Call
817      *  Conduit SMC, inval call  Trap to EL2         Undef insn
818      *  Conduit not SMC          Trap to EL2         Undef insn
819      *
820      *
821      *  -> !ARM_FEATURE_EL3
822      *                           HCR_TSC && NS EL1   !HCR_TSC || !NS EL1
823      *
824      *  Conduit SMC, valid call  Trap to EL2         PSCI Call
825      *  Conduit SMC, inval call  Trap to EL2         Undef insn
826      *  Conduit not SMC          Undef insn          Undef insn
827      */
828
829     /* On ARMv8 with EL3 AArch64, SMD applies to both S and NS state.
830      * On ARMv8 with EL3 AArch32, or ARMv7 with the Virtualization
831      *  extensions, SMD only applies to NS state.
832      * On ARMv7 without the Virtualization extensions, the SMD bit
833      * doesn't exist, but we forbid the guest to set it to 1 in scr_write(),
834      * so we need not special case this here.
835      */
836     bool smd = arm_feature(env, ARM_FEATURE_AARCH64) ? smd_flag
837                                                      : smd_flag && !secure;
838
839     if (!arm_feature(env, ARM_FEATURE_EL3) &&
840         cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
841         /* If we have no EL3 then SMC always UNDEFs and can't be
842          * trapped to EL2. PSCI-via-SMC is a sort of ersatz EL3
843          * firmware within QEMU, and we want an EL2 guest to be able
844          * to forbid its EL1 from making PSCI calls into QEMU's
845          * "firmware" via HCR.TSC, so for these purposes treat
846          * PSCI-via-SMC as implying an EL3.
847          * This handles the very last line of the previous table.
848          */
849         raise_exception(env, EXCP_UDEF, syn_uncategorized(),
850                         exception_target_el(env));
851     }
852
853     if (cur_el == 1 && (arm_hcr_el2_eff(env) & HCR_TSC)) {
854         /* In NS EL1, HCR controlled routing to EL2 has priority over SMD.
855          * We also want an EL2 guest to be able to forbid its EL1 from
856          * making PSCI calls into QEMU's "firmware" via HCR.TSC.
857          * This handles all the "Trap to EL2" cases of the previous table.
858          */
859         raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
860     }
861
862     /* Catch the two remaining "Undef insn" cases of the previous table:
863      *    - PSCI conduit is SMC but we don't have a valid PCSI call,
864      *    - We don't have EL3 or SMD is set.
865      */
866     if (!arm_is_psci_call(cpu, EXCP_SMC) &&
867         (smd || !arm_feature(env, ARM_FEATURE_EL3))) {
868         raise_exception(env, EXCP_UDEF, syn_uncategorized(),
869                         exception_target_el(env));
870     }
871 }
872
873 /* ??? Flag setting arithmetic is awkward because we need to do comparisons.
874    The only way to do that in TCG is a conditional branch, which clobbers
875    all our temporaries.  For now implement these as helper functions.  */
876
877 /* Similarly for variable shift instructions.  */
878
879 uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i)
880 {
881     int shift = i & 0xff;
882     if (shift >= 32) {
883         if (shift == 32)
884             env->CF = x & 1;
885         else
886             env->CF = 0;
887         return 0;
888     } else if (shift != 0) {
889         env->CF = (x >> (32 - shift)) & 1;
890         return x << shift;
891     }
892     return x;
893 }
894
895 uint32_t HELPER(shr_cc)(CPUARMState *env, uint32_t x, uint32_t i)
896 {
897     int shift = i & 0xff;
898     if (shift >= 32) {
899         if (shift == 32)
900             env->CF = (x >> 31) & 1;
901         else
902             env->CF = 0;
903         return 0;
904     } else if (shift != 0) {
905         env->CF = (x >> (shift - 1)) & 1;
906         return x >> shift;
907     }
908     return x;
909 }
910
911 uint32_t HELPER(sar_cc)(CPUARMState *env, uint32_t x, uint32_t i)
912 {
913     int shift = i & 0xff;
914     if (shift >= 32) {
915         env->CF = (x >> 31) & 1;
916         return (int32_t)x >> 31;
917     } else if (shift != 0) {
918         env->CF = (x >> (shift - 1)) & 1;
919         return (int32_t)x >> shift;
920     }
921     return x;
922 }
923
924 uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i)
925 {
926     int shift1, shift;
927     shift1 = i & 0xff;
928     shift = shift1 & 0x1f;
929     if (shift == 0) {
930         if (shift1 != 0)
931             env->CF = (x >> 31) & 1;
932         return x;
933     } else {
934         env->CF = (x >> (shift - 1)) & 1;
935         return ((uint32_t)x >> shift) | (x << (32 - shift));
936     }
937 }
This page took 0.075793 seconds and 4 git commands to generate.