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