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