xref: /openbmc/qemu/target/arm/tcg/m_helper.c (revision 74781c08)
1 /*
2  * ARM generic helpers.
3  *
4  * This code is licensed under the GNU GPL v2 or later.
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #include "qemu/osdep.h"
10 #include "cpu.h"
11 #include "internals.h"
12 #include "cpu-features.h"
13 #include "gdbstub/helpers.h"
14 #include "exec/helper-proto.h"
15 #include "qemu/main-loop.h"
16 #include "qemu/bitops.h"
17 #include "qemu/log.h"
18 #include "exec/exec-all.h"
19 #include "exec/page-protection.h"
20 #ifdef CONFIG_TCG
21 #include "exec/cpu_ldst.h"
22 #include "semihosting/common-semi.h"
23 #endif
24 #if !defined(CONFIG_USER_ONLY)
25 #include "hw/intc/armv7m_nvic.h"
26 #endif
27 
v7m_msr_xpsr(CPUARMState * env,uint32_t mask,uint32_t reg,uint32_t val)28 static void v7m_msr_xpsr(CPUARMState *env, uint32_t mask,
29                          uint32_t reg, uint32_t val)
30 {
31     /* Only APSR is actually writable */
32     if (!(reg & 4)) {
33         uint32_t apsrmask = 0;
34 
35         if (mask & 8) {
36             apsrmask |= XPSR_NZCV | XPSR_Q;
37         }
38         if ((mask & 4) && arm_feature(env, ARM_FEATURE_THUMB_DSP)) {
39             apsrmask |= XPSR_GE;
40         }
41         xpsr_write(env, val, apsrmask);
42     }
43 }
44 
v7m_mrs_xpsr(CPUARMState * env,uint32_t reg,unsigned el)45 static uint32_t v7m_mrs_xpsr(CPUARMState *env, uint32_t reg, unsigned el)
46 {
47     uint32_t mask = 0;
48 
49     if ((reg & 1) && el) {
50         mask |= XPSR_EXCP; /* IPSR (unpriv. reads as zero) */
51     }
52     if (!(reg & 4)) {
53         mask |= XPSR_NZCV | XPSR_Q; /* APSR */
54         if (arm_feature(env, ARM_FEATURE_THUMB_DSP)) {
55             mask |= XPSR_GE;
56         }
57     }
58     /* EPSR reads as zero */
59     return xpsr_read(env) & mask;
60 }
61 
arm_v7m_mrs_control(CPUARMState * env,uint32_t secure)62 uint32_t arm_v7m_mrs_control(CPUARMState *env, uint32_t secure)
63 {
64     uint32_t value = env->v7m.control[secure];
65 
66     if (!secure) {
67         /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
68         value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
69     }
70     return value;
71 }
72 
73 #ifdef CONFIG_USER_ONLY
74 
HELPER(v7m_msr)75 void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
76 {
77     uint32_t mask = extract32(maskreg, 8, 4);
78     uint32_t reg = extract32(maskreg, 0, 8);
79 
80     switch (reg) {
81     case 0 ... 7: /* xPSR sub-fields */
82         v7m_msr_xpsr(env, mask, reg, val);
83         break;
84     case 20: /* CONTROL */
85         /* There are no sub-fields that are actually writable from EL0. */
86         break;
87     default:
88         /* Unprivileged writes to other registers are ignored */
89         break;
90     }
91 }
92 
HELPER(v7m_mrs)93 uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
94 {
95     switch (reg) {
96     case 0 ... 7: /* xPSR sub-fields */
97         return v7m_mrs_xpsr(env, reg, 0);
98     case 20: /* CONTROL */
99         return arm_v7m_mrs_control(env, 0);
100     default:
101         /* Unprivileged reads others as zero.  */
102         return 0;
103     }
104 }
105 
HELPER(v7m_bxns)106 void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
107 {
108     /* translate.c should never generate calls here in user-only mode */
109     g_assert_not_reached();
110 }
111 
HELPER(v7m_blxns)112 void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
113 {
114     /* translate.c should never generate calls here in user-only mode */
115     g_assert_not_reached();
116 }
117 
HELPER(v7m_preserve_fp_state)118 void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
119 {
120     /* translate.c should never generate calls here in user-only mode */
121     g_assert_not_reached();
122 }
123 
HELPER(v7m_vlstm)124 void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
125 {
126     /* translate.c should never generate calls here in user-only mode */
127     g_assert_not_reached();
128 }
129 
HELPER(v7m_vlldm)130 void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
131 {
132     /* translate.c should never generate calls here in user-only mode */
133     g_assert_not_reached();
134 }
135 
HELPER(v7m_tt)136 uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
137 {
138     /*
139      * The TT instructions can be used by unprivileged code, but in
140      * user-only emulation we don't have the MPU.
141      * Luckily since we know we are NonSecure unprivileged (and that in
142      * turn means that the A flag wasn't specified), all the bits in the
143      * register must be zero:
144      *  IREGION: 0 because IRVALID is 0
145      *  IRVALID: 0 because NS
146      *  S: 0 because NS
147      *  NSRW: 0 because NS
148      *  NSR: 0 because NS
149      *  RW: 0 because unpriv and A flag not set
150      *  R: 0 because unpriv and A flag not set
151      *  SRVALID: 0 because NS
152      *  MRVALID: 0 because unpriv and A flag not set
153      *  SREGION: 0 because SRVALID is 0
154      *  MREGION: 0 because MRVALID is 0
155      */
156     return 0;
157 }
158 
arm_v7m_mmu_idx_for_secstate(CPUARMState * env,bool secstate)159 ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
160 {
161     return ARMMMUIdx_MUser;
162 }
163 
164 #else /* !CONFIG_USER_ONLY */
165 
arm_v7m_mmu_idx_all(CPUARMState * env,bool secstate,bool priv,bool negpri)166 static ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
167                                      bool secstate, bool priv, bool negpri)
168 {
169     ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
170 
171     if (priv) {
172         mmu_idx |= ARM_MMU_IDX_M_PRIV;
173     }
174 
175     if (negpri) {
176         mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
177     }
178 
179     if (secstate) {
180         mmu_idx |= ARM_MMU_IDX_M_S;
181     }
182 
183     return mmu_idx;
184 }
185 
arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState * env,bool secstate,bool priv)186 static ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
187                                                        bool secstate, bool priv)
188 {
189     bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
190 
191     return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
192 }
193 
194 /* Return the MMU index for a v7M CPU in the specified security state */
arm_v7m_mmu_idx_for_secstate(CPUARMState * env,bool secstate)195 ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
196 {
197     bool priv = arm_v7m_is_handler_mode(env) ||
198         !(env->v7m.control[secstate] & 1);
199 
200     return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
201 }
202 
203 /*
204  * What kind of stack write are we doing? This affects how exceptions
205  * generated during the stacking are treated.
206  */
207 typedef enum StackingMode {
208     STACK_NORMAL,
209     STACK_IGNFAULTS,
210     STACK_LAZYFP,
211 } StackingMode;
212 
v7m_stack_write(ARMCPU * cpu,uint32_t addr,uint32_t value,ARMMMUIdx mmu_idx,StackingMode mode)213 static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
214                             ARMMMUIdx mmu_idx, StackingMode mode)
215 {
216     CPUState *cs = CPU(cpu);
217     CPUARMState *env = &cpu->env;
218     MemTxResult txres;
219     GetPhysAddrResult res = {};
220     ARMMMUFaultInfo fi = {};
221     bool secure = mmu_idx & ARM_MMU_IDX_M_S;
222     int exc;
223     bool exc_secure;
224 
225     if (get_phys_addr(env, addr, MMU_DATA_STORE, mmu_idx, &res, &fi)) {
226         /* MPU/SAU lookup failed */
227         if (fi.type == ARMFault_QEMU_SFault) {
228             if (mode == STACK_LAZYFP) {
229                 qemu_log_mask(CPU_LOG_INT,
230                               "...SecureFault with SFSR.LSPERR "
231                               "during lazy stacking\n");
232                 env->v7m.sfsr |= R_V7M_SFSR_LSPERR_MASK;
233             } else {
234                 qemu_log_mask(CPU_LOG_INT,
235                               "...SecureFault with SFSR.AUVIOL "
236                               "during stacking\n");
237                 env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
238             }
239             env->v7m.sfsr |= R_V7M_SFSR_SFARVALID_MASK;
240             env->v7m.sfar = addr;
241             exc = ARMV7M_EXCP_SECURE;
242             exc_secure = false;
243         } else {
244             if (mode == STACK_LAZYFP) {
245                 qemu_log_mask(CPU_LOG_INT,
246                               "...MemManageFault with CFSR.MLSPERR\n");
247                 env->v7m.cfsr[secure] |= R_V7M_CFSR_MLSPERR_MASK;
248             } else {
249                 qemu_log_mask(CPU_LOG_INT,
250                               "...MemManageFault with CFSR.MSTKERR\n");
251                 env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
252             }
253             exc = ARMV7M_EXCP_MEM;
254             exc_secure = secure;
255         }
256         goto pend_fault;
257     }
258     address_space_stl_le(arm_addressspace(cs, res.f.attrs), res.f.phys_addr,
259                          value, res.f.attrs, &txres);
260     if (txres != MEMTX_OK) {
261         /* BusFault trying to write the data */
262         if (mode == STACK_LAZYFP) {
263             qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.LSPERR\n");
264             env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_LSPERR_MASK;
265         } else {
266             qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
267             env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
268         }
269         exc = ARMV7M_EXCP_BUS;
270         exc_secure = false;
271         goto pend_fault;
272     }
273     return true;
274 
275 pend_fault:
276     /*
277      * By pending the exception at this point we are making
278      * the IMPDEF choice "overridden exceptions pended" (see the
279      * MergeExcInfo() pseudocode). The other choice would be to not
280      * pend them now and then make a choice about which to throw away
281      * later if we have two derived exceptions.
282      * The only case when we must not pend the exception but instead
283      * throw it away is if we are doing the push of the callee registers
284      * and we've already generated a derived exception (this is indicated
285      * by the caller passing STACK_IGNFAULTS). Even in this case we will
286      * still update the fault status registers.
287      */
288     switch (mode) {
289     case STACK_NORMAL:
290         armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
291         break;
292     case STACK_LAZYFP:
293         armv7m_nvic_set_pending_lazyfp(env->nvic, exc, exc_secure);
294         break;
295     case STACK_IGNFAULTS:
296         break;
297     }
298     return false;
299 }
300 
v7m_stack_read(ARMCPU * cpu,uint32_t * dest,uint32_t addr,ARMMMUIdx mmu_idx)301 static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
302                            ARMMMUIdx mmu_idx)
303 {
304     CPUState *cs = CPU(cpu);
305     CPUARMState *env = &cpu->env;
306     MemTxResult txres;
307     GetPhysAddrResult res = {};
308     ARMMMUFaultInfo fi = {};
309     bool secure = mmu_idx & ARM_MMU_IDX_M_S;
310     int exc;
311     bool exc_secure;
312     uint32_t value;
313 
314     if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &res, &fi)) {
315         /* MPU/SAU lookup failed */
316         if (fi.type == ARMFault_QEMU_SFault) {
317             qemu_log_mask(CPU_LOG_INT,
318                           "...SecureFault with SFSR.AUVIOL during unstack\n");
319             env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
320             env->v7m.sfar = addr;
321             exc = ARMV7M_EXCP_SECURE;
322             exc_secure = false;
323         } else {
324             qemu_log_mask(CPU_LOG_INT,
325                           "...MemManageFault with CFSR.MUNSTKERR\n");
326             env->v7m.cfsr[secure] |= R_V7M_CFSR_MUNSTKERR_MASK;
327             exc = ARMV7M_EXCP_MEM;
328             exc_secure = secure;
329         }
330         goto pend_fault;
331     }
332 
333     value = address_space_ldl(arm_addressspace(cs, res.f.attrs),
334                               res.f.phys_addr, res.f.attrs, &txres);
335     if (txres != MEMTX_OK) {
336         /* BusFault trying to read the data */
337         qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.UNSTKERR\n");
338         env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_UNSTKERR_MASK;
339         exc = ARMV7M_EXCP_BUS;
340         exc_secure = false;
341         goto pend_fault;
342     }
343 
344     *dest = value;
345     return true;
346 
347 pend_fault:
348     /*
349      * By pending the exception at this point we are making
350      * the IMPDEF choice "overridden exceptions pended" (see the
351      * MergeExcInfo() pseudocode). The other choice would be to not
352      * pend them now and then make a choice about which to throw away
353      * later if we have two derived exceptions.
354      */
355     armv7m_nvic_set_pending(env->nvic, exc, exc_secure);
356     return false;
357 }
358 
HELPER(v7m_preserve_fp_state)359 void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
360 {
361     /*
362      * Preserve FP state (because LSPACT was set and we are about
363      * to execute an FP instruction). This corresponds to the
364      * PreserveFPState() pseudocode.
365      * We may throw an exception if the stacking fails.
366      */
367     ARMCPU *cpu = env_archcpu(env);
368     bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
369     bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
370     bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
371     bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
372     uint32_t fpcar = env->v7m.fpcar[is_secure];
373     bool stacked_ok = true;
374     bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
375     bool take_exception;
376 
377     /* Take the BQL as we are going to touch the NVIC */
378     bql_lock();
379 
380     /* Check the background context had access to the FPU */
381     if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
382         armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
383         env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
384         stacked_ok = false;
385     } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
386         armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
387         env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
388         stacked_ok = false;
389     }
390 
391     if (!splimviol && stacked_ok) {
392         /* We only stack if the stack limit wasn't violated */
393         int i;
394         ARMMMUIdx mmu_idx;
395 
396         mmu_idx = arm_v7m_mmu_idx_all(env, is_secure, is_priv, negpri);
397         for (i = 0; i < (ts ? 32 : 16); i += 2) {
398             uint64_t dn = *aa32_vfp_dreg(env, i / 2);
399             uint32_t faddr = fpcar + 4 * i;
400             uint32_t slo = extract64(dn, 0, 32);
401             uint32_t shi = extract64(dn, 32, 32);
402 
403             if (i >= 16) {
404                 faddr += 8; /* skip the slot for the FPSCR/VPR */
405             }
406             stacked_ok = stacked_ok &&
407                 v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) &&
408                 v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, STACK_LAZYFP);
409         }
410 
411         stacked_ok = stacked_ok &&
412             v7m_stack_write(cpu, fpcar + 0x40,
413                             vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP);
414         if (cpu_isar_feature(aa32_mve, cpu)) {
415             stacked_ok = stacked_ok &&
416                 v7m_stack_write(cpu, fpcar + 0x44,
417                                 env->v7m.vpr, mmu_idx, STACK_LAZYFP);
418         }
419     }
420 
421     /*
422      * We definitely pended an exception, but it's possible that it
423      * might not be able to be taken now. If its priority permits us
424      * to take it now, then we must not update the LSPACT or FP regs,
425      * but instead jump out to take the exception immediately.
426      * If it's just pending and won't be taken until the current
427      * handler exits, then we do update LSPACT and the FP regs.
428      */
429     take_exception = !stacked_ok &&
430         armv7m_nvic_can_take_pending_exception(env->nvic);
431 
432     bql_unlock();
433 
434     if (take_exception) {
435         raise_exception_ra(env, EXCP_LAZYFP, 0, 1, GETPC());
436     }
437 
438     env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
439 
440     if (ts) {
441         /* Clear s0 to s31 and the FPSCR and VPR */
442         int i;
443 
444         for (i = 0; i < 32; i += 2) {
445             *aa32_vfp_dreg(env, i / 2) = 0;
446         }
447         vfp_set_fpscr(env, 0);
448         if (cpu_isar_feature(aa32_mve, cpu)) {
449             env->v7m.vpr = 0;
450         }
451     }
452     /*
453      * Otherwise s0 to s15, FPSCR and VPR are UNKNOWN; we choose to leave them
454      * unchanged.
455      */
456 }
457 
458 /*
459  * Write to v7M CONTROL.SPSEL bit for the specified security bank.
460  * This may change the current stack pointer between Main and Process
461  * stack pointers if it is done for the CONTROL register for the current
462  * security state.
463  */
write_v7m_control_spsel_for_secstate(CPUARMState * env,bool new_spsel,bool secstate)464 static void write_v7m_control_spsel_for_secstate(CPUARMState *env,
465                                                  bool new_spsel,
466                                                  bool secstate)
467 {
468     bool old_is_psp = v7m_using_psp(env);
469 
470     env->v7m.control[secstate] =
471         deposit32(env->v7m.control[secstate],
472                   R_V7M_CONTROL_SPSEL_SHIFT,
473                   R_V7M_CONTROL_SPSEL_LENGTH, new_spsel);
474 
475     if (secstate == env->v7m.secure) {
476         bool new_is_psp = v7m_using_psp(env);
477         uint32_t tmp;
478 
479         if (old_is_psp != new_is_psp) {
480             tmp = env->v7m.other_sp;
481             env->v7m.other_sp = env->regs[13];
482             env->regs[13] = tmp;
483         }
484     }
485 }
486 
487 /*
488  * Write to v7M CONTROL.SPSEL bit. This may change the current
489  * stack pointer between Main and Process stack pointers.
490  */
write_v7m_control_spsel(CPUARMState * env,bool new_spsel)491 static void write_v7m_control_spsel(CPUARMState *env, bool new_spsel)
492 {
493     write_v7m_control_spsel_for_secstate(env, new_spsel, env->v7m.secure);
494 }
495 
write_v7m_exception(CPUARMState * env,uint32_t new_exc)496 void write_v7m_exception(CPUARMState *env, uint32_t new_exc)
497 {
498     /*
499      * Write a new value to v7m.exception, thus transitioning into or out
500      * of Handler mode; this may result in a change of active stack pointer.
501      */
502     bool new_is_psp, old_is_psp = v7m_using_psp(env);
503     uint32_t tmp;
504 
505     env->v7m.exception = new_exc;
506 
507     new_is_psp = v7m_using_psp(env);
508 
509     if (old_is_psp != new_is_psp) {
510         tmp = env->v7m.other_sp;
511         env->v7m.other_sp = env->regs[13];
512         env->regs[13] = tmp;
513     }
514 }
515 
516 /* Switch M profile security state between NS and S */
switch_v7m_security_state(CPUARMState * env,bool new_secstate)517 static void switch_v7m_security_state(CPUARMState *env, bool new_secstate)
518 {
519     uint32_t new_ss_msp, new_ss_psp;
520 
521     if (env->v7m.secure == new_secstate) {
522         return;
523     }
524 
525     /*
526      * All the banked state is accessed by looking at env->v7m.secure
527      * except for the stack pointer; rearrange the SP appropriately.
528      */
529     new_ss_msp = env->v7m.other_ss_msp;
530     new_ss_psp = env->v7m.other_ss_psp;
531 
532     if (v7m_using_psp(env)) {
533         env->v7m.other_ss_psp = env->regs[13];
534         env->v7m.other_ss_msp = env->v7m.other_sp;
535     } else {
536         env->v7m.other_ss_msp = env->regs[13];
537         env->v7m.other_ss_psp = env->v7m.other_sp;
538     }
539 
540     env->v7m.secure = new_secstate;
541 
542     if (v7m_using_psp(env)) {
543         env->regs[13] = new_ss_psp;
544         env->v7m.other_sp = new_ss_msp;
545     } else {
546         env->regs[13] = new_ss_msp;
547         env->v7m.other_sp = new_ss_psp;
548     }
549 }
550 
HELPER(v7m_bxns)551 void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
552 {
553     /*
554      * Handle v7M BXNS:
555      *  - if the return value is a magic value, do exception return (like BX)
556      *  - otherwise bit 0 of the return value is the target security state
557      */
558     uint32_t min_magic;
559 
560     if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
561         /* Covers FNC_RETURN and EXC_RETURN magic */
562         min_magic = FNC_RETURN_MIN_MAGIC;
563     } else {
564         /* EXC_RETURN magic only */
565         min_magic = EXC_RETURN_MIN_MAGIC;
566     }
567 
568     if (dest >= min_magic) {
569         /*
570          * This is an exception return magic value; put it where
571          * do_v7m_exception_exit() expects and raise EXCEPTION_EXIT.
572          * Note that if we ever add gen_ss_advance() singlestep support to
573          * M profile this should count as an "instruction execution complete"
574          * event (compare gen_bx_excret_final_code()).
575          */
576         env->regs[15] = dest & ~1;
577         env->thumb = dest & 1;
578         HELPER(exception_internal)(env, EXCP_EXCEPTION_EXIT);
579         /* notreached */
580     }
581 
582     /* translate.c should have made BXNS UNDEF unless we're secure */
583     assert(env->v7m.secure);
584 
585     if (!(dest & 1)) {
586         env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
587     }
588     switch_v7m_security_state(env, dest & 1);
589     env->thumb = true;
590     env->regs[15] = dest & ~1;
591     arm_rebuild_hflags(env);
592 }
593 
HELPER(v7m_blxns)594 void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
595 {
596     /*
597      * Handle v7M BLXNS:
598      *  - bit 0 of the destination address is the target security state
599      */
600 
601     /* At this point regs[15] is the address just after the BLXNS */
602     uint32_t nextinst = env->regs[15] | 1;
603     uint32_t sp = env->regs[13] - 8;
604     uint32_t saved_psr;
605 
606     /* translate.c will have made BLXNS UNDEF unless we're secure */
607     assert(env->v7m.secure);
608 
609     if (dest & 1) {
610         /*
611          * Target is Secure, so this is just a normal BLX,
612          * except that the low bit doesn't indicate Thumb/not.
613          */
614         env->regs[14] = nextinst;
615         env->thumb = true;
616         env->regs[15] = dest & ~1;
617         return;
618     }
619 
620     /* Target is non-secure: first push a stack frame */
621     if (!QEMU_IS_ALIGNED(sp, 8)) {
622         qemu_log_mask(LOG_GUEST_ERROR,
623                       "BLXNS with misaligned SP is UNPREDICTABLE\n");
624     }
625 
626     if (sp < v7m_sp_limit(env)) {
627         raise_exception(env, EXCP_STKOF, 0, 1);
628     }
629 
630     saved_psr = env->v7m.exception;
631     if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK) {
632         saved_psr |= XPSR_SFPA;
633     }
634 
635     /* Note that these stores can throw exceptions on MPU faults */
636     cpu_stl_data_ra(env, sp, nextinst, GETPC());
637     cpu_stl_data_ra(env, sp + 4, saved_psr, GETPC());
638 
639     env->regs[13] = sp;
640     env->regs[14] = 0xfeffffff;
641     if (arm_v7m_is_handler_mode(env)) {
642         /*
643          * Write a dummy value to IPSR, to avoid leaking the current secure
644          * exception number to non-secure code. This is guaranteed not
645          * to cause write_v7m_exception() to actually change stacks.
646          */
647         write_v7m_exception(env, 1);
648     }
649     env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
650     switch_v7m_security_state(env, 0);
651     env->thumb = true;
652     env->regs[15] = dest;
653     arm_rebuild_hflags(env);
654 }
655 
arm_v7m_load_vector(ARMCPU * cpu,int exc,bool targets_secure,uint32_t * pvec)656 static bool arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure,
657                                 uint32_t *pvec)
658 {
659     CPUState *cs = CPU(cpu);
660     CPUARMState *env = &cpu->env;
661     MemTxResult result;
662     uint32_t addr = env->v7m.vecbase[targets_secure] + exc * 4;
663     uint32_t vector_entry;
664     MemTxAttrs attrs = {};
665     ARMMMUIdx mmu_idx;
666     bool exc_secure;
667 
668     qemu_log_mask(CPU_LOG_INT,
669                   "...loading from element %d of %s vector table at 0x%x\n",
670                   exc, targets_secure ? "secure" : "non-secure", addr);
671 
672     mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, targets_secure, true);
673 
674     /*
675      * We don't do a get_phys_addr() here because the rules for vector
676      * loads are special: they always use the default memory map, and
677      * the default memory map permits reads from all addresses.
678      * Since there's no easy way to pass through to pmsav8_mpu_lookup()
679      * that we want this special case which would always say "yes",
680      * we just do the SAU lookup here followed by a direct physical load.
681      */
682     attrs.secure = targets_secure;
683     attrs.user = false;
684 
685     if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
686         V8M_SAttributes sattrs = {};
687 
688         v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
689                             targets_secure, &sattrs);
690         if (sattrs.ns) {
691             attrs.secure = false;
692         } else if (!targets_secure) {
693             /*
694              * NS access to S memory: the underlying exception which we escalate
695              * to HardFault is SecureFault, which always targets Secure.
696              */
697             exc_secure = true;
698             goto load_fail;
699         }
700     }
701 
702     vector_entry = address_space_ldl(arm_addressspace(cs, attrs), addr,
703                                      attrs, &result);
704     if (result != MEMTX_OK) {
705         /*
706          * Underlying exception is BusFault: its target security state
707          * depends on BFHFNMINS.
708          */
709         exc_secure = !(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK);
710         goto load_fail;
711     }
712     *pvec = vector_entry;
713     qemu_log_mask(CPU_LOG_INT, "...loaded new PC 0x%x\n", *pvec);
714     return true;
715 
716 load_fail:
717     /*
718      * All vector table fetch fails are reported as HardFault, with
719      * HFSR.VECTTBL and .FORCED set. (FORCED is set because
720      * technically the underlying exception is a SecureFault or BusFault
721      * that is escalated to HardFault.) This is a terminal exception,
722      * so we will either take the HardFault immediately or else enter
723      * lockup (the latter case is handled in armv7m_nvic_set_pending_derived()).
724      * The HardFault is Secure if BFHFNMINS is 0 (meaning that all HFs are
725      * secure); otherwise it targets the same security state as the
726      * underlying exception.
727      * In v8.1M HardFaults from vector table fetch fails don't set FORCED.
728      */
729     if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
730         exc_secure = true;
731     }
732     env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK;
733     if (!arm_feature(env, ARM_FEATURE_V8_1M)) {
734         env->v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
735     }
736     armv7m_nvic_set_pending_derived(env->nvic, ARMV7M_EXCP_HARD, exc_secure);
737     return false;
738 }
739 
v7m_integrity_sig(CPUARMState * env,uint32_t lr)740 static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
741 {
742     /*
743      * Return the integrity signature value for the callee-saves
744      * stack frame section. @lr is the exception return payload/LR value
745      * whose FType bit forms bit 0 of the signature if FP is present.
746      */
747     uint32_t sig = 0xfefa125a;
748 
749     if (!cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))
750         || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
751         sig |= 1;
752     }
753     return sig;
754 }
755 
v7m_push_callee_stack(ARMCPU * cpu,uint32_t lr,bool dotailchain,bool ignore_faults)756 static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
757                                   bool ignore_faults)
758 {
759     /*
760      * For v8M, push the callee-saves register part of the stack frame.
761      * Compare the v8M pseudocode PushCalleeStack().
762      * In the tailchaining case this may not be the current stack.
763      */
764     CPUARMState *env = &cpu->env;
765     uint32_t *frame_sp_p;
766     uint32_t frameptr;
767     ARMMMUIdx mmu_idx;
768     bool stacked_ok;
769     uint32_t limit;
770     bool want_psp;
771     uint32_t sig;
772     StackingMode smode = ignore_faults ? STACK_IGNFAULTS : STACK_NORMAL;
773 
774     if (dotailchain) {
775         bool mode = lr & R_V7M_EXCRET_MODE_MASK;
776         bool priv = !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_NPRIV_MASK) ||
777             !mode;
778 
779         mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, M_REG_S, priv);
780         frame_sp_p = arm_v7m_get_sp_ptr(env, M_REG_S, mode,
781                                         lr & R_V7M_EXCRET_SPSEL_MASK);
782         want_psp = mode && (lr & R_V7M_EXCRET_SPSEL_MASK);
783         if (want_psp) {
784             limit = env->v7m.psplim[M_REG_S];
785         } else {
786             limit = env->v7m.msplim[M_REG_S];
787         }
788     } else {
789         mmu_idx = arm_mmu_idx(env);
790         frame_sp_p = &env->regs[13];
791         limit = v7m_sp_limit(env);
792     }
793 
794     frameptr = *frame_sp_p - 0x28;
795     if (frameptr < limit) {
796         /*
797          * Stack limit failure: set SP to the limit value, and generate
798          * STKOF UsageFault. Stack pushes below the limit must not be
799          * performed. It is IMPDEF whether pushes above the limit are
800          * performed; we choose not to.
801          */
802         qemu_log_mask(CPU_LOG_INT,
803                       "...STKOF during callee-saves register stacking\n");
804         env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
805         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
806                                 env->v7m.secure);
807         *frame_sp_p = limit;
808         return true;
809     }
810 
811     /*
812      * Write as much of the stack frame as we can. A write failure may
813      * cause us to pend a derived exception.
814      */
815     sig = v7m_integrity_sig(env, lr);
816     stacked_ok =
817         v7m_stack_write(cpu, frameptr, sig, mmu_idx, smode) &&
818         v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx, smode) &&
819         v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx, smode) &&
820         v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx, smode) &&
821         v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx, smode) &&
822         v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx, smode) &&
823         v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx, smode) &&
824         v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx, smode) &&
825         v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx, smode);
826 
827     /* Update SP regardless of whether any of the stack accesses failed. */
828     *frame_sp_p = frameptr;
829 
830     return !stacked_ok;
831 }
832 
v7m_exception_taken(ARMCPU * cpu,uint32_t lr,bool dotailchain,bool ignore_stackfaults)833 static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
834                                 bool ignore_stackfaults)
835 {
836     /*
837      * Do the "take the exception" parts of exception entry,
838      * but not the pushing of state to the stack. This is
839      * similar to the pseudocode ExceptionTaken() function.
840      */
841     CPUARMState *env = &cpu->env;
842     uint32_t addr;
843     bool targets_secure;
844     int exc;
845     bool push_failed = false;
846 
847     armv7m_nvic_get_pending_irq_info(env->nvic, &exc, &targets_secure);
848     qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
849                   targets_secure ? "secure" : "nonsecure", exc);
850 
851     if (dotailchain) {
852         /* Sanitize LR FType and PREFIX bits */
853         if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
854             lr |= R_V7M_EXCRET_FTYPE_MASK;
855         }
856         lr = deposit32(lr, 24, 8, 0xff);
857     }
858 
859     if (arm_feature(env, ARM_FEATURE_V8)) {
860         if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
861             (lr & R_V7M_EXCRET_S_MASK)) {
862             /*
863              * The background code (the owner of the registers in the
864              * exception frame) is Secure. This means it may either already
865              * have or now needs to push callee-saves registers.
866              */
867             if (targets_secure) {
868                 if (dotailchain && !(lr & R_V7M_EXCRET_ES_MASK)) {
869                     /*
870                      * We took an exception from Secure to NonSecure
871                      * (which means the callee-saved registers got stacked)
872                      * and are now tailchaining to a Secure exception.
873                      * Clear DCRS so eventual return from this Secure
874                      * exception unstacks the callee-saved registers.
875                      */
876                     lr &= ~R_V7M_EXCRET_DCRS_MASK;
877                 }
878             } else {
879                 /*
880                  * We're going to a non-secure exception; push the
881                  * callee-saves registers to the stack now, if they're
882                  * not already saved.
883                  */
884                 if (lr & R_V7M_EXCRET_DCRS_MASK &&
885                     !(dotailchain && !(lr & R_V7M_EXCRET_ES_MASK))) {
886                     push_failed = v7m_push_callee_stack(cpu, lr, dotailchain,
887                                                         ignore_stackfaults);
888                 }
889                 lr |= R_V7M_EXCRET_DCRS_MASK;
890             }
891         }
892 
893         lr &= ~R_V7M_EXCRET_ES_MASK;
894         if (targets_secure) {
895             lr |= R_V7M_EXCRET_ES_MASK;
896         }
897         lr &= ~R_V7M_EXCRET_SPSEL_MASK;
898         if (env->v7m.control[targets_secure] & R_V7M_CONTROL_SPSEL_MASK) {
899             lr |= R_V7M_EXCRET_SPSEL_MASK;
900         }
901 
902         /*
903          * Clear registers if necessary to prevent non-secure exception
904          * code being able to see register values from secure code.
905          * Where register values become architecturally UNKNOWN we leave
906          * them with their previous values. v8.1M is tighter than v8.0M
907          * here and always zeroes the caller-saved registers regardless
908          * of the security state the exception is targeting.
909          */
910         if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
911             if (!targets_secure || arm_feature(env, ARM_FEATURE_V8_1M)) {
912                 /*
913                  * Always clear the caller-saved registers (they have been
914                  * pushed to the stack earlier in v7m_push_stack()).
915                  * Clear callee-saved registers if the background code is
916                  * Secure (in which case these regs were saved in
917                  * v7m_push_callee_stack()).
918                  */
919                 int i;
920                 /*
921                  * r4..r11 are callee-saves, zero only if background
922                  * state was Secure (EXCRET.S == 1) and exception
923                  * targets Non-secure state
924                  */
925                 bool zero_callee_saves = !targets_secure &&
926                     (lr & R_V7M_EXCRET_S_MASK);
927 
928                 for (i = 0; i < 13; i++) {
929                     if (i < 4 || i > 11 || zero_callee_saves) {
930                         env->regs[i] = 0;
931                     }
932                 }
933                 /* Clear EAPSR */
934                 xpsr_write(env, 0, XPSR_NZCV | XPSR_Q | XPSR_GE | XPSR_IT);
935             }
936         }
937     }
938 
939     if (push_failed && !ignore_stackfaults) {
940         /*
941          * Derived exception on callee-saves register stacking:
942          * we might now want to take a different exception which
943          * targets a different security state, so try again from the top.
944          */
945         qemu_log_mask(CPU_LOG_INT,
946                       "...derived exception on callee-saves register stacking");
947         v7m_exception_taken(cpu, lr, true, true);
948         return;
949     }
950 
951     if (!arm_v7m_load_vector(cpu, exc, targets_secure, &addr)) {
952         /* Vector load failed: derived exception */
953         qemu_log_mask(CPU_LOG_INT, "...derived exception on vector table load");
954         v7m_exception_taken(cpu, lr, true, true);
955         return;
956     }
957 
958     /*
959      * Now we've done everything that might cause a derived exception
960      * we can go ahead and activate whichever exception we're going to
961      * take (which might now be the derived exception).
962      */
963     armv7m_nvic_acknowledge_irq(env->nvic);
964 
965     /* Switch to target security state -- must do this before writing SPSEL */
966     switch_v7m_security_state(env, targets_secure);
967     write_v7m_control_spsel(env, 0);
968     arm_clear_exclusive(env);
969     /* Clear SFPA and FPCA (has no effect if no FPU) */
970     env->v7m.control[M_REG_S] &=
971         ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
972     /* Clear IT bits */
973     env->condexec_bits = 0;
974     env->regs[14] = lr;
975     env->regs[15] = addr & 0xfffffffe;
976     env->thumb = addr & 1;
977     arm_rebuild_hflags(env);
978 }
979 
v7m_update_fpccr(CPUARMState * env,uint32_t frameptr,bool apply_splim)980 static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
981                              bool apply_splim)
982 {
983     /*
984      * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
985      * that we will need later in order to do lazy FP reg stacking.
986      */
987     bool is_secure = env->v7m.secure;
988     NVICState *nvic = env->nvic;
989     /*
990      * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
991      * are banked and we want to update the bit in the bank for the
992      * current security state; and in one case we want to specifically
993      * update the NS banked version of a bit even if we are secure.
994      */
995     uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S];
996     uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS];
997     uint32_t *fpccr = &env->v7m.fpccr[is_secure];
998     bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy;
999 
1000     env->v7m.fpcar[is_secure] = frameptr & ~0x7;
1001 
1002     if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
1003         bool splimviol;
1004         uint32_t splim = v7m_sp_limit(env);
1005         bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
1006             (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
1007 
1008         splimviol = !ign && frameptr < splim;
1009         *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
1010     }
1011 
1012     *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
1013 
1014     *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
1015 
1016     *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
1017 
1018     *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
1019                         !arm_v7m_is_handler_mode(env));
1020 
1021     hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
1022     *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
1023 
1024     bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
1025     *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
1026 
1027     mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure);
1028     *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy);
1029 
1030     ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false);
1031     *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy);
1032 
1033     monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false);
1034     *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy);
1035 
1036     if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
1037         s_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, true);
1038         *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy);
1039 
1040         sfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, false);
1041         *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, SFRDY, sfrdy);
1042     }
1043 }
1044 
HELPER(v7m_vlstm)1045 void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
1046 {
1047     /* fptr is the value of Rn, the frame pointer we store the FP regs to */
1048     ARMCPU *cpu = env_archcpu(env);
1049     bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
1050     bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
1051     uintptr_t ra = GETPC();
1052 
1053     assert(env->v7m.secure);
1054 
1055     if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
1056         return;
1057     }
1058 
1059     /* Check access to the coprocessor is permitted */
1060     if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
1061         raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
1062     }
1063 
1064     if (lspact) {
1065         /* LSPACT should not be active when there is active FP state */
1066         raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
1067     }
1068 
1069     if (fptr & 7) {
1070         raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
1071     }
1072 
1073     /*
1074      * Note that we do not use v7m_stack_write() here, because the
1075      * accesses should not set the FSR bits for stacking errors if they
1076      * fail. (In pseudocode terms, they are AccType_NORMAL, not AccType_STACK
1077      * or AccType_LAZYFP). Faults in cpu_stl_data_ra() will throw exceptions
1078      * and longjmp out.
1079      */
1080     if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
1081         bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
1082         int i;
1083 
1084         for (i = 0; i < (ts ? 32 : 16); i += 2) {
1085             uint64_t dn = *aa32_vfp_dreg(env, i / 2);
1086             uint32_t faddr = fptr + 4 * i;
1087             uint32_t slo = extract64(dn, 0, 32);
1088             uint32_t shi = extract64(dn, 32, 32);
1089 
1090             if (i >= 16) {
1091                 faddr += 8; /* skip the slot for the FPSCR */
1092             }
1093             cpu_stl_data_ra(env, faddr, slo, ra);
1094             cpu_stl_data_ra(env, faddr + 4, shi, ra);
1095         }
1096         cpu_stl_data_ra(env, fptr + 0x40, vfp_get_fpscr(env), ra);
1097         if (cpu_isar_feature(aa32_mve, cpu)) {
1098             cpu_stl_data_ra(env, fptr + 0x44, env->v7m.vpr, ra);
1099         }
1100 
1101         /*
1102          * If TS is 0 then s0 to s15, FPSCR and VPR are UNKNOWN; we choose to
1103          * leave them unchanged, matching our choice in v7m_preserve_fp_state.
1104          */
1105         if (ts) {
1106             for (i = 0; i < 32; i += 2) {
1107                 *aa32_vfp_dreg(env, i / 2) = 0;
1108             }
1109             vfp_set_fpscr(env, 0);
1110             if (cpu_isar_feature(aa32_mve, cpu)) {
1111                 env->v7m.vpr = 0;
1112             }
1113         }
1114     } else {
1115         v7m_update_fpccr(env, fptr, false);
1116     }
1117 
1118     env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
1119 }
1120 
HELPER(v7m_vlldm)1121 void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
1122 {
1123     ARMCPU *cpu = env_archcpu(env);
1124     uintptr_t ra = GETPC();
1125 
1126     /* fptr is the value of Rn, the frame pointer we load the FP regs from */
1127     assert(env->v7m.secure);
1128 
1129     if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
1130         return;
1131     }
1132 
1133     /* Check access to the coprocessor is permitted */
1134     if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
1135         raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
1136     }
1137 
1138     if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
1139         /* State in FP is still valid */
1140         env->v7m.fpccr[M_REG_S] &= ~R_V7M_FPCCR_LSPACT_MASK;
1141     } else {
1142         bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
1143         int i;
1144         uint32_t fpscr;
1145 
1146         if (fptr & 7) {
1147             raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
1148         }
1149 
1150         for (i = 0; i < (ts ? 32 : 16); i += 2) {
1151             uint32_t slo, shi;
1152             uint64_t dn;
1153             uint32_t faddr = fptr + 4 * i;
1154 
1155             if (i >= 16) {
1156                 faddr += 8; /* skip the slot for the FPSCR and VPR */
1157             }
1158 
1159             slo = cpu_ldl_data_ra(env, faddr, ra);
1160             shi = cpu_ldl_data_ra(env, faddr + 4, ra);
1161 
1162             dn = (uint64_t) shi << 32 | slo;
1163             *aa32_vfp_dreg(env, i / 2) = dn;
1164         }
1165         fpscr = cpu_ldl_data_ra(env, fptr + 0x40, ra);
1166         vfp_set_fpscr(env, fpscr);
1167         if (cpu_isar_feature(aa32_mve, cpu)) {
1168             env->v7m.vpr = cpu_ldl_data_ra(env, fptr + 0x44, ra);
1169         }
1170     }
1171 
1172     env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
1173 }
1174 
v7m_push_stack(ARMCPU * cpu)1175 static bool v7m_push_stack(ARMCPU *cpu)
1176 {
1177     /*
1178      * Do the "set up stack frame" part of exception entry,
1179      * similar to pseudocode PushStack().
1180      * Return true if we generate a derived exception (and so
1181      * should ignore further stack faults trying to process
1182      * that derived exception.)
1183      */
1184     bool stacked_ok = true, limitviol = false;
1185     CPUARMState *env = &cpu->env;
1186     uint32_t xpsr = xpsr_read(env);
1187     uint32_t frameptr = env->regs[13];
1188     ARMMMUIdx mmu_idx = arm_mmu_idx(env);
1189     uint32_t framesize;
1190     bool nsacr_cp10 = extract32(env->v7m.nsacr, 10, 1);
1191 
1192     if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
1193         (env->v7m.secure || nsacr_cp10)) {
1194         if (env->v7m.secure &&
1195             env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
1196             framesize = 0xa8;
1197         } else {
1198             framesize = 0x68;
1199         }
1200     } else {
1201         framesize = 0x20;
1202     }
1203 
1204     /* Align stack pointer if the guest wants that */
1205     if ((frameptr & 4) &&
1206         (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKALIGN_MASK)) {
1207         frameptr -= 4;
1208         xpsr |= XPSR_SPREALIGN;
1209     }
1210 
1211     xpsr &= ~XPSR_SFPA;
1212     if (env->v7m.secure &&
1213         (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
1214         xpsr |= XPSR_SFPA;
1215     }
1216 
1217     frameptr -= framesize;
1218 
1219     if (arm_feature(env, ARM_FEATURE_V8)) {
1220         uint32_t limit = v7m_sp_limit(env);
1221 
1222         if (frameptr < limit) {
1223             /*
1224              * Stack limit failure: set SP to the limit value, and generate
1225              * STKOF UsageFault. Stack pushes below the limit must not be
1226              * performed. It is IMPDEF whether pushes above the limit are
1227              * performed; we choose not to.
1228              */
1229             qemu_log_mask(CPU_LOG_INT,
1230                           "...STKOF during stacking\n");
1231             env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
1232             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
1233                                     env->v7m.secure);
1234             env->regs[13] = limit;
1235             /*
1236              * We won't try to perform any further memory accesses but
1237              * we must continue through the following code to check for
1238              * permission faults during FPU state preservation, and we
1239              * must update FPCCR if lazy stacking is enabled.
1240              */
1241             limitviol = true;
1242             stacked_ok = false;
1243         }
1244     }
1245 
1246     /*
1247      * Write as much of the stack frame as we can. If we fail a stack
1248      * write this will result in a derived exception being pended
1249      * (which may be taken in preference to the one we started with
1250      * if it has higher priority).
1251      */
1252     stacked_ok = stacked_ok &&
1253         v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, STACK_NORMAL) &&
1254         v7m_stack_write(cpu, frameptr + 4, env->regs[1],
1255                         mmu_idx, STACK_NORMAL) &&
1256         v7m_stack_write(cpu, frameptr + 8, env->regs[2],
1257                         mmu_idx, STACK_NORMAL) &&
1258         v7m_stack_write(cpu, frameptr + 12, env->regs[3],
1259                         mmu_idx, STACK_NORMAL) &&
1260         v7m_stack_write(cpu, frameptr + 16, env->regs[12],
1261                         mmu_idx, STACK_NORMAL) &&
1262         v7m_stack_write(cpu, frameptr + 20, env->regs[14],
1263                         mmu_idx, STACK_NORMAL) &&
1264         v7m_stack_write(cpu, frameptr + 24, env->regs[15],
1265                         mmu_idx, STACK_NORMAL) &&
1266         v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, STACK_NORMAL);
1267 
1268     if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
1269         /* FPU is active, try to save its registers */
1270         bool fpccr_s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
1271         bool lspact = env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK;
1272 
1273         if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) {
1274             qemu_log_mask(CPU_LOG_INT,
1275                           "...SecureFault because LSPACT and FPCA both set\n");
1276             env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
1277             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
1278         } else if (!env->v7m.secure && !nsacr_cp10) {
1279             qemu_log_mask(CPU_LOG_INT,
1280                           "...Secure UsageFault with CFSR.NOCP because "
1281                           "NSACR.CP10 prevents stacking FP regs\n");
1282             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
1283             env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
1284         } else {
1285             if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
1286                 /* Lazy stacking disabled, save registers now */
1287                 int i;
1288                 bool cpacr_pass = v7m_cpacr_pass(env, env->v7m.secure,
1289                                                  arm_current_el(env) != 0);
1290 
1291                 if (stacked_ok && !cpacr_pass) {
1292                     /*
1293                      * Take UsageFault if CPACR forbids access. The pseudocode
1294                      * here does a full CheckCPEnabled() but we know the NSACR
1295                      * check can never fail as we have already handled that.
1296                      */
1297                     qemu_log_mask(CPU_LOG_INT,
1298                                   "...UsageFault with CFSR.NOCP because "
1299                                   "CPACR.CP10 prevents stacking FP regs\n");
1300                     armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
1301                                             env->v7m.secure);
1302                     env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
1303                     stacked_ok = false;
1304                 }
1305 
1306                 for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
1307                     uint64_t dn = *aa32_vfp_dreg(env, i / 2);
1308                     uint32_t faddr = frameptr + 0x20 + 4 * i;
1309                     uint32_t slo = extract64(dn, 0, 32);
1310                     uint32_t shi = extract64(dn, 32, 32);
1311 
1312                     if (i >= 16) {
1313                         faddr += 8; /* skip the slot for the FPSCR and VPR */
1314                     }
1315                     stacked_ok = stacked_ok &&
1316                         v7m_stack_write(cpu, faddr, slo,
1317                                         mmu_idx, STACK_NORMAL) &&
1318                         v7m_stack_write(cpu, faddr + 4, shi,
1319                                         mmu_idx, STACK_NORMAL);
1320                 }
1321                 stacked_ok = stacked_ok &&
1322                     v7m_stack_write(cpu, frameptr + 0x60,
1323                                     vfp_get_fpscr(env), mmu_idx, STACK_NORMAL);
1324                 if (cpu_isar_feature(aa32_mve, cpu)) {
1325                     stacked_ok = stacked_ok &&
1326                         v7m_stack_write(cpu, frameptr + 0x64,
1327                                         env->v7m.vpr, mmu_idx, STACK_NORMAL);
1328                 }
1329                 if (cpacr_pass) {
1330                     for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
1331                         *aa32_vfp_dreg(env, i / 2) = 0;
1332                     }
1333                     vfp_set_fpscr(env, 0);
1334                     if (cpu_isar_feature(aa32_mve, cpu)) {
1335                         env->v7m.vpr = 0;
1336                     }
1337                 }
1338             } else {
1339                 /* Lazy stacking enabled, save necessary info to stack later */
1340                 v7m_update_fpccr(env, frameptr + 0x20, true);
1341             }
1342         }
1343     }
1344 
1345     /*
1346      * If we broke a stack limit then SP was already updated earlier;
1347      * otherwise we update SP regardless of whether any of the stack
1348      * accesses failed or we took some other kind of fault.
1349      */
1350     if (!limitviol) {
1351         env->regs[13] = frameptr;
1352     }
1353 
1354     return !stacked_ok;
1355 }
1356 
do_v7m_exception_exit(ARMCPU * cpu)1357 static void do_v7m_exception_exit(ARMCPU *cpu)
1358 {
1359     CPUARMState *env = &cpu->env;
1360     uint32_t excret;
1361     uint32_t xpsr, xpsr_mask;
1362     bool ufault = false;
1363     bool sfault = false;
1364     bool return_to_sp_process;
1365     bool return_to_handler;
1366     bool rettobase = false;
1367     bool exc_secure = false;
1368     bool return_to_secure;
1369     bool ftype;
1370     bool restore_s16_s31 = false;
1371 
1372     /*
1373      * If we're not in Handler mode then jumps to magic exception-exit
1374      * addresses don't have magic behaviour. However for the v8M
1375      * security extensions the magic secure-function-return has to
1376      * work in thread mode too, so to avoid doing an extra check in
1377      * the generated code we allow exception-exit magic to also cause the
1378      * internal exception and bring us here in thread mode. Correct code
1379      * will never try to do this (the following insn fetch will always
1380      * fault) so we the overhead of having taken an unnecessary exception
1381      * doesn't matter.
1382      */
1383     if (!arm_v7m_is_handler_mode(env)) {
1384         return;
1385     }
1386 
1387     /*
1388      * In the spec pseudocode ExceptionReturn() is called directly
1389      * from BXWritePC() and gets the full target PC value including
1390      * bit zero. In QEMU's implementation we treat it as a normal
1391      * jump-to-register (which is then caught later on), and so split
1392      * the target value up between env->regs[15] and env->thumb in
1393      * gen_bx(). Reconstitute it.
1394      */
1395     excret = env->regs[15];
1396     if (env->thumb) {
1397         excret |= 1;
1398     }
1399 
1400     qemu_log_mask(CPU_LOG_INT, "Exception return: magic PC %" PRIx32
1401                   " previous exception %d\n",
1402                   excret, env->v7m.exception);
1403 
1404     if ((excret & R_V7M_EXCRET_RES1_MASK) != R_V7M_EXCRET_RES1_MASK) {
1405         qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero high bits in exception "
1406                       "exit PC value 0x%" PRIx32 " are UNPREDICTABLE\n",
1407                       excret);
1408     }
1409 
1410     ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
1411 
1412     if (!ftype && !cpu_isar_feature(aa32_vfp_simd, cpu)) {
1413         qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
1414                       "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
1415                       "if FPU not present\n",
1416                       excret);
1417         ftype = true;
1418     }
1419 
1420     if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
1421         /*
1422          * EXC_RETURN.ES validation check (R_SMFL). We must do this before
1423          * we pick which FAULTMASK to clear.
1424          */
1425         if (!env->v7m.secure &&
1426             ((excret & R_V7M_EXCRET_ES_MASK) ||
1427              !(excret & R_V7M_EXCRET_DCRS_MASK))) {
1428             sfault = 1;
1429             /* For all other purposes, treat ES as 0 (R_HXSR) */
1430             excret &= ~R_V7M_EXCRET_ES_MASK;
1431         }
1432         exc_secure = excret & R_V7M_EXCRET_ES_MASK;
1433     }
1434 
1435     if (env->v7m.exception != ARMV7M_EXCP_NMI) {
1436         /*
1437          * Auto-clear FAULTMASK on return from other than NMI.
1438          * If the security extension is implemented then this only
1439          * happens if the raw execution priority is >= 0; the
1440          * value of the ES bit in the exception return value indicates
1441          * which security state's faultmask to clear. (v8M ARM ARM R_KBNF.)
1442          */
1443         if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
1444             if (armv7m_nvic_raw_execution_priority(env->nvic) >= 0) {
1445                 env->v7m.faultmask[exc_secure] = 0;
1446             }
1447         } else {
1448             env->v7m.faultmask[M_REG_NS] = 0;
1449         }
1450     }
1451 
1452     switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception,
1453                                      exc_secure)) {
1454     case -1:
1455         /* attempt to exit an exception that isn't active */
1456         ufault = true;
1457         break;
1458     case 0:
1459         /* still an irq active now */
1460         break;
1461     case 1:
1462         /*
1463          * We returned to base exception level, no nesting.
1464          * (In the pseudocode this is written using "NestedActivation != 1"
1465          * where we have 'rettobase == false'.)
1466          */
1467         rettobase = true;
1468         break;
1469     default:
1470         g_assert_not_reached();
1471     }
1472 
1473     return_to_handler = !(excret & R_V7M_EXCRET_MODE_MASK);
1474     return_to_sp_process = excret & R_V7M_EXCRET_SPSEL_MASK;
1475     return_to_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
1476         (excret & R_V7M_EXCRET_S_MASK);
1477 
1478     if (arm_feature(env, ARM_FEATURE_V8)) {
1479         if (!arm_feature(env, ARM_FEATURE_M_SECURITY)) {
1480             /*
1481              * UNPREDICTABLE if S == 1 or DCRS == 0 or ES == 1 (R_XLCP);
1482              * we choose to take the UsageFault.
1483              */
1484             if ((excret & R_V7M_EXCRET_S_MASK) ||
1485                 (excret & R_V7M_EXCRET_ES_MASK) ||
1486                 !(excret & R_V7M_EXCRET_DCRS_MASK)) {
1487                 ufault = true;
1488             }
1489         }
1490         if (excret & R_V7M_EXCRET_RES0_MASK) {
1491             ufault = true;
1492         }
1493     } else {
1494         /* For v7M we only recognize certain combinations of the low bits */
1495         switch (excret & 0xf) {
1496         case 1: /* Return to Handler */
1497             break;
1498         case 13: /* Return to Thread using Process stack */
1499         case 9: /* Return to Thread using Main stack */
1500             /*
1501              * We only need to check NONBASETHRDENA for v7M, because in
1502              * v8M this bit does not exist (it is RES1).
1503              */
1504             if (!rettobase &&
1505                 !(env->v7m.ccr[env->v7m.secure] &
1506                   R_V7M_CCR_NONBASETHRDENA_MASK)) {
1507                 ufault = true;
1508             }
1509             break;
1510         default:
1511             ufault = true;
1512         }
1513     }
1514 
1515     /*
1516      * Set CONTROL.SPSEL from excret.SPSEL. Since we're still in
1517      * Handler mode (and will be until we write the new XPSR.Interrupt
1518      * field) this does not switch around the current stack pointer.
1519      * We must do this before we do any kind of tailchaining, including
1520      * for the derived exceptions on integrity check failures, or we will
1521      * give the guest an incorrect EXCRET.SPSEL value on exception entry.
1522      */
1523     write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
1524 
1525     /*
1526      * Clear scratch FP values left in caller saved registers; this
1527      * must happen before any kind of tail chaining.
1528      */
1529     if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
1530         (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
1531         if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
1532             env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
1533             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
1534             qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
1535                           "stackframe: error during lazy state deactivation\n");
1536             v7m_exception_taken(cpu, excret, true, false);
1537             return;
1538         } else {
1539             if (arm_feature(env, ARM_FEATURE_V8_1M)) {
1540                 /* v8.1M adds this NOCP check */
1541                 bool nsacr_pass = exc_secure ||
1542                     extract32(env->v7m.nsacr, 10, 1);
1543                 bool cpacr_pass = v7m_cpacr_pass(env, exc_secure, true);
1544                 if (!nsacr_pass) {
1545                     armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
1546                     env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
1547                     qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
1548                         "stackframe: NSACR prevents clearing FPU registers\n");
1549                     v7m_exception_taken(cpu, excret, true, false);
1550                     return;
1551                 } else if (!cpacr_pass) {
1552                     armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
1553                                             exc_secure);
1554                     env->v7m.cfsr[exc_secure] |= R_V7M_CFSR_NOCP_MASK;
1555                     qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
1556                         "stackframe: CPACR prevents clearing FPU registers\n");
1557                     v7m_exception_taken(cpu, excret, true, false);
1558                     return;
1559                 }
1560             }
1561             /* Clear s0..s15, FPSCR and VPR */
1562             int i;
1563 
1564             for (i = 0; i < 16; i += 2) {
1565                 *aa32_vfp_dreg(env, i / 2) = 0;
1566             }
1567             vfp_set_fpscr(env, 0);
1568             if (cpu_isar_feature(aa32_mve, cpu)) {
1569                 env->v7m.vpr = 0;
1570             }
1571         }
1572     }
1573 
1574     if (sfault) {
1575         env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
1576         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
1577         qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
1578                       "stackframe: failed EXC_RETURN.ES validity check\n");
1579         v7m_exception_taken(cpu, excret, true, false);
1580         return;
1581     }
1582 
1583     if (ufault) {
1584         /*
1585          * Bad exception return: instead of popping the exception
1586          * stack, directly take a usage fault on the current stack.
1587          */
1588         env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
1589         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
1590         qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
1591                       "stackframe: failed exception return integrity check\n");
1592         v7m_exception_taken(cpu, excret, true, false);
1593         return;
1594     }
1595 
1596     /*
1597      * Tailchaining: if there is currently a pending exception that
1598      * is high enough priority to preempt execution at the level we're
1599      * about to return to, then just directly take that exception now,
1600      * avoiding an unstack-and-then-stack. Note that now we have
1601      * deactivated the previous exception by calling armv7m_nvic_complete_irq()
1602      * our current execution priority is already the execution priority we are
1603      * returning to -- none of the state we would unstack or set based on
1604      * the EXCRET value affects it.
1605      */
1606     if (armv7m_nvic_can_take_pending_exception(env->nvic)) {
1607         qemu_log_mask(CPU_LOG_INT, "...tailchaining to pending exception\n");
1608         v7m_exception_taken(cpu, excret, true, false);
1609         return;
1610     }
1611 
1612     switch_v7m_security_state(env, return_to_secure);
1613 
1614     {
1615         /*
1616          * The stack pointer we should be reading the exception frame from
1617          * depends on bits in the magic exception return type value (and
1618          * for v8M isn't necessarily the stack pointer we will eventually
1619          * end up resuming execution with). Get a pointer to the location
1620          * in the CPU state struct where the SP we need is currently being
1621          * stored; we will use and modify it in place.
1622          * We use this limited C variable scope so we don't accidentally
1623          * use 'frame_sp_p' after we do something that makes it invalid.
1624          */
1625         bool spsel = env->v7m.control[return_to_secure] & R_V7M_CONTROL_SPSEL_MASK;
1626         uint32_t *frame_sp_p = arm_v7m_get_sp_ptr(env, return_to_secure,
1627                                                   !return_to_handler, spsel);
1628         uint32_t frameptr = *frame_sp_p;
1629         bool pop_ok = true;
1630         ARMMMUIdx mmu_idx;
1631         bool return_to_priv = return_to_handler ||
1632             !(env->v7m.control[return_to_secure] & R_V7M_CONTROL_NPRIV_MASK);
1633 
1634         mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, return_to_secure,
1635                                                         return_to_priv);
1636 
1637         if (!QEMU_IS_ALIGNED(frameptr, 8) &&
1638             arm_feature(env, ARM_FEATURE_V8)) {
1639             qemu_log_mask(LOG_GUEST_ERROR,
1640                           "M profile exception return with non-8-aligned SP "
1641                           "for destination state is UNPREDICTABLE\n");
1642         }
1643 
1644         /* Do we need to pop callee-saved registers? */
1645         if (return_to_secure &&
1646             ((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
1647              (excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
1648             uint32_t actual_sig;
1649 
1650             pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
1651 
1652             if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
1653                 /* Take a SecureFault on the current stack */
1654                 env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
1655                 armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
1656                 qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
1657                               "stackframe: failed exception return integrity "
1658                               "signature check\n");
1659                 v7m_exception_taken(cpu, excret, true, false);
1660                 return;
1661             }
1662 
1663             pop_ok = pop_ok &&
1664                 v7m_stack_read(cpu, &env->regs[4], frameptr + 0x8, mmu_idx) &&
1665                 v7m_stack_read(cpu, &env->regs[5], frameptr + 0xc, mmu_idx) &&
1666                 v7m_stack_read(cpu, &env->regs[6], frameptr + 0x10, mmu_idx) &&
1667                 v7m_stack_read(cpu, &env->regs[7], frameptr + 0x14, mmu_idx) &&
1668                 v7m_stack_read(cpu, &env->regs[8], frameptr + 0x18, mmu_idx) &&
1669                 v7m_stack_read(cpu, &env->regs[9], frameptr + 0x1c, mmu_idx) &&
1670                 v7m_stack_read(cpu, &env->regs[10], frameptr + 0x20, mmu_idx) &&
1671                 v7m_stack_read(cpu, &env->regs[11], frameptr + 0x24, mmu_idx);
1672 
1673             frameptr += 0x28;
1674         }
1675 
1676         /* Pop registers */
1677         pop_ok = pop_ok &&
1678             v7m_stack_read(cpu, &env->regs[0], frameptr, mmu_idx) &&
1679             v7m_stack_read(cpu, &env->regs[1], frameptr + 0x4, mmu_idx) &&
1680             v7m_stack_read(cpu, &env->regs[2], frameptr + 0x8, mmu_idx) &&
1681             v7m_stack_read(cpu, &env->regs[3], frameptr + 0xc, mmu_idx) &&
1682             v7m_stack_read(cpu, &env->regs[12], frameptr + 0x10, mmu_idx) &&
1683             v7m_stack_read(cpu, &env->regs[14], frameptr + 0x14, mmu_idx) &&
1684             v7m_stack_read(cpu, &env->regs[15], frameptr + 0x18, mmu_idx) &&
1685             v7m_stack_read(cpu, &xpsr, frameptr + 0x1c, mmu_idx);
1686 
1687         if (!pop_ok) {
1688             /*
1689              * v7m_stack_read() pended a fault, so take it (as a tail
1690              * chained exception on the same stack frame)
1691              */
1692             qemu_log_mask(CPU_LOG_INT, "...derived exception on unstacking\n");
1693             v7m_exception_taken(cpu, excret, true, false);
1694             return;
1695         }
1696 
1697         /*
1698          * Returning from an exception with a PC with bit 0 set is defined
1699          * behaviour on v8M (bit 0 is ignored), but for v7M it was specified
1700          * to be UNPREDICTABLE. In practice actual v7M hardware seems to ignore
1701          * the lsbit, and there are several RTOSes out there which incorrectly
1702          * assume the r15 in the stack frame should be a Thumb-style "lsbit
1703          * indicates ARM/Thumb" value, so ignore the bit on v7M as well, but
1704          * complain about the badly behaved guest.
1705          */
1706         if (env->regs[15] & 1) {
1707             env->regs[15] &= ~1U;
1708             if (!arm_feature(env, ARM_FEATURE_V8)) {
1709                 qemu_log_mask(LOG_GUEST_ERROR,
1710                               "M profile return from interrupt with misaligned "
1711                               "PC is UNPREDICTABLE on v7M\n");
1712             }
1713         }
1714 
1715         if (arm_feature(env, ARM_FEATURE_V8)) {
1716             /*
1717              * For v8M we have to check whether the xPSR exception field
1718              * matches the EXCRET value for return to handler/thread
1719              * before we commit to changing the SP and xPSR.
1720              */
1721             bool will_be_handler = (xpsr & XPSR_EXCP) != 0;
1722             if (return_to_handler != will_be_handler) {
1723                 /*
1724                  * Take an INVPC UsageFault on the current stack.
1725                  * By this point we will have switched to the security state
1726                  * for the background state, so this UsageFault will target
1727                  * that state.
1728                  */
1729                 armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
1730                                         env->v7m.secure);
1731                 env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
1732                 qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
1733                               "stackframe: failed exception return integrity "
1734                               "check\n");
1735                 v7m_exception_taken(cpu, excret, true, false);
1736                 return;
1737             }
1738         }
1739 
1740         if (!ftype) {
1741             /* FP present and we need to handle it */
1742             if (!return_to_secure &&
1743                 (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK)) {
1744                 armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
1745                 env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
1746                 qemu_log_mask(CPU_LOG_INT,
1747                               "...taking SecureFault on existing stackframe: "
1748                               "Secure LSPACT set but exception return is "
1749                               "not to secure state\n");
1750                 v7m_exception_taken(cpu, excret, true, false);
1751                 return;
1752             }
1753 
1754             restore_s16_s31 = return_to_secure &&
1755                 (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
1756 
1757             if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
1758                 /* State in FPU is still valid, just clear LSPACT */
1759                 env->v7m.fpccr[return_to_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
1760             } else {
1761                 int i;
1762                 uint32_t fpscr;
1763                 bool cpacr_pass, nsacr_pass;
1764 
1765                 cpacr_pass = v7m_cpacr_pass(env, return_to_secure,
1766                                             return_to_priv);
1767                 nsacr_pass = return_to_secure ||
1768                     extract32(env->v7m.nsacr, 10, 1);
1769 
1770                 if (!cpacr_pass) {
1771                     armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
1772                                             return_to_secure);
1773                     env->v7m.cfsr[return_to_secure] |= R_V7M_CFSR_NOCP_MASK;
1774                     qemu_log_mask(CPU_LOG_INT,
1775                                   "...taking UsageFault on existing "
1776                                   "stackframe: CPACR.CP10 prevents unstacking "
1777                                   "FP regs\n");
1778                     v7m_exception_taken(cpu, excret, true, false);
1779                     return;
1780                 } else if (!nsacr_pass) {
1781                     armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
1782                     env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_INVPC_MASK;
1783                     qemu_log_mask(CPU_LOG_INT,
1784                                   "...taking Secure UsageFault on existing "
1785                                   "stackframe: NSACR.CP10 prevents unstacking "
1786                                   "FP regs\n");
1787                     v7m_exception_taken(cpu, excret, true, false);
1788                     return;
1789                 }
1790 
1791                 for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
1792                     uint32_t slo, shi;
1793                     uint64_t dn;
1794                     uint32_t faddr = frameptr + 0x20 + 4 * i;
1795 
1796                     if (i >= 16) {
1797                         faddr += 8; /* Skip the slot for the FPSCR and VPR */
1798                     }
1799 
1800                     pop_ok = pop_ok &&
1801                         v7m_stack_read(cpu, &slo, faddr, mmu_idx) &&
1802                         v7m_stack_read(cpu, &shi, faddr + 4, mmu_idx);
1803 
1804                     if (!pop_ok) {
1805                         break;
1806                     }
1807 
1808                     dn = (uint64_t)shi << 32 | slo;
1809                     *aa32_vfp_dreg(env, i / 2) = dn;
1810                 }
1811                 pop_ok = pop_ok &&
1812                     v7m_stack_read(cpu, &fpscr, frameptr + 0x60, mmu_idx);
1813                 if (pop_ok) {
1814                     vfp_set_fpscr(env, fpscr);
1815                 }
1816                 if (cpu_isar_feature(aa32_mve, cpu)) {
1817                     pop_ok = pop_ok &&
1818                         v7m_stack_read(cpu, &env->v7m.vpr,
1819                                        frameptr + 0x64, mmu_idx);
1820                 }
1821                 if (!pop_ok) {
1822                     /*
1823                      * These regs are 0 if security extension present;
1824                      * otherwise merely UNKNOWN. We zero always.
1825                      */
1826                     for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
1827                         *aa32_vfp_dreg(env, i / 2) = 0;
1828                     }
1829                     vfp_set_fpscr(env, 0);
1830                     if (cpu_isar_feature(aa32_mve, cpu)) {
1831                         env->v7m.vpr = 0;
1832                     }
1833                 }
1834             }
1835         }
1836         env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
1837                                                V7M_CONTROL, FPCA, !ftype);
1838 
1839         /* Commit to consuming the stack frame */
1840         frameptr += 0x20;
1841         if (!ftype) {
1842             frameptr += 0x48;
1843             if (restore_s16_s31) {
1844                 frameptr += 0x40;
1845             }
1846         }
1847         /*
1848          * Undo stack alignment (the SPREALIGN bit indicates that the original
1849          * pre-exception SP was not 8-aligned and we added a padding word to
1850          * align it, so we undo this by ORing in the bit that increases it
1851          * from the current 8-aligned value to the 8-unaligned value. (Adding 4
1852          * would work too but a logical OR is how the pseudocode specifies it.)
1853          */
1854         if (xpsr & XPSR_SPREALIGN) {
1855             frameptr |= 4;
1856         }
1857         *frame_sp_p = frameptr;
1858     }
1859 
1860     xpsr_mask = ~(XPSR_SPREALIGN | XPSR_SFPA);
1861     if (!arm_feature(env, ARM_FEATURE_THUMB_DSP)) {
1862         xpsr_mask &= ~XPSR_GE;
1863     }
1864     /* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
1865     xpsr_write(env, xpsr, xpsr_mask);
1866 
1867     if (env->v7m.secure) {
1868         bool sfpa = xpsr & XPSR_SFPA;
1869 
1870         env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
1871                                                V7M_CONTROL, SFPA, sfpa);
1872     }
1873 
1874     /*
1875      * The restored xPSR exception field will be zero if we're
1876      * resuming in Thread mode. If that doesn't match what the
1877      * exception return excret specified then this is a UsageFault.
1878      * v7M requires we make this check here; v8M did it earlier.
1879      */
1880     if (return_to_handler != arm_v7m_is_handler_mode(env)) {
1881         /*
1882          * Take an INVPC UsageFault by pushing the stack again;
1883          * we know we're v7M so this is never a Secure UsageFault.
1884          */
1885         bool ignore_stackfaults;
1886 
1887         assert(!arm_feature(env, ARM_FEATURE_V8));
1888         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, false);
1889         env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
1890         ignore_stackfaults = v7m_push_stack(cpu);
1891         qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on new stackframe: "
1892                       "failed exception return integrity check\n");
1893         v7m_exception_taken(cpu, excret, false, ignore_stackfaults);
1894         return;
1895     }
1896 
1897     /* Otherwise, we have a successful exception exit. */
1898     arm_clear_exclusive(env);
1899     arm_rebuild_hflags(env);
1900     qemu_log_mask(CPU_LOG_INT, "...successful exception return\n");
1901 }
1902 
do_v7m_function_return(ARMCPU * cpu)1903 static bool do_v7m_function_return(ARMCPU *cpu)
1904 {
1905     /*
1906      * v8M security extensions magic function return.
1907      * We may either:
1908      *  (1) throw an exception (longjump)
1909      *  (2) return true if we successfully handled the function return
1910      *  (3) return false if we failed a consistency check and have
1911      *      pended a UsageFault that needs to be taken now
1912      *
1913      * At this point the magic return value is split between env->regs[15]
1914      * and env->thumb. We don't bother to reconstitute it because we don't
1915      * need it (all values are handled the same way).
1916      */
1917     CPUARMState *env = &cpu->env;
1918     uint32_t newpc, newpsr, newpsr_exc;
1919 
1920     qemu_log_mask(CPU_LOG_INT, "...really v7M secure function return\n");
1921 
1922     {
1923         bool threadmode, spsel;
1924         MemOpIdx oi;
1925         ARMMMUIdx mmu_idx;
1926         uint32_t *frame_sp_p;
1927         uint32_t frameptr;
1928 
1929         /* Pull the return address and IPSR from the Secure stack */
1930         threadmode = !arm_v7m_is_handler_mode(env);
1931         spsel = env->v7m.control[M_REG_S] & R_V7M_CONTROL_SPSEL_MASK;
1932 
1933         frame_sp_p = arm_v7m_get_sp_ptr(env, true, threadmode, spsel);
1934         frameptr = *frame_sp_p;
1935 
1936         /*
1937          * These loads may throw an exception (for MPU faults). We want to
1938          * do them as secure, so work out what MMU index that is.
1939          */
1940         mmu_idx = arm_v7m_mmu_idx_for_secstate(env, true);
1941         oi = make_memop_idx(MO_LEUL, arm_to_core_mmu_idx(mmu_idx));
1942         newpc = cpu_ldl_mmu(env, frameptr, oi, 0);
1943         newpsr = cpu_ldl_mmu(env, frameptr + 4, oi, 0);
1944 
1945         /* Consistency checks on new IPSR */
1946         newpsr_exc = newpsr & XPSR_EXCP;
1947         if (!((env->v7m.exception == 0 && newpsr_exc == 0) ||
1948               (env->v7m.exception == 1 && newpsr_exc != 0))) {
1949             /* Pend the fault and tell our caller to take it */
1950             env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
1951             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
1952                                     env->v7m.secure);
1953             qemu_log_mask(CPU_LOG_INT,
1954                           "...taking INVPC UsageFault: "
1955                           "IPSR consistency check failed\n");
1956             return false;
1957         }
1958 
1959         *frame_sp_p = frameptr + 8;
1960     }
1961 
1962     /* This invalidates frame_sp_p */
1963     switch_v7m_security_state(env, true);
1964     env->v7m.exception = newpsr_exc;
1965     env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
1966     if (newpsr & XPSR_SFPA) {
1967         env->v7m.control[M_REG_S] |= R_V7M_CONTROL_SFPA_MASK;
1968     }
1969     xpsr_write(env, 0, XPSR_IT);
1970     env->thumb = newpc & 1;
1971     env->regs[15] = newpc & ~1;
1972     arm_rebuild_hflags(env);
1973 
1974     qemu_log_mask(CPU_LOG_INT, "...function return successful\n");
1975     return true;
1976 }
1977 
v7m_read_half_insn(ARMCPU * cpu,ARMMMUIdx mmu_idx,bool secure,uint32_t addr,uint16_t * insn)1978 static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx, bool secure,
1979                                uint32_t addr, uint16_t *insn)
1980 {
1981     /*
1982      * Load a 16-bit portion of a v7M instruction, returning true on success,
1983      * or false on failure (in which case we will have pended the appropriate
1984      * exception).
1985      * We need to do the instruction fetch's MPU and SAU checks
1986      * like this because there is no MMU index that would allow
1987      * doing the load with a single function call. Instead we must
1988      * first check that the security attributes permit the load
1989      * and that they don't mismatch on the two halves of the instruction,
1990      * and then we do the load as a secure load (ie using the security
1991      * attributes of the address, not the CPU, as architecturally required).
1992      */
1993     CPUState *cs = CPU(cpu);
1994     CPUARMState *env = &cpu->env;
1995     V8M_SAttributes sattrs = {};
1996     GetPhysAddrResult res = {};
1997     ARMMMUFaultInfo fi = {};
1998     MemTxResult txres;
1999 
2000     v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx, secure, &sattrs);
2001     if (!sattrs.nsc || sattrs.ns) {
2002         /*
2003          * This must be the second half of the insn, and it straddles a
2004          * region boundary with the second half not being S&NSC.
2005          */
2006         env->v7m.sfsr |= R_V7M_SFSR_INVEP_MASK;
2007         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
2008         qemu_log_mask(CPU_LOG_INT,
2009                       "...really SecureFault with SFSR.INVEP\n");
2010         return false;
2011     }
2012     if (get_phys_addr(env, addr, MMU_INST_FETCH, mmu_idx, &res, &fi)) {
2013         /* the MPU lookup failed */
2014         env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK;
2015         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, env->v7m.secure);
2016         qemu_log_mask(CPU_LOG_INT, "...really MemManage with CFSR.IACCVIOL\n");
2017         return false;
2018     }
2019     *insn = address_space_lduw_le(arm_addressspace(cs, res.f.attrs),
2020                                   res.f.phys_addr, res.f.attrs, &txres);
2021     if (txres != MEMTX_OK) {
2022         env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_IBUSERR_MASK;
2023         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
2024         qemu_log_mask(CPU_LOG_INT, "...really BusFault with CFSR.IBUSERR\n");
2025         return false;
2026     }
2027     return true;
2028 }
2029 
v7m_read_sg_stack_word(ARMCPU * cpu,ARMMMUIdx mmu_idx,uint32_t addr,uint32_t * spdata)2030 static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx,
2031                                    uint32_t addr, uint32_t *spdata)
2032 {
2033     /*
2034      * Read a word of data from the stack for the SG instruction,
2035      * writing the value into *spdata. If the load succeeds, return
2036      * true; otherwise pend an appropriate exception and return false.
2037      * (We can't use data load helpers here that throw an exception
2038      * because of the context we're called in, which is halfway through
2039      * arm_v7m_cpu_do_interrupt().)
2040      */
2041     CPUState *cs = CPU(cpu);
2042     CPUARMState *env = &cpu->env;
2043     MemTxResult txres;
2044     GetPhysAddrResult res = {};
2045     ARMMMUFaultInfo fi = {};
2046     uint32_t value;
2047 
2048     if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &res, &fi)) {
2049         /* MPU/SAU lookup failed */
2050         if (fi.type == ARMFault_QEMU_SFault) {
2051             qemu_log_mask(CPU_LOG_INT,
2052                           "...SecureFault during stack word read\n");
2053             env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
2054             env->v7m.sfar = addr;
2055             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
2056         } else {
2057             qemu_log_mask(CPU_LOG_INT,
2058                           "...MemManageFault during stack word read\n");
2059             env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_DACCVIOL_MASK |
2060                 R_V7M_CFSR_MMARVALID_MASK;
2061             env->v7m.mmfar[M_REG_S] = addr;
2062             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, false);
2063         }
2064         return false;
2065     }
2066     value = address_space_ldl(arm_addressspace(cs, res.f.attrs),
2067                               res.f.phys_addr, res.f.attrs, &txres);
2068     if (txres != MEMTX_OK) {
2069         /* BusFault trying to read the data */
2070         qemu_log_mask(CPU_LOG_INT,
2071                       "...BusFault during stack word read\n");
2072         env->v7m.cfsr[M_REG_NS] |=
2073             (R_V7M_CFSR_PRECISERR_MASK | R_V7M_CFSR_BFARVALID_MASK);
2074         env->v7m.bfar = addr;
2075         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
2076         return false;
2077     }
2078 
2079     *spdata = value;
2080     return true;
2081 }
2082 
v7m_handle_execute_nsc(ARMCPU * cpu)2083 static bool v7m_handle_execute_nsc(ARMCPU *cpu)
2084 {
2085     /*
2086      * Check whether this attempt to execute code in a Secure & NS-Callable
2087      * memory region is for an SG instruction; if so, then emulate the
2088      * effect of the SG instruction and return true. Otherwise pend
2089      * the correct kind of exception and return false.
2090      */
2091     CPUARMState *env = &cpu->env;
2092     ARMMMUIdx mmu_idx;
2093     uint16_t insn;
2094 
2095     /*
2096      * We should never get here unless get_phys_addr_pmsav8() caused
2097      * an exception for NS executing in S&NSC memory.
2098      */
2099     assert(!env->v7m.secure);
2100     assert(arm_feature(env, ARM_FEATURE_M_SECURITY));
2101 
2102     /* We want to do the MPU lookup as secure; work out what mmu_idx that is */
2103     mmu_idx = arm_v7m_mmu_idx_for_secstate(env, true);
2104 
2105     if (!v7m_read_half_insn(cpu, mmu_idx, true, env->regs[15], &insn)) {
2106         return false;
2107     }
2108 
2109     if (!env->thumb) {
2110         goto gen_invep;
2111     }
2112 
2113     if (insn != 0xe97f) {
2114         /*
2115          * Not an SG instruction first half (we choose the IMPDEF
2116          * early-SG-check option).
2117          */
2118         goto gen_invep;
2119     }
2120 
2121     if (!v7m_read_half_insn(cpu, mmu_idx, true, env->regs[15] + 2, &insn)) {
2122         return false;
2123     }
2124 
2125     if (insn != 0xe97f) {
2126         /*
2127          * Not an SG instruction second half (yes, both halves of the SG
2128          * insn have the same hex value)
2129          */
2130         goto gen_invep;
2131     }
2132 
2133     /*
2134      * OK, we have confirmed that we really have an SG instruction.
2135      * We know we're NS in S memory so don't need to repeat those checks.
2136      */
2137     qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
2138                   ", executing it\n", env->regs[15]);
2139 
2140     if (cpu_isar_feature(aa32_m_sec_state, cpu) &&
2141         !arm_v7m_is_handler_mode(env)) {
2142         /*
2143          * v8.1M exception stack frame integrity check. Note that we
2144          * must perform the memory access even if CCR_S.TRD is zero
2145          * and we aren't going to check what the data loaded is.
2146          */
2147         uint32_t spdata, sp;
2148 
2149         /*
2150          * We know we are currently NS, so the S stack pointers must be
2151          * in other_ss_{psp,msp}, not in regs[13]/other_sp.
2152          */
2153         sp = v7m_using_psp(env) ? env->v7m.other_ss_psp : env->v7m.other_ss_msp;
2154         if (!v7m_read_sg_stack_word(cpu, mmu_idx, sp, &spdata)) {
2155             /* Stack access failed and an exception has been pended */
2156             return false;
2157         }
2158 
2159         if (env->v7m.ccr[M_REG_S] & R_V7M_CCR_TRD_MASK) {
2160             if (((spdata & ~1) == 0xfefa125a) ||
2161                 !(env->v7m.control[M_REG_S] & 1)) {
2162                 goto gen_invep;
2163             }
2164         }
2165     }
2166 
2167     env->regs[14] &= ~1;
2168     env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
2169     switch_v7m_security_state(env, true);
2170     xpsr_write(env, 0, XPSR_IT);
2171     env->regs[15] += 4;
2172     arm_rebuild_hflags(env);
2173     return true;
2174 
2175 gen_invep:
2176     env->v7m.sfsr |= R_V7M_SFSR_INVEP_MASK;
2177     armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
2178     qemu_log_mask(CPU_LOG_INT,
2179                   "...really SecureFault with SFSR.INVEP\n");
2180     return false;
2181 }
2182 
arm_v7m_cpu_do_interrupt(CPUState * cs)2183 void arm_v7m_cpu_do_interrupt(CPUState *cs)
2184 {
2185     ARMCPU *cpu = ARM_CPU(cs);
2186     CPUARMState *env = &cpu->env;
2187     uint32_t lr;
2188     bool ignore_stackfaults;
2189 
2190     arm_log_exception(cs);
2191 
2192     /*
2193      * For exceptions we just mark as pending on the NVIC, and let that
2194      * handle it.
2195      */
2196     switch (cs->exception_index) {
2197     case EXCP_UDEF:
2198         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
2199         env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
2200         break;
2201     case EXCP_NOCP:
2202     {
2203         /*
2204          * NOCP might be directed to something other than the current
2205          * security state if this fault is because of NSACR; we indicate
2206          * the target security state using exception.target_el.
2207          */
2208         int target_secstate;
2209 
2210         if (env->exception.target_el == 3) {
2211             target_secstate = M_REG_S;
2212         } else {
2213             target_secstate = env->v7m.secure;
2214         }
2215         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
2216         env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
2217         break;
2218     }
2219     case EXCP_INVSTATE:
2220         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
2221         env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
2222         break;
2223     case EXCP_STKOF:
2224         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
2225         env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
2226         break;
2227     case EXCP_LSERR:
2228         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
2229         env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
2230         break;
2231     case EXCP_UNALIGNED:
2232         /* Unaligned faults reported by M-profile aware code */
2233         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
2234         env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
2235         break;
2236     case EXCP_DIVBYZERO:
2237         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
2238         env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_DIVBYZERO_MASK;
2239         break;
2240     case EXCP_SWI:
2241         /* The PC already points to the next instruction.  */
2242         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
2243         break;
2244     case EXCP_PREFETCH_ABORT:
2245     case EXCP_DATA_ABORT:
2246         /*
2247          * Note that for M profile we don't have a guest facing FSR, but
2248          * the env->exception.fsr will be populated by the code that
2249          * raises the fault, in the A profile short-descriptor format.
2250          *
2251          * Log the exception.vaddress now regardless of subtype, because
2252          * logging below only logs it when it goes into a guest visible
2253          * register.
2254          */
2255         qemu_log_mask(CPU_LOG_INT, "...at fault address 0x%x\n",
2256                       (uint32_t)env->exception.vaddress);
2257         switch (env->exception.fsr & 0xf) {
2258         case M_FAKE_FSR_NSC_EXEC:
2259             /*
2260              * Exception generated when we try to execute code at an address
2261              * which is marked as Secure & Non-Secure Callable and the CPU
2262              * is in the Non-Secure state. The only instruction which can
2263              * be executed like this is SG (and that only if both halves of
2264              * the SG instruction have the same security attributes.)
2265              * Everything else must generate an INVEP SecureFault, so we
2266              * emulate the SG instruction here.
2267              */
2268             if (v7m_handle_execute_nsc(cpu)) {
2269                 return;
2270             }
2271             break;
2272         case M_FAKE_FSR_SFAULT:
2273             /*
2274              * Various flavours of SecureFault for attempts to execute or
2275              * access data in the wrong security state.
2276              */
2277             switch (cs->exception_index) {
2278             case EXCP_PREFETCH_ABORT:
2279                 if (env->v7m.secure) {
2280                     env->v7m.sfsr |= R_V7M_SFSR_INVTRAN_MASK;
2281                     qemu_log_mask(CPU_LOG_INT,
2282                                   "...really SecureFault with SFSR.INVTRAN\n");
2283                 } else {
2284                     env->v7m.sfsr |= R_V7M_SFSR_INVEP_MASK;
2285                     qemu_log_mask(CPU_LOG_INT,
2286                                   "...really SecureFault with SFSR.INVEP\n");
2287                 }
2288                 break;
2289             case EXCP_DATA_ABORT:
2290                 /* This must be an NS access to S memory */
2291                 env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
2292                 qemu_log_mask(CPU_LOG_INT,
2293                               "...really SecureFault with SFSR.AUVIOL\n");
2294                 break;
2295             }
2296             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
2297             break;
2298         case 0x8: /* External Abort */
2299             switch (cs->exception_index) {
2300             case EXCP_PREFETCH_ABORT:
2301                 env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_IBUSERR_MASK;
2302                 qemu_log_mask(CPU_LOG_INT, "...with CFSR.IBUSERR\n");
2303                 break;
2304             case EXCP_DATA_ABORT:
2305                 env->v7m.cfsr[M_REG_NS] |=
2306                     (R_V7M_CFSR_PRECISERR_MASK | R_V7M_CFSR_BFARVALID_MASK);
2307                 env->v7m.bfar = env->exception.vaddress;
2308                 qemu_log_mask(CPU_LOG_INT,
2309                               "...with CFSR.PRECISERR and BFAR 0x%x\n",
2310                               env->v7m.bfar);
2311                 break;
2312             }
2313             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
2314             break;
2315         case 0x1: /* Alignment fault reported by generic code */
2316             qemu_log_mask(CPU_LOG_INT,
2317                           "...really UsageFault with UFSR.UNALIGNED\n");
2318             env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
2319             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
2320                                     env->v7m.secure);
2321             break;
2322         default:
2323             /*
2324              * All other FSR values are either MPU faults or "can't happen
2325              * for M profile" cases.
2326              */
2327             switch (cs->exception_index) {
2328             case EXCP_PREFETCH_ABORT:
2329                 env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK;
2330                 qemu_log_mask(CPU_LOG_INT, "...with CFSR.IACCVIOL\n");
2331                 break;
2332             case EXCP_DATA_ABORT:
2333                 env->v7m.cfsr[env->v7m.secure] |=
2334                     (R_V7M_CFSR_DACCVIOL_MASK | R_V7M_CFSR_MMARVALID_MASK);
2335                 env->v7m.mmfar[env->v7m.secure] = env->exception.vaddress;
2336                 qemu_log_mask(CPU_LOG_INT,
2337                               "...with CFSR.DACCVIOL and MMFAR 0x%x\n",
2338                               env->v7m.mmfar[env->v7m.secure]);
2339                 break;
2340             }
2341             armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM,
2342                                     env->v7m.secure);
2343             break;
2344         }
2345         break;
2346     case EXCP_SEMIHOST:
2347         qemu_log_mask(CPU_LOG_INT,
2348                       "...handling as semihosting call 0x%x\n",
2349                       env->regs[0]);
2350 #ifdef CONFIG_TCG
2351         do_common_semihosting(cs);
2352 #else
2353         g_assert_not_reached();
2354 #endif
2355         env->regs[15] += env->thumb ? 2 : 4;
2356         return;
2357     case EXCP_BKPT:
2358         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG, false);
2359         break;
2360     case EXCP_IRQ:
2361         break;
2362     case EXCP_EXCEPTION_EXIT:
2363         if (env->regs[15] < EXC_RETURN_MIN_MAGIC) {
2364             /* Must be v8M security extension function return */
2365             assert(env->regs[15] >= FNC_RETURN_MIN_MAGIC);
2366             assert(arm_feature(env, ARM_FEATURE_M_SECURITY));
2367             if (do_v7m_function_return(cpu)) {
2368                 return;
2369             }
2370         } else {
2371             do_v7m_exception_exit(cpu);
2372             return;
2373         }
2374         break;
2375     case EXCP_LAZYFP:
2376         /*
2377          * We already pended the specific exception in the NVIC in the
2378          * v7m_preserve_fp_state() helper function.
2379          */
2380         break;
2381     default:
2382         cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
2383         return; /* Never happens.  Keep compiler happy.  */
2384     }
2385 
2386     if (arm_feature(env, ARM_FEATURE_V8)) {
2387         lr = R_V7M_EXCRET_RES1_MASK |
2388             R_V7M_EXCRET_DCRS_MASK;
2389         /*
2390          * The S bit indicates whether we should return to Secure
2391          * or NonSecure (ie our current state).
2392          * The ES bit indicates whether we're taking this exception
2393          * to Secure or NonSecure (ie our target state). We set it
2394          * later, in v7m_exception_taken().
2395          * The SPSEL bit is also set in v7m_exception_taken() for v8M.
2396          * This corresponds to the ARM ARM pseudocode for v8M setting
2397          * some LR bits in PushStack() and some in ExceptionTaken();
2398          * the distinction matters for the tailchain cases where we
2399          * can take an exception without pushing the stack.
2400          */
2401         if (env->v7m.secure) {
2402             lr |= R_V7M_EXCRET_S_MASK;
2403         }
2404     } else {
2405         lr = R_V7M_EXCRET_RES1_MASK |
2406             R_V7M_EXCRET_S_MASK |
2407             R_V7M_EXCRET_DCRS_MASK |
2408             R_V7M_EXCRET_ES_MASK;
2409         if (env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSEL_MASK) {
2410             lr |= R_V7M_EXCRET_SPSEL_MASK;
2411         }
2412     }
2413     if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
2414         lr |= R_V7M_EXCRET_FTYPE_MASK;
2415     }
2416     if (!arm_v7m_is_handler_mode(env)) {
2417         lr |= R_V7M_EXCRET_MODE_MASK;
2418     }
2419 
2420     ignore_stackfaults = v7m_push_stack(cpu);
2421     v7m_exception_taken(cpu, lr, false, ignore_stackfaults);
2422 }
2423 
HELPER(v7m_mrs)2424 uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
2425 {
2426     unsigned el = arm_current_el(env);
2427 
2428     /* First handle registers which unprivileged can read */
2429     switch (reg) {
2430     case 0 ... 7: /* xPSR sub-fields */
2431         return v7m_mrs_xpsr(env, reg, el);
2432     case 20: /* CONTROL */
2433         return arm_v7m_mrs_control(env, env->v7m.secure);
2434     case 0x94: /* CONTROL_NS */
2435         /*
2436          * We have to handle this here because unprivileged Secure code
2437          * can read the NS CONTROL register.
2438          */
2439         if (!env->v7m.secure) {
2440             return 0;
2441         }
2442         return env->v7m.control[M_REG_NS] |
2443             (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
2444     }
2445 
2446     if (el == 0) {
2447         return 0; /* unprivileged reads others as zero */
2448     }
2449 
2450     if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
2451         switch (reg) {
2452         case 0x88: /* MSP_NS */
2453             if (!env->v7m.secure) {
2454                 return 0;
2455             }
2456             return env->v7m.other_ss_msp;
2457         case 0x89: /* PSP_NS */
2458             if (!env->v7m.secure) {
2459                 return 0;
2460             }
2461             return env->v7m.other_ss_psp;
2462         case 0x8a: /* MSPLIM_NS */
2463             if (!env->v7m.secure) {
2464                 return 0;
2465             }
2466             return env->v7m.msplim[M_REG_NS];
2467         case 0x8b: /* PSPLIM_NS */
2468             if (!env->v7m.secure) {
2469                 return 0;
2470             }
2471             return env->v7m.psplim[M_REG_NS];
2472         case 0x90: /* PRIMASK_NS */
2473             if (!env->v7m.secure) {
2474                 return 0;
2475             }
2476             return env->v7m.primask[M_REG_NS];
2477         case 0x91: /* BASEPRI_NS */
2478             if (!arm_feature(env, ARM_FEATURE_M_MAIN)) {
2479                 goto bad_reg;
2480             }
2481             if (!env->v7m.secure) {
2482                 return 0;
2483             }
2484             return env->v7m.basepri[M_REG_NS];
2485         case 0x93: /* FAULTMASK_NS */
2486             if (!arm_feature(env, ARM_FEATURE_M_MAIN)) {
2487                 goto bad_reg;
2488             }
2489             if (!env->v7m.secure) {
2490                 return 0;
2491             }
2492             return env->v7m.faultmask[M_REG_NS];
2493         case 0x98: /* SP_NS */
2494         {
2495             /*
2496              * This gives the non-secure SP selected based on whether we're
2497              * currently in handler mode or not, using the NS CONTROL.SPSEL.
2498              */
2499             bool spsel = env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSEL_MASK;
2500 
2501             if (!env->v7m.secure) {
2502                 return 0;
2503             }
2504             if (!arm_v7m_is_handler_mode(env) && spsel) {
2505                 return env->v7m.other_ss_psp;
2506             } else {
2507                 return env->v7m.other_ss_msp;
2508             }
2509         }
2510         default:
2511             break;
2512         }
2513     }
2514 
2515     switch (reg) {
2516     case 8: /* MSP */
2517         return v7m_using_psp(env) ? env->v7m.other_sp : env->regs[13];
2518     case 9: /* PSP */
2519         return v7m_using_psp(env) ? env->regs[13] : env->v7m.other_sp;
2520     case 10: /* MSPLIM */
2521         if (!arm_feature(env, ARM_FEATURE_V8)) {
2522             goto bad_reg;
2523         }
2524         return env->v7m.msplim[env->v7m.secure];
2525     case 11: /* PSPLIM */
2526         if (!arm_feature(env, ARM_FEATURE_V8)) {
2527             goto bad_reg;
2528         }
2529         return env->v7m.psplim[env->v7m.secure];
2530     case 16: /* PRIMASK */
2531         return env->v7m.primask[env->v7m.secure];
2532     case 17: /* BASEPRI */
2533     case 18: /* BASEPRI_MAX */
2534         if (!arm_feature(env, ARM_FEATURE_M_MAIN)) {
2535             goto bad_reg;
2536         }
2537         return env->v7m.basepri[env->v7m.secure];
2538     case 19: /* FAULTMASK */
2539         if (!arm_feature(env, ARM_FEATURE_M_MAIN)) {
2540             goto bad_reg;
2541         }
2542         return env->v7m.faultmask[env->v7m.secure];
2543     default:
2544     bad_reg:
2545         qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special"
2546                                        " register %d\n", reg);
2547         return 0;
2548     }
2549 }
2550 
HELPER(v7m_msr)2551 void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
2552 {
2553     /*
2554      * We're passed bits [11..0] of the instruction; extract
2555      * SYSm and the mask bits.
2556      * Invalid combinations of SYSm and mask are UNPREDICTABLE;
2557      * we choose to treat them as if the mask bits were valid.
2558      * NB that the pseudocode 'mask' variable is bits [11..10],
2559      * whereas ours is [11..8].
2560      */
2561     uint32_t mask = extract32(maskreg, 8, 4);
2562     uint32_t reg = extract32(maskreg, 0, 8);
2563     int cur_el = arm_current_el(env);
2564 
2565     if (cur_el == 0 && reg > 7 && reg != 20) {
2566         /*
2567          * only xPSR sub-fields and CONTROL.SFPA may be written by
2568          * unprivileged code
2569          */
2570         return;
2571     }
2572 
2573     if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
2574         switch (reg) {
2575         case 0x88: /* MSP_NS */
2576             if (!env->v7m.secure) {
2577                 return;
2578             }
2579             env->v7m.other_ss_msp = val & ~3;
2580             return;
2581         case 0x89: /* PSP_NS */
2582             if (!env->v7m.secure) {
2583                 return;
2584             }
2585             env->v7m.other_ss_psp = val & ~3;
2586             return;
2587         case 0x8a: /* MSPLIM_NS */
2588             if (!env->v7m.secure) {
2589                 return;
2590             }
2591             env->v7m.msplim[M_REG_NS] = val & ~7;
2592             return;
2593         case 0x8b: /* PSPLIM_NS */
2594             if (!env->v7m.secure) {
2595                 return;
2596             }
2597             env->v7m.psplim[M_REG_NS] = val & ~7;
2598             return;
2599         case 0x90: /* PRIMASK_NS */
2600             if (!env->v7m.secure) {
2601                 return;
2602             }
2603             env->v7m.primask[M_REG_NS] = val & 1;
2604             return;
2605         case 0x91: /* BASEPRI_NS */
2606             if (!arm_feature(env, ARM_FEATURE_M_MAIN)) {
2607                 goto bad_reg;
2608             }
2609             if (!env->v7m.secure) {
2610                 return;
2611             }
2612             env->v7m.basepri[M_REG_NS] = val & 0xff;
2613             return;
2614         case 0x93: /* FAULTMASK_NS */
2615             if (!arm_feature(env, ARM_FEATURE_M_MAIN)) {
2616                 goto bad_reg;
2617             }
2618             if (!env->v7m.secure) {
2619                 return;
2620             }
2621             env->v7m.faultmask[M_REG_NS] = val & 1;
2622             return;
2623         case 0x94: /* CONTROL_NS */
2624             if (!env->v7m.secure) {
2625                 return;
2626             }
2627             write_v7m_control_spsel_for_secstate(env,
2628                                                  val & R_V7M_CONTROL_SPSEL_MASK,
2629                                                  M_REG_NS);
2630             if (arm_feature(env, ARM_FEATURE_M_MAIN)) {
2631                 env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
2632                 env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
2633             }
2634             /*
2635              * SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
2636              * RES0 if the FPU is not present, and is stored in the S bank
2637              */
2638             if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env)) &&
2639                 extract32(env->v7m.nsacr, 10, 1)) {
2640                 env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
2641                 env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
2642             }
2643             return;
2644         case 0x98: /* SP_NS */
2645         {
2646             /*
2647              * This gives the non-secure SP selected based on whether we're
2648              * currently in handler mode or not, using the NS CONTROL.SPSEL.
2649              */
2650             bool spsel = env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSEL_MASK;
2651             bool is_psp = !arm_v7m_is_handler_mode(env) && spsel;
2652             uint32_t limit;
2653 
2654             if (!env->v7m.secure) {
2655                 return;
2656             }
2657 
2658             limit = is_psp ? env->v7m.psplim[false] : env->v7m.msplim[false];
2659 
2660             val &= ~0x3;
2661 
2662             if (val < limit) {
2663                 raise_exception_ra(env, EXCP_STKOF, 0, 1, GETPC());
2664             }
2665 
2666             if (is_psp) {
2667                 env->v7m.other_ss_psp = val;
2668             } else {
2669                 env->v7m.other_ss_msp = val;
2670             }
2671             return;
2672         }
2673         default:
2674             break;
2675         }
2676     }
2677 
2678     switch (reg) {
2679     case 0 ... 7: /* xPSR sub-fields */
2680         v7m_msr_xpsr(env, mask, reg, val);
2681         break;
2682     case 8: /* MSP */
2683         if (v7m_using_psp(env)) {
2684             env->v7m.other_sp = val & ~3;
2685         } else {
2686             env->regs[13] = val & ~3;
2687         }
2688         break;
2689     case 9: /* PSP */
2690         if (v7m_using_psp(env)) {
2691             env->regs[13] = val & ~3;
2692         } else {
2693             env->v7m.other_sp = val & ~3;
2694         }
2695         break;
2696     case 10: /* MSPLIM */
2697         if (!arm_feature(env, ARM_FEATURE_V8)) {
2698             goto bad_reg;
2699         }
2700         env->v7m.msplim[env->v7m.secure] = val & ~7;
2701         break;
2702     case 11: /* PSPLIM */
2703         if (!arm_feature(env, ARM_FEATURE_V8)) {
2704             goto bad_reg;
2705         }
2706         env->v7m.psplim[env->v7m.secure] = val & ~7;
2707         break;
2708     case 16: /* PRIMASK */
2709         env->v7m.primask[env->v7m.secure] = val & 1;
2710         break;
2711     case 17: /* BASEPRI */
2712         if (!arm_feature(env, ARM_FEATURE_M_MAIN)) {
2713             goto bad_reg;
2714         }
2715         env->v7m.basepri[env->v7m.secure] = val & 0xff;
2716         break;
2717     case 18: /* BASEPRI_MAX */
2718         if (!arm_feature(env, ARM_FEATURE_M_MAIN)) {
2719             goto bad_reg;
2720         }
2721         val &= 0xff;
2722         if (val != 0 && (val < env->v7m.basepri[env->v7m.secure]
2723                          || env->v7m.basepri[env->v7m.secure] == 0)) {
2724             env->v7m.basepri[env->v7m.secure] = val;
2725         }
2726         break;
2727     case 19: /* FAULTMASK */
2728         if (!arm_feature(env, ARM_FEATURE_M_MAIN)) {
2729             goto bad_reg;
2730         }
2731         env->v7m.faultmask[env->v7m.secure] = val & 1;
2732         break;
2733     case 20: /* CONTROL */
2734         /*
2735          * Writing to the SPSEL bit only has an effect if we are in
2736          * thread mode; other bits can be updated by any privileged code.
2737          * write_v7m_control_spsel() deals with updating the SPSEL bit in
2738          * env->v7m.control, so we only need update the others.
2739          * For v7M, we must just ignore explicit writes to SPSEL in handler
2740          * mode; for v8M the write is permitted but will have no effect.
2741          * All these bits are writes-ignored from non-privileged code,
2742          * except for SFPA.
2743          */
2744         if (cur_el > 0 && (arm_feature(env, ARM_FEATURE_V8) ||
2745                            !arm_v7m_is_handler_mode(env))) {
2746             write_v7m_control_spsel(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
2747         }
2748         if (cur_el > 0 && arm_feature(env, ARM_FEATURE_M_MAIN)) {
2749             env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
2750             env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
2751         }
2752         if (cpu_isar_feature(aa32_vfp_simd, env_archcpu(env))) {
2753             /*
2754              * SFPA is RAZ/WI from NS or if no FPU.
2755              * FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
2756              * Both are stored in the S bank.
2757              */
2758             if (env->v7m.secure) {
2759                 env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
2760                 env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_SFPA_MASK;
2761             }
2762             if (cur_el > 0 &&
2763                 (env->v7m.secure || !arm_feature(env, ARM_FEATURE_M_SECURITY) ||
2764                  extract32(env->v7m.nsacr, 10, 1))) {
2765                 env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
2766                 env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
2767             }
2768         }
2769         break;
2770     default:
2771     bad_reg:
2772         qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special"
2773                                        " register %d\n", reg);
2774         return;
2775     }
2776 }
2777 
HELPER(v7m_tt)2778 uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
2779 {
2780     /* Implement the TT instruction. op is bits [7:6] of the insn. */
2781     bool forceunpriv = op & 1;
2782     bool alt = op & 2;
2783     V8M_SAttributes sattrs = {};
2784     uint32_t tt_resp;
2785     bool r, rw, nsr, nsrw, mrvalid;
2786     ARMMMUIdx mmu_idx;
2787     uint32_t mregion;
2788     bool targetpriv;
2789     bool targetsec = env->v7m.secure;
2790 
2791     /*
2792      * Work out what the security state and privilege level we're
2793      * interested in is...
2794      */
2795     if (alt) {
2796         targetsec = !targetsec;
2797     }
2798 
2799     if (forceunpriv) {
2800         targetpriv = false;
2801     } else {
2802         targetpriv = arm_v7m_is_handler_mode(env) ||
2803             !(env->v7m.control[targetsec] & R_V7M_CONTROL_NPRIV_MASK);
2804     }
2805 
2806     /* ...and then figure out which MMU index this is */
2807     mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, targetsec, targetpriv);
2808 
2809     /*
2810      * We know that the MPU and SAU don't care about the access type
2811      * for our purposes beyond that we don't want to claim to be
2812      * an insn fetch, so we arbitrarily call this a read.
2813      */
2814 
2815     /*
2816      * MPU region info only available for privileged or if
2817      * inspecting the other MPU state.
2818      */
2819     if (arm_current_el(env) != 0 || alt) {
2820         GetPhysAddrResult res = {};
2821         ARMMMUFaultInfo fi = {};
2822 
2823         /* We can ignore the return value as prot is always set */
2824         pmsav8_mpu_lookup(env, addr, MMU_DATA_LOAD, mmu_idx, targetsec,
2825                           &res, &fi, &mregion);
2826         if (mregion == -1) {
2827             mrvalid = false;
2828             mregion = 0;
2829         } else {
2830             mrvalid = true;
2831         }
2832         r = res.f.prot & PAGE_READ;
2833         rw = res.f.prot & PAGE_WRITE;
2834     } else {
2835         r = false;
2836         rw = false;
2837         mrvalid = false;
2838         mregion = 0;
2839     }
2840 
2841     if (env->v7m.secure) {
2842         v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
2843                             targetsec, &sattrs);
2844         nsr = sattrs.ns && r;
2845         nsrw = sattrs.ns && rw;
2846     } else {
2847         sattrs.ns = true;
2848         nsr = false;
2849         nsrw = false;
2850     }
2851 
2852     tt_resp = (sattrs.iregion << 24) |
2853         (sattrs.irvalid << 23) |
2854         ((!sattrs.ns) << 22) |
2855         (nsrw << 21) |
2856         (nsr << 20) |
2857         (rw << 19) |
2858         (r << 18) |
2859         (sattrs.srvalid << 17) |
2860         (mrvalid << 16) |
2861         (sattrs.sregion << 8) |
2862         mregion;
2863 
2864     return tt_resp;
2865 }
2866 
2867 #endif /* !CONFIG_USER_ONLY */
2868 
arm_v7m_get_sp_ptr(CPUARMState * env,bool secure,bool threadmode,bool spsel)2869 uint32_t *arm_v7m_get_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
2870                              bool spsel)
2871 {
2872     /*
2873      * Return a pointer to the location where we currently store the
2874      * stack pointer for the requested security state and thread mode.
2875      * This pointer will become invalid if the CPU state is updated
2876      * such that the stack pointers are switched around (eg changing
2877      * the SPSEL control bit).
2878      * Compare the v8M ARM ARM pseudocode LookUpSP_with_security_mode().
2879      * Unlike that pseudocode, we require the caller to pass us in the
2880      * SPSEL control bit value; this is because we also use this
2881      * function in handling of pushing of the callee-saves registers
2882      * part of the v8M stack frame (pseudocode PushCalleeStack()),
2883      * and in the tailchain codepath the SPSEL bit comes from the exception
2884      * return magic LR value from the previous exception. The pseudocode
2885      * opencodes the stack-selection in PushCalleeStack(), but we prefer
2886      * to make this utility function generic enough to do the job.
2887      */
2888     bool want_psp = threadmode && spsel;
2889 
2890     if (secure == env->v7m.secure) {
2891         if (want_psp == v7m_using_psp(env)) {
2892             return &env->regs[13];
2893         } else {
2894             return &env->v7m.other_sp;
2895         }
2896     } else {
2897         if (want_psp) {
2898             return &env->v7m.other_ss_psp;
2899         } else {
2900             return &env->v7m.other_ss_msp;
2901         }
2902     }
2903 }
2904