]> Git Repo - qemu.git/blame - target/arm/op_helper.c
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
[qemu.git] / target / arm / op_helper.c
CommitLineData
b7bcbe95
FB
1/*
2 * ARM helper routines
5fafdf24 3 *
9ee6e8bb 4 * Copyright (c) 2005-2007 CodeSourcery, LLC
b7bcbe95
FB
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
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
b7bcbe95 18 */
74c21bd0 19#include "qemu/osdep.h"
c9b61d9a 20#include "qemu/log.h"
8d04fb55 21#include "qemu/main-loop.h"
3e457172 22#include "cpu.h"
2ef6175a 23#include "exec/helper-proto.h"
ccd38087 24#include "internals.h"
63c91552 25#include "exec/exec-all.h"
f08b6170 26#include "exec/cpu_ldst.h"
b7bcbe95 27
ad69471c
PB
28#define SIGNBIT (uint32_t)0x80000000
29#define SIGNBIT64 ((uint64_t)1 << 63)
30
7469f6c6
RH
31static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
32 uint32_t syndrome, uint32_t target_el)
b7bcbe95 33{
2fc0cc0e 34 CPUState *cs = env_cpu(env);
27103424 35
7c208e0f 36 if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
7556edfb
PM
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;
64b91e3f 44 if (syn_get_ec(syndrome) == EC_ADVSIMDFPACCESSTRAP) {
7556edfb
PM
45 syndrome = syn_uncategorized();
46 }
47 }
48
c6328599
PM
49 assert(!excp_is_internal(excp));
50 cs->exception_index = excp;
51 env->exception.syndrome = syndrome;
52 env->exception.target_el = target_el;
7469f6c6
RH
53
54 return cs;
55}
56
57void 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);
5638d180 61 cpu_loop_exit(cs);
b7bcbe95
FB
62}
63
7469f6c6
RH
64void 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
e7c06c4e
RH
71uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, void *vn,
72 uint32_t maxindex)
9ee6e8bb 73{
e7c06c4e
RH
74 uint32_t val, shift;
75 uint64_t *table = vn;
76
9ee6e8bb 77 val = 0;
9ee6e8bb 78 for (shift = 0; shift < 32; shift += 8) {
e7c06c4e 79 uint32_t index = (ireg >> shift) & 0xff;
8f8e3aa4 80 if (index < maxindex) {
e7c06c4e 81 uint32_t tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff;
9ee6e8bb
PB
82 val |= tmp << shift;
83 } else {
8f8e3aa4 84 val |= def & (0xff << shift);
9ee6e8bb
PB
85 }
86 }
8f8e3aa4 87 return val;
9ee6e8bb
PB
88}
89
55203189
PM
90void 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)) {
2fc0cc0e 97 CPUState *cs = env_cpu(env);
55203189
PM
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
9ef39277 109uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
1497c961
PB
110{
111 uint32_t res = a + b;
112 if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT))
113 env->QF = 1;
114 return res;
115}
116
9ef39277 117uint32_t HELPER(add_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
1497c961
PB
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
9ef39277 127uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
1497c961
PB
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
9ef39277 137uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
1497c961
PB
138{
139 uint32_t res = a + b;
140 if (res < a) {
141 env->QF = 1;
142 res = ~0;
143 }
144 return res;
145}
146
9ef39277 147uint32_t HELPER(sub_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
1497c961
PB
148{
149 uint32_t res = a - b;
150 if (res > a) {
151 env->QF = 1;
152 res = 0;
153 }
154 return res;
155}
156
6ddbc6e4 157/* Signed saturation. */
9ef39277 158static inline uint32_t do_ssat(CPUARMState *env, int32_t val, int shift)
6ddbc6e4
PB
159{
160 int32_t top;
161 uint32_t mask;
162
6ddbc6e4
PB
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. */
9ef39277 176static inline uint32_t do_usat(CPUARMState *env, int32_t val, int shift)
6ddbc6e4
PB
177{
178 uint32_t max;
179
6ddbc6e4
PB
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. */
9ef39277 192uint32_t HELPER(ssat)(CPUARMState *env, uint32_t x, uint32_t shift)
6ddbc6e4 193{
9ef39277 194 return do_ssat(env, x, shift);
6ddbc6e4
PB
195}
196
197/* Dual halfword signed saturate. */
9ef39277 198uint32_t HELPER(ssat16)(CPUARMState *env, uint32_t x, uint32_t shift)
6ddbc6e4
PB
199{
200 uint32_t res;
201
9ef39277
BS
202 res = (uint16_t)do_ssat(env, (int16_t)x, shift);
203 res |= do_ssat(env, ((int32_t)x) >> 16, shift) << 16;
6ddbc6e4
PB
204 return res;
205}
206
207/* Unsigned saturate. */
9ef39277 208uint32_t HELPER(usat)(CPUARMState *env, uint32_t x, uint32_t shift)
6ddbc6e4 209{
9ef39277 210 return do_usat(env, x, shift);
6ddbc6e4
PB
211}
212
213/* Dual halfword unsigned saturate. */
9ef39277 214uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift)
6ddbc6e4
PB
215{
216 uint32_t res;
217
9ef39277
BS
218 res = (uint16_t)do_usat(env, (int16_t)x, shift);
219 res |= do_usat(env, ((int32_t)x) >> 16, shift) << 16;
6ddbc6e4
PB
220 return res;
221}
d9ba4830 222
9886ecdf
PB
223void HELPER(setend)(CPUARMState *env)
224{
225 env->uncached_cpsr ^= CPSR_E;
7b2625eb 226 arm_rebuild_hflags(env);
9886ecdf
PB
227}
228
b1eced71
GB
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 */
233static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
234{
235 int cur_el = arm_current_el(env);
236 uint64_t mask;
237
0e284568
PM
238 if (arm_feature(env, ARM_FEATURE_M)) {
239 /* M profile cores can never trap WFI/WFE. */
240 return 0;
241 }
242
b1eced71
GB
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 */
7c208e0f
RH
266 if (cur_el < 2) {
267 mask = is_wfe ? HCR_TWE : HCR_TWI;
268 if (arm_hcr_el2_eff(env) & mask) {
b1eced71
GB
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
58803318 284void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
d9ba4830 285{
2fc0cc0e 286 CPUState *cs = env_cpu(env);
b1eced71 287 int target_el = check_wfx_trap(env, false);
259186a7 288
84549b6d
PM
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
b1eced71 296 if (target_el) {
85553291
JK
297 if (env->aarch64) {
298 env->pc -= insn_len;
299 } else {
300 env->regs[15] -= insn_len;
301 }
302
58803318
SS
303 raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2),
304 target_el);
b1eced71
GB
305 }
306
27103424 307 cs->exception_index = EXCP_HLT;
259186a7 308 cs->halted = 1;
5638d180 309 cpu_loop_exit(cs);
d9ba4830
PB
310}
311
72c1d3af
PM
312void HELPER(wfe)(CPUARMState *env)
313{
049e24a1
PM
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
b1eced71
GB
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.
72c1d3af 320 */
049e24a1
PM
321 HELPER(yield)(env);
322}
323
324void HELPER(yield)(CPUARMState *env)
325{
2fc0cc0e 326 CPUState *cs = env_cpu(env);
049e24a1
PM
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 */
27103424 332 cs->exception_index = EXCP_YIELD;
5638d180 333 cpu_loop_exit(cs);
72c1d3af
PM
334}
335
d4a2dc67
PM
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 */
342void HELPER(exception_internal)(CPUARMState *env, uint32_t excp)
343{
2fc0cc0e 344 CPUState *cs = env_cpu(env);
d4a2dc67
PM
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 */
352void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp,
73710361 353 uint32_t syndrome, uint32_t target_el)
d9ba4830 354{
c6328599 355 raise_exception(env, excp, syndrome, target_el);
d9ba4830
PB
356}
357
c900a2e6
PM
358/* Raise an EXCP_BKPT with the specified syndrome register value,
359 * targeting the correct exception level for debug exceptions.
360 */
361void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
362{
987a2322
PM
363 int debug_el = arm_debug_target_el(env);
364 int cur_el = arm_current_el(env);
365
62b94f31
PM
366 /* FSR will only be used if the debug target EL is AArch32. */
367 env->exception.fsr = arm_debug_exception_fsr(env);
548f514c
PM
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;
987a2322
PM
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);
c900a2e6
PM
385}
386
9ef39277 387uint32_t HELPER(cpsr_read)(CPUARMState *env)
d9ba4830 388{
70dae0d0
RH
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);
d9ba4830
PB
397}
398
1ce94f81 399void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
d9ba4830 400{
50866ba5 401 cpsr_write(env, val, mask, CPSRWriteByInstr);
7b2625eb
RH
402 /* TODO: Not all cpsr bits are relevant to hflags. */
403 arm_rebuild_hflags(env);
d9ba4830 404}
b0109805 405
235ea1f5
PM
406/* Write the CPSR for a 32-bit exception return */
407void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
408{
43786421
RH
409 uint32_t mask;
410
b5c53d1b 411 qemu_mutex_lock_iothread();
2fc0cc0e 412 arm_call_pre_el_change_hook(env_archcpu(env));
b5c53d1b
AL
413 qemu_mutex_unlock_iothread();
414
43786421
RH
415 mask = aarch32_cpsr_valid_mask(env->features, &env_archcpu(env)->isar);
416 cpsr_write(env, val, mask, CPSRWriteExceptionReturn);
bd7d00fc 417
fb0e8e79
PM
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);
a8a79c7a 424 arm_rebuild_hflags(env);
fb0e8e79 425
8d04fb55 426 qemu_mutex_lock_iothread();
2fc0cc0e 427 arm_call_el_change_hook(env_archcpu(env));
8d04fb55 428 qemu_mutex_unlock_iothread();
235ea1f5
PM
429}
430
b0109805 431/* Access to user mode registers from privileged modes. */
9ef39277 432uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
b0109805
PB
433{
434 uint32_t val;
435
436 if (regno == 13) {
99a99c1f 437 val = env->banked_r13[BANK_USRSYS];
b0109805 438 } else if (regno == 14) {
99a99c1f 439 val = env->banked_r14[BANK_USRSYS];
b0109805
PB
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
1ce94f81 449void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
b0109805
PB
450{
451 if (regno == 13) {
99a99c1f 452 env->banked_r13[BANK_USRSYS] = val;
b0109805 453 } else if (regno == 14) {
99a99c1f 454 env->banked_r14[BANK_USRSYS] = val;
b0109805
PB
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}
4b6a83fb 462
72309cee
PM
463void 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
472uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
473{
f01377f5
PM
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
72309cee
PM
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}
72309cee 488
8bfd0550
PM
489static 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
aec4dd09
PM
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
8bfd0550
PM
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) {
aec4dd09
PM
534 /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
535 if (curmode != ARM_CPU_MODE_MON) {
536 goto undef;
8bfd0550
PM
537 }
538 }
539
540 return;
541
542undef:
543 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
544 exception_target_el(env));
545}
546
547void 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:
593cfa2b 563 env->banked_r14[r14_bank_number(tgtmode)] = value;
8bfd0550
PM
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
582uint32_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:
593cfa2b 594 return env->banked_r14[r14_bank_number(tgtmode)];
8bfd0550
PM
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
3f208fd7
PM
609void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
610 uint32_t isread)
f59df3f2
PM
611{
612 const ARMCPRegInfo *ri = rip;
38836a2c 613 int target_el;
c0f4af17
PM
614
615 if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14
616 && extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {
c6328599 617 raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
c0f4af17
PM
618 }
619
5bb0a20b
MZ
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
c0f4af17
PM
641 if (!ri->accessfn) {
642 return;
643 }
644
3f208fd7 645 switch (ri->accessfn(env, ri, isread)) {
f59df3f2
PM
646 case CP_ACCESS_OK:
647 return;
648 case CP_ACCESS_TRAP:
38836a2c
PM
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 */
3fc827d5 655 assert(!arm_is_secure(env) && arm_current_el(env) != 3);
38836a2c
PM
656 target_el = 2;
657 break;
658 case CP_ACCESS_TRAP_EL3:
659 target_el = 3;
8bcbf37c 660 break;
f59df3f2 661 case CP_ACCESS_TRAP_UNCATEGORIZED:
38836a2c 662 target_el = exception_target_el(env);
c6328599 663 syndrome = syn_uncategorized();
f59df3f2 664 break;
e7615726
PM
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;
f2cae609
PM
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;
f59df3f2
PM
686 default:
687 g_assert_not_reached();
688 }
c6328599 689
5bb0a20b 690exept:
38836a2c 691 raise_exception(env, EXCP_UDEF, syndrome, target_el);
f59df3f2
PM
692}
693
4b6a83fb
PM
694void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
695{
696 const ARMCPRegInfo *ri = rip;
c4241c7d 697
8d04fb55
JK
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 }
4b6a83fb
PM
705}
706
707uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)
708{
709 const ARMCPRegInfo *ri = rip;
8d04fb55 710 uint32_t res;
c4241c7d 711
8d04fb55
JK
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;
4b6a83fb
PM
721}
722
723void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value)
724{
725 const ARMCPRegInfo *ri = rip;
c4241c7d 726
8d04fb55
JK
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 }
4b6a83fb
PM
734}
735
736uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
737{
738 const ARMCPRegInfo *ri = rip;
8d04fb55
JK
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 }
c4241c7d 748
8d04fb55 749 return res;
4b6a83fb 750}
b0109805 751
35979d71
EI
752void HELPER(pre_hvc)(CPUARMState *env)
753{
2fc0cc0e 754 ARMCPU *cpu = env_archcpu(env);
dcbff19b 755 int cur_el = arm_current_el(env);
35979d71
EI
756 /* FIXME: Use actual secure state. */
757 bool secure = false;
758 bool undef;
759
98128601
RH
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
39404338
PM
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. */
35979d71
EI
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) {
c6328599
PM
787 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
788 exception_target_el(env));
35979d71
EI
789 }
790}
791
e0d6e6a5
EI
792void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
793{
2fc0cc0e 794 ARMCPU *cpu = env_archcpu(env);
dcbff19b 795 int cur_el = arm_current_el(env);
dbe9d163 796 bool secure = arm_is_secure(env);
7760da72
LM
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
f096e92b
PM
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.
e0d6e6a5 835 */
7760da72
LM
836 bool smd = arm_feature(env, ARM_FEATURE_AARCH64) ? smd_flag
837 : smd_flag && !secure;
e0d6e6a5 838
77077a83
JK
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.
7760da72 847 * This handles the very last line of the previous table.
98128601 848 */
7760da72
LM
849 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
850 exception_target_el(env));
851 }
852
7c208e0f 853 if (cur_el == 1 && (arm_hcr_el2_eff(env) & HCR_TSC)) {
77077a83
JK
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.
7760da72 857 * This handles all the "Trap to EL2" cases of the previous table.
77077a83 858 */
c6328599 859 raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
e0d6e6a5
EI
860 }
861
7760da72
LM
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.
77077a83 865 */
7760da72
LM
866 if (!arm_is_psci_call(cpu, EXCP_SMC) &&
867 (smd || !arm_feature(env, ARM_FEATURE_EL3))) {
c6328599
PM
868 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
869 exception_target_el(env));
e0d6e6a5
EI
870 }
871}
872
8984bd2e
PB
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
8984bd2e
PB
877/* Similarly for variable shift instructions. */
878
9ef39277 879uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i)
8984bd2e
PB
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
9ef39277 895uint32_t HELPER(shr_cc)(CPUARMState *env, uint32_t x, uint32_t i)
8984bd2e
PB
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
9ef39277 911uint32_t HELPER(sar_cc)(CPUARMState *env, uint32_t x, uint32_t i)
8984bd2e
PB
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
9ef39277 924uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i)
8984bd2e
PB
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 1.218908 seconds and 4 git commands to generate.