xref: /openbmc/qemu/hw/intc/armv7m_nvic.c (revision ae3c12a0)
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 "qemu-common.h"
16 #include "cpu.h"
17 #include "hw/sysbus.h"
18 #include "qemu/timer.h"
19 #include "hw/arm/arm.h"
20 #include "hw/intc/armv7m_nvic.h"
21 #include "target/arm/cpu.h"
22 #include "exec/exec-all.h"
23 #include "qemu/log.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;
817     int ret;
818 
819     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
820 
821     if (secure && exc_is_banked(irq)) {
822         vec = &s->sec_vectors[irq];
823     } else {
824         vec = &s->vectors[irq];
825     }
826 
827     trace_nvic_complete_irq(irq, secure);
828 
829     if (!vec->active) {
830         /* Tell the caller this was an illegal exception return */
831         return -1;
832     }
833 
834     ret = nvic_rettobase(s);
835 
836     vec->active = 0;
837     if (vec->level) {
838         /* Re-pend the exception if it's still held high; only
839          * happens for extenal IRQs
840          */
841         assert(irq >= NVIC_FIRST_IRQ);
842         vec->pending = 1;
843     }
844 
845     nvic_irq_update(s);
846 
847     return ret;
848 }
849 
850 bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
851 {
852     /*
853      * Return whether an exception is "ready", i.e. it is enabled and is
854      * configured at a priority which would allow it to interrupt the
855      * current execution priority.
856      *
857      * irq and secure have the same semantics as for armv7m_nvic_set_pending():
858      * for non-banked exceptions secure is always false; for banked exceptions
859      * it indicates which of the exceptions is required.
860      */
861     NVICState *s = (NVICState *)opaque;
862     bool banked = exc_is_banked(irq);
863     VecInfo *vec;
864     int running = nvic_exec_prio(s);
865 
866     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
867     assert(!secure || banked);
868 
869     /*
870      * HardFault is an odd special case: we always check against -1,
871      * even if we're secure and HardFault has priority -3; we never
872      * need to check for enabled state.
873      */
874     if (irq == ARMV7M_EXCP_HARD) {
875         return running > -1;
876     }
877 
878     vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
879 
880     return vec->enabled &&
881         exc_group_prio(s, vec->prio, secure) < running;
882 }
883 
884 /* callback when external interrupt line is changed */
885 static void set_irq_level(void *opaque, int n, int level)
886 {
887     NVICState *s = opaque;
888     VecInfo *vec;
889 
890     n += NVIC_FIRST_IRQ;
891 
892     assert(n >= NVIC_FIRST_IRQ && n < s->num_irq);
893 
894     trace_nvic_set_irq_level(n, level);
895 
896     /* The pending status of an external interrupt is
897      * latched on rising edge and exception handler return.
898      *
899      * Pulsing the IRQ will always run the handler
900      * once, and the handler will re-run until the
901      * level is low when the handler completes.
902      */
903     vec = &s->vectors[n];
904     if (level != vec->level) {
905         vec->level = level;
906         if (level) {
907             armv7m_nvic_set_pending(s, n, false);
908         }
909     }
910 }
911 
912 /* callback when external NMI line is changed */
913 static void nvic_nmi_trigger(void *opaque, int n, int level)
914 {
915     NVICState *s = opaque;
916 
917     trace_nvic_set_nmi_level(level);
918 
919     /*
920      * The architecture doesn't specify whether NMI should share
921      * the normal-interrupt behaviour of being resampled on
922      * exception handler return. We choose not to, so just
923      * set NMI pending here and don't track the current level.
924      */
925     if (level) {
926         armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
927     }
928 }
929 
930 static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
931 {
932     ARMCPU *cpu = s->cpu;
933     uint32_t val;
934 
935     switch (offset) {
936     case 4: /* Interrupt Control Type.  */
937         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
938             goto bad_offset;
939         }
940         return ((s->num_irq - NVIC_FIRST_IRQ) / 32) - 1;
941     case 0xc: /* CPPWR */
942         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
943             goto bad_offset;
944         }
945         /* We make the IMPDEF choice that nothing can ever go into a
946          * non-retentive power state, which allows us to RAZ/WI this.
947          */
948         return 0;
949     case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
950     {
951         int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ;
952         int i;
953 
954         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
955             goto bad_offset;
956         }
957         if (!attrs.secure) {
958             return 0;
959         }
960         val = 0;
961         for (i = 0; i < 32 && startvec + i < s->num_irq; i++) {
962             if (s->itns[startvec + i]) {
963                 val |= (1 << i);
964             }
965         }
966         return val;
967     }
968     case 0xd00: /* CPUID Base.  */
969         return cpu->midr;
970     case 0xd04: /* Interrupt Control State (ICSR) */
971         /* VECTACTIVE */
972         val = cpu->env.v7m.exception;
973         /* VECTPENDING */
974         val |= (s->vectpending & 0xff) << 12;
975         /* ISRPENDING - set if any external IRQ is pending */
976         if (nvic_isrpending(s)) {
977             val |= (1 << 22);
978         }
979         /* RETTOBASE - set if only one handler is active */
980         if (nvic_rettobase(s)) {
981             val |= (1 << 11);
982         }
983         if (attrs.secure) {
984             /* PENDSTSET */
985             if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].pending) {
986                 val |= (1 << 26);
987             }
988             /* PENDSVSET */
989             if (s->sec_vectors[ARMV7M_EXCP_PENDSV].pending) {
990                 val |= (1 << 28);
991             }
992         } else {
993             /* PENDSTSET */
994             if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) {
995                 val |= (1 << 26);
996             }
997             /* PENDSVSET */
998             if (s->vectors[ARMV7M_EXCP_PENDSV].pending) {
999                 val |= (1 << 28);
1000             }
1001         }
1002         /* NMIPENDSET */
1003         if ((attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))
1004             && s->vectors[ARMV7M_EXCP_NMI].pending) {
1005             val |= (1 << 31);
1006         }
1007         /* ISRPREEMPT: RES0 when halting debug not implemented */
1008         /* STTNS: RES0 for the Main Extension */
1009         return val;
1010     case 0xd08: /* Vector Table Offset.  */
1011         return cpu->env.v7m.vecbase[attrs.secure];
1012     case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */
1013         val = 0xfa050000 | (s->prigroup[attrs.secure] << 8);
1014         if (attrs.secure) {
1015             /* s->aircr stores PRIS, BFHFNMINS, SYSRESETREQS */
1016             val |= cpu->env.v7m.aircr;
1017         } else {
1018             if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1019                 /* BFHFNMINS is R/O from NS; other bits are RAZ/WI. If
1020                  * security isn't supported then BFHFNMINS is RAO (and
1021                  * the bit in env.v7m.aircr is always set).
1022                  */
1023                 val |= cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK;
1024             }
1025         }
1026         return val;
1027     case 0xd10: /* System Control.  */
1028         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
1029             goto bad_offset;
1030         }
1031         return cpu->env.v7m.scr[attrs.secure];
1032     case 0xd14: /* Configuration Control.  */
1033         /* The BFHFNMIGN bit is the only non-banked bit; we
1034          * keep it in the non-secure copy of the register.
1035          */
1036         val = cpu->env.v7m.ccr[attrs.secure];
1037         val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
1038         return val;
1039     case 0xd24: /* System Handler Control and State (SHCSR) */
1040         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
1041             goto bad_offset;
1042         }
1043         val = 0;
1044         if (attrs.secure) {
1045             if (s->sec_vectors[ARMV7M_EXCP_MEM].active) {
1046                 val |= (1 << 0);
1047             }
1048             if (s->sec_vectors[ARMV7M_EXCP_HARD].active) {
1049                 val |= (1 << 2);
1050             }
1051             if (s->sec_vectors[ARMV7M_EXCP_USAGE].active) {
1052                 val |= (1 << 3);
1053             }
1054             if (s->sec_vectors[ARMV7M_EXCP_SVC].active) {
1055                 val |= (1 << 7);
1056             }
1057             if (s->sec_vectors[ARMV7M_EXCP_PENDSV].active) {
1058                 val |= (1 << 10);
1059             }
1060             if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].active) {
1061                 val |= (1 << 11);
1062             }
1063             if (s->sec_vectors[ARMV7M_EXCP_USAGE].pending) {
1064                 val |= (1 << 12);
1065             }
1066             if (s->sec_vectors[ARMV7M_EXCP_MEM].pending) {
1067                 val |= (1 << 13);
1068             }
1069             if (s->sec_vectors[ARMV7M_EXCP_SVC].pending) {
1070                 val |= (1 << 15);
1071             }
1072             if (s->sec_vectors[ARMV7M_EXCP_MEM].enabled) {
1073                 val |= (1 << 16);
1074             }
1075             if (s->sec_vectors[ARMV7M_EXCP_USAGE].enabled) {
1076                 val |= (1 << 18);
1077             }
1078             if (s->sec_vectors[ARMV7M_EXCP_HARD].pending) {
1079                 val |= (1 << 21);
1080             }
1081             /* SecureFault is not banked but is always RAZ/WI to NS */
1082             if (s->vectors[ARMV7M_EXCP_SECURE].active) {
1083                 val |= (1 << 4);
1084             }
1085             if (s->vectors[ARMV7M_EXCP_SECURE].enabled) {
1086                 val |= (1 << 19);
1087             }
1088             if (s->vectors[ARMV7M_EXCP_SECURE].pending) {
1089                 val |= (1 << 20);
1090             }
1091         } else {
1092             if (s->vectors[ARMV7M_EXCP_MEM].active) {
1093                 val |= (1 << 0);
1094             }
1095             if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1096                 /* HARDFAULTACT, HARDFAULTPENDED not present in v7M */
1097                 if (s->vectors[ARMV7M_EXCP_HARD].active) {
1098                     val |= (1 << 2);
1099                 }
1100                 if (s->vectors[ARMV7M_EXCP_HARD].pending) {
1101                     val |= (1 << 21);
1102                 }
1103             }
1104             if (s->vectors[ARMV7M_EXCP_USAGE].active) {
1105                 val |= (1 << 3);
1106             }
1107             if (s->vectors[ARMV7M_EXCP_SVC].active) {
1108                 val |= (1 << 7);
1109             }
1110             if (s->vectors[ARMV7M_EXCP_PENDSV].active) {
1111                 val |= (1 << 10);
1112             }
1113             if (s->vectors[ARMV7M_EXCP_SYSTICK].active) {
1114                 val |= (1 << 11);
1115             }
1116             if (s->vectors[ARMV7M_EXCP_USAGE].pending) {
1117                 val |= (1 << 12);
1118             }
1119             if (s->vectors[ARMV7M_EXCP_MEM].pending) {
1120                 val |= (1 << 13);
1121             }
1122             if (s->vectors[ARMV7M_EXCP_SVC].pending) {
1123                 val |= (1 << 15);
1124             }
1125             if (s->vectors[ARMV7M_EXCP_MEM].enabled) {
1126                 val |= (1 << 16);
1127             }
1128             if (s->vectors[ARMV7M_EXCP_USAGE].enabled) {
1129                 val |= (1 << 18);
1130             }
1131         }
1132         if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
1133             if (s->vectors[ARMV7M_EXCP_BUS].active) {
1134                 val |= (1 << 1);
1135             }
1136             if (s->vectors[ARMV7M_EXCP_BUS].pending) {
1137                 val |= (1 << 14);
1138             }
1139             if (s->vectors[ARMV7M_EXCP_BUS].enabled) {
1140                 val |= (1 << 17);
1141             }
1142             if (arm_feature(&cpu->env, ARM_FEATURE_V8) &&
1143                 s->vectors[ARMV7M_EXCP_NMI].active) {
1144                 /* NMIACT is not present in v7M */
1145                 val |= (1 << 5);
1146             }
1147         }
1148 
1149         /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */
1150         if (s->vectors[ARMV7M_EXCP_DEBUG].active) {
1151             val |= (1 << 8);
1152         }
1153         return val;
1154     case 0xd2c: /* Hard Fault Status.  */
1155         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1156             goto bad_offset;
1157         }
1158         return cpu->env.v7m.hfsr;
1159     case 0xd30: /* Debug Fault Status.  */
1160         return cpu->env.v7m.dfsr;
1161     case 0xd34: /* MMFAR MemManage Fault Address */
1162         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1163             goto bad_offset;
1164         }
1165         return cpu->env.v7m.mmfar[attrs.secure];
1166     case 0xd38: /* Bus Fault Address.  */
1167         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1168             goto bad_offset;
1169         }
1170         if (!attrs.secure &&
1171             !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
1172             return 0;
1173         }
1174         return cpu->env.v7m.bfar;
1175     case 0xd3c: /* Aux Fault Status.  */
1176         /* TODO: Implement fault status registers.  */
1177         qemu_log_mask(LOG_UNIMP,
1178                       "Aux Fault status registers unimplemented\n");
1179         return 0;
1180     case 0xd40: /* PFR0.  */
1181         return cpu->id_pfr0;
1182     case 0xd44: /* PFR1.  */
1183         return cpu->id_pfr1;
1184     case 0xd48: /* DFR0.  */
1185         return cpu->id_dfr0;
1186     case 0xd4c: /* AFR0.  */
1187         return cpu->id_afr0;
1188     case 0xd50: /* MMFR0.  */
1189         return cpu->id_mmfr0;
1190     case 0xd54: /* MMFR1.  */
1191         return cpu->id_mmfr1;
1192     case 0xd58: /* MMFR2.  */
1193         return cpu->id_mmfr2;
1194     case 0xd5c: /* MMFR3.  */
1195         return cpu->id_mmfr3;
1196     case 0xd60: /* ISAR0.  */
1197         return cpu->isar.id_isar0;
1198     case 0xd64: /* ISAR1.  */
1199         return cpu->isar.id_isar1;
1200     case 0xd68: /* ISAR2.  */
1201         return cpu->isar.id_isar2;
1202     case 0xd6c: /* ISAR3.  */
1203         return cpu->isar.id_isar3;
1204     case 0xd70: /* ISAR4.  */
1205         return cpu->isar.id_isar4;
1206     case 0xd74: /* ISAR5.  */
1207         return cpu->isar.id_isar5;
1208     case 0xd78: /* CLIDR */
1209         return cpu->clidr;
1210     case 0xd7c: /* CTR */
1211         return cpu->ctr;
1212     case 0xd80: /* CSSIDR */
1213     {
1214         int idx = cpu->env.v7m.csselr[attrs.secure] & R_V7M_CSSELR_INDEX_MASK;
1215         return cpu->ccsidr[idx];
1216     }
1217     case 0xd84: /* CSSELR */
1218         return cpu->env.v7m.csselr[attrs.secure];
1219     case 0xd88: /* CPACR */
1220         if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
1221             return 0;
1222         }
1223         return cpu->env.v7m.cpacr[attrs.secure];
1224     case 0xd8c: /* NSACR */
1225         if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
1226             return 0;
1227         }
1228         return cpu->env.v7m.nsacr;
1229     /* TODO: Implement debug registers.  */
1230     case 0xd90: /* MPU_TYPE */
1231         /* Unified MPU; if the MPU is not present this value is zero */
1232         return cpu->pmsav7_dregion << 8;
1233         break;
1234     case 0xd94: /* MPU_CTRL */
1235         return cpu->env.v7m.mpu_ctrl[attrs.secure];
1236     case 0xd98: /* MPU_RNR */
1237         return cpu->env.pmsav7.rnr[attrs.secure];
1238     case 0xd9c: /* MPU_RBAR */
1239     case 0xda4: /* MPU_RBAR_A1 */
1240     case 0xdac: /* MPU_RBAR_A2 */
1241     case 0xdb4: /* MPU_RBAR_A3 */
1242     {
1243         int region = cpu->env.pmsav7.rnr[attrs.secure];
1244 
1245         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1246             /* PMSAv8M handling of the aliases is different from v7M:
1247              * aliases A1, A2, A3 override the low two bits of the region
1248              * number in MPU_RNR, and there is no 'region' field in the
1249              * RBAR register.
1250              */
1251             int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
1252             if (aliasno) {
1253                 region = deposit32(region, 0, 2, aliasno);
1254             }
1255             if (region >= cpu->pmsav7_dregion) {
1256                 return 0;
1257             }
1258             return cpu->env.pmsav8.rbar[attrs.secure][region];
1259         }
1260 
1261         if (region >= cpu->pmsav7_dregion) {
1262             return 0;
1263         }
1264         return (cpu->env.pmsav7.drbar[region] & ~0x1f) | (region & 0xf);
1265     }
1266     case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
1267     case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
1268     case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
1269     case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
1270     {
1271         int region = cpu->env.pmsav7.rnr[attrs.secure];
1272 
1273         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1274             /* PMSAv8M handling of the aliases is different from v7M:
1275              * aliases A1, A2, A3 override the low two bits of the region
1276              * number in MPU_RNR.
1277              */
1278             int aliasno = (offset - 0xda0) / 8; /* 0..3 */
1279             if (aliasno) {
1280                 region = deposit32(region, 0, 2, aliasno);
1281             }
1282             if (region >= cpu->pmsav7_dregion) {
1283                 return 0;
1284             }
1285             return cpu->env.pmsav8.rlar[attrs.secure][region];
1286         }
1287 
1288         if (region >= cpu->pmsav7_dregion) {
1289             return 0;
1290         }
1291         return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) |
1292             (cpu->env.pmsav7.drsr[region] & 0xffff);
1293     }
1294     case 0xdc0: /* MPU_MAIR0 */
1295         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1296             goto bad_offset;
1297         }
1298         return cpu->env.pmsav8.mair0[attrs.secure];
1299     case 0xdc4: /* MPU_MAIR1 */
1300         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1301             goto bad_offset;
1302         }
1303         return cpu->env.pmsav8.mair1[attrs.secure];
1304     case 0xdd0: /* SAU_CTRL */
1305         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1306             goto bad_offset;
1307         }
1308         if (!attrs.secure) {
1309             return 0;
1310         }
1311         return cpu->env.sau.ctrl;
1312     case 0xdd4: /* SAU_TYPE */
1313         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1314             goto bad_offset;
1315         }
1316         if (!attrs.secure) {
1317             return 0;
1318         }
1319         return cpu->sau_sregion;
1320     case 0xdd8: /* SAU_RNR */
1321         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1322             goto bad_offset;
1323         }
1324         if (!attrs.secure) {
1325             return 0;
1326         }
1327         return cpu->env.sau.rnr;
1328     case 0xddc: /* SAU_RBAR */
1329     {
1330         int region = cpu->env.sau.rnr;
1331 
1332         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1333             goto bad_offset;
1334         }
1335         if (!attrs.secure) {
1336             return 0;
1337         }
1338         if (region >= cpu->sau_sregion) {
1339             return 0;
1340         }
1341         return cpu->env.sau.rbar[region];
1342     }
1343     case 0xde0: /* SAU_RLAR */
1344     {
1345         int region = cpu->env.sau.rnr;
1346 
1347         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1348             goto bad_offset;
1349         }
1350         if (!attrs.secure) {
1351             return 0;
1352         }
1353         if (region >= cpu->sau_sregion) {
1354             return 0;
1355         }
1356         return cpu->env.sau.rlar[region];
1357     }
1358     case 0xde4: /* SFSR */
1359         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1360             goto bad_offset;
1361         }
1362         if (!attrs.secure) {
1363             return 0;
1364         }
1365         return cpu->env.v7m.sfsr;
1366     case 0xde8: /* SFAR */
1367         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1368             goto bad_offset;
1369         }
1370         if (!attrs.secure) {
1371             return 0;
1372         }
1373         return cpu->env.v7m.sfar;
1374     case 0xf34: /* FPCCR */
1375         if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
1376             return 0;
1377         }
1378         if (attrs.secure) {
1379             return cpu->env.v7m.fpccr[M_REG_S];
1380         } else {
1381             /*
1382              * NS can read LSPEN, CLRONRET and MONRDY. It can read
1383              * BFRDY and HFRDY if AIRCR.BFHFNMINS != 0;
1384              * other non-banked bits RAZ.
1385              * TODO: MONRDY should RAZ/WI if DEMCR.SDME is set.
1386              */
1387             uint32_t value = cpu->env.v7m.fpccr[M_REG_S];
1388             uint32_t mask = R_V7M_FPCCR_LSPEN_MASK |
1389                 R_V7M_FPCCR_CLRONRET_MASK |
1390                 R_V7M_FPCCR_MONRDY_MASK;
1391 
1392             if (s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
1393                 mask |= R_V7M_FPCCR_BFRDY_MASK | R_V7M_FPCCR_HFRDY_MASK;
1394             }
1395 
1396             value &= mask;
1397 
1398             value |= cpu->env.v7m.fpccr[M_REG_NS];
1399             return value;
1400         }
1401     case 0xf38: /* FPCAR */
1402         if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
1403             return 0;
1404         }
1405         return cpu->env.v7m.fpcar[attrs.secure];
1406     case 0xf3c: /* FPDSCR */
1407         if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
1408             return 0;
1409         }
1410         return cpu->env.v7m.fpdscr[attrs.secure];
1411     case 0xf40: /* MVFR0 */
1412         return cpu->isar.mvfr0;
1413     case 0xf44: /* MVFR1 */
1414         return cpu->isar.mvfr1;
1415     case 0xf48: /* MVFR2 */
1416         return cpu->isar.mvfr2;
1417     default:
1418     bad_offset:
1419         qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
1420         return 0;
1421     }
1422 }
1423 
1424 static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
1425                         MemTxAttrs attrs)
1426 {
1427     ARMCPU *cpu = s->cpu;
1428 
1429     switch (offset) {
1430     case 0xc: /* CPPWR */
1431         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1432             goto bad_offset;
1433         }
1434         /* Make the IMPDEF choice to RAZ/WI this. */
1435         break;
1436     case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
1437     {
1438         int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ;
1439         int i;
1440 
1441         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1442             goto bad_offset;
1443         }
1444         if (!attrs.secure) {
1445             break;
1446         }
1447         for (i = 0; i < 32 && startvec + i < s->num_irq; i++) {
1448             s->itns[startvec + i] = (value >> i) & 1;
1449         }
1450         nvic_irq_update(s);
1451         break;
1452     }
1453     case 0xd04: /* Interrupt Control State (ICSR) */
1454         if (attrs.secure || cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
1455             if (value & (1 << 31)) {
1456                 armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
1457             } else if (value & (1 << 30) &&
1458                        arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1459                 /* PENDNMICLR didn't exist in v7M */
1460                 armv7m_nvic_clear_pending(s, ARMV7M_EXCP_NMI, false);
1461             }
1462         }
1463         if (value & (1 << 28)) {
1464             armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure);
1465         } else if (value & (1 << 27)) {
1466             armv7m_nvic_clear_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure);
1467         }
1468         if (value & (1 << 26)) {
1469             armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure);
1470         } else if (value & (1 << 25)) {
1471             armv7m_nvic_clear_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure);
1472         }
1473         break;
1474     case 0xd08: /* Vector Table Offset.  */
1475         cpu->env.v7m.vecbase[attrs.secure] = value & 0xffffff80;
1476         break;
1477     case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */
1478         if ((value >> R_V7M_AIRCR_VECTKEY_SHIFT) == 0x05fa) {
1479             if (value & R_V7M_AIRCR_SYSRESETREQ_MASK) {
1480                 if (attrs.secure ||
1481                     !(cpu->env.v7m.aircr & R_V7M_AIRCR_SYSRESETREQS_MASK)) {
1482                     qemu_irq_pulse(s->sysresetreq);
1483                 }
1484             }
1485             if (value & R_V7M_AIRCR_VECTCLRACTIVE_MASK) {
1486                 qemu_log_mask(LOG_GUEST_ERROR,
1487                               "Setting VECTCLRACTIVE when not in DEBUG mode "
1488                               "is UNPREDICTABLE\n");
1489             }
1490             if (value & R_V7M_AIRCR_VECTRESET_MASK) {
1491                 /* NB: this bit is RES0 in v8M */
1492                 qemu_log_mask(LOG_GUEST_ERROR,
1493                               "Setting VECTRESET when not in DEBUG mode "
1494                               "is UNPREDICTABLE\n");
1495             }
1496             if (arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1497                 s->prigroup[attrs.secure] =
1498                     extract32(value,
1499                               R_V7M_AIRCR_PRIGROUP_SHIFT,
1500                               R_V7M_AIRCR_PRIGROUP_LENGTH);
1501             }
1502             if (attrs.secure) {
1503                 /* These bits are only writable by secure */
1504                 cpu->env.v7m.aircr = value &
1505                     (R_V7M_AIRCR_SYSRESETREQS_MASK |
1506                      R_V7M_AIRCR_BFHFNMINS_MASK |
1507                      R_V7M_AIRCR_PRIS_MASK);
1508                 /* BFHFNMINS changes the priority of Secure HardFault, and
1509                  * allows a pending Non-secure HardFault to preempt (which
1510                  * we implement by marking it enabled).
1511                  */
1512                 if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
1513                     s->sec_vectors[ARMV7M_EXCP_HARD].prio = -3;
1514                     s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
1515                 } else {
1516                     s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
1517                     s->vectors[ARMV7M_EXCP_HARD].enabled = 0;
1518                 }
1519             }
1520             nvic_irq_update(s);
1521         }
1522         break;
1523     case 0xd10: /* System Control.  */
1524         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
1525             goto bad_offset;
1526         }
1527         /* We don't implement deep-sleep so these bits are RAZ/WI.
1528          * The other bits in the register are banked.
1529          * QEMU's implementation ignores SEVONPEND and SLEEPONEXIT, which
1530          * is architecturally permitted.
1531          */
1532         value &= ~(R_V7M_SCR_SLEEPDEEP_MASK | R_V7M_SCR_SLEEPDEEPS_MASK);
1533         cpu->env.v7m.scr[attrs.secure] = value;
1534         break;
1535     case 0xd14: /* Configuration Control.  */
1536         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1537             goto bad_offset;
1538         }
1539 
1540         /* Enforce RAZ/WI on reserved and must-RAZ/WI bits */
1541         value &= (R_V7M_CCR_STKALIGN_MASK |
1542                   R_V7M_CCR_BFHFNMIGN_MASK |
1543                   R_V7M_CCR_DIV_0_TRP_MASK |
1544                   R_V7M_CCR_UNALIGN_TRP_MASK |
1545                   R_V7M_CCR_USERSETMPEND_MASK |
1546                   R_V7M_CCR_NONBASETHRDENA_MASK);
1547 
1548         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1549             /* v8M makes NONBASETHRDENA and STKALIGN be RES1 */
1550             value |= R_V7M_CCR_NONBASETHRDENA_MASK
1551                 | R_V7M_CCR_STKALIGN_MASK;
1552         }
1553         if (attrs.secure) {
1554             /* the BFHFNMIGN bit is not banked; keep that in the NS copy */
1555             cpu->env.v7m.ccr[M_REG_NS] =
1556                 (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)
1557                 | (value & R_V7M_CCR_BFHFNMIGN_MASK);
1558             value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
1559         }
1560 
1561         cpu->env.v7m.ccr[attrs.secure] = value;
1562         break;
1563     case 0xd24: /* System Handler Control and State (SHCSR) */
1564         if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
1565             goto bad_offset;
1566         }
1567         if (attrs.secure) {
1568             s->sec_vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;
1569             /* Secure HardFault active bit cannot be written */
1570             s->sec_vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0;
1571             s->sec_vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0;
1572             s->sec_vectors[ARMV7M_EXCP_PENDSV].active =
1573                 (value & (1 << 10)) != 0;
1574             s->sec_vectors[ARMV7M_EXCP_SYSTICK].active =
1575                 (value & (1 << 11)) != 0;
1576             s->sec_vectors[ARMV7M_EXCP_USAGE].pending =
1577                 (value & (1 << 12)) != 0;
1578             s->sec_vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0;
1579             s->sec_vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0;
1580             s->sec_vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
1581             s->sec_vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
1582             s->sec_vectors[ARMV7M_EXCP_USAGE].enabled =
1583                 (value & (1 << 18)) != 0;
1584             s->sec_vectors[ARMV7M_EXCP_HARD].pending = (value & (1 << 21)) != 0;
1585             /* SecureFault not banked, but RAZ/WI to NS */
1586             s->vectors[ARMV7M_EXCP_SECURE].active = (value & (1 << 4)) != 0;
1587             s->vectors[ARMV7M_EXCP_SECURE].enabled = (value & (1 << 19)) != 0;
1588             s->vectors[ARMV7M_EXCP_SECURE].pending = (value & (1 << 20)) != 0;
1589         } else {
1590             s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;
1591             if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1592                 /* HARDFAULTPENDED is not present in v7M */
1593                 s->vectors[ARMV7M_EXCP_HARD].pending = (value & (1 << 21)) != 0;
1594             }
1595             s->vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0;
1596             s->vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0;
1597             s->vectors[ARMV7M_EXCP_PENDSV].active = (value & (1 << 10)) != 0;
1598             s->vectors[ARMV7M_EXCP_SYSTICK].active = (value & (1 << 11)) != 0;
1599             s->vectors[ARMV7M_EXCP_USAGE].pending = (value & (1 << 12)) != 0;
1600             s->vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0;
1601             s->vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0;
1602             s->vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
1603             s->vectors[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;
1604         }
1605         if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
1606             s->vectors[ARMV7M_EXCP_BUS].active = (value & (1 << 1)) != 0;
1607             s->vectors[ARMV7M_EXCP_BUS].pending = (value & (1 << 14)) != 0;
1608             s->vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
1609         }
1610         /* NMIACT can only be written if the write is of a zero, with
1611          * BFHFNMINS 1, and by the CPU in secure state via the NS alias.
1612          */
1613         if (!attrs.secure && cpu->env.v7m.secure &&
1614             (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&
1615             (value & (1 << 5)) == 0) {
1616             s->vectors[ARMV7M_EXCP_NMI].active = 0;
1617         }
1618         /* HARDFAULTACT can only be written if the write is of a zero
1619          * to the non-secure HardFault state by the CPU in secure state.
1620          * The only case where we can be targeting the non-secure HF state
1621          * when in secure state is if this is a write via the NS alias
1622          * and BFHFNMINS is 1.
1623          */
1624         if (!attrs.secure && cpu->env.v7m.secure &&
1625             (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&
1626             (value & (1 << 2)) == 0) {
1627             s->vectors[ARMV7M_EXCP_HARD].active = 0;
1628         }
1629 
1630         /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */
1631         s->vectors[ARMV7M_EXCP_DEBUG].active = (value & (1 << 8)) != 0;
1632         nvic_irq_update(s);
1633         break;
1634     case 0xd2c: /* Hard Fault Status.  */
1635         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1636             goto bad_offset;
1637         }
1638         cpu->env.v7m.hfsr &= ~value; /* W1C */
1639         break;
1640     case 0xd30: /* Debug Fault Status.  */
1641         cpu->env.v7m.dfsr &= ~value; /* W1C */
1642         break;
1643     case 0xd34: /* Mem Manage Address.  */
1644         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1645             goto bad_offset;
1646         }
1647         cpu->env.v7m.mmfar[attrs.secure] = value;
1648         return;
1649     case 0xd38: /* Bus Fault Address.  */
1650         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1651             goto bad_offset;
1652         }
1653         if (!attrs.secure &&
1654             !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
1655             return;
1656         }
1657         cpu->env.v7m.bfar = value;
1658         return;
1659     case 0xd3c: /* Aux Fault Status.  */
1660         qemu_log_mask(LOG_UNIMP,
1661                       "NVIC: Aux fault status registers unimplemented\n");
1662         break;
1663     case 0xd84: /* CSSELR */
1664         if (!arm_v7m_csselr_razwi(cpu)) {
1665             cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK;
1666         }
1667         break;
1668     case 0xd88: /* CPACR */
1669         if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
1670             /* We implement only the Floating Point extension's CP10/CP11 */
1671             cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
1672         }
1673         break;
1674     case 0xd8c: /* NSACR */
1675         if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
1676             /* We implement only the Floating Point extension's CP10/CP11 */
1677             cpu->env.v7m.nsacr = value & (3 << 10);
1678         }
1679         break;
1680     case 0xd90: /* MPU_TYPE */
1681         return; /* RO */
1682     case 0xd94: /* MPU_CTRL */
1683         if ((value &
1684              (R_V7M_MPU_CTRL_HFNMIENA_MASK | R_V7M_MPU_CTRL_ENABLE_MASK))
1685             == R_V7M_MPU_CTRL_HFNMIENA_MASK) {
1686             qemu_log_mask(LOG_GUEST_ERROR, "MPU_CTRL: HFNMIENA and !ENABLE is "
1687                           "UNPREDICTABLE\n");
1688         }
1689         cpu->env.v7m.mpu_ctrl[attrs.secure]
1690             = value & (R_V7M_MPU_CTRL_ENABLE_MASK |
1691                        R_V7M_MPU_CTRL_HFNMIENA_MASK |
1692                        R_V7M_MPU_CTRL_PRIVDEFENA_MASK);
1693         tlb_flush(CPU(cpu));
1694         break;
1695     case 0xd98: /* MPU_RNR */
1696         if (value >= cpu->pmsav7_dregion) {
1697             qemu_log_mask(LOG_GUEST_ERROR, "MPU region out of range %"
1698                           PRIu32 "/%" PRIu32 "\n",
1699                           value, cpu->pmsav7_dregion);
1700         } else {
1701             cpu->env.pmsav7.rnr[attrs.secure] = value;
1702         }
1703         break;
1704     case 0xd9c: /* MPU_RBAR */
1705     case 0xda4: /* MPU_RBAR_A1 */
1706     case 0xdac: /* MPU_RBAR_A2 */
1707     case 0xdb4: /* MPU_RBAR_A3 */
1708     {
1709         int region;
1710 
1711         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1712             /* PMSAv8M handling of the aliases is different from v7M:
1713              * aliases A1, A2, A3 override the low two bits of the region
1714              * number in MPU_RNR, and there is no 'region' field in the
1715              * RBAR register.
1716              */
1717             int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
1718 
1719             region = cpu->env.pmsav7.rnr[attrs.secure];
1720             if (aliasno) {
1721                 region = deposit32(region, 0, 2, aliasno);
1722             }
1723             if (region >= cpu->pmsav7_dregion) {
1724                 return;
1725             }
1726             cpu->env.pmsav8.rbar[attrs.secure][region] = value;
1727             tlb_flush(CPU(cpu));
1728             return;
1729         }
1730 
1731         if (value & (1 << 4)) {
1732             /* VALID bit means use the region number specified in this
1733              * value and also update MPU_RNR.REGION with that value.
1734              */
1735             region = extract32(value, 0, 4);
1736             if (region >= cpu->pmsav7_dregion) {
1737                 qemu_log_mask(LOG_GUEST_ERROR,
1738                               "MPU region out of range %u/%" PRIu32 "\n",
1739                               region, cpu->pmsav7_dregion);
1740                 return;
1741             }
1742             cpu->env.pmsav7.rnr[attrs.secure] = region;
1743         } else {
1744             region = cpu->env.pmsav7.rnr[attrs.secure];
1745         }
1746 
1747         if (region >= cpu->pmsav7_dregion) {
1748             return;
1749         }
1750 
1751         cpu->env.pmsav7.drbar[region] = value & ~0x1f;
1752         tlb_flush(CPU(cpu));
1753         break;
1754     }
1755     case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
1756     case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
1757     case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
1758     case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
1759     {
1760         int region = cpu->env.pmsav7.rnr[attrs.secure];
1761 
1762         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1763             /* PMSAv8M handling of the aliases is different from v7M:
1764              * aliases A1, A2, A3 override the low two bits of the region
1765              * number in MPU_RNR.
1766              */
1767             int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
1768 
1769             region = cpu->env.pmsav7.rnr[attrs.secure];
1770             if (aliasno) {
1771                 region = deposit32(region, 0, 2, aliasno);
1772             }
1773             if (region >= cpu->pmsav7_dregion) {
1774                 return;
1775             }
1776             cpu->env.pmsav8.rlar[attrs.secure][region] = value;
1777             tlb_flush(CPU(cpu));
1778             return;
1779         }
1780 
1781         if (region >= cpu->pmsav7_dregion) {
1782             return;
1783         }
1784 
1785         cpu->env.pmsav7.drsr[region] = value & 0xff3f;
1786         cpu->env.pmsav7.dracr[region] = (value >> 16) & 0x173f;
1787         tlb_flush(CPU(cpu));
1788         break;
1789     }
1790     case 0xdc0: /* MPU_MAIR0 */
1791         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1792             goto bad_offset;
1793         }
1794         if (cpu->pmsav7_dregion) {
1795             /* Register is RES0 if no MPU regions are implemented */
1796             cpu->env.pmsav8.mair0[attrs.secure] = value;
1797         }
1798         /* We don't need to do anything else because memory attributes
1799          * only affect cacheability, and we don't implement caching.
1800          */
1801         break;
1802     case 0xdc4: /* MPU_MAIR1 */
1803         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1804             goto bad_offset;
1805         }
1806         if (cpu->pmsav7_dregion) {
1807             /* Register is RES0 if no MPU regions are implemented */
1808             cpu->env.pmsav8.mair1[attrs.secure] = value;
1809         }
1810         /* We don't need to do anything else because memory attributes
1811          * only affect cacheability, and we don't implement caching.
1812          */
1813         break;
1814     case 0xdd0: /* SAU_CTRL */
1815         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1816             goto bad_offset;
1817         }
1818         if (!attrs.secure) {
1819             return;
1820         }
1821         cpu->env.sau.ctrl = value & 3;
1822         break;
1823     case 0xdd4: /* SAU_TYPE */
1824         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1825             goto bad_offset;
1826         }
1827         break;
1828     case 0xdd8: /* SAU_RNR */
1829         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1830             goto bad_offset;
1831         }
1832         if (!attrs.secure) {
1833             return;
1834         }
1835         if (value >= cpu->sau_sregion) {
1836             qemu_log_mask(LOG_GUEST_ERROR, "SAU region out of range %"
1837                           PRIu32 "/%" PRIu32 "\n",
1838                           value, cpu->sau_sregion);
1839         } else {
1840             cpu->env.sau.rnr = value;
1841         }
1842         break;
1843     case 0xddc: /* SAU_RBAR */
1844     {
1845         int region = cpu->env.sau.rnr;
1846 
1847         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1848             goto bad_offset;
1849         }
1850         if (!attrs.secure) {
1851             return;
1852         }
1853         if (region >= cpu->sau_sregion) {
1854             return;
1855         }
1856         cpu->env.sau.rbar[region] = value & ~0x1f;
1857         tlb_flush(CPU(cpu));
1858         break;
1859     }
1860     case 0xde0: /* SAU_RLAR */
1861     {
1862         int region = cpu->env.sau.rnr;
1863 
1864         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1865             goto bad_offset;
1866         }
1867         if (!attrs.secure) {
1868             return;
1869         }
1870         if (region >= cpu->sau_sregion) {
1871             return;
1872         }
1873         cpu->env.sau.rlar[region] = value & ~0x1c;
1874         tlb_flush(CPU(cpu));
1875         break;
1876     }
1877     case 0xde4: /* SFSR */
1878         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1879             goto bad_offset;
1880         }
1881         if (!attrs.secure) {
1882             return;
1883         }
1884         cpu->env.v7m.sfsr &= ~value; /* W1C */
1885         break;
1886     case 0xde8: /* SFAR */
1887         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1888             goto bad_offset;
1889         }
1890         if (!attrs.secure) {
1891             return;
1892         }
1893         cpu->env.v7m.sfsr = value;
1894         break;
1895     case 0xf00: /* Software Triggered Interrupt Register */
1896     {
1897         int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ;
1898 
1899         if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
1900             goto bad_offset;
1901         }
1902 
1903         if (excnum < s->num_irq) {
1904             armv7m_nvic_set_pending(s, excnum, false);
1905         }
1906         break;
1907     }
1908     case 0xf34: /* FPCCR */
1909         if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
1910             /* Not all bits here are banked. */
1911             uint32_t fpccr_s;
1912 
1913             if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
1914                 /* Don't allow setting of bits not present in v7M */
1915                 value &= (R_V7M_FPCCR_LSPACT_MASK |
1916                           R_V7M_FPCCR_USER_MASK |
1917                           R_V7M_FPCCR_THREAD_MASK |
1918                           R_V7M_FPCCR_HFRDY_MASK |
1919                           R_V7M_FPCCR_MMRDY_MASK |
1920                           R_V7M_FPCCR_BFRDY_MASK |
1921                           R_V7M_FPCCR_MONRDY_MASK |
1922                           R_V7M_FPCCR_LSPEN_MASK |
1923                           R_V7M_FPCCR_ASPEN_MASK);
1924             }
1925             value &= ~R_V7M_FPCCR_RES0_MASK;
1926 
1927             if (!attrs.secure) {
1928                 /* Some non-banked bits are configurably writable by NS */
1929                 fpccr_s = cpu->env.v7m.fpccr[M_REG_S];
1930                 if (!(fpccr_s & R_V7M_FPCCR_LSPENS_MASK)) {
1931                     uint32_t lspen = FIELD_EX32(value, V7M_FPCCR, LSPEN);
1932                     fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, LSPEN, lspen);
1933                 }
1934                 if (!(fpccr_s & R_V7M_FPCCR_CLRONRETS_MASK)) {
1935                     uint32_t cor = FIELD_EX32(value, V7M_FPCCR, CLRONRET);
1936                     fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, CLRONRET, cor);
1937                 }
1938                 if ((s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
1939                     uint32_t hfrdy = FIELD_EX32(value, V7M_FPCCR, HFRDY);
1940                     uint32_t bfrdy = FIELD_EX32(value, V7M_FPCCR, BFRDY);
1941                     fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
1942                     fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
1943                 }
1944                 /* TODO MONRDY should RAZ/WI if DEMCR.SDME is set */
1945                 {
1946                     uint32_t monrdy = FIELD_EX32(value, V7M_FPCCR, MONRDY);
1947                     fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, MONRDY, monrdy);
1948                 }
1949 
1950                 /*
1951                  * All other non-banked bits are RAZ/WI from NS; write
1952                  * just the banked bits to fpccr[M_REG_NS].
1953                  */
1954                 value &= R_V7M_FPCCR_BANKED_MASK;
1955                 cpu->env.v7m.fpccr[M_REG_NS] = value;
1956             } else {
1957                 fpccr_s = value;
1958             }
1959             cpu->env.v7m.fpccr[M_REG_S] = fpccr_s;
1960         }
1961         break;
1962     case 0xf38: /* FPCAR */
1963         if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
1964             value &= ~7;
1965             cpu->env.v7m.fpcar[attrs.secure] = value;
1966         }
1967         break;
1968     case 0xf3c: /* FPDSCR */
1969         if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
1970             value &= 0x07c00000;
1971             cpu->env.v7m.fpdscr[attrs.secure] = value;
1972         }
1973         break;
1974     case 0xf50: /* ICIALLU */
1975     case 0xf58: /* ICIMVAU */
1976     case 0xf5c: /* DCIMVAC */
1977     case 0xf60: /* DCISW */
1978     case 0xf64: /* DCCMVAU */
1979     case 0xf68: /* DCCMVAC */
1980     case 0xf6c: /* DCCSW */
1981     case 0xf70: /* DCCIMVAC */
1982     case 0xf74: /* DCCISW */
1983     case 0xf78: /* BPIALL */
1984         /* Cache and branch predictor maintenance: for QEMU these always NOP */
1985         break;
1986     default:
1987     bad_offset:
1988         qemu_log_mask(LOG_GUEST_ERROR,
1989                       "NVIC: Bad write offset 0x%x\n", offset);
1990     }
1991 }
1992 
1993 static bool nvic_user_access_ok(NVICState *s, hwaddr offset, MemTxAttrs attrs)
1994 {
1995     /* Return true if unprivileged access to this register is permitted. */
1996     switch (offset) {
1997     case 0xf00: /* STIR: accessible only if CCR.USERSETMPEND permits */
1998         /* For access via STIR_NS it is the NS CCR.USERSETMPEND that
1999          * controls access even though the CPU is in Secure state (I_QDKX).
2000          */
2001         return s->cpu->env.v7m.ccr[attrs.secure] & R_V7M_CCR_USERSETMPEND_MASK;
2002     default:
2003         /* All other user accesses cause a BusFault unconditionally */
2004         return false;
2005     }
2006 }
2007 
2008 static int shpr_bank(NVICState *s, int exc, MemTxAttrs attrs)
2009 {
2010     /* Behaviour for the SHPR register field for this exception:
2011      * return M_REG_NS to use the nonsecure vector (including for
2012      * non-banked exceptions), M_REG_S for the secure version of
2013      * a banked exception, and -1 if this field should RAZ/WI.
2014      */
2015     switch (exc) {
2016     case ARMV7M_EXCP_MEM:
2017     case ARMV7M_EXCP_USAGE:
2018     case ARMV7M_EXCP_SVC:
2019     case ARMV7M_EXCP_PENDSV:
2020     case ARMV7M_EXCP_SYSTICK:
2021         /* Banked exceptions */
2022         return attrs.secure;
2023     case ARMV7M_EXCP_BUS:
2024         /* Not banked, RAZ/WI from nonsecure if BFHFNMINS is zero */
2025         if (!attrs.secure &&
2026             !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
2027             return -1;
2028         }
2029         return M_REG_NS;
2030     case ARMV7M_EXCP_SECURE:
2031         /* Not banked, RAZ/WI from nonsecure */
2032         if (!attrs.secure) {
2033             return -1;
2034         }
2035         return M_REG_NS;
2036     case ARMV7M_EXCP_DEBUG:
2037         /* Not banked. TODO should RAZ/WI if DEMCR.SDME is set */
2038         return M_REG_NS;
2039     case 8 ... 10:
2040     case 13:
2041         /* RES0 */
2042         return -1;
2043     default:
2044         /* Not reachable due to decode of SHPR register addresses */
2045         g_assert_not_reached();
2046     }
2047 }
2048 
2049 static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
2050                                     uint64_t *data, unsigned size,
2051                                     MemTxAttrs attrs)
2052 {
2053     NVICState *s = (NVICState *)opaque;
2054     uint32_t offset = addr;
2055     unsigned i, startvec, end;
2056     uint32_t val;
2057 
2058     if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
2059         /* Generate BusFault for unprivileged accesses */
2060         return MEMTX_ERROR;
2061     }
2062 
2063     switch (offset) {
2064     /* reads of set and clear both return the status */
2065     case 0x100 ... 0x13f: /* NVIC Set enable */
2066         offset += 0x80;
2067         /* fall through */
2068     case 0x180 ... 0x1bf: /* NVIC Clear enable */
2069         val = 0;
2070         startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ; /* vector # */
2071 
2072         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
2073             if (s->vectors[startvec + i].enabled &&
2074                 (attrs.secure || s->itns[startvec + i])) {
2075                 val |= (1 << i);
2076             }
2077         }
2078         break;
2079     case 0x200 ... 0x23f: /* NVIC Set pend */
2080         offset += 0x80;
2081         /* fall through */
2082     case 0x280 ... 0x2bf: /* NVIC Clear pend */
2083         val = 0;
2084         startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */
2085         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
2086             if (s->vectors[startvec + i].pending &&
2087                 (attrs.secure || s->itns[startvec + i])) {
2088                 val |= (1 << i);
2089             }
2090         }
2091         break;
2092     case 0x300 ... 0x33f: /* NVIC Active */
2093         val = 0;
2094 
2095         if (!arm_feature(&s->cpu->env, ARM_FEATURE_V7)) {
2096             break;
2097         }
2098 
2099         startvec = 8 * (offset - 0x300) + NVIC_FIRST_IRQ; /* vector # */
2100 
2101         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
2102             if (s->vectors[startvec + i].active &&
2103                 (attrs.secure || s->itns[startvec + i])) {
2104                 val |= (1 << i);
2105             }
2106         }
2107         break;
2108     case 0x400 ... 0x5ef: /* NVIC Priority */
2109         val = 0;
2110         startvec = offset - 0x400 + NVIC_FIRST_IRQ; /* vector # */
2111 
2112         for (i = 0; i < size && startvec + i < s->num_irq; i++) {
2113             if (attrs.secure || s->itns[startvec + i]) {
2114                 val |= s->vectors[startvec + i].prio << (8 * i);
2115             }
2116         }
2117         break;
2118     case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
2119         if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
2120             val = 0;
2121             break;
2122         }
2123         /* fall through */
2124     case 0xd1c ... 0xd23: /* System Handler Priority (SHPR2, SHPR3) */
2125         val = 0;
2126         for (i = 0; i < size; i++) {
2127             unsigned hdlidx = (offset - 0xd14) + i;
2128             int sbank = shpr_bank(s, hdlidx, attrs);
2129 
2130             if (sbank < 0) {
2131                 continue;
2132             }
2133             val = deposit32(val, i * 8, 8, get_prio(s, hdlidx, sbank));
2134         }
2135         break;
2136     case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
2137         if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
2138             val = 0;
2139             break;
2140         };
2141         /*
2142          * The BFSR bits [15:8] are shared between security states
2143          * and we store them in the NS copy. They are RAZ/WI for
2144          * NS code if AIRCR.BFHFNMINS is 0.
2145          */
2146         val = s->cpu->env.v7m.cfsr[attrs.secure];
2147         if (!attrs.secure &&
2148             !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
2149             val &= ~R_V7M_CFSR_BFSR_MASK;
2150         } else {
2151             val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
2152         }
2153         val = extract32(val, (offset - 0xd28) * 8, size * 8);
2154         break;
2155     case 0xfe0 ... 0xfff: /* ID.  */
2156         if (offset & 3) {
2157             val = 0;
2158         } else {
2159             val = nvic_id[(offset - 0xfe0) >> 2];
2160         }
2161         break;
2162     default:
2163         if (size == 4) {
2164             val = nvic_readl(s, offset, attrs);
2165         } else {
2166             qemu_log_mask(LOG_GUEST_ERROR,
2167                           "NVIC: Bad read of size %d at offset 0x%x\n",
2168                           size, offset);
2169             val = 0;
2170         }
2171     }
2172 
2173     trace_nvic_sysreg_read(addr, val, size);
2174     *data = val;
2175     return MEMTX_OK;
2176 }
2177 
2178 static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
2179                                      uint64_t value, unsigned size,
2180                                      MemTxAttrs attrs)
2181 {
2182     NVICState *s = (NVICState *)opaque;
2183     uint32_t offset = addr;
2184     unsigned i, startvec, end;
2185     unsigned setval = 0;
2186 
2187     trace_nvic_sysreg_write(addr, value, size);
2188 
2189     if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
2190         /* Generate BusFault for unprivileged accesses */
2191         return MEMTX_ERROR;
2192     }
2193 
2194     switch (offset) {
2195     case 0x100 ... 0x13f: /* NVIC Set enable */
2196         offset += 0x80;
2197         setval = 1;
2198         /* fall through */
2199     case 0x180 ... 0x1bf: /* NVIC Clear enable */
2200         startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ;
2201 
2202         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
2203             if (value & (1 << i) &&
2204                 (attrs.secure || s->itns[startvec + i])) {
2205                 s->vectors[startvec + i].enabled = setval;
2206             }
2207         }
2208         nvic_irq_update(s);
2209         return MEMTX_OK;
2210     case 0x200 ... 0x23f: /* NVIC Set pend */
2211         /* the special logic in armv7m_nvic_set_pending()
2212          * is not needed since IRQs are never escalated
2213          */
2214         offset += 0x80;
2215         setval = 1;
2216         /* fall through */
2217     case 0x280 ... 0x2bf: /* NVIC Clear pend */
2218         startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */
2219 
2220         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
2221             if (value & (1 << i) &&
2222                 (attrs.secure || s->itns[startvec + i])) {
2223                 s->vectors[startvec + i].pending = setval;
2224             }
2225         }
2226         nvic_irq_update(s);
2227         return MEMTX_OK;
2228     case 0x300 ... 0x33f: /* NVIC Active */
2229         return MEMTX_OK; /* R/O */
2230     case 0x400 ... 0x5ef: /* NVIC Priority */
2231         startvec = (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
2232 
2233         for (i = 0; i < size && startvec + i < s->num_irq; i++) {
2234             if (attrs.secure || s->itns[startvec + i]) {
2235                 set_prio(s, startvec + i, false, (value >> (i * 8)) & 0xff);
2236             }
2237         }
2238         nvic_irq_update(s);
2239         return MEMTX_OK;
2240     case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
2241         if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
2242             return MEMTX_OK;
2243         }
2244         /* fall through */
2245     case 0xd1c ... 0xd23: /* System Handler Priority (SHPR2, SHPR3) */
2246         for (i = 0; i < size; i++) {
2247             unsigned hdlidx = (offset - 0xd14) + i;
2248             int newprio = extract32(value, i * 8, 8);
2249             int sbank = shpr_bank(s, hdlidx, attrs);
2250 
2251             if (sbank < 0) {
2252                 continue;
2253             }
2254             set_prio(s, hdlidx, sbank, newprio);
2255         }
2256         nvic_irq_update(s);
2257         return MEMTX_OK;
2258     case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
2259         if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
2260             return MEMTX_OK;
2261         }
2262         /* All bits are W1C, so construct 32 bit value with 0s in
2263          * the parts not written by the access size
2264          */
2265         value <<= ((offset - 0xd28) * 8);
2266 
2267         if (!attrs.secure &&
2268             !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
2269             /* BFSR bits are RAZ/WI for NS if BFHFNMINS is set */
2270             value &= ~R_V7M_CFSR_BFSR_MASK;
2271         }
2272 
2273         s->cpu->env.v7m.cfsr[attrs.secure] &= ~value;
2274         if (attrs.secure) {
2275             /* The BFSR bits [15:8] are shared between security states
2276              * and we store them in the NS copy.
2277              */
2278             s->cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
2279         }
2280         return MEMTX_OK;
2281     }
2282     if (size == 4) {
2283         nvic_writel(s, offset, value, attrs);
2284         return MEMTX_OK;
2285     }
2286     qemu_log_mask(LOG_GUEST_ERROR,
2287                   "NVIC: Bad write of size %d at offset 0x%x\n", size, offset);
2288     /* This is UNPREDICTABLE; treat as RAZ/WI */
2289     return MEMTX_OK;
2290 }
2291 
2292 static const MemoryRegionOps nvic_sysreg_ops = {
2293     .read_with_attrs = nvic_sysreg_read,
2294     .write_with_attrs = nvic_sysreg_write,
2295     .endianness = DEVICE_NATIVE_ENDIAN,
2296 };
2297 
2298 static MemTxResult nvic_sysreg_ns_write(void *opaque, hwaddr addr,
2299                                         uint64_t value, unsigned size,
2300                                         MemTxAttrs attrs)
2301 {
2302     MemoryRegion *mr = opaque;
2303 
2304     if (attrs.secure) {
2305         /* S accesses to the alias act like NS accesses to the real region */
2306         attrs.secure = 0;
2307         return memory_region_dispatch_write(mr, addr, value, size, attrs);
2308     } else {
2309         /* NS attrs are RAZ/WI for privileged, and BusFault for user */
2310         if (attrs.user) {
2311             return MEMTX_ERROR;
2312         }
2313         return MEMTX_OK;
2314     }
2315 }
2316 
2317 static MemTxResult nvic_sysreg_ns_read(void *opaque, hwaddr addr,
2318                                        uint64_t *data, unsigned size,
2319                                        MemTxAttrs attrs)
2320 {
2321     MemoryRegion *mr = opaque;
2322 
2323     if (attrs.secure) {
2324         /* S accesses to the alias act like NS accesses to the real region */
2325         attrs.secure = 0;
2326         return memory_region_dispatch_read(mr, addr, data, size, attrs);
2327     } else {
2328         /* NS attrs are RAZ/WI for privileged, and BusFault for user */
2329         if (attrs.user) {
2330             return MEMTX_ERROR;
2331         }
2332         *data = 0;
2333         return MEMTX_OK;
2334     }
2335 }
2336 
2337 static const MemoryRegionOps nvic_sysreg_ns_ops = {
2338     .read_with_attrs = nvic_sysreg_ns_read,
2339     .write_with_attrs = nvic_sysreg_ns_write,
2340     .endianness = DEVICE_NATIVE_ENDIAN,
2341 };
2342 
2343 static MemTxResult nvic_systick_write(void *opaque, hwaddr addr,
2344                                       uint64_t value, unsigned size,
2345                                       MemTxAttrs attrs)
2346 {
2347     NVICState *s = opaque;
2348     MemoryRegion *mr;
2349 
2350     /* Direct the access to the correct systick */
2351     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
2352     return memory_region_dispatch_write(mr, addr, value, size, attrs);
2353 }
2354 
2355 static MemTxResult nvic_systick_read(void *opaque, hwaddr addr,
2356                                      uint64_t *data, unsigned size,
2357                                      MemTxAttrs attrs)
2358 {
2359     NVICState *s = opaque;
2360     MemoryRegion *mr;
2361 
2362     /* Direct the access to the correct systick */
2363     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
2364     return memory_region_dispatch_read(mr, addr, data, size, attrs);
2365 }
2366 
2367 static const MemoryRegionOps nvic_systick_ops = {
2368     .read_with_attrs = nvic_systick_read,
2369     .write_with_attrs = nvic_systick_write,
2370     .endianness = DEVICE_NATIVE_ENDIAN,
2371 };
2372 
2373 static int nvic_post_load(void *opaque, int version_id)
2374 {
2375     NVICState *s = opaque;
2376     unsigned i;
2377     int resetprio;
2378 
2379     /* Check for out of range priority settings */
2380     resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3;
2381 
2382     if (s->vectors[ARMV7M_EXCP_RESET].prio != resetprio ||
2383         s->vectors[ARMV7M_EXCP_NMI].prio != -2 ||
2384         s->vectors[ARMV7M_EXCP_HARD].prio != -1) {
2385         return 1;
2386     }
2387     for (i = ARMV7M_EXCP_MEM; i < s->num_irq; i++) {
2388         if (s->vectors[i].prio & ~0xff) {
2389             return 1;
2390         }
2391     }
2392 
2393     nvic_recompute_state(s);
2394 
2395     return 0;
2396 }
2397 
2398 static const VMStateDescription vmstate_VecInfo = {
2399     .name = "armv7m_nvic_info",
2400     .version_id = 1,
2401     .minimum_version_id = 1,
2402     .fields = (VMStateField[]) {
2403         VMSTATE_INT16(prio, VecInfo),
2404         VMSTATE_UINT8(enabled, VecInfo),
2405         VMSTATE_UINT8(pending, VecInfo),
2406         VMSTATE_UINT8(active, VecInfo),
2407         VMSTATE_UINT8(level, VecInfo),
2408         VMSTATE_END_OF_LIST()
2409     }
2410 };
2411 
2412 static bool nvic_security_needed(void *opaque)
2413 {
2414     NVICState *s = opaque;
2415 
2416     return arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY);
2417 }
2418 
2419 static int nvic_security_post_load(void *opaque, int version_id)
2420 {
2421     NVICState *s = opaque;
2422     int i;
2423 
2424     /* Check for out of range priority settings */
2425     if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1
2426         && s->sec_vectors[ARMV7M_EXCP_HARD].prio != -3) {
2427         /* We can't cross-check against AIRCR.BFHFNMINS as we don't know
2428          * if the CPU state has been migrated yet; a mismatch won't
2429          * cause the emulation to blow up, though.
2430          */
2431         return 1;
2432     }
2433     for (i = ARMV7M_EXCP_MEM; i < ARRAY_SIZE(s->sec_vectors); i++) {
2434         if (s->sec_vectors[i].prio & ~0xff) {
2435             return 1;
2436         }
2437     }
2438     return 0;
2439 }
2440 
2441 static const VMStateDescription vmstate_nvic_security = {
2442     .name = "armv7m_nvic/m-security",
2443     .version_id = 1,
2444     .minimum_version_id = 1,
2445     .needed = nvic_security_needed,
2446     .post_load = &nvic_security_post_load,
2447     .fields = (VMStateField[]) {
2448         VMSTATE_STRUCT_ARRAY(sec_vectors, NVICState, NVIC_INTERNAL_VECTORS, 1,
2449                              vmstate_VecInfo, VecInfo),
2450         VMSTATE_UINT32(prigroup[M_REG_S], NVICState),
2451         VMSTATE_BOOL_ARRAY(itns, NVICState, NVIC_MAX_VECTORS),
2452         VMSTATE_END_OF_LIST()
2453     }
2454 };
2455 
2456 static const VMStateDescription vmstate_nvic = {
2457     .name = "armv7m_nvic",
2458     .version_id = 4,
2459     .minimum_version_id = 4,
2460     .post_load = &nvic_post_load,
2461     .fields = (VMStateField[]) {
2462         VMSTATE_STRUCT_ARRAY(vectors, NVICState, NVIC_MAX_VECTORS, 1,
2463                              vmstate_VecInfo, VecInfo),
2464         VMSTATE_UINT32(prigroup[M_REG_NS], NVICState),
2465         VMSTATE_END_OF_LIST()
2466     },
2467     .subsections = (const VMStateDescription*[]) {
2468         &vmstate_nvic_security,
2469         NULL
2470     }
2471 };
2472 
2473 static Property props_nvic[] = {
2474     /* Number of external IRQ lines (so excluding the 16 internal exceptions) */
2475     DEFINE_PROP_UINT32("num-irq", NVICState, num_irq, 64),
2476     DEFINE_PROP_END_OF_LIST()
2477 };
2478 
2479 static void armv7m_nvic_reset(DeviceState *dev)
2480 {
2481     int resetprio;
2482     NVICState *s = NVIC(dev);
2483 
2484     memset(s->vectors, 0, sizeof(s->vectors));
2485     memset(s->sec_vectors, 0, sizeof(s->sec_vectors));
2486     s->prigroup[M_REG_NS] = 0;
2487     s->prigroup[M_REG_S] = 0;
2488 
2489     s->vectors[ARMV7M_EXCP_NMI].enabled = 1;
2490     /* MEM, BUS, and USAGE are enabled through
2491      * the System Handler Control register
2492      */
2493     s->vectors[ARMV7M_EXCP_SVC].enabled = 1;
2494     s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
2495     s->vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
2496 
2497     /* DebugMonitor is enabled via DEMCR.MON_EN */
2498     s->vectors[ARMV7M_EXCP_DEBUG].enabled = 0;
2499 
2500     resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3;
2501     s->vectors[ARMV7M_EXCP_RESET].prio = resetprio;
2502     s->vectors[ARMV7M_EXCP_NMI].prio = -2;
2503     s->vectors[ARMV7M_EXCP_HARD].prio = -1;
2504 
2505     if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
2506         s->sec_vectors[ARMV7M_EXCP_HARD].enabled = 1;
2507         s->sec_vectors[ARMV7M_EXCP_SVC].enabled = 1;
2508         s->sec_vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
2509         s->sec_vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
2510 
2511         /* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC) */
2512         s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
2513         /* If AIRCR.BFHFNMINS is 0 then NS HF is (effectively) disabled */
2514         s->vectors[ARMV7M_EXCP_HARD].enabled = 0;
2515     } else {
2516         s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
2517     }
2518 
2519     /* Strictly speaking the reset handler should be enabled.
2520      * However, we don't simulate soft resets through the NVIC,
2521      * and the reset vector should never be pended.
2522      * So we leave it disabled to catch logic errors.
2523      */
2524 
2525     s->exception_prio = NVIC_NOEXC_PRIO;
2526     s->vectpending = 0;
2527     s->vectpending_is_s_banked = false;
2528     s->vectpending_prio = NVIC_NOEXC_PRIO;
2529 
2530     if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
2531         memset(s->itns, 0, sizeof(s->itns));
2532     } else {
2533         /* This state is constant and not guest accessible in a non-security
2534          * NVIC; we set the bits to true to avoid having to do a feature
2535          * bit check in the NVIC enable/pend/etc register accessors.
2536          */
2537         int i;
2538 
2539         for (i = NVIC_FIRST_IRQ; i < ARRAY_SIZE(s->itns); i++) {
2540             s->itns[i] = true;
2541         }
2542     }
2543 }
2544 
2545 static void nvic_systick_trigger(void *opaque, int n, int level)
2546 {
2547     NVICState *s = opaque;
2548 
2549     if (level) {
2550         /* SysTick just asked us to pend its exception.
2551          * (This is different from an external interrupt line's
2552          * behaviour.)
2553          * n == 0 : NonSecure systick
2554          * n == 1 : Secure systick
2555          */
2556         armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, n);
2557     }
2558 }
2559 
2560 static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
2561 {
2562     NVICState *s = NVIC(dev);
2563     Error *err = NULL;
2564     int regionlen;
2565 
2566     /* The armv7m container object will have set our CPU pointer */
2567     if (!s->cpu || !arm_feature(&s->cpu->env, ARM_FEATURE_M)) {
2568         error_setg(errp, "The NVIC can only be used with a Cortex-M CPU");
2569         return;
2570     }
2571 
2572     if (s->num_irq > NVIC_MAX_IRQ) {
2573         error_setg(errp, "num-irq %d exceeds NVIC maximum", s->num_irq);
2574         return;
2575     }
2576 
2577     qdev_init_gpio_in(dev, set_irq_level, s->num_irq);
2578 
2579     /* include space for internal exception vectors */
2580     s->num_irq += NVIC_FIRST_IRQ;
2581 
2582     s->num_prio_bits = arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 8 : 2;
2583 
2584     object_property_set_bool(OBJECT(&s->systick[M_REG_NS]), true,
2585                              "realized", &err);
2586     if (err != NULL) {
2587         error_propagate(errp, err);
2588         return;
2589     }
2590     sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), 0,
2591                        qdev_get_gpio_in_named(dev, "systick-trigger",
2592                                               M_REG_NS));
2593 
2594     if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
2595         /* We couldn't init the secure systick device in instance_init
2596          * as we didn't know then if the CPU had the security extensions;
2597          * so we have to do it here.
2598          */
2599         object_initialize(&s->systick[M_REG_S], sizeof(s->systick[M_REG_S]),
2600                           TYPE_SYSTICK);
2601         qdev_set_parent_bus(DEVICE(&s->systick[M_REG_S]), sysbus_get_default());
2602 
2603         object_property_set_bool(OBJECT(&s->systick[M_REG_S]), true,
2604                                  "realized", &err);
2605         if (err != NULL) {
2606             error_propagate(errp, err);
2607             return;
2608         }
2609         sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_S]), 0,
2610                            qdev_get_gpio_in_named(dev, "systick-trigger",
2611                                                   M_REG_S));
2612     }
2613 
2614     /* The NVIC and System Control Space (SCS) starts at 0xe000e000
2615      * and looks like this:
2616      *  0x004 - ICTR
2617      *  0x010 - 0xff - systick
2618      *  0x100..0x7ec - NVIC
2619      *  0x7f0..0xcff - Reserved
2620      *  0xd00..0xd3c - SCS registers
2621      *  0xd40..0xeff - Reserved or Not implemented
2622      *  0xf00 - STIR
2623      *
2624      * Some registers within this space are banked between security states.
2625      * In v8M there is a second range 0xe002e000..0xe002efff which is the
2626      * NonSecure alias SCS; secure accesses to this behave like NS accesses
2627      * to the main SCS range, and non-secure accesses (including when
2628      * the security extension is not implemented) are RAZ/WI.
2629      * Note that both the main SCS range and the alias range are defined
2630      * to be exempt from memory attribution (R_BLJT) and so the memory
2631      * transaction attribute always matches the current CPU security
2632      * state (attrs.secure == env->v7m.secure). In the nvic_sysreg_ns_ops
2633      * wrappers we change attrs.secure to indicate the NS access; so
2634      * generally code determining which banked register to use should
2635      * use attrs.secure; code determining actual behaviour of the system
2636      * should use env->v7m.secure.
2637      */
2638     regionlen = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? 0x21000 : 0x1000;
2639     memory_region_init(&s->container, OBJECT(s), "nvic", regionlen);
2640     /* The system register region goes at the bottom of the priority
2641      * stack as it covers the whole page.
2642      */
2643     memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
2644                           "nvic_sysregs", 0x1000);
2645     memory_region_add_subregion(&s->container, 0, &s->sysregmem);
2646 
2647     memory_region_init_io(&s->systickmem, OBJECT(s),
2648                           &nvic_systick_ops, s,
2649                           "nvic_systick", 0xe0);
2650 
2651     memory_region_add_subregion_overlap(&s->container, 0x10,
2652                                         &s->systickmem, 1);
2653 
2654     if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
2655         memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
2656                               &nvic_sysreg_ns_ops, &s->sysregmem,
2657                               "nvic_sysregs_ns", 0x1000);
2658         memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
2659         memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
2660                               &nvic_sysreg_ns_ops, &s->systickmem,
2661                               "nvic_systick_ns", 0xe0);
2662         memory_region_add_subregion_overlap(&s->container, 0x20010,
2663                                             &s->systick_ns_mem, 1);
2664     }
2665 
2666     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
2667 }
2668 
2669 static void armv7m_nvic_instance_init(Object *obj)
2670 {
2671     /* We have a different default value for the num-irq property
2672      * than our superclass. This function runs after qdev init
2673      * has set the defaults from the Property array and before
2674      * any user-specified property setting, so just modify the
2675      * value in the GICState struct.
2676      */
2677     DeviceState *dev = DEVICE(obj);
2678     NVICState *nvic = NVIC(obj);
2679     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
2680 
2681     sysbus_init_child_obj(obj, "systick-reg-ns", &nvic->systick[M_REG_NS],
2682                           sizeof(nvic->systick[M_REG_NS]), TYPE_SYSTICK);
2683     /* We can't initialize the secure systick here, as we don't know
2684      * yet if we need it.
2685      */
2686 
2687     sysbus_init_irq(sbd, &nvic->excpout);
2688     qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
2689     qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger",
2690                             M_REG_NUM_BANKS);
2691     qdev_init_gpio_in_named(dev, nvic_nmi_trigger, "NMI", 1);
2692 }
2693 
2694 static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
2695 {
2696     DeviceClass *dc = DEVICE_CLASS(klass);
2697 
2698     dc->vmsd  = &vmstate_nvic;
2699     dc->props = props_nvic;
2700     dc->reset = armv7m_nvic_reset;
2701     dc->realize = armv7m_nvic_realize;
2702 }
2703 
2704 static const TypeInfo armv7m_nvic_info = {
2705     .name          = TYPE_NVIC,
2706     .parent        = TYPE_SYS_BUS_DEVICE,
2707     .instance_init = armv7m_nvic_instance_init,
2708     .instance_size = sizeof(NVICState),
2709     .class_init    = armv7m_nvic_class_init,
2710     .class_size    = sizeof(SysBusDeviceClass),
2711 };
2712 
2713 static void armv7m_nvic_register_types(void)
2714 {
2715     type_register_static(&armv7m_nvic_info);
2716 }
2717 
2718 type_init(armv7m_nvic_register_types)
2719