xref: /openbmc/qemu/hw/intc/armv7m_nvic.c (revision 2c9728c0)
1 /*
2  * ARM Nested Vectored Interrupt Controller
3  *
4  * Copyright (c) 2006-2007 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * This code is licensed under the GPL.
8  *
9  * The ARMv7M System controller is fairly tightly tied in with the
10  * NVIC.  Much of that is also implemented here.
11  */
12 
13 #include "qemu/osdep.h"
14 #include "qapi/error.h"
15 #include "cpu.h"
16 #include "hw/sysbus.h"
17 #include "migration/vmstate.h"
18 #include "qemu/timer.h"
19 #include "hw/intc/armv7m_nvic.h"
20 #include "hw/irq.h"
21 #include "hw/qdev-properties.h"
22 #include "target/arm/cpu.h"
23 #include "exec/exec-all.h"
24 #include "exec/memop.h"
25 #include "qemu/log.h"
26 #include "qemu/module.h"
27 #include "trace.h"
28 
29 /* IRQ number counting:
30  *
31  * the num-irq property counts the number of external IRQ lines
32  *
33  * NVICState::num_irq counts the total number of exceptions
34  * (external IRQs, the 15 internal exceptions including reset,
35  * and one for the unused exception number 0).
36  *
37  * NVIC_MAX_IRQ is the highest permitted number of external IRQ lines.
38  *
39  * NVIC_MAX_VECTORS is the highest permitted number of exceptions.
40  *
41  * Iterating through all exceptions should typically be done with
42  * for (i = 1; i < s->num_irq; i++) to avoid the unused slot 0.
43  *
44  * The external qemu_irq lines are the NVIC's external IRQ lines,
45  * so line 0 is exception 16.
46  *
47  * In the terminology of the architecture manual, "interrupts" are
48  * a subcategory of exception referring to the external interrupts
49  * (which are exception numbers NVIC_FIRST_IRQ and upward).
50  * For historical reasons QEMU tends to use "interrupt" and
51  * "exception" more or less interchangeably.
52  */
53 #define NVIC_FIRST_IRQ NVIC_INTERNAL_VECTORS
54 #define NVIC_MAX_IRQ (NVIC_MAX_VECTORS - NVIC_FIRST_IRQ)
55 
56 /* Effective running priority of the CPU when no exception is active
57  * (higher than the highest possible priority value)
58  */
59 #define NVIC_NOEXC_PRIO 0x100
60 /* Maximum priority of non-secure exceptions when AIRCR.PRIS is set */
61 #define NVIC_NS_PRIO_LIMIT 0x80
62 
63 static const uint8_t nvic_id[] = {
64     0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1
65 };
66 
67 static int nvic_pending_prio(NVICState *s)
68 {
69     /* return the group priority of the current pending interrupt,
70      * or NVIC_NOEXC_PRIO if no interrupt is pending
71      */
72     return s->vectpending_prio;
73 }
74 
75 /* Return the value of the ISCR RETTOBASE bit:
76  * 1 if there is exactly one active exception
77  * 0 if there is more than one active exception
78  * UNKNOWN if there are no active exceptions (we choose 1,
79  * which matches the choice Cortex-M3 is documented as making).
80  *
81  * NB: some versions of the documentation talk about this
82  * counting "active exceptions other than the one shown by IPSR";
83  * this is only different in the obscure corner case where guest
84  * code has manually deactivated an exception and is about
85  * to fail an exception-return integrity check. The definition
86  * above is the one from the v8M ARM ARM and is also in line
87  * with the behaviour documented for the Cortex-M3.
88  */
89 static bool nvic_rettobase(NVICState *s)
90 {
91     int irq, nhand = 0;
92     bool check_sec = arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY);
93 
94     for (irq = ARMV7M_EXCP_RESET; irq < s->num_irq; irq++) {
95         if (s->vectors[irq].active ||
96             (check_sec && irq < NVIC_INTERNAL_VECTORS &&
97              s->sec_vectors[irq].active)) {
98             nhand++;
99             if (nhand == 2) {
100                 return 0;
101             }
102         }
103     }
104 
105     return 1;
106 }
107 
108 /* Return the value of the ISCR ISRPENDING bit:
109  * 1 if an external interrupt is pending
110  * 0 if no external interrupt is pending
111  */
112 static bool nvic_isrpending(NVICState *s)
113 {
114     int irq;
115 
116     /* We can shortcut if the highest priority pending interrupt
117      * happens to be external or if there is nothing pending.
118      */
119     if (s->vectpending > NVIC_FIRST_IRQ) {
120         return true;
121     }
122     if (s->vectpending == 0) {
123         return false;
124     }
125 
126     for (irq = NVIC_FIRST_IRQ; irq < s->num_irq; irq++) {
127         if (s->vectors[irq].pending) {
128             return true;
129         }
130     }
131     return false;
132 }
133 
134 static bool exc_is_banked(int exc)
135 {
136     /* Return true if this is one of the limited set of exceptions which
137      * are banked (and thus have state in sec_vectors[])
138      */
139     return exc == ARMV7M_EXCP_HARD ||
140         exc == ARMV7M_EXCP_MEM ||
141         exc == ARMV7M_EXCP_USAGE ||
142         exc == ARMV7M_EXCP_SVC ||
143         exc == ARMV7M_EXCP_PENDSV ||
144         exc == ARMV7M_EXCP_SYSTICK;
145 }
146 
147 /* Return a mask word which clears the subpriority bits from
148  * a priority value for an M-profile exception, leaving only
149  * the group priority.
150  */
151 static inline uint32_t nvic_gprio_mask(NVICState *s, bool secure)
152 {
153     return ~0U << (s->prigroup[secure] + 1);
154 }
155 
156 static bool exc_targets_secure(NVICState *s, int exc)
157 {
158     /* Return true if this non-banked exception targets Secure state. */
159     if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
160         return false;
161     }
162 
163     if (exc >= NVIC_FIRST_IRQ) {
164         return !s->itns[exc];
165     }
166 
167     /* Function shouldn't be called for banked exceptions. */
168     assert(!exc_is_banked(exc));
169 
170     switch (exc) {
171     case ARMV7M_EXCP_NMI:
172     case ARMV7M_EXCP_BUS:
173         return !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK);
174     case ARMV7M_EXCP_SECURE:
175         return true;
176     case ARMV7M_EXCP_DEBUG:
177         /* TODO: controlled by DEMCR.SDME, which we don't yet implement */
178         return false;
179     default:
180         /* reset, and reserved (unused) low exception numbers.
181          * We'll get called by code that loops through all the exception
182          * numbers, but it doesn't matter what we return here as these
183          * non-existent exceptions will never be pended or active.
184          */
185         return true;
186     }
187 }
188 
189 static int exc_group_prio(NVICState *s, int rawprio, bool targets_secure)
190 {
191     /* Return the group priority for this exception, given its raw
192      * (group-and-subgroup) priority value and whether it is targeting
193      * secure state or not.
194      */
195     if (rawprio < 0) {
196         return rawprio;
197     }
198     rawprio &= nvic_gprio_mask(s, targets_secure);
199     /* AIRCR.PRIS causes us to squash all NS priorities into the
200      * lower half of the total range
201      */
202     if (!targets_secure &&
203         (s->cpu->env.v7m.aircr & R_V7M_AIRCR_PRIS_MASK)) {
204         rawprio = (rawprio >> 1) + NVIC_NS_PRIO_LIMIT;
205     }
206     return rawprio;
207 }
208 
209 /* Recompute vectpending and exception_prio for a CPU which implements
210  * the Security extension
211  */
212 static void nvic_recompute_state_secure(NVICState *s)
213 {
214     int i, bank;
215     int pend_prio = NVIC_NOEXC_PRIO;
216     int active_prio = NVIC_NOEXC_PRIO;
217     int pend_irq = 0;
218     bool pending_is_s_banked = false;
219     int pend_subprio = 0;
220 
221     /* R_CQRV: precedence is by:
222      *  - lowest group priority; if both the same then
223      *  - lowest subpriority; if both the same then
224      *  - lowest exception number; if both the same (ie banked) then
225      *  - secure exception takes precedence
226      * Compare pseudocode RawExecutionPriority.
227      * Annoyingly, now we have two prigroup values (for S and NS)
228      * we can't do the loop comparison on raw priority values.
229      */
230     for (i = 1; i < s->num_irq; i++) {
231         for (bank = M_REG_S; bank >= M_REG_NS; bank--) {
232             VecInfo *vec;
233             int prio, subprio;
234             bool targets_secure;
235 
236             if (bank == M_REG_S) {
237                 if (!exc_is_banked(i)) {
238                     continue;
239                 }
240                 vec = &s->sec_vectors[i];
241                 targets_secure = true;
242             } else {
243                 vec = &s->vectors[i];
244                 targets_secure = !exc_is_banked(i) && exc_targets_secure(s, i);
245             }
246 
247             prio = exc_group_prio(s, vec->prio, targets_secure);
248             subprio = vec->prio & ~nvic_gprio_mask(s, targets_secure);
249             if (vec->enabled && vec->pending &&
250                 ((prio < pend_prio) ||
251                  (prio == pend_prio && prio >= 0 && subprio < pend_subprio))) {
252                 pend_prio = prio;
253                 pend_subprio = subprio;
254                 pend_irq = i;
255                 pending_is_s_banked = (bank == M_REG_S);
256             }
257             if (vec->active && prio < active_prio) {
258                 active_prio = prio;
259             }
260         }
261     }
262 
263     s->vectpending_is_s_banked = pending_is_s_banked;
264     s->vectpending = pend_irq;
265     s->vectpending_prio = pend_prio;
266     s->exception_prio = active_prio;
267 
268     trace_nvic_recompute_state_secure(s->vectpending,
269                                       s->vectpending_is_s_banked,
270                                       s->vectpending_prio,
271                                       s->exception_prio);
272 }
273 
274 /* Recompute vectpending and exception_prio */
275 static void nvic_recompute_state(NVICState *s)
276 {
277     int i;
278     int pend_prio = NVIC_NOEXC_PRIO;
279     int active_prio = NVIC_NOEXC_PRIO;
280     int pend_irq = 0;
281 
282     /* In theory we could write one function that handled both
283      * the "security extension present" and "not present"; however
284      * the security related changes significantly complicate the
285      * recomputation just by themselves and mixing both cases together
286      * would be even worse, so we retain a separate non-secure-only
287      * version for CPUs which don't implement the security extension.
288      */
289     if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
290         nvic_recompute_state_secure(s);
291         return;
292     }
293 
294     for (i = 1; i < s->num_irq; i++) {
295         VecInfo *vec = &s->vectors[i];
296 
297         if (vec->enabled && vec->pending && vec->prio < pend_prio) {
298             pend_prio = vec->prio;
299             pend_irq = i;
300         }
301         if (vec->active && vec->prio < active_prio) {
302             active_prio = vec->prio;
303         }
304     }
305 
306     if (active_prio > 0) {
307         active_prio &= nvic_gprio_mask(s, false);
308     }
309 
310     if (pend_prio > 0) {
311         pend_prio &= nvic_gprio_mask(s, false);
312     }
313 
314     s->vectpending = pend_irq;
315     s->vectpending_prio = pend_prio;
316     s->exception_prio = active_prio;
317 
318     trace_nvic_recompute_state(s->vectpending,
319                                s->vectpending_prio,
320                                s->exception_prio);
321 }
322 
323 /* Return the current execution priority of the CPU
324  * (equivalent to the pseudocode ExecutionPriority function).
325  * This is a value between -2 (NMI priority) and NVIC_NOEXC_PRIO.
326  */
327 static inline int nvic_exec_prio(NVICState *s)
328 {
329     CPUARMState *env = &s->cpu->env;
330     int running = NVIC_NOEXC_PRIO;
331 
332     if (env->v7m.basepri[M_REG_NS] > 0) {
333         running = exc_group_prio(s, env->v7m.basepri[M_REG_NS], M_REG_NS);
334     }
335 
336     if (env->v7m.basepri[M_REG_S] > 0) {
337         int basepri = exc_group_prio(s, env->v7m.basepri[M_REG_S], M_REG_S);
338         if (running > basepri) {
339             running = basepri;
340         }
341     }
342 
343     if (env->v7m.primask[M_REG_NS]) {
344         if (env->v7m.aircr & R_V7M_AIRCR_PRIS_MASK) {
345             if (running > NVIC_NS_PRIO_LIMIT) {
346                 running = NVIC_NS_PRIO_LIMIT;
347             }
348         } else {
349             running = 0;
350         }
351     }
352 
353     if (env->v7m.primask[M_REG_S]) {
354         running = 0;
355     }
356 
357     if (env->v7m.faultmask[M_REG_NS]) {
358         if (env->v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
359             running = -1;
360         } else {
361             if (env->v7m.aircr & R_V7M_AIRCR_PRIS_MASK) {
362                 if (running > NVIC_NS_PRIO_LIMIT) {
363                     running = NVIC_NS_PRIO_LIMIT;
364                 }
365             } else {
366                 running = 0;
367             }
368         }
369     }
370 
371     if (env->v7m.faultmask[M_REG_S]) {
372         running = (env->v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) ? -3 : -1;
373     }
374 
375     /* consider priority of active handler */
376     return MIN(running, s->exception_prio);
377 }
378 
379 bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
380 {
381     /* Return true if the requested execution priority is negative
382      * for the specified security state, ie that security state
383      * has an active NMI or HardFault or has set its FAULTMASK.
384      * Note that this is not the same as whether the execution
385      * priority is actually negative (for instance AIRCR.PRIS may
386      * mean we don't allow FAULTMASK_NS to actually make the execution
387      * priority negative). Compare pseudocode IsReqExcPriNeg().
388      */
389     NVICState *s = opaque;
390 
391     if (s->cpu->env.v7m.faultmask[secure]) {
392         return true;
393     }
394 
395     if (secure ? s->sec_vectors[ARMV7M_EXCP_HARD].active :
396         s->vectors[ARMV7M_EXCP_HARD].active) {
397         return true;
398     }
399 
400     if (s->vectors[ARMV7M_EXCP_NMI].active &&
401         exc_targets_secure(s, ARMV7M_EXCP_NMI) == secure) {
402         return true;
403     }
404 
405     return false;
406 }
407 
408 bool armv7m_nvic_can_take_pending_exception(void *opaque)
409 {
410     NVICState *s = opaque;
411 
412     return nvic_exec_prio(s) > nvic_pending_prio(s);
413 }
414 
415 int armv7m_nvic_raw_execution_priority(void *opaque)
416 {
417     NVICState *s = opaque;
418 
419     return s->exception_prio;
420 }
421 
422 /* caller must call nvic_irq_update() after this.
423  * secure indicates the bank to use for banked exceptions (we assert if
424  * we are passed secure=true for a non-banked exception).
425  */
426 static void set_prio(NVICState *s, unsigned irq, bool secure, uint8_t prio)
427 {
428     assert(irq > ARMV7M_EXCP_NMI); /* only use for configurable prios */
429     assert(irq < s->num_irq);
430 
431     prio &= MAKE_64BIT_MASK(8 - s->num_prio_bits, s->num_prio_bits);
432 
433     if (secure) {
434         assert(exc_is_banked(irq));
435         s->sec_vectors[irq].prio = prio;
436     } else {
437         s->vectors[irq].prio = prio;
438     }
439 
440     trace_nvic_set_prio(irq, secure, prio);
441 }
442 
443 /* Return the current raw priority register value.
444  * secure indicates the bank to use for banked exceptions (we assert if
445  * we are passed secure=true for a non-banked exception).
446  */
447 static int get_prio(NVICState *s, unsigned irq, bool secure)
448 {
449     assert(irq > ARMV7M_EXCP_NMI); /* only use for configurable prios */
450     assert(irq < s->num_irq);
451 
452     if (secure) {
453         assert(exc_is_banked(irq));
454         return s->sec_vectors[irq].prio;
455     } else {
456         return s->vectors[irq].prio;
457     }
458 }
459 
460 /* Recompute state and assert irq line accordingly.
461  * Must be called after changes to:
462  *  vec->active, vec->enabled, vec->pending or vec->prio for any vector
463  *  prigroup
464  */
465 static void nvic_irq_update(NVICState *s)
466 {
467     int lvl;
468     int pend_prio;
469 
470     nvic_recompute_state(s);
471     pend_prio = nvic_pending_prio(s);
472 
473     /* Raise NVIC output if this IRQ would be taken, except that we
474      * ignore the effects of the BASEPRI, FAULTMASK and PRIMASK (which
475      * will be checked for in arm_v7m_cpu_exec_interrupt()); changes
476      * to those CPU registers don't cause us to recalculate the NVIC
477      * pending info.
478      */
479     lvl = (pend_prio < s->exception_prio);
480     trace_nvic_irq_update(s->vectpending, pend_prio, s->exception_prio, lvl);
481     qemu_set_irq(s->excpout, lvl);
482 }
483 
484 /**
485  * armv7m_nvic_clear_pending: mark the specified exception as not pending
486  * @opaque: the NVIC
487  * @irq: the exception number to mark as not pending
488  * @secure: false for non-banked exceptions or for the nonsecure
489  * version of a banked exception, true for the secure version of a banked
490  * exception.
491  *
492  * Marks the specified exception as not pending. Note that we will assert()
493  * if @secure is true and @irq does not specify one of the fixed set
494  * of architecturally banked exceptions.
495  */
496 static void armv7m_nvic_clear_pending(void *opaque, int irq, bool secure)
497 {
498     NVICState *s = (NVICState *)opaque;
499     VecInfo *vec;
500 
501     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
502 
503     if (secure) {
504         assert(exc_is_banked(irq));
505         vec = &s->sec_vectors[irq];
506     } else {
507         vec = &s->vectors[irq];
508     }
509     trace_nvic_clear_pending(irq, secure, vec->enabled, vec->prio);
510     if (vec->pending) {
511         vec->pending = 0;
512         nvic_irq_update(s);
513     }
514 }
515 
516 static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
517                                        bool derived)
518 {
519     /* Pend an exception, including possibly escalating it to HardFault.
520      *
521      * This function handles both "normal" pending of interrupts and
522      * exceptions, and also derived exceptions (ones which occur as
523      * a result of trying to take some other exception).
524      *
525      * If derived == true, the caller guarantees that we are part way through
526      * trying to take an exception (but have not yet called
527      * armv7m_nvic_acknowledge_irq() to make it active), and so:
528      *  - s->vectpending is the "original exception" we were trying to take
529      *  - irq is the "derived exception"
530      *  - nvic_exec_prio(s) gives the priority before exception entry
531      * Here we handle the prioritization logic which the pseudocode puts
532      * in the DerivedLateArrival() function.
533      */
534 
535     NVICState *s = (NVICState *)opaque;
536     bool banked = exc_is_banked(irq);
537     VecInfo *vec;
538     bool targets_secure;
539 
540     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
541     assert(!secure || banked);
542 
543     vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
544 
545     targets_secure = banked ? secure : exc_targets_secure(s, irq);
546 
547     trace_nvic_set_pending(irq, secure, targets_secure,
548                            derived, vec->enabled, vec->prio);
549 
550     if (derived) {
551         /* Derived exceptions are always synchronous. */
552         assert(irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV);
553 
554         if (irq == ARMV7M_EXCP_DEBUG &&
555             exc_group_prio(s, vec->prio, secure) >= nvic_exec_prio(s)) {
556             /* DebugMonitorFault, but its priority is lower than the
557              * preempted exception priority: just ignore it.
558              */
559             return;
560         }
561 
562         if (irq == ARMV7M_EXCP_HARD && vec->prio >= s->vectpending_prio) {
563             /* If this is a terminal exception (one which means we cannot
564              * take the original exception, like a failure to read its
565              * vector table entry), then we must take the derived exception.
566              * If the derived exception can't take priority over the
567              * original exception, then we go into Lockup.
568              *
569              * For QEMU, we rely on the fact that a derived exception is
570              * terminal if and only if it's reported to us as HardFault,
571              * which saves having to have an extra argument is_terminal
572              * that we'd only use in one place.
573              */
574             cpu_abort(&s->cpu->parent_obj,
575                       "Lockup: can't take terminal derived exception "
576                       "(original exception priority %d)\n",
577                       s->vectpending_prio);
578         }
579         /* We now continue with the same code as for a normal pending
580          * exception, which will cause us to pend the derived exception.
581          * We'll then take either the original or the derived exception
582          * based on which is higher priority by the usual mechanism
583          * for selecting the highest priority pending interrupt.
584          */
585     }
586 
587     if (irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV) {
588         /* If a synchronous exception is pending then it may be
589          * escalated to HardFault if:
590          *  * it is equal or lower priority to current execution
591          *  * it is disabled
592          * (ie we need to take it immediately but we can't do so).
593          * Asynchronous exceptions (and interrupts) simply remain pending.
594          *
595          * For QEMU, we don't have any imprecise (asynchronous) faults,
596          * so we can assume that PREFETCH_ABORT and DATA_ABORT are always
597          * synchronous.
598          * Debug exceptions are awkward because only Debug exceptions
599          * resulting from the BKPT instruction should be escalated,
600          * but we don't currently implement any Debug exceptions other
601          * than those that result from BKPT, so we treat all debug exceptions
602          * as needing escalation.
603          *
604          * This all means we can identify whether to escalate based only on
605          * the exception number and don't (yet) need the caller to explicitly
606          * tell us whether this exception is synchronous or not.
607          */
608         int running = nvic_exec_prio(s);
609         bool escalate = false;
610 
611         if (exc_group_prio(s, vec->prio, secure) >= running) {
612             trace_nvic_escalate_prio(irq, vec->prio, running);
613             escalate = true;
614         } else if (!vec->enabled) {
615             trace_nvic_escalate_disabled(irq);
616             escalate = true;
617         }
618 
619         if (escalate) {
620 
621             /* We need to escalate this exception to a synchronous HardFault.
622              * If BFHFNMINS is set then we escalate to the banked HF for
623              * the target security state of the original exception; otherwise
624              * we take a Secure HardFault.
625              */
626             irq = ARMV7M_EXCP_HARD;
627             if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
628                 (targets_secure ||
629                  !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) {
630                 vec = &s->sec_vectors[irq];
631             } else {
632                 vec = &s->vectors[irq];
633             }
634             if (running <= vec->prio) {
635                 /* We want to escalate to HardFault but we can't take the
636                  * synchronous HardFault at this point either. This is a
637                  * Lockup condition due to a guest bug. We don't model
638                  * Lockup, so report via cpu_abort() instead.
639                  */
640                 cpu_abort(&s->cpu->parent_obj,
641                           "Lockup: can't escalate %d to HardFault "
642                           "(current priority %d)\n", irq, running);
643             }
644 
645             /* HF may be banked but there is only one shared HFSR */
646             s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
647         }
648     }
649 
650     if (!vec->pending) {
651         vec->pending = 1;
652         nvic_irq_update(s);
653     }
654 }
655 
656 void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
657 {
658     do_armv7m_nvic_set_pending(opaque, irq, secure, false);
659 }
660 
661 void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
662 {
663     do_armv7m_nvic_set_pending(opaque, irq, secure, true);
664 }
665 
666 void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
667 {
668     /*
669      * Pend an exception during lazy FP stacking. This differs
670      * from the usual exception pending because the logic for
671      * whether we should escalate depends on the saved context
672      * in the FPCCR register, not on the current state of the CPU/NVIC.
673      */
674     NVICState *s = (NVICState *)opaque;
675     bool banked = exc_is_banked(irq);
676     VecInfo *vec;
677     bool targets_secure;
678     bool escalate = false;
679     /*
680      * We will only look at bits in fpccr if this is a banked exception
681      * (in which case 'secure' tells us whether it is the S or NS version).
682      * All the bits for the non-banked exceptions are in fpccr_s.
683      */
684     uint32_t fpccr_s = s->cpu->env.v7m.fpccr[M_REG_S];
685     uint32_t fpccr = s->cpu->env.v7m.fpccr[secure];
686 
687     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
688     assert(!secure || banked);
689 
690     vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
691 
692     targets_secure = banked ? secure : exc_targets_secure(s, irq);
693 
694     switch (irq) {
695     case ARMV7M_EXCP_DEBUG:
696         if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
697             /* Ignore DebugMonitor exception */
698             return;
699         }
700         break;
701     case ARMV7M_EXCP_MEM:
702         escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
703         break;
704     case ARMV7M_EXCP_USAGE:
705         escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
706         break;
707     case ARMV7M_EXCP_BUS:
708         escalate = !(fpccr_s & R_V7M_FPCCR_BFRDY_MASK);
709         break;
710     case ARMV7M_EXCP_SECURE:
711         escalate = !(fpccr_s & R_V7M_FPCCR_SFRDY_MASK);
712         break;
713     default:
714         g_assert_not_reached();
715     }
716 
717     if (escalate) {
718         /*
719          * Escalate to HardFault: faults that initially targeted Secure
720          * continue to do so, even if HF normally targets NonSecure.
721          */
722         irq = ARMV7M_EXCP_HARD;
723         if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
724             (targets_secure ||
725              !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) {
726             vec = &s->sec_vectors[irq];
727         } else {
728             vec = &s->vectors[irq];
729         }
730     }
731 
732     if (!vec->enabled ||
733         nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
734         if (!(fpccr_s & R_V7M_FPCCR_HFRDY_MASK)) {
735             /*
736              * We want to escalate to HardFault but the context the
737              * FP state belongs to prevents the exception pre-empting.
738              */
739             cpu_abort(&s->cpu->parent_obj,
740                       "Lockup: can't escalate to HardFault during "
741                       "lazy FP register stacking\n");
742         }
743     }
744 
745     if (escalate) {
746         s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
747     }
748     if (!vec->pending) {
749         vec->pending = 1;
750         /*
751          * We do not call nvic_irq_update(), because we know our caller
752          * is going to handle causing us to take the exception by
753          * raising EXCP_LAZYFP, so raising the IRQ line would be
754          * pointless extra work. We just need to recompute the
755          * priorities so that armv7m_nvic_can_take_pending_exception()
756          * returns the right answer.
757          */
758         nvic_recompute_state(s);
759     }
760 }
761 
762 /* Make pending IRQ active.  */
763 void armv7m_nvic_acknowledge_irq(void *opaque)
764 {
765     NVICState *s = (NVICState *)opaque;
766     CPUARMState *env = &s->cpu->env;
767     const int pending = s->vectpending;
768     const int running = nvic_exec_prio(s);
769     VecInfo *vec;
770 
771     assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
772 
773     if (s->vectpending_is_s_banked) {
774         vec = &s->sec_vectors[pending];
775     } else {
776         vec = &s->vectors[pending];
777     }
778 
779     assert(vec->enabled);
780     assert(vec->pending);
781 
782     assert(s->vectpending_prio < running);
783 
784     trace_nvic_acknowledge_irq(pending, s->vectpending_prio);
785 
786     vec->active = 1;
787     vec->pending = 0;
788 
789     write_v7m_exception(env, s->vectpending);
790 
791     nvic_irq_update(s);
792 }
793 
794 void armv7m_nvic_get_pending_irq_info(void *opaque,
795                                       int *pirq, bool *ptargets_secure)
796 {
797     NVICState *s = (NVICState *)opaque;
798     const int pending = s->vectpending;
799     bool targets_secure;
800 
801     assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
802 
803     if (s->vectpending_is_s_banked) {
804         targets_secure = true;
805     } else {
806         targets_secure = !exc_is_banked(pending) &&
807             exc_targets_secure(s, pending);
808     }
809 
810     trace_nvic_get_pending_irq_info(pending, targets_secure);
811 
812     *ptargets_secure = targets_secure;
813     *pirq = pending;
814 }
815 
816 int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
817 {
818     NVICState *s = (NVICState *)opaque;
819     VecInfo *vec = NULL;
820     int ret;
821 
822     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
823 
824     /*
825      * For negative priorities, v8M will forcibly deactivate the appropriate
826      * NMI or HardFault regardless of what interrupt we're being asked to
827      * deactivate (compare the DeActivate() pseudocode). This is a guard
828      * against software returning from NMI or HardFault with a corrupted
829      * IPSR and leaving the CPU in a negative-priority state.
830      * v7M does not do this, but simply deactivates the requested interrupt.
831      */
832     if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
833         switch (armv7m_nvic_raw_execution_priority(s)) {
834         case -1:
835             if (s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
836                 vec = &s->vectors[ARMV7M_EXCP_HARD];
837             } else {
838                 vec = &s->sec_vectors[ARMV7M_EXCP_HARD];
839             }
840             break;
841         case -2:
842             vec = &s->vectors[ARMV7M_EXCP_NMI];
843             break;
844         case -3:
845             vec = &s->sec_vectors[ARMV7M_EXCP_HARD];
846             break;
847         default:
848             break;
849         }
850     }
851 
852     if (!vec) {
853         if (secure && exc_is_banked(irq)) {
854             vec = &s->sec_vectors[irq];
855         } else {
856             vec = &s->vectors[irq];
857         }
858     }
859 
860     trace_nvic_complete_irq(irq, secure);
861 
862     if (!vec->active) {
863         /* Tell the caller this was an illegal exception return */
864         return -1;
865     }
866 
867     /*
868      * If this is a configurable exception and it is currently
869      * targeting the opposite security state from the one we're trying
870      * to complete it for, this counts as an illegal exception return.
871      * We still need to deactivate whatever vector the logic above has
872      * selected, though, as it might not be the same as the one for the
873      * requested exception number.
874      */
875     if (!exc_is_banked(irq) && exc_targets_secure(s, irq) != secure) {
876         ret = -1;
877     } else {
878         ret = nvic_rettobase(s);
879     }
880 
881     vec->active = 0;
882     if (vec->level) {
883         /* Re-pend the exception if it's still held high; only
884          * happens for extenal IRQs
885          */
886         assert(irq >= NVIC_FIRST_IRQ);
887         vec->pending = 1;
888     }
889 
890     nvic_irq_update(s);
891 
892     return ret;
893 }
894 
895 bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
896 {
897     /*
898      * Return whether an exception is "ready", i.e. it is enabled and is
899      * configured at a priority which would allow it to interrupt the
900      * current execution priority.
901      *
902      * irq and secure have the same semantics as for armv7m_nvic_set_pending():
903      * for non-banked exceptions secure is always false; for banked exceptions
904      * it indicates which of the exceptions is required.
905      */
906     NVICState *s = (NVICState *)opaque;
907     bool banked = exc_is_banked(irq);
908     VecInfo *vec;
909     int running = nvic_exec_prio(s);
910 
911     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
912     assert(!secure || banked);
913 
914     /*
915      * HardFault is an odd special case: we always check against -1,
916      * even if we're secure and HardFault has priority -3; we never
917      * need to check for enabled state.
918      */
919     if (irq == ARMV7M_EXCP_HARD) {
920         return running > -1;
921     }
922 
923     vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
924 
925     return vec->enabled &&
926         exc_group_prio(s, vec->prio, secure) < running;
927 }
928 
929 /* callback when external interrupt line is changed */
930 static void set_irq_level(void *opaque, int n, int level)
931 {
932     NVICState *s = opaque;
933     VecInfo *vec;
934 
935     n += NVIC_FIRST_IRQ;
936 
937     assert(n >= NVIC_FIRST_IRQ && n < s->num_irq);
938 
939     trace_nvic_set_irq_level(n, level);
940 
941     /* The pending status of an external interrupt is
942      * latched on rising edge and exception handler return.
943      *
944      * Pulsing the IRQ will always run the handler
945      * once, and the handler will re-run until the
946      * level is low when the handler completes.
947      */
948     vec = &s->vectors[n];
949     if (level != vec->level) {
950         vec->level = level;
951         if (level) {
952             armv7m_nvic_set_pending(s, n, false);
953         }
954     }
955 }
956 
957 /* callback when external NMI line is changed */
958 static void nvic_nmi_trigger(void *opaque, int n, int level)
959 {
960     NVICState *s = opaque;
961 
962     trace_nvic_set_nmi_level(level);
963 
964     /*
965      * The architecture doesn't specify whether NMI should share
966      * the normal-interrupt behaviour of being resampled on
967      * exception handler return. We choose not to, so just
968      * set NMI pending here and don't track the current level.
969      */
970     if (level) {
971         armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
972     }
973 }
974 
975 static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
976 {
977     ARMCPU *cpu = s->cpu;
978     uint32_t val;
979 
980     switch (offset) {
981     case 4: /* Interrupt Control Type.  */
982         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
983             goto bad_offset;
984         }
985         return ((s->num_irq - NVIC_FIRST_IRQ) / 32) - 1;
986     case 0xc: /* CPPWR */
987         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
988             goto bad_offset;
989         }
990         /* We make the IMPDEF choice that nothing can ever go into a
991          * non-retentive power state, which allows us to RAZ/WI this.
992          */
993         return 0;
994     case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
995     {
996         int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ;
997         int i;
998 
999         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1000             goto bad_offset;
1001         }
1002         if (!attrs.secure) {
1003             return 0;
1004         }
1005         val = 0;
1006         for (i = 0; i < 32 && startvec + i < s->num_irq; i++) {
1007             if (s->itns[startvec + i]) {
1008                 val |= (1 << i);
1009             }
1010         }
1011         return val;
1012     }
1013     case 0xd00: /* CPUID Base.  */
1014         return cpu->midr;
1015     case 0xd04: /* Interrupt Control State (ICSR) */
1016         /* VECTACTIVE */
1017         val = cpu->env.v7m.exception;
1018         /* VECTPENDING */
1019         val |= (s->vectpending & 0xff) << 12;
1020         /* ISRPENDING - set if any external IRQ is pending */
1021         if (nvic_isrpending(s)) {
1022             val |= (1 << 22);
1023         }
1024         /* RETTOBASE - set if only one handler is active */
1025         if (nvic_rettobase(s)) {
1026             val |= (1 << 11);
1027         }
1028         if (attrs.secure) {
1029             /* PENDSTSET */
1030             if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].pending) {
1031                 val |= (1 << 26);
1032             }
1033             /* PENDSVSET */
1034             if (s->sec_vectors[ARMV7M_EXCP_PENDSV].pending) {
1035                 val |= (1 << 28);
1036             }
1037         } else {
1038             /* PENDSTSET */
1039             if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) {
1040                 val |= (1 << 26);
1041             }
1042             /* PENDSVSET */
1043             if (s->vectors[ARMV7M_EXCP_PENDSV].pending) {
1044                 val |= (1 << 28);
1045             }
1046         }
1047         /* NMIPENDSET */
1048         if ((attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))
1049             && s->vectors[ARMV7M_EXCP_NMI].pending) {
1050             val |= (1 << 31);
1051         }
1052         /* ISRPREEMPT: RES0 when halting debug not implemented */
1053         /* STTNS: RES0 for the Main Extension */
1054         return val;
1055     case 0xd08: /* Vector Table Offset.  */
1056         return cpu->env.v7m.vecbase[attrs.secure];
1057     case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */
1058         val = 0xfa050000 | (s->prigroup[attrs.secure] << 8);
1059         if (attrs.secure) {
1060             /* s->aircr stores PRIS, BFHFNMINS, SYSRESETREQS */
1061             val |= cpu->env.v7m.aircr;
1062         } else {
1063             if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1064                 /* BFHFNMINS is R/O from NS; other bits are RAZ/WI. If
1065                  * security isn't supported then BFHFNMINS is RAO (and
1066                  * the bit in env.v7m.aircr is always set).
1067                  */
1068                 val |= cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK;
1069             }
1070         }
1071         return val;
1072     case 0xd10: /* System Control.  */
1073         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
1074             goto bad_offset;
1075         }
1076         return cpu->env.v7m.scr[attrs.secure];
1077     case 0xd14: /* Configuration Control.  */
1078         /* The BFHFNMIGN bit is the only non-banked bit; we
1079          * keep it in the non-secure copy of the register.
1080          */
1081         val = cpu->env.v7m.ccr[attrs.secure];
1082         val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
1083         return val;
1084     case 0xd24: /* System Handler Control and State (SHCSR) */
1085         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
1086             goto bad_offset;
1087         }
1088         val = 0;
1089         if (attrs.secure) {
1090             if (s->sec_vectors[ARMV7M_EXCP_MEM].active) {
1091                 val |= (1 << 0);
1092             }
1093             if (s->sec_vectors[ARMV7M_EXCP_HARD].active) {
1094                 val |= (1 << 2);
1095             }
1096             if (s->sec_vectors[ARMV7M_EXCP_USAGE].active) {
1097                 val |= (1 << 3);
1098             }
1099             if (s->sec_vectors[ARMV7M_EXCP_SVC].active) {
1100                 val |= (1 << 7);
1101             }
1102             if (s->sec_vectors[ARMV7M_EXCP_PENDSV].active) {
1103                 val |= (1 << 10);
1104             }
1105             if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].active) {
1106                 val |= (1 << 11);
1107             }
1108             if (s->sec_vectors[ARMV7M_EXCP_USAGE].pending) {
1109                 val |= (1 << 12);
1110             }
1111             if (s->sec_vectors[ARMV7M_EXCP_MEM].pending) {
1112                 val |= (1 << 13);
1113             }
1114             if (s->sec_vectors[ARMV7M_EXCP_SVC].pending) {
1115                 val |= (1 << 15);
1116             }
1117             if (s->sec_vectors[ARMV7M_EXCP_MEM].enabled) {
1118                 val |= (1 << 16);
1119             }
1120             if (s->sec_vectors[ARMV7M_EXCP_USAGE].enabled) {
1121                 val |= (1 << 18);
1122             }
1123             if (s->sec_vectors[ARMV7M_EXCP_HARD].pending) {
1124                 val |= (1 << 21);
1125             }
1126             /* SecureFault is not banked but is always RAZ/WI to NS */
1127             if (s->vectors[ARMV7M_EXCP_SECURE].active) {
1128                 val |= (1 << 4);
1129             }
1130             if (s->vectors[ARMV7M_EXCP_SECURE].enabled) {
1131                 val |= (1 << 19);
1132             }
1133             if (s->vectors[ARMV7M_EXCP_SECURE].pending) {
1134                 val |= (1 << 20);
1135             }
1136         } else {
1137             if (s->vectors[ARMV7M_EXCP_MEM].active) {
1138                 val |= (1 << 0);
1139             }
1140             if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1141                 /* HARDFAULTACT, HARDFAULTPENDED not present in v7M */
1142                 if (s->vectors[ARMV7M_EXCP_HARD].active) {
1143                     val |= (1 << 2);
1144                 }
1145                 if (s->vectors[ARMV7M_EXCP_HARD].pending) {
1146                     val |= (1 << 21);
1147                 }
1148             }
1149             if (s->vectors[ARMV7M_EXCP_USAGE].active) {
1150                 val |= (1 << 3);
1151             }
1152             if (s->vectors[ARMV7M_EXCP_SVC].active) {
1153                 val |= (1 << 7);
1154             }
1155             if (s->vectors[ARMV7M_EXCP_PENDSV].active) {
1156                 val |= (1 << 10);
1157             }
1158             if (s->vectors[ARMV7M_EXCP_SYSTICK].active) {
1159                 val |= (1 << 11);
1160             }
1161             if (s->vectors[ARMV7M_EXCP_USAGE].pending) {
1162                 val |= (1 << 12);
1163             }
1164             if (s->vectors[ARMV7M_EXCP_MEM].pending) {
1165                 val |= (1 << 13);
1166             }
1167             if (s->vectors[ARMV7M_EXCP_SVC].pending) {
1168                 val |= (1 << 15);
1169             }
1170             if (s->vectors[ARMV7M_EXCP_MEM].enabled) {
1171                 val |= (1 << 16);
1172             }
1173             if (s->vectors[ARMV7M_EXCP_USAGE].enabled) {
1174                 val |= (1 << 18);
1175             }
1176         }
1177         if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
1178             if (s->vectors[ARMV7M_EXCP_BUS].active) {
1179                 val |= (1 << 1);
1180             }
1181             if (s->vectors[ARMV7M_EXCP_BUS].pending) {
1182                 val |= (1 << 14);
1183             }
1184             if (s->vectors[ARMV7M_EXCP_BUS].enabled) {
1185                 val |= (1 << 17);
1186             }
1187             if (arm_feature(&cpu->env, ARM_FEATURE_V8) &&
1188                 s->vectors[ARMV7M_EXCP_NMI].active) {
1189                 /* NMIACT is not present in v7M */
1190                 val |= (1 << 5);
1191             }
1192         }
1193 
1194         /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */
1195         if (s->vectors[ARMV7M_EXCP_DEBUG].active) {
1196             val |= (1 << 8);
1197         }
1198         return val;
1199     case 0xd2c: /* Hard Fault Status.  */
1200         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1201             goto bad_offset;
1202         }
1203         return cpu->env.v7m.hfsr;
1204     case 0xd30: /* Debug Fault Status.  */
1205         return cpu->env.v7m.dfsr;
1206     case 0xd34: /* MMFAR MemManage Fault Address */
1207         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1208             goto bad_offset;
1209         }
1210         return cpu->env.v7m.mmfar[attrs.secure];
1211     case 0xd38: /* Bus Fault Address.  */
1212         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1213             goto bad_offset;
1214         }
1215         if (!attrs.secure &&
1216             !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
1217             return 0;
1218         }
1219         return cpu->env.v7m.bfar;
1220     case 0xd3c: /* Aux Fault Status.  */
1221         /* TODO: Implement fault status registers.  */
1222         qemu_log_mask(LOG_UNIMP,
1223                       "Aux Fault status registers unimplemented\n");
1224         return 0;
1225     case 0xd40: /* PFR0.  */
1226         return cpu->id_pfr0;
1227     case 0xd44: /* PFR1.  */
1228         return cpu->id_pfr1;
1229     case 0xd48: /* DFR0.  */
1230         return cpu->isar.id_dfr0;
1231     case 0xd4c: /* AFR0.  */
1232         return cpu->id_afr0;
1233     case 0xd50: /* MMFR0.  */
1234         return cpu->isar.id_mmfr0;
1235     case 0xd54: /* MMFR1.  */
1236         return cpu->isar.id_mmfr1;
1237     case 0xd58: /* MMFR2.  */
1238         return cpu->isar.id_mmfr2;
1239     case 0xd5c: /* MMFR3.  */
1240         return cpu->isar.id_mmfr3;
1241     case 0xd60: /* ISAR0.  */
1242         return cpu->isar.id_isar0;
1243     case 0xd64: /* ISAR1.  */
1244         return cpu->isar.id_isar1;
1245     case 0xd68: /* ISAR2.  */
1246         return cpu->isar.id_isar2;
1247     case 0xd6c: /* ISAR3.  */
1248         return cpu->isar.id_isar3;
1249     case 0xd70: /* ISAR4.  */
1250         return cpu->isar.id_isar4;
1251     case 0xd74: /* ISAR5.  */
1252         return cpu->isar.id_isar5;
1253     case 0xd78: /* CLIDR */
1254         return cpu->clidr;
1255     case 0xd7c: /* CTR */
1256         return cpu->ctr;
1257     case 0xd80: /* CSSIDR */
1258     {
1259         int idx = cpu->env.v7m.csselr[attrs.secure] & R_V7M_CSSELR_INDEX_MASK;
1260         return cpu->ccsidr[idx];
1261     }
1262     case 0xd84: /* CSSELR */
1263         return cpu->env.v7m.csselr[attrs.secure];
1264     case 0xd88: /* CPACR */
1265         if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
1266             return 0;
1267         }
1268         return cpu->env.v7m.cpacr[attrs.secure];
1269     case 0xd8c: /* NSACR */
1270         if (!attrs.secure || !cpu_isar_feature(aa32_vfp_simd, cpu)) {
1271             return 0;
1272         }
1273         return cpu->env.v7m.nsacr;
1274     /* TODO: Implement debug registers.  */
1275     case 0xd90: /* MPU_TYPE */
1276         /* Unified MPU; if the MPU is not present this value is zero */
1277         return cpu->pmsav7_dregion << 8;
1278         break;
1279     case 0xd94: /* MPU_CTRL */
1280         return cpu->env.v7m.mpu_ctrl[attrs.secure];
1281     case 0xd98: /* MPU_RNR */
1282         return cpu->env.pmsav7.rnr[attrs.secure];
1283     case 0xd9c: /* MPU_RBAR */
1284     case 0xda4: /* MPU_RBAR_A1 */
1285     case 0xdac: /* MPU_RBAR_A2 */
1286     case 0xdb4: /* MPU_RBAR_A3 */
1287     {
1288         int region = cpu->env.pmsav7.rnr[attrs.secure];
1289 
1290         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1291             /* PMSAv8M handling of the aliases is different from v7M:
1292              * aliases A1, A2, A3 override the low two bits of the region
1293              * number in MPU_RNR, and there is no 'region' field in the
1294              * RBAR register.
1295              */
1296             int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
1297             if (aliasno) {
1298                 region = deposit32(region, 0, 2, aliasno);
1299             }
1300             if (region >= cpu->pmsav7_dregion) {
1301                 return 0;
1302             }
1303             return cpu->env.pmsav8.rbar[attrs.secure][region];
1304         }
1305 
1306         if (region >= cpu->pmsav7_dregion) {
1307             return 0;
1308         }
1309         return (cpu->env.pmsav7.drbar[region] & ~0x1f) | (region & 0xf);
1310     }
1311     case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
1312     case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
1313     case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
1314     case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
1315     {
1316         int region = cpu->env.pmsav7.rnr[attrs.secure];
1317 
1318         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1319             /* PMSAv8M handling of the aliases is different from v7M:
1320              * aliases A1, A2, A3 override the low two bits of the region
1321              * number in MPU_RNR.
1322              */
1323             int aliasno = (offset - 0xda0) / 8; /* 0..3 */
1324             if (aliasno) {
1325                 region = deposit32(region, 0, 2, aliasno);
1326             }
1327             if (region >= cpu->pmsav7_dregion) {
1328                 return 0;
1329             }
1330             return cpu->env.pmsav8.rlar[attrs.secure][region];
1331         }
1332 
1333         if (region >= cpu->pmsav7_dregion) {
1334             return 0;
1335         }
1336         return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) |
1337             (cpu->env.pmsav7.drsr[region] & 0xffff);
1338     }
1339     case 0xdc0: /* MPU_MAIR0 */
1340         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1341             goto bad_offset;
1342         }
1343         return cpu->env.pmsav8.mair0[attrs.secure];
1344     case 0xdc4: /* MPU_MAIR1 */
1345         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1346             goto bad_offset;
1347         }
1348         return cpu->env.pmsav8.mair1[attrs.secure];
1349     case 0xdd0: /* SAU_CTRL */
1350         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1351             goto bad_offset;
1352         }
1353         if (!attrs.secure) {
1354             return 0;
1355         }
1356         return cpu->env.sau.ctrl;
1357     case 0xdd4: /* SAU_TYPE */
1358         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1359             goto bad_offset;
1360         }
1361         if (!attrs.secure) {
1362             return 0;
1363         }
1364         return cpu->sau_sregion;
1365     case 0xdd8: /* SAU_RNR */
1366         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1367             goto bad_offset;
1368         }
1369         if (!attrs.secure) {
1370             return 0;
1371         }
1372         return cpu->env.sau.rnr;
1373     case 0xddc: /* SAU_RBAR */
1374     {
1375         int region = cpu->env.sau.rnr;
1376 
1377         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1378             goto bad_offset;
1379         }
1380         if (!attrs.secure) {
1381             return 0;
1382         }
1383         if (region >= cpu->sau_sregion) {
1384             return 0;
1385         }
1386         return cpu->env.sau.rbar[region];
1387     }
1388     case 0xde0: /* SAU_RLAR */
1389     {
1390         int region = cpu->env.sau.rnr;
1391 
1392         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1393             goto bad_offset;
1394         }
1395         if (!attrs.secure) {
1396             return 0;
1397         }
1398         if (region >= cpu->sau_sregion) {
1399             return 0;
1400         }
1401         return cpu->env.sau.rlar[region];
1402     }
1403     case 0xde4: /* SFSR */
1404         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1405             goto bad_offset;
1406         }
1407         if (!attrs.secure) {
1408             return 0;
1409         }
1410         return cpu->env.v7m.sfsr;
1411     case 0xde8: /* SFAR */
1412         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1413             goto bad_offset;
1414         }
1415         if (!attrs.secure) {
1416             return 0;
1417         }
1418         return cpu->env.v7m.sfar;
1419     case 0xf34: /* FPCCR */
1420         if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
1421             return 0;
1422         }
1423         if (attrs.secure) {
1424             return cpu->env.v7m.fpccr[M_REG_S];
1425         } else {
1426             /*
1427              * NS can read LSPEN, CLRONRET and MONRDY. It can read
1428              * BFRDY and HFRDY if AIRCR.BFHFNMINS != 0;
1429              * other non-banked bits RAZ.
1430              * TODO: MONRDY should RAZ/WI if DEMCR.SDME is set.
1431              */
1432             uint32_t value = cpu->env.v7m.fpccr[M_REG_S];
1433             uint32_t mask = R_V7M_FPCCR_LSPEN_MASK |
1434                 R_V7M_FPCCR_CLRONRET_MASK |
1435                 R_V7M_FPCCR_MONRDY_MASK;
1436 
1437             if (s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
1438                 mask |= R_V7M_FPCCR_BFRDY_MASK | R_V7M_FPCCR_HFRDY_MASK;
1439             }
1440 
1441             value &= mask;
1442 
1443             value |= cpu->env.v7m.fpccr[M_REG_NS];
1444             return value;
1445         }
1446     case 0xf38: /* FPCAR */
1447         if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
1448             return 0;
1449         }
1450         return cpu->env.v7m.fpcar[attrs.secure];
1451     case 0xf3c: /* FPDSCR */
1452         if (!cpu_isar_feature(aa32_vfp_simd, cpu)) {
1453             return 0;
1454         }
1455         return cpu->env.v7m.fpdscr[attrs.secure];
1456     case 0xf40: /* MVFR0 */
1457         return cpu->isar.mvfr0;
1458     case 0xf44: /* MVFR1 */
1459         return cpu->isar.mvfr1;
1460     case 0xf48: /* MVFR2 */
1461         return cpu->isar.mvfr2;
1462     default:
1463     bad_offset:
1464         qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
1465         return 0;
1466     }
1467 }
1468 
1469 static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
1470                         MemTxAttrs attrs)
1471 {
1472     ARMCPU *cpu = s->cpu;
1473 
1474     switch (offset) {
1475     case 0xc: /* CPPWR */
1476         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1477             goto bad_offset;
1478         }
1479         /* Make the IMPDEF choice to RAZ/WI this. */
1480         break;
1481     case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
1482     {
1483         int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ;
1484         int i;
1485 
1486         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1487             goto bad_offset;
1488         }
1489         if (!attrs.secure) {
1490             break;
1491         }
1492         for (i = 0; i < 32 && startvec + i < s->num_irq; i++) {
1493             s->itns[startvec + i] = (value >> i) & 1;
1494         }
1495         nvic_irq_update(s);
1496         break;
1497     }
1498     case 0xd04: /* Interrupt Control State (ICSR) */
1499         if (attrs.secure || cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
1500             if (value & (1 << 31)) {
1501                 armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
1502             } else if (value & (1 << 30) &&
1503                        arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1504                 /* PENDNMICLR didn't exist in v7M */
1505                 armv7m_nvic_clear_pending(s, ARMV7M_EXCP_NMI, false);
1506             }
1507         }
1508         if (value & (1 << 28)) {
1509             armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure);
1510         } else if (value & (1 << 27)) {
1511             armv7m_nvic_clear_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure);
1512         }
1513         if (value & (1 << 26)) {
1514             armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure);
1515         } else if (value & (1 << 25)) {
1516             armv7m_nvic_clear_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure);
1517         }
1518         break;
1519     case 0xd08: /* Vector Table Offset.  */
1520         cpu->env.v7m.vecbase[attrs.secure] = value & 0xffffff80;
1521         break;
1522     case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */
1523         if ((value >> R_V7M_AIRCR_VECTKEY_SHIFT) == 0x05fa) {
1524             if (value & R_V7M_AIRCR_SYSRESETREQ_MASK) {
1525                 if (attrs.secure ||
1526                     !(cpu->env.v7m.aircr & R_V7M_AIRCR_SYSRESETREQS_MASK)) {
1527                     qemu_irq_pulse(s->sysresetreq);
1528                 }
1529             }
1530             if (value & R_V7M_AIRCR_VECTCLRACTIVE_MASK) {
1531                 qemu_log_mask(LOG_GUEST_ERROR,
1532                               "Setting VECTCLRACTIVE when not in DEBUG mode "
1533                               "is UNPREDICTABLE\n");
1534             }
1535             if (value & R_V7M_AIRCR_VECTRESET_MASK) {
1536                 /* NB: this bit is RES0 in v8M */
1537                 qemu_log_mask(LOG_GUEST_ERROR,
1538                               "Setting VECTRESET when not in DEBUG mode "
1539                               "is UNPREDICTABLE\n");
1540             }
1541             if (arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1542                 s->prigroup[attrs.secure] =
1543                     extract32(value,
1544                               R_V7M_AIRCR_PRIGROUP_SHIFT,
1545                               R_V7M_AIRCR_PRIGROUP_LENGTH);
1546             }
1547             if (attrs.secure) {
1548                 /* These bits are only writable by secure */
1549                 cpu->env.v7m.aircr = value &
1550                     (R_V7M_AIRCR_SYSRESETREQS_MASK |
1551                      R_V7M_AIRCR_BFHFNMINS_MASK |
1552                      R_V7M_AIRCR_PRIS_MASK);
1553                 /* BFHFNMINS changes the priority of Secure HardFault, and
1554                  * allows a pending Non-secure HardFault to preempt (which
1555                  * we implement by marking it enabled).
1556                  */
1557                 if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
1558                     s->sec_vectors[ARMV7M_EXCP_HARD].prio = -3;
1559                     s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
1560                 } else {
1561                     s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
1562                     s->vectors[ARMV7M_EXCP_HARD].enabled = 0;
1563                 }
1564             }
1565             nvic_irq_update(s);
1566         }
1567         break;
1568     case 0xd10: /* System Control.  */
1569         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
1570             goto bad_offset;
1571         }
1572         /* We don't implement deep-sleep so these bits are RAZ/WI.
1573          * The other bits in the register are banked.
1574          * QEMU's implementation ignores SEVONPEND and SLEEPONEXIT, which
1575          * is architecturally permitted.
1576          */
1577         value &= ~(R_V7M_SCR_SLEEPDEEP_MASK | R_V7M_SCR_SLEEPDEEPS_MASK);
1578         cpu->env.v7m.scr[attrs.secure] = value;
1579         break;
1580     case 0xd14: /* Configuration Control.  */
1581         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1582             goto bad_offset;
1583         }
1584 
1585         /* Enforce RAZ/WI on reserved and must-RAZ/WI bits */
1586         value &= (R_V7M_CCR_STKALIGN_MASK |
1587                   R_V7M_CCR_BFHFNMIGN_MASK |
1588                   R_V7M_CCR_DIV_0_TRP_MASK |
1589                   R_V7M_CCR_UNALIGN_TRP_MASK |
1590                   R_V7M_CCR_USERSETMPEND_MASK |
1591                   R_V7M_CCR_NONBASETHRDENA_MASK);
1592 
1593         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1594             /* v8M makes NONBASETHRDENA and STKALIGN be RES1 */
1595             value |= R_V7M_CCR_NONBASETHRDENA_MASK
1596                 | R_V7M_CCR_STKALIGN_MASK;
1597         }
1598         if (attrs.secure) {
1599             /* the BFHFNMIGN bit is not banked; keep that in the NS copy */
1600             cpu->env.v7m.ccr[M_REG_NS] =
1601                 (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)
1602                 | (value & R_V7M_CCR_BFHFNMIGN_MASK);
1603             value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
1604         }
1605 
1606         cpu->env.v7m.ccr[attrs.secure] = value;
1607         break;
1608     case 0xd24: /* System Handler Control and State (SHCSR) */
1609         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
1610             goto bad_offset;
1611         }
1612         if (attrs.secure) {
1613             s->sec_vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;
1614             /* Secure HardFault active bit cannot be written */
1615             s->sec_vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0;
1616             s->sec_vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0;
1617             s->sec_vectors[ARMV7M_EXCP_PENDSV].active =
1618                 (value & (1 << 10)) != 0;
1619             s->sec_vectors[ARMV7M_EXCP_SYSTICK].active =
1620                 (value & (1 << 11)) != 0;
1621             s->sec_vectors[ARMV7M_EXCP_USAGE].pending =
1622                 (value & (1 << 12)) != 0;
1623             s->sec_vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0;
1624             s->sec_vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0;
1625             s->sec_vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
1626             s->sec_vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
1627             s->sec_vectors[ARMV7M_EXCP_USAGE].enabled =
1628                 (value & (1 << 18)) != 0;
1629             s->sec_vectors[ARMV7M_EXCP_HARD].pending = (value & (1 << 21)) != 0;
1630             /* SecureFault not banked, but RAZ/WI to NS */
1631             s->vectors[ARMV7M_EXCP_SECURE].active = (value & (1 << 4)) != 0;
1632             s->vectors[ARMV7M_EXCP_SECURE].enabled = (value & (1 << 19)) != 0;
1633             s->vectors[ARMV7M_EXCP_SECURE].pending = (value & (1 << 20)) != 0;
1634         } else {
1635             s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;
1636             if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1637                 /* HARDFAULTPENDED is not present in v7M */
1638                 s->vectors[ARMV7M_EXCP_HARD].pending = (value & (1 << 21)) != 0;
1639             }
1640             s->vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0;
1641             s->vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0;
1642             s->vectors[ARMV7M_EXCP_PENDSV].active = (value & (1 << 10)) != 0;
1643             s->vectors[ARMV7M_EXCP_SYSTICK].active = (value & (1 << 11)) != 0;
1644             s->vectors[ARMV7M_EXCP_USAGE].pending = (value & (1 << 12)) != 0;
1645             s->vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0;
1646             s->vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0;
1647             s->vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
1648             s->vectors[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;
1649         }
1650         if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
1651             s->vectors[ARMV7M_EXCP_BUS].active = (value & (1 << 1)) != 0;
1652             s->vectors[ARMV7M_EXCP_BUS].pending = (value & (1 << 14)) != 0;
1653             s->vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
1654         }
1655         /* NMIACT can only be written if the write is of a zero, with
1656          * BFHFNMINS 1, and by the CPU in secure state via the NS alias.
1657          */
1658         if (!attrs.secure && cpu->env.v7m.secure &&
1659             (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&
1660             (value & (1 << 5)) == 0) {
1661             s->vectors[ARMV7M_EXCP_NMI].active = 0;
1662         }
1663         /* HARDFAULTACT can only be written if the write is of a zero
1664          * to the non-secure HardFault state by the CPU in secure state.
1665          * The only case where we can be targeting the non-secure HF state
1666          * when in secure state is if this is a write via the NS alias
1667          * and BFHFNMINS is 1.
1668          */
1669         if (!attrs.secure && cpu->env.v7m.secure &&
1670             (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&
1671             (value & (1 << 2)) == 0) {
1672             s->vectors[ARMV7M_EXCP_HARD].active = 0;
1673         }
1674 
1675         /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */
1676         s->vectors[ARMV7M_EXCP_DEBUG].active = (value & (1 << 8)) != 0;
1677         nvic_irq_update(s);
1678         break;
1679     case 0xd2c: /* Hard Fault Status.  */
1680         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1681             goto bad_offset;
1682         }
1683         cpu->env.v7m.hfsr &= ~value; /* W1C */
1684         break;
1685     case 0xd30: /* Debug Fault Status.  */
1686         cpu->env.v7m.dfsr &= ~value; /* W1C */
1687         break;
1688     case 0xd34: /* Mem Manage Address.  */
1689         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1690             goto bad_offset;
1691         }
1692         cpu->env.v7m.mmfar[attrs.secure] = value;
1693         return;
1694     case 0xd38: /* Bus Fault Address.  */
1695         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1696             goto bad_offset;
1697         }
1698         if (!attrs.secure &&
1699             !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
1700             return;
1701         }
1702         cpu->env.v7m.bfar = value;
1703         return;
1704     case 0xd3c: /* Aux Fault Status.  */
1705         qemu_log_mask(LOG_UNIMP,
1706                       "NVIC: Aux fault status registers unimplemented\n");
1707         break;
1708     case 0xd84: /* CSSELR */
1709         if (!arm_v7m_csselr_razwi(cpu)) {
1710             cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK;
1711         }
1712         break;
1713     case 0xd88: /* CPACR */
1714         if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
1715             /* We implement only the Floating Point extension's CP10/CP11 */
1716             cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
1717         }
1718         break;
1719     case 0xd8c: /* NSACR */
1720         if (attrs.secure && cpu_isar_feature(aa32_vfp_simd, cpu)) {
1721             /* We implement only the Floating Point extension's CP10/CP11 */
1722             cpu->env.v7m.nsacr = value & (3 << 10);
1723         }
1724         break;
1725     case 0xd90: /* MPU_TYPE */
1726         return; /* RO */
1727     case 0xd94: /* MPU_CTRL */
1728         if ((value &
1729              (R_V7M_MPU_CTRL_HFNMIENA_MASK | R_V7M_MPU_CTRL_ENABLE_MASK))
1730             == R_V7M_MPU_CTRL_HFNMIENA_MASK) {
1731             qemu_log_mask(LOG_GUEST_ERROR, "MPU_CTRL: HFNMIENA and !ENABLE is "
1732                           "UNPREDICTABLE\n");
1733         }
1734         cpu->env.v7m.mpu_ctrl[attrs.secure]
1735             = value & (R_V7M_MPU_CTRL_ENABLE_MASK |
1736                        R_V7M_MPU_CTRL_HFNMIENA_MASK |
1737                        R_V7M_MPU_CTRL_PRIVDEFENA_MASK);
1738         tlb_flush(CPU(cpu));
1739         break;
1740     case 0xd98: /* MPU_RNR */
1741         if (value >= cpu->pmsav7_dregion) {
1742             qemu_log_mask(LOG_GUEST_ERROR, "MPU region out of range %"
1743                           PRIu32 "/%" PRIu32 "\n",
1744                           value, cpu->pmsav7_dregion);
1745         } else {
1746             cpu->env.pmsav7.rnr[attrs.secure] = value;
1747         }
1748         break;
1749     case 0xd9c: /* MPU_RBAR */
1750     case 0xda4: /* MPU_RBAR_A1 */
1751     case 0xdac: /* MPU_RBAR_A2 */
1752     case 0xdb4: /* MPU_RBAR_A3 */
1753     {
1754         int region;
1755 
1756         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1757             /* PMSAv8M handling of the aliases is different from v7M:
1758              * aliases A1, A2, A3 override the low two bits of the region
1759              * number in MPU_RNR, and there is no 'region' field in the
1760              * RBAR register.
1761              */
1762             int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
1763 
1764             region = cpu->env.pmsav7.rnr[attrs.secure];
1765             if (aliasno) {
1766                 region = deposit32(region, 0, 2, aliasno);
1767             }
1768             if (region >= cpu->pmsav7_dregion) {
1769                 return;
1770             }
1771             cpu->env.pmsav8.rbar[attrs.secure][region] = value;
1772             tlb_flush(CPU(cpu));
1773             return;
1774         }
1775 
1776         if (value & (1 << 4)) {
1777             /* VALID bit means use the region number specified in this
1778              * value and also update MPU_RNR.REGION with that value.
1779              */
1780             region = extract32(value, 0, 4);
1781             if (region >= cpu->pmsav7_dregion) {
1782                 qemu_log_mask(LOG_GUEST_ERROR,
1783                               "MPU region out of range %u/%" PRIu32 "\n",
1784                               region, cpu->pmsav7_dregion);
1785                 return;
1786             }
1787             cpu->env.pmsav7.rnr[attrs.secure] = region;
1788         } else {
1789             region = cpu->env.pmsav7.rnr[attrs.secure];
1790         }
1791 
1792         if (region >= cpu->pmsav7_dregion) {
1793             return;
1794         }
1795 
1796         cpu->env.pmsav7.drbar[region] = value & ~0x1f;
1797         tlb_flush(CPU(cpu));
1798         break;
1799     }
1800     case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
1801     case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
1802     case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
1803     case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
1804     {
1805         int region = cpu->env.pmsav7.rnr[attrs.secure];
1806 
1807         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1808             /* PMSAv8M handling of the aliases is different from v7M:
1809              * aliases A1, A2, A3 override the low two bits of the region
1810              * number in MPU_RNR.
1811              */
1812             int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
1813 
1814             region = cpu->env.pmsav7.rnr[attrs.secure];
1815             if (aliasno) {
1816                 region = deposit32(region, 0, 2, aliasno);
1817             }
1818             if (region >= cpu->pmsav7_dregion) {
1819                 return;
1820             }
1821             cpu->env.pmsav8.rlar[attrs.secure][region] = value;
1822             tlb_flush(CPU(cpu));
1823             return;
1824         }
1825 
1826         if (region >= cpu->pmsav7_dregion) {
1827             return;
1828         }
1829 
1830         cpu->env.pmsav7.drsr[region] = value & 0xff3f;
1831         cpu->env.pmsav7.dracr[region] = (value >> 16) & 0x173f;
1832         tlb_flush(CPU(cpu));
1833         break;
1834     }
1835     case 0xdc0: /* MPU_MAIR0 */
1836         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1837             goto bad_offset;
1838         }
1839         if (cpu->pmsav7_dregion) {
1840             /* Register is RES0 if no MPU regions are implemented */
1841             cpu->env.pmsav8.mair0[attrs.secure] = value;
1842         }
1843         /* We don't need to do anything else because memory attributes
1844          * only affect cacheability, and we don't implement caching.
1845          */
1846         break;
1847     case 0xdc4: /* MPU_MAIR1 */
1848         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1849             goto bad_offset;
1850         }
1851         if (cpu->pmsav7_dregion) {
1852             /* Register is RES0 if no MPU regions are implemented */
1853             cpu->env.pmsav8.mair1[attrs.secure] = value;
1854         }
1855         /* We don't need to do anything else because memory attributes
1856          * only affect cacheability, and we don't implement caching.
1857          */
1858         break;
1859     case 0xdd0: /* SAU_CTRL */
1860         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1861             goto bad_offset;
1862         }
1863         if (!attrs.secure) {
1864             return;
1865         }
1866         cpu->env.sau.ctrl = value & 3;
1867         break;
1868     case 0xdd4: /* SAU_TYPE */
1869         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1870             goto bad_offset;
1871         }
1872         break;
1873     case 0xdd8: /* SAU_RNR */
1874         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1875             goto bad_offset;
1876         }
1877         if (!attrs.secure) {
1878             return;
1879         }
1880         if (value >= cpu->sau_sregion) {
1881             qemu_log_mask(LOG_GUEST_ERROR, "SAU region out of range %"
1882                           PRIu32 "/%" PRIu32 "\n",
1883                           value, cpu->sau_sregion);
1884         } else {
1885             cpu->env.sau.rnr = value;
1886         }
1887         break;
1888     case 0xddc: /* SAU_RBAR */
1889     {
1890         int region = cpu->env.sau.rnr;
1891 
1892         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1893             goto bad_offset;
1894         }
1895         if (!attrs.secure) {
1896             return;
1897         }
1898         if (region >= cpu->sau_sregion) {
1899             return;
1900         }
1901         cpu->env.sau.rbar[region] = value & ~0x1f;
1902         tlb_flush(CPU(cpu));
1903         break;
1904     }
1905     case 0xde0: /* SAU_RLAR */
1906     {
1907         int region = cpu->env.sau.rnr;
1908 
1909         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1910             goto bad_offset;
1911         }
1912         if (!attrs.secure) {
1913             return;
1914         }
1915         if (region >= cpu->sau_sregion) {
1916             return;
1917         }
1918         cpu->env.sau.rlar[region] = value & ~0x1c;
1919         tlb_flush(CPU(cpu));
1920         break;
1921     }
1922     case 0xde4: /* SFSR */
1923         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1924             goto bad_offset;
1925         }
1926         if (!attrs.secure) {
1927             return;
1928         }
1929         cpu->env.v7m.sfsr &= ~value; /* W1C */
1930         break;
1931     case 0xde8: /* SFAR */
1932         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1933             goto bad_offset;
1934         }
1935         if (!attrs.secure) {
1936             return;
1937         }
1938         cpu->env.v7m.sfsr = value;
1939         break;
1940     case 0xf00: /* Software Triggered Interrupt Register */
1941     {
1942         int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ;
1943 
1944         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1945             goto bad_offset;
1946         }
1947 
1948         if (excnum < s->num_irq) {
1949             armv7m_nvic_set_pending(s, excnum, false);
1950         }
1951         break;
1952     }
1953     case 0xf34: /* FPCCR */
1954         if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
1955             /* Not all bits here are banked. */
1956             uint32_t fpccr_s;
1957 
1958             if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1959                 /* Don't allow setting of bits not present in v7M */
1960                 value &= (R_V7M_FPCCR_LSPACT_MASK |
1961                           R_V7M_FPCCR_USER_MASK |
1962                           R_V7M_FPCCR_THREAD_MASK |
1963                           R_V7M_FPCCR_HFRDY_MASK |
1964                           R_V7M_FPCCR_MMRDY_MASK |
1965                           R_V7M_FPCCR_BFRDY_MASK |
1966                           R_V7M_FPCCR_MONRDY_MASK |
1967                           R_V7M_FPCCR_LSPEN_MASK |
1968                           R_V7M_FPCCR_ASPEN_MASK);
1969             }
1970             value &= ~R_V7M_FPCCR_RES0_MASK;
1971 
1972             if (!attrs.secure) {
1973                 /* Some non-banked bits are configurably writable by NS */
1974                 fpccr_s = cpu->env.v7m.fpccr[M_REG_S];
1975                 if (!(fpccr_s & R_V7M_FPCCR_LSPENS_MASK)) {
1976                     uint32_t lspen = FIELD_EX32(value, V7M_FPCCR, LSPEN);
1977                     fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, LSPEN, lspen);
1978                 }
1979                 if (!(fpccr_s & R_V7M_FPCCR_CLRONRETS_MASK)) {
1980                     uint32_t cor = FIELD_EX32(value, V7M_FPCCR, CLRONRET);
1981                     fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, CLRONRET, cor);
1982                 }
1983                 if ((s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
1984                     uint32_t hfrdy = FIELD_EX32(value, V7M_FPCCR, HFRDY);
1985                     uint32_t bfrdy = FIELD_EX32(value, V7M_FPCCR, BFRDY);
1986                     fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
1987                     fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
1988                 }
1989                 /* TODO MONRDY should RAZ/WI if DEMCR.SDME is set */
1990                 {
1991                     uint32_t monrdy = FIELD_EX32(value, V7M_FPCCR, MONRDY);
1992                     fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, MONRDY, monrdy);
1993                 }
1994 
1995                 /*
1996                  * All other non-banked bits are RAZ/WI from NS; write
1997                  * just the banked bits to fpccr[M_REG_NS].
1998                  */
1999                 value &= R_V7M_FPCCR_BANKED_MASK;
2000                 cpu->env.v7m.fpccr[M_REG_NS] = value;
2001             } else {
2002                 fpccr_s = value;
2003             }
2004             cpu->env.v7m.fpccr[M_REG_S] = fpccr_s;
2005         }
2006         break;
2007     case 0xf38: /* FPCAR */
2008         if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
2009             value &= ~7;
2010             cpu->env.v7m.fpcar[attrs.secure] = value;
2011         }
2012         break;
2013     case 0xf3c: /* FPDSCR */
2014         if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
2015             value &= 0x07c00000;
2016             cpu->env.v7m.fpdscr[attrs.secure] = value;
2017         }
2018         break;
2019     case 0xf50: /* ICIALLU */
2020     case 0xf58: /* ICIMVAU */
2021     case 0xf5c: /* DCIMVAC */
2022     case 0xf60: /* DCISW */
2023     case 0xf64: /* DCCMVAU */
2024     case 0xf68: /* DCCMVAC */
2025     case 0xf6c: /* DCCSW */
2026     case 0xf70: /* DCCIMVAC */
2027     case 0xf74: /* DCCISW */
2028     case 0xf78: /* BPIALL */
2029         /* Cache and branch predictor maintenance: for QEMU these always NOP */
2030         break;
2031     default:
2032     bad_offset:
2033         qemu_log_mask(LOG_GUEST_ERROR,
2034                       "NVIC: Bad write offset 0x%x\n", offset);
2035     }
2036 }
2037 
2038 static bool nvic_user_access_ok(NVICState *s, hwaddr offset, MemTxAttrs attrs)
2039 {
2040     /* Return true if unprivileged access to this register is permitted. */
2041     switch (offset) {
2042     case 0xf00: /* STIR: accessible only if CCR.USERSETMPEND permits */
2043         /* For access via STIR_NS it is the NS CCR.USERSETMPEND that
2044          * controls access even though the CPU is in Secure state (I_QDKX).
2045          */
2046         return s->cpu->env.v7m.ccr[attrs.secure] & R_V7M_CCR_USERSETMPEND_MASK;
2047     default:
2048         /* All other user accesses cause a BusFault unconditionally */
2049         return false;
2050     }
2051 }
2052 
2053 static int shpr_bank(NVICState *s, int exc, MemTxAttrs attrs)
2054 {
2055     /* Behaviour for the SHPR register field for this exception:
2056      * return M_REG_NS to use the nonsecure vector (including for
2057      * non-banked exceptions), M_REG_S for the secure version of
2058      * a banked exception, and -1 if this field should RAZ/WI.
2059      */
2060     switch (exc) {
2061     case ARMV7M_EXCP_MEM:
2062     case ARMV7M_EXCP_USAGE:
2063     case ARMV7M_EXCP_SVC:
2064     case ARMV7M_EXCP_PENDSV:
2065     case ARMV7M_EXCP_SYSTICK:
2066         /* Banked exceptions */
2067         return attrs.secure;
2068     case ARMV7M_EXCP_BUS:
2069         /* Not banked, RAZ/WI from nonsecure if BFHFNMINS is zero */
2070         if (!attrs.secure &&
2071             !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
2072             return -1;
2073         }
2074         return M_REG_NS;
2075     case ARMV7M_EXCP_SECURE:
2076         /* Not banked, RAZ/WI from nonsecure */
2077         if (!attrs.secure) {
2078             return -1;
2079         }
2080         return M_REG_NS;
2081     case ARMV7M_EXCP_DEBUG:
2082         /* Not banked. TODO should RAZ/WI if DEMCR.SDME is set */
2083         return M_REG_NS;
2084     case 8 ... 10:
2085     case 13:
2086         /* RES0 */
2087         return -1;
2088     default:
2089         /* Not reachable due to decode of SHPR register addresses */
2090         g_assert_not_reached();
2091     }
2092 }
2093 
2094 static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
2095                                     uint64_t *data, unsigned size,
2096                                     MemTxAttrs attrs)
2097 {
2098     NVICState *s = (NVICState *)opaque;
2099     uint32_t offset = addr;
2100     unsigned i, startvec, end;
2101     uint32_t val;
2102 
2103     if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
2104         /* Generate BusFault for unprivileged accesses */
2105         return MEMTX_ERROR;
2106     }
2107 
2108     switch (offset) {
2109     /* reads of set and clear both return the status */
2110     case 0x100 ... 0x13f: /* NVIC Set enable */
2111         offset += 0x80;
2112         /* fall through */
2113     case 0x180 ... 0x1bf: /* NVIC Clear enable */
2114         val = 0;
2115         startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ; /* vector # */
2116 
2117         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
2118             if (s->vectors[startvec + i].enabled &&
2119                 (attrs.secure || s->itns[startvec + i])) {
2120                 val |= (1 << i);
2121             }
2122         }
2123         break;
2124     case 0x200 ... 0x23f: /* NVIC Set pend */
2125         offset += 0x80;
2126         /* fall through */
2127     case 0x280 ... 0x2bf: /* NVIC Clear pend */
2128         val = 0;
2129         startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */
2130         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
2131             if (s->vectors[startvec + i].pending &&
2132                 (attrs.secure || s->itns[startvec + i])) {
2133                 val |= (1 << i);
2134             }
2135         }
2136         break;
2137     case 0x300 ... 0x33f: /* NVIC Active */
2138         val = 0;
2139 
2140         if (!arm_feature(&s->cpu->env, ARM_FEATURE_V7)) {
2141             break;
2142         }
2143 
2144         startvec = 8 * (offset - 0x300) + NVIC_FIRST_IRQ; /* vector # */
2145 
2146         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
2147             if (s->vectors[startvec + i].active &&
2148                 (attrs.secure || s->itns[startvec + i])) {
2149                 val |= (1 << i);
2150             }
2151         }
2152         break;
2153     case 0x400 ... 0x5ef: /* NVIC Priority */
2154         val = 0;
2155         startvec = offset - 0x400 + NVIC_FIRST_IRQ; /* vector # */
2156 
2157         for (i = 0; i < size && startvec + i < s->num_irq; i++) {
2158             if (attrs.secure || s->itns[startvec + i]) {
2159                 val |= s->vectors[startvec + i].prio << (8 * i);
2160             }
2161         }
2162         break;
2163     case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
2164         if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
2165             val = 0;
2166             break;
2167         }
2168         /* fall through */
2169     case 0xd1c ... 0xd23: /* System Handler Priority (SHPR2, SHPR3) */
2170         val = 0;
2171         for (i = 0; i < size; i++) {
2172             unsigned hdlidx = (offset - 0xd14) + i;
2173             int sbank = shpr_bank(s, hdlidx, attrs);
2174 
2175             if (sbank < 0) {
2176                 continue;
2177             }
2178             val = deposit32(val, i * 8, 8, get_prio(s, hdlidx, sbank));
2179         }
2180         break;
2181     case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
2182         if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
2183             val = 0;
2184             break;
2185         };
2186         /*
2187          * The BFSR bits [15:8] are shared between security states
2188          * and we store them in the NS copy. They are RAZ/WI for
2189          * NS code if AIRCR.BFHFNMINS is 0.
2190          */
2191         val = s->cpu->env.v7m.cfsr[attrs.secure];
2192         if (!attrs.secure &&
2193             !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
2194             val &= ~R_V7M_CFSR_BFSR_MASK;
2195         } else {
2196             val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
2197         }
2198         val = extract32(val, (offset - 0xd28) * 8, size * 8);
2199         break;
2200     case 0xfe0 ... 0xfff: /* ID.  */
2201         if (offset & 3) {
2202             val = 0;
2203         } else {
2204             val = nvic_id[(offset - 0xfe0) >> 2];
2205         }
2206         break;
2207     default:
2208         if (size == 4) {
2209             val = nvic_readl(s, offset, attrs);
2210         } else {
2211             qemu_log_mask(LOG_GUEST_ERROR,
2212                           "NVIC: Bad read of size %d at offset 0x%x\n",
2213                           size, offset);
2214             val = 0;
2215         }
2216     }
2217 
2218     trace_nvic_sysreg_read(addr, val, size);
2219     *data = val;
2220     return MEMTX_OK;
2221 }
2222 
2223 static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
2224                                      uint64_t value, unsigned size,
2225                                      MemTxAttrs attrs)
2226 {
2227     NVICState *s = (NVICState *)opaque;
2228     uint32_t offset = addr;
2229     unsigned i, startvec, end;
2230     unsigned setval = 0;
2231 
2232     trace_nvic_sysreg_write(addr, value, size);
2233 
2234     if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
2235         /* Generate BusFault for unprivileged accesses */
2236         return MEMTX_ERROR;
2237     }
2238 
2239     switch (offset) {
2240     case 0x100 ... 0x13f: /* NVIC Set enable */
2241         offset += 0x80;
2242         setval = 1;
2243         /* fall through */
2244     case 0x180 ... 0x1bf: /* NVIC Clear enable */
2245         startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ;
2246 
2247         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
2248             if (value & (1 << i) &&
2249                 (attrs.secure || s->itns[startvec + i])) {
2250                 s->vectors[startvec + i].enabled = setval;
2251             }
2252         }
2253         nvic_irq_update(s);
2254         goto exit_ok;
2255     case 0x200 ... 0x23f: /* NVIC Set pend */
2256         /* the special logic in armv7m_nvic_set_pending()
2257          * is not needed since IRQs are never escalated
2258          */
2259         offset += 0x80;
2260         setval = 1;
2261         /* fall through */
2262     case 0x280 ... 0x2bf: /* NVIC Clear pend */
2263         startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */
2264 
2265         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
2266             if (value & (1 << i) &&
2267                 (attrs.secure || s->itns[startvec + i])) {
2268                 s->vectors[startvec + i].pending = setval;
2269             }
2270         }
2271         nvic_irq_update(s);
2272         goto exit_ok;
2273     case 0x300 ... 0x33f: /* NVIC Active */
2274         goto exit_ok; /* R/O */
2275     case 0x400 ... 0x5ef: /* NVIC Priority */
2276         startvec = (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
2277 
2278         for (i = 0; i < size && startvec + i < s->num_irq; i++) {
2279             if (attrs.secure || s->itns[startvec + i]) {
2280                 set_prio(s, startvec + i, false, (value >> (i * 8)) & 0xff);
2281             }
2282         }
2283         nvic_irq_update(s);
2284         goto exit_ok;
2285     case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
2286         if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
2287             goto exit_ok;
2288         }
2289         /* fall through */
2290     case 0xd1c ... 0xd23: /* System Handler Priority (SHPR2, SHPR3) */
2291         for (i = 0; i < size; i++) {
2292             unsigned hdlidx = (offset - 0xd14) + i;
2293             int newprio = extract32(value, i * 8, 8);
2294             int sbank = shpr_bank(s, hdlidx, attrs);
2295 
2296             if (sbank < 0) {
2297                 continue;
2298             }
2299             set_prio(s, hdlidx, sbank, newprio);
2300         }
2301         nvic_irq_update(s);
2302         goto exit_ok;
2303     case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
2304         if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
2305             goto exit_ok;
2306         }
2307         /* All bits are W1C, so construct 32 bit value with 0s in
2308          * the parts not written by the access size
2309          */
2310         value <<= ((offset - 0xd28) * 8);
2311 
2312         if (!attrs.secure &&
2313             !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
2314             /* BFSR bits are RAZ/WI for NS if BFHFNMINS is set */
2315             value &= ~R_V7M_CFSR_BFSR_MASK;
2316         }
2317 
2318         s->cpu->env.v7m.cfsr[attrs.secure] &= ~value;
2319         if (attrs.secure) {
2320             /* The BFSR bits [15:8] are shared between security states
2321              * and we store them in the NS copy.
2322              */
2323             s->cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
2324         }
2325         goto exit_ok;
2326     }
2327     if (size == 4) {
2328         nvic_writel(s, offset, value, attrs);
2329         goto exit_ok;
2330     }
2331     qemu_log_mask(LOG_GUEST_ERROR,
2332                   "NVIC: Bad write of size %d at offset 0x%x\n", size, offset);
2333     /* This is UNPREDICTABLE; treat as RAZ/WI */
2334 
2335  exit_ok:
2336     /* Ensure any changes made are reflected in the cached hflags.  */
2337     arm_rebuild_hflags(&s->cpu->env);
2338     return MEMTX_OK;
2339 }
2340 
2341 static const MemoryRegionOps nvic_sysreg_ops = {
2342     .read_with_attrs = nvic_sysreg_read,
2343     .write_with_attrs = nvic_sysreg_write,
2344     .endianness = DEVICE_NATIVE_ENDIAN,
2345 };
2346 
2347 static MemTxResult nvic_sysreg_ns_write(void *opaque, hwaddr addr,
2348                                         uint64_t value, unsigned size,
2349                                         MemTxAttrs attrs)
2350 {
2351     MemoryRegion *mr = opaque;
2352 
2353     if (attrs.secure) {
2354         /* S accesses to the alias act like NS accesses to the real region */
2355         attrs.secure = 0;
2356         return memory_region_dispatch_write(mr, addr, value,
2357                                             size_memop(size) | MO_TE, attrs);
2358     } else {
2359         /* NS attrs are RAZ/WI for privileged, and BusFault for user */
2360         if (attrs.user) {
2361             return MEMTX_ERROR;
2362         }
2363         return MEMTX_OK;
2364     }
2365 }
2366 
2367 static MemTxResult nvic_sysreg_ns_read(void *opaque, hwaddr addr,
2368                                        uint64_t *data, unsigned size,
2369                                        MemTxAttrs attrs)
2370 {
2371     MemoryRegion *mr = opaque;
2372 
2373     if (attrs.secure) {
2374         /* S accesses to the alias act like NS accesses to the real region */
2375         attrs.secure = 0;
2376         return memory_region_dispatch_read(mr, addr, data,
2377                                            size_memop(size) | MO_TE, attrs);
2378     } else {
2379         /* NS attrs are RAZ/WI for privileged, and BusFault for user */
2380         if (attrs.user) {
2381             return MEMTX_ERROR;
2382         }
2383         *data = 0;
2384         return MEMTX_OK;
2385     }
2386 }
2387 
2388 static const MemoryRegionOps nvic_sysreg_ns_ops = {
2389     .read_with_attrs = nvic_sysreg_ns_read,
2390     .write_with_attrs = nvic_sysreg_ns_write,
2391     .endianness = DEVICE_NATIVE_ENDIAN,
2392 };
2393 
2394 static MemTxResult nvic_systick_write(void *opaque, hwaddr addr,
2395                                       uint64_t value, unsigned size,
2396                                       MemTxAttrs attrs)
2397 {
2398     NVICState *s = opaque;
2399     MemoryRegion *mr;
2400 
2401     /* Direct the access to the correct systick */
2402     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
2403     return memory_region_dispatch_write(mr, addr, value,
2404                                         size_memop(size) | MO_TE, attrs);
2405 }
2406 
2407 static MemTxResult nvic_systick_read(void *opaque, hwaddr addr,
2408                                      uint64_t *data, unsigned size,
2409                                      MemTxAttrs attrs)
2410 {
2411     NVICState *s = opaque;
2412     MemoryRegion *mr;
2413 
2414     /* Direct the access to the correct systick */
2415     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
2416     return memory_region_dispatch_read(mr, addr, data, size_memop(size) | MO_TE,
2417                                        attrs);
2418 }
2419 
2420 static const MemoryRegionOps nvic_systick_ops = {
2421     .read_with_attrs = nvic_systick_read,
2422     .write_with_attrs = nvic_systick_write,
2423     .endianness = DEVICE_NATIVE_ENDIAN,
2424 };
2425 
2426 static int nvic_post_load(void *opaque, int version_id)
2427 {
2428     NVICState *s = opaque;
2429     unsigned i;
2430     int resetprio;
2431 
2432     /* Check for out of range priority settings */
2433     resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3;
2434 
2435     if (s->vectors[ARMV7M_EXCP_RESET].prio != resetprio ||
2436         s->vectors[ARMV7M_EXCP_NMI].prio != -2 ||
2437         s->vectors[ARMV7M_EXCP_HARD].prio != -1) {
2438         return 1;
2439     }
2440     for (i = ARMV7M_EXCP_MEM; i < s->num_irq; i++) {
2441         if (s->vectors[i].prio & ~0xff) {
2442             return 1;
2443         }
2444     }
2445 
2446     nvic_recompute_state(s);
2447 
2448     return 0;
2449 }
2450 
2451 static const VMStateDescription vmstate_VecInfo = {
2452     .name = "armv7m_nvic_info",
2453     .version_id = 1,
2454     .minimum_version_id = 1,
2455     .fields = (VMStateField[]) {
2456         VMSTATE_INT16(prio, VecInfo),
2457         VMSTATE_UINT8(enabled, VecInfo),
2458         VMSTATE_UINT8(pending, VecInfo),
2459         VMSTATE_UINT8(active, VecInfo),
2460         VMSTATE_UINT8(level, VecInfo),
2461         VMSTATE_END_OF_LIST()
2462     }
2463 };
2464 
2465 static bool nvic_security_needed(void *opaque)
2466 {
2467     NVICState *s = opaque;
2468 
2469     return arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY);
2470 }
2471 
2472 static int nvic_security_post_load(void *opaque, int version_id)
2473 {
2474     NVICState *s = opaque;
2475     int i;
2476 
2477     /* Check for out of range priority settings */
2478     if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1
2479         && s->sec_vectors[ARMV7M_EXCP_HARD].prio != -3) {
2480         /* We can't cross-check against AIRCR.BFHFNMINS as we don't know
2481          * if the CPU state has been migrated yet; a mismatch won't
2482          * cause the emulation to blow up, though.
2483          */
2484         return 1;
2485     }
2486     for (i = ARMV7M_EXCP_MEM; i < ARRAY_SIZE(s->sec_vectors); i++) {
2487         if (s->sec_vectors[i].prio & ~0xff) {
2488             return 1;
2489         }
2490     }
2491     return 0;
2492 }
2493 
2494 static const VMStateDescription vmstate_nvic_security = {
2495     .name = "armv7m_nvic/m-security",
2496     .version_id = 1,
2497     .minimum_version_id = 1,
2498     .needed = nvic_security_needed,
2499     .post_load = &nvic_security_post_load,
2500     .fields = (VMStateField[]) {
2501         VMSTATE_STRUCT_ARRAY(sec_vectors, NVICState, NVIC_INTERNAL_VECTORS, 1,
2502                              vmstate_VecInfo, VecInfo),
2503         VMSTATE_UINT32(prigroup[M_REG_S], NVICState),
2504         VMSTATE_BOOL_ARRAY(itns, NVICState, NVIC_MAX_VECTORS),
2505         VMSTATE_END_OF_LIST()
2506     }
2507 };
2508 
2509 static const VMStateDescription vmstate_nvic = {
2510     .name = "armv7m_nvic",
2511     .version_id = 4,
2512     .minimum_version_id = 4,
2513     .post_load = &nvic_post_load,
2514     .fields = (VMStateField[]) {
2515         VMSTATE_STRUCT_ARRAY(vectors, NVICState, NVIC_MAX_VECTORS, 1,
2516                              vmstate_VecInfo, VecInfo),
2517         VMSTATE_UINT32(prigroup[M_REG_NS], NVICState),
2518         VMSTATE_END_OF_LIST()
2519     },
2520     .subsections = (const VMStateDescription*[]) {
2521         &vmstate_nvic_security,
2522         NULL
2523     }
2524 };
2525 
2526 static Property props_nvic[] = {
2527     /* Number of external IRQ lines (so excluding the 16 internal exceptions) */
2528     DEFINE_PROP_UINT32("num-irq", NVICState, num_irq, 64),
2529     DEFINE_PROP_END_OF_LIST()
2530 };
2531 
2532 static void armv7m_nvic_reset(DeviceState *dev)
2533 {
2534     int resetprio;
2535     NVICState *s = NVIC(dev);
2536 
2537     memset(s->vectors, 0, sizeof(s->vectors));
2538     memset(s->sec_vectors, 0, sizeof(s->sec_vectors));
2539     s->prigroup[M_REG_NS] = 0;
2540     s->prigroup[M_REG_S] = 0;
2541 
2542     s->vectors[ARMV7M_EXCP_NMI].enabled = 1;
2543     /* MEM, BUS, and USAGE are enabled through
2544      * the System Handler Control register
2545      */
2546     s->vectors[ARMV7M_EXCP_SVC].enabled = 1;
2547     s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
2548     s->vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
2549 
2550     /* DebugMonitor is enabled via DEMCR.MON_EN */
2551     s->vectors[ARMV7M_EXCP_DEBUG].enabled = 0;
2552 
2553     resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3;
2554     s->vectors[ARMV7M_EXCP_RESET].prio = resetprio;
2555     s->vectors[ARMV7M_EXCP_NMI].prio = -2;
2556     s->vectors[ARMV7M_EXCP_HARD].prio = -1;
2557 
2558     if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
2559         s->sec_vectors[ARMV7M_EXCP_HARD].enabled = 1;
2560         s->sec_vectors[ARMV7M_EXCP_SVC].enabled = 1;
2561         s->sec_vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
2562         s->sec_vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
2563 
2564         /* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC) */
2565         s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
2566         /* If AIRCR.BFHFNMINS is 0 then NS HF is (effectively) disabled */
2567         s->vectors[ARMV7M_EXCP_HARD].enabled = 0;
2568     } else {
2569         s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
2570     }
2571 
2572     /* Strictly speaking the reset handler should be enabled.
2573      * However, we don't simulate soft resets through the NVIC,
2574      * and the reset vector should never be pended.
2575      * So we leave it disabled to catch logic errors.
2576      */
2577 
2578     s->exception_prio = NVIC_NOEXC_PRIO;
2579     s->vectpending = 0;
2580     s->vectpending_is_s_banked = false;
2581     s->vectpending_prio = NVIC_NOEXC_PRIO;
2582 
2583     if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
2584         memset(s->itns, 0, sizeof(s->itns));
2585     } else {
2586         /* This state is constant and not guest accessible in a non-security
2587          * NVIC; we set the bits to true to avoid having to do a feature
2588          * bit check in the NVIC enable/pend/etc register accessors.
2589          */
2590         int i;
2591 
2592         for (i = NVIC_FIRST_IRQ; i < ARRAY_SIZE(s->itns); i++) {
2593             s->itns[i] = true;
2594         }
2595     }
2596 
2597     /*
2598      * We updated state that affects the CPU's MMUidx and thus its hflags;
2599      * and we can't guarantee that we run before the CPU reset function.
2600      */
2601     arm_rebuild_hflags(&s->cpu->env);
2602 }
2603 
2604 static void nvic_systick_trigger(void *opaque, int n, int level)
2605 {
2606     NVICState *s = opaque;
2607 
2608     if (level) {
2609         /* SysTick just asked us to pend its exception.
2610          * (This is different from an external interrupt line's
2611          * behaviour.)
2612          * n == 0 : NonSecure systick
2613          * n == 1 : Secure systick
2614          */
2615         armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, n);
2616     }
2617 }
2618 
2619 static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
2620 {
2621     NVICState *s = NVIC(dev);
2622     int regionlen;
2623 
2624     /* The armv7m container object will have set our CPU pointer */
2625     if (!s->cpu || !arm_feature(&s->cpu->env, ARM_FEATURE_M)) {
2626         error_setg(errp, "The NVIC can only be used with a Cortex-M CPU");
2627         return;
2628     }
2629 
2630     if (s->num_irq > NVIC_MAX_IRQ) {
2631         error_setg(errp, "num-irq %d exceeds NVIC maximum", s->num_irq);
2632         return;
2633     }
2634 
2635     qdev_init_gpio_in(dev, set_irq_level, s->num_irq);
2636 
2637     /* include space for internal exception vectors */
2638     s->num_irq += NVIC_FIRST_IRQ;
2639 
2640     s->num_prio_bits = arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 8 : 2;
2641 
2642     if (!sysbus_realize(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), errp)) {
2643         return;
2644     }
2645     sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), 0,
2646                        qdev_get_gpio_in_named(dev, "systick-trigger",
2647                                               M_REG_NS));
2648 
2649     if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
2650         /* We couldn't init the secure systick device in instance_init
2651          * as we didn't know then if the CPU had the security extensions;
2652          * so we have to do it here.
2653          */
2654         object_initialize_child(OBJECT(dev), "systick-reg-s",
2655                                 &s->systick[M_REG_S], TYPE_SYSTICK);
2656 
2657         if (!sysbus_realize(SYS_BUS_DEVICE(&s->systick[M_REG_S]), errp)) {
2658             return;
2659         }
2660         sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_S]), 0,
2661                            qdev_get_gpio_in_named(dev, "systick-trigger",
2662                                                   M_REG_S));
2663     }
2664 
2665     /* The NVIC and System Control Space (SCS) starts at 0xe000e000
2666      * and looks like this:
2667      *  0x004 - ICTR
2668      *  0x010 - 0xff - systick
2669      *  0x100..0x7ec - NVIC
2670      *  0x7f0..0xcff - Reserved
2671      *  0xd00..0xd3c - SCS registers
2672      *  0xd40..0xeff - Reserved or Not implemented
2673      *  0xf00 - STIR
2674      *
2675      * Some registers within this space are banked between security states.
2676      * In v8M there is a second range 0xe002e000..0xe002efff which is the
2677      * NonSecure alias SCS; secure accesses to this behave like NS accesses
2678      * to the main SCS range, and non-secure accesses (including when
2679      * the security extension is not implemented) are RAZ/WI.
2680      * Note that both the main SCS range and the alias range are defined
2681      * to be exempt from memory attribution (R_BLJT) and so the memory
2682      * transaction attribute always matches the current CPU security
2683      * state (attrs.secure == env->v7m.secure). In the nvic_sysreg_ns_ops
2684      * wrappers we change attrs.secure to indicate the NS access; so
2685      * generally code determining which banked register to use should
2686      * use attrs.secure; code determining actual behaviour of the system
2687      * should use env->v7m.secure.
2688      */
2689     regionlen = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? 0x21000 : 0x1000;
2690     memory_region_init(&s->container, OBJECT(s), "nvic", regionlen);
2691     /* The system register region goes at the bottom of the priority
2692      * stack as it covers the whole page.
2693      */
2694     memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
2695                           "nvic_sysregs", 0x1000);
2696     memory_region_add_subregion(&s->container, 0, &s->sysregmem);
2697 
2698     memory_region_init_io(&s->systickmem, OBJECT(s),
2699                           &nvic_systick_ops, s,
2700                           "nvic_systick", 0xe0);
2701 
2702     memory_region_add_subregion_overlap(&s->container, 0x10,
2703                                         &s->systickmem, 1);
2704 
2705     if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
2706         memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
2707                               &nvic_sysreg_ns_ops, &s->sysregmem,
2708                               "nvic_sysregs_ns", 0x1000);
2709         memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
2710         memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
2711                               &nvic_sysreg_ns_ops, &s->systickmem,
2712                               "nvic_systick_ns", 0xe0);
2713         memory_region_add_subregion_overlap(&s->container, 0x20010,
2714                                             &s->systick_ns_mem, 1);
2715     }
2716 
2717     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
2718 }
2719 
2720 static void armv7m_nvic_instance_init(Object *obj)
2721 {
2722     /* We have a different default value for the num-irq property
2723      * than our superclass. This function runs after qdev init
2724      * has set the defaults from the Property array and before
2725      * any user-specified property setting, so just modify the
2726      * value in the GICState struct.
2727      */
2728     DeviceState *dev = DEVICE(obj);
2729     NVICState *nvic = NVIC(obj);
2730     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
2731 
2732     object_initialize_child(obj, "systick-reg-ns", &nvic->systick[M_REG_NS],
2733                             TYPE_SYSTICK);
2734     /* We can't initialize the secure systick here, as we don't know
2735      * yet if we need it.
2736      */
2737 
2738     sysbus_init_irq(sbd, &nvic->excpout);
2739     qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
2740     qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger",
2741                             M_REG_NUM_BANKS);
2742     qdev_init_gpio_in_named(dev, nvic_nmi_trigger, "NMI", 1);
2743 }
2744 
2745 static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
2746 {
2747     DeviceClass *dc = DEVICE_CLASS(klass);
2748 
2749     dc->vmsd  = &vmstate_nvic;
2750     device_class_set_props(dc, props_nvic);
2751     dc->reset = armv7m_nvic_reset;
2752     dc->realize = armv7m_nvic_realize;
2753 }
2754 
2755 static const TypeInfo armv7m_nvic_info = {
2756     .name          = TYPE_NVIC,
2757     .parent        = TYPE_SYS_BUS_DEVICE,
2758     .instance_init = armv7m_nvic_instance_init,
2759     .instance_size = sizeof(NVICState),
2760     .class_init    = armv7m_nvic_class_init,
2761     .class_size    = sizeof(SysBusDeviceClass),
2762 };
2763 
2764 static void armv7m_nvic_register_types(void)
2765 {
2766     type_register_static(&armv7m_nvic_info);
2767 }
2768 
2769 type_init(armv7m_nvic_register_types)
2770