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