xref: /openbmc/qemu/hw/intc/armv7m_nvic.c (revision da1849c1)
1 /*
2  * ARM Nested Vectored Interrupt Controller
3  *
4  * Copyright (c) 2006-2007 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * This code is licensed under the GPL.
8  *
9  * The ARMv7M System controller is fairly tightly tied in with the
10  * NVIC.  Much of that is also implemented here.
11  */
12 
13 #include "qemu/osdep.h"
14 #include "qapi/error.h"
15 #include "qemu-common.h"
16 #include "cpu.h"
17 #include "hw/sysbus.h"
18 #include "qemu/timer.h"
19 #include "hw/arm/arm.h"
20 #include "hw/intc/armv7m_nvic.h"
21 #include "target/arm/cpu.h"
22 #include "exec/exec-all.h"
23 #include "qemu/log.h"
24 #include "trace.h"
25 
26 /* IRQ number counting:
27  *
28  * the num-irq property counts the number of external IRQ lines
29  *
30  * NVICState::num_irq counts the total number of exceptions
31  * (external IRQs, the 15 internal exceptions including reset,
32  * and one for the unused exception number 0).
33  *
34  * NVIC_MAX_IRQ is the highest permitted number of external IRQ lines.
35  *
36  * NVIC_MAX_VECTORS is the highest permitted number of exceptions.
37  *
38  * Iterating through all exceptions should typically be done with
39  * for (i = 1; i < s->num_irq; i++) to avoid the unused slot 0.
40  *
41  * The external qemu_irq lines are the NVIC's external IRQ lines,
42  * so line 0 is exception 16.
43  *
44  * In the terminology of the architecture manual, "interrupts" are
45  * a subcategory of exception referring to the external interrupts
46  * (which are exception numbers NVIC_FIRST_IRQ and upward).
47  * For historical reasons QEMU tends to use "interrupt" and
48  * "exception" more or less interchangeably.
49  */
50 #define NVIC_FIRST_IRQ 16
51 #define NVIC_MAX_IRQ (NVIC_MAX_VECTORS - NVIC_FIRST_IRQ)
52 
53 /* Effective running priority of the CPU when no exception is active
54  * (higher than the highest possible priority value)
55  */
56 #define NVIC_NOEXC_PRIO 0x100
57 
58 static const uint8_t nvic_id[] = {
59     0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1
60 };
61 
62 static int nvic_pending_prio(NVICState *s)
63 {
64     /* return the priority of the current pending interrupt,
65      * or NVIC_NOEXC_PRIO if no interrupt is pending
66      */
67     return s->vectpending ? s->vectors[s->vectpending].prio : NVIC_NOEXC_PRIO;
68 }
69 
70 /* Return the value of the ISCR RETTOBASE bit:
71  * 1 if there is exactly one active exception
72  * 0 if there is more than one active exception
73  * UNKNOWN if there are no active exceptions (we choose 1,
74  * which matches the choice Cortex-M3 is documented as making).
75  *
76  * NB: some versions of the documentation talk about this
77  * counting "active exceptions other than the one shown by IPSR";
78  * this is only different in the obscure corner case where guest
79  * code has manually deactivated an exception and is about
80  * to fail an exception-return integrity check. The definition
81  * above is the one from the v8M ARM ARM and is also in line
82  * with the behaviour documented for the Cortex-M3.
83  */
84 static bool nvic_rettobase(NVICState *s)
85 {
86     int irq, nhand = 0;
87 
88     for (irq = ARMV7M_EXCP_RESET; irq < s->num_irq; irq++) {
89         if (s->vectors[irq].active) {
90             nhand++;
91             if (nhand == 2) {
92                 return 0;
93             }
94         }
95     }
96 
97     return 1;
98 }
99 
100 /* Return the value of the ISCR ISRPENDING bit:
101  * 1 if an external interrupt is pending
102  * 0 if no external interrupt is pending
103  */
104 static bool nvic_isrpending(NVICState *s)
105 {
106     int irq;
107 
108     /* We can shortcut if the highest priority pending interrupt
109      * happens to be external or if there is nothing pending.
110      */
111     if (s->vectpending > NVIC_FIRST_IRQ) {
112         return true;
113     }
114     if (s->vectpending == 0) {
115         return false;
116     }
117 
118     for (irq = NVIC_FIRST_IRQ; irq < s->num_irq; irq++) {
119         if (s->vectors[irq].pending) {
120             return true;
121         }
122     }
123     return false;
124 }
125 
126 /* Return a mask word which clears the subpriority bits from
127  * a priority value for an M-profile exception, leaving only
128  * the group priority.
129  */
130 static inline uint32_t nvic_gprio_mask(NVICState *s)
131 {
132     return ~0U << (s->prigroup + 1);
133 }
134 
135 /* Recompute vectpending and exception_prio */
136 static void nvic_recompute_state(NVICState *s)
137 {
138     int i;
139     int pend_prio = NVIC_NOEXC_PRIO;
140     int active_prio = NVIC_NOEXC_PRIO;
141     int pend_irq = 0;
142 
143     for (i = 1; i < s->num_irq; i++) {
144         VecInfo *vec = &s->vectors[i];
145 
146         if (vec->enabled && vec->pending && vec->prio < pend_prio) {
147             pend_prio = vec->prio;
148             pend_irq = i;
149         }
150         if (vec->active && vec->prio < active_prio) {
151             active_prio = vec->prio;
152         }
153     }
154 
155     if (active_prio > 0) {
156         active_prio &= nvic_gprio_mask(s);
157     }
158 
159     s->vectpending = pend_irq;
160     s->exception_prio = active_prio;
161 
162     trace_nvic_recompute_state(s->vectpending, s->exception_prio);
163 }
164 
165 /* Return the current execution priority of the CPU
166  * (equivalent to the pseudocode ExecutionPriority function).
167  * This is a value between -2 (NMI priority) and NVIC_NOEXC_PRIO.
168  */
169 static inline int nvic_exec_prio(NVICState *s)
170 {
171     CPUARMState *env = &s->cpu->env;
172     int running;
173 
174     if (env->v7m.faultmask[env->v7m.secure]) {
175         running = -1;
176     } else if (env->v7m.primask[env->v7m.secure]) {
177         running = 0;
178     } else if (env->v7m.basepri[env->v7m.secure] > 0) {
179         running = env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s);
180     } else {
181         running = NVIC_NOEXC_PRIO; /* lower than any possible priority */
182     }
183     /* consider priority of active handler */
184     return MIN(running, s->exception_prio);
185 }
186 
187 bool armv7m_nvic_can_take_pending_exception(void *opaque)
188 {
189     NVICState *s = opaque;
190 
191     return nvic_exec_prio(s) > nvic_pending_prio(s);
192 }
193 
194 int armv7m_nvic_raw_execution_priority(void *opaque)
195 {
196     NVICState *s = opaque;
197 
198     return s->exception_prio;
199 }
200 
201 /* caller must call nvic_irq_update() after this */
202 static void set_prio(NVICState *s, unsigned irq, uint8_t prio)
203 {
204     assert(irq > ARMV7M_EXCP_NMI); /* only use for configurable prios */
205     assert(irq < s->num_irq);
206 
207     s->vectors[irq].prio = prio;
208 
209     trace_nvic_set_prio(irq, prio);
210 }
211 
212 /* Recompute state and assert irq line accordingly.
213  * Must be called after changes to:
214  *  vec->active, vec->enabled, vec->pending or vec->prio for any vector
215  *  prigroup
216  */
217 static void nvic_irq_update(NVICState *s)
218 {
219     int lvl;
220     int pend_prio;
221 
222     nvic_recompute_state(s);
223     pend_prio = nvic_pending_prio(s);
224 
225     /* Raise NVIC output if this IRQ would be taken, except that we
226      * ignore the effects of the BASEPRI, FAULTMASK and PRIMASK (which
227      * will be checked for in arm_v7m_cpu_exec_interrupt()); changes
228      * to those CPU registers don't cause us to recalculate the NVIC
229      * pending info.
230      */
231     lvl = (pend_prio < s->exception_prio);
232     trace_nvic_irq_update(s->vectpending, pend_prio, s->exception_prio, lvl);
233     qemu_set_irq(s->excpout, lvl);
234 }
235 
236 static void armv7m_nvic_clear_pending(void *opaque, int irq)
237 {
238     NVICState *s = (NVICState *)opaque;
239     VecInfo *vec;
240 
241     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
242 
243     vec = &s->vectors[irq];
244     trace_nvic_clear_pending(irq, vec->enabled, vec->prio);
245     if (vec->pending) {
246         vec->pending = 0;
247         nvic_irq_update(s);
248     }
249 }
250 
251 void armv7m_nvic_set_pending(void *opaque, int irq)
252 {
253     NVICState *s = (NVICState *)opaque;
254     VecInfo *vec;
255 
256     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
257 
258     vec = &s->vectors[irq];
259     trace_nvic_set_pending(irq, vec->enabled, vec->prio);
260 
261 
262     if (irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV) {
263         /* If a synchronous exception is pending then it may be
264          * escalated to HardFault if:
265          *  * it is equal or lower priority to current execution
266          *  * it is disabled
267          * (ie we need to take it immediately but we can't do so).
268          * Asynchronous exceptions (and interrupts) simply remain pending.
269          *
270          * For QEMU, we don't have any imprecise (asynchronous) faults,
271          * so we can assume that PREFETCH_ABORT and DATA_ABORT are always
272          * synchronous.
273          * Debug exceptions are awkward because only Debug exceptions
274          * resulting from the BKPT instruction should be escalated,
275          * but we don't currently implement any Debug exceptions other
276          * than those that result from BKPT, so we treat all debug exceptions
277          * as needing escalation.
278          *
279          * This all means we can identify whether to escalate based only on
280          * the exception number and don't (yet) need the caller to explicitly
281          * tell us whether this exception is synchronous or not.
282          */
283         int running = nvic_exec_prio(s);
284         bool escalate = false;
285 
286         if (vec->prio >= running) {
287             trace_nvic_escalate_prio(irq, vec->prio, running);
288             escalate = true;
289         } else if (!vec->enabled) {
290             trace_nvic_escalate_disabled(irq);
291             escalate = true;
292         }
293 
294         if (escalate) {
295             if (running < 0) {
296                 /* We want to escalate to HardFault but we can't take a
297                  * synchronous HardFault at this point either. This is a
298                  * Lockup condition due to a guest bug. We don't model
299                  * Lockup, so report via cpu_abort() instead.
300                  */
301                 cpu_abort(&s->cpu->parent_obj,
302                           "Lockup: can't escalate %d to HardFault "
303                           "(current priority %d)\n", irq, running);
304             }
305 
306             /* We can do the escalation, so we take HardFault instead */
307             irq = ARMV7M_EXCP_HARD;
308             vec = &s->vectors[irq];
309             s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
310         }
311     }
312 
313     if (!vec->pending) {
314         vec->pending = 1;
315         nvic_irq_update(s);
316     }
317 }
318 
319 /* Make pending IRQ active.  */
320 void armv7m_nvic_acknowledge_irq(void *opaque)
321 {
322     NVICState *s = (NVICState *)opaque;
323     CPUARMState *env = &s->cpu->env;
324     const int pending = s->vectpending;
325     const int running = nvic_exec_prio(s);
326     int pendgroupprio;
327     VecInfo *vec;
328 
329     assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
330 
331     vec = &s->vectors[pending];
332 
333     assert(vec->enabled);
334     assert(vec->pending);
335 
336     pendgroupprio = vec->prio;
337     if (pendgroupprio > 0) {
338         pendgroupprio &= nvic_gprio_mask(s);
339     }
340     assert(pendgroupprio < running);
341 
342     trace_nvic_acknowledge_irq(pending, vec->prio);
343 
344     vec->active = 1;
345     vec->pending = 0;
346 
347     env->v7m.exception = s->vectpending;
348 
349     nvic_irq_update(s);
350 }
351 
352 int armv7m_nvic_complete_irq(void *opaque, int irq)
353 {
354     NVICState *s = (NVICState *)opaque;
355     VecInfo *vec;
356     int ret;
357 
358     assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
359 
360     vec = &s->vectors[irq];
361 
362     trace_nvic_complete_irq(irq);
363 
364     if (!vec->active) {
365         /* Tell the caller this was an illegal exception return */
366         return -1;
367     }
368 
369     ret = nvic_rettobase(s);
370 
371     vec->active = 0;
372     if (vec->level) {
373         /* Re-pend the exception if it's still held high; only
374          * happens for extenal IRQs
375          */
376         assert(irq >= NVIC_FIRST_IRQ);
377         vec->pending = 1;
378     }
379 
380     nvic_irq_update(s);
381 
382     return ret;
383 }
384 
385 /* callback when external interrupt line is changed */
386 static void set_irq_level(void *opaque, int n, int level)
387 {
388     NVICState *s = opaque;
389     VecInfo *vec;
390 
391     n += NVIC_FIRST_IRQ;
392 
393     assert(n >= NVIC_FIRST_IRQ && n < s->num_irq);
394 
395     trace_nvic_set_irq_level(n, level);
396 
397     /* The pending status of an external interrupt is
398      * latched on rising edge and exception handler return.
399      *
400      * Pulsing the IRQ will always run the handler
401      * once, and the handler will re-run until the
402      * level is low when the handler completes.
403      */
404     vec = &s->vectors[n];
405     if (level != vec->level) {
406         vec->level = level;
407         if (level) {
408             armv7m_nvic_set_pending(s, n);
409         }
410     }
411 }
412 
413 static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
414 {
415     ARMCPU *cpu = s->cpu;
416     uint32_t val;
417 
418     switch (offset) {
419     case 4: /* Interrupt Control Type.  */
420         return ((s->num_irq - NVIC_FIRST_IRQ) / 32) - 1;
421     case 0xd00: /* CPUID Base.  */
422         return cpu->midr;
423     case 0xd04: /* Interrupt Control State.  */
424         /* VECTACTIVE */
425         val = cpu->env.v7m.exception;
426         /* VECTPENDING */
427         val |= (s->vectpending & 0xff) << 12;
428         /* ISRPENDING - set if any external IRQ is pending */
429         if (nvic_isrpending(s)) {
430             val |= (1 << 22);
431         }
432         /* RETTOBASE - set if only one handler is active */
433         if (nvic_rettobase(s)) {
434             val |= (1 << 11);
435         }
436         /* PENDSTSET */
437         if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) {
438             val |= (1 << 26);
439         }
440         /* PENDSVSET */
441         if (s->vectors[ARMV7M_EXCP_PENDSV].pending) {
442             val |= (1 << 28);
443         }
444         /* NMIPENDSET */
445         if (s->vectors[ARMV7M_EXCP_NMI].pending) {
446             val |= (1 << 31);
447         }
448         /* ISRPREEMPT not implemented */
449         return val;
450     case 0xd08: /* Vector Table Offset.  */
451         return cpu->env.v7m.vecbase[attrs.secure];
452     case 0xd0c: /* Application Interrupt/Reset Control.  */
453         return 0xfa050000 | (s->prigroup << 8);
454     case 0xd10: /* System Control.  */
455         /* TODO: Implement SLEEPONEXIT.  */
456         return 0;
457     case 0xd14: /* Configuration Control.  */
458         /* The BFHFNMIGN bit is the only non-banked bit; we
459          * keep it in the non-secure copy of the register.
460          */
461         val = cpu->env.v7m.ccr[attrs.secure];
462         val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
463         return val;
464     case 0xd24: /* System Handler Status.  */
465         val = 0;
466         if (s->vectors[ARMV7M_EXCP_MEM].active) {
467             val |= (1 << 0);
468         }
469         if (s->vectors[ARMV7M_EXCP_BUS].active) {
470             val |= (1 << 1);
471         }
472         if (s->vectors[ARMV7M_EXCP_USAGE].active) {
473             val |= (1 << 3);
474         }
475         if (s->vectors[ARMV7M_EXCP_SVC].active) {
476             val |= (1 << 7);
477         }
478         if (s->vectors[ARMV7M_EXCP_DEBUG].active) {
479             val |= (1 << 8);
480         }
481         if (s->vectors[ARMV7M_EXCP_PENDSV].active) {
482             val |= (1 << 10);
483         }
484         if (s->vectors[ARMV7M_EXCP_SYSTICK].active) {
485             val |= (1 << 11);
486         }
487         if (s->vectors[ARMV7M_EXCP_USAGE].pending) {
488             val |= (1 << 12);
489         }
490         if (s->vectors[ARMV7M_EXCP_MEM].pending) {
491             val |= (1 << 13);
492         }
493         if (s->vectors[ARMV7M_EXCP_BUS].pending) {
494             val |= (1 << 14);
495         }
496         if (s->vectors[ARMV7M_EXCP_SVC].pending) {
497             val |= (1 << 15);
498         }
499         if (s->vectors[ARMV7M_EXCP_MEM].enabled) {
500             val |= (1 << 16);
501         }
502         if (s->vectors[ARMV7M_EXCP_BUS].enabled) {
503             val |= (1 << 17);
504         }
505         if (s->vectors[ARMV7M_EXCP_USAGE].enabled) {
506             val |= (1 << 18);
507         }
508         return val;
509     case 0xd28: /* Configurable Fault Status.  */
510         /* The BFSR bits [15:8] are shared between security states
511          * and we store them in the NS copy
512          */
513         val = cpu->env.v7m.cfsr[attrs.secure];
514         val |= cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
515         return val;
516     case 0xd2c: /* Hard Fault Status.  */
517         return cpu->env.v7m.hfsr;
518     case 0xd30: /* Debug Fault Status.  */
519         return cpu->env.v7m.dfsr;
520     case 0xd34: /* MMFAR MemManage Fault Address */
521         return cpu->env.v7m.mmfar[attrs.secure];
522     case 0xd38: /* Bus Fault Address.  */
523         return cpu->env.v7m.bfar;
524     case 0xd3c: /* Aux Fault Status.  */
525         /* TODO: Implement fault status registers.  */
526         qemu_log_mask(LOG_UNIMP,
527                       "Aux Fault status registers unimplemented\n");
528         return 0;
529     case 0xd40: /* PFR0.  */
530         return 0x00000030;
531     case 0xd44: /* PRF1.  */
532         return 0x00000200;
533     case 0xd48: /* DFR0.  */
534         return 0x00100000;
535     case 0xd4c: /* AFR0.  */
536         return 0x00000000;
537     case 0xd50: /* MMFR0.  */
538         return 0x00000030;
539     case 0xd54: /* MMFR1.  */
540         return 0x00000000;
541     case 0xd58: /* MMFR2.  */
542         return 0x00000000;
543     case 0xd5c: /* MMFR3.  */
544         return 0x00000000;
545     case 0xd60: /* ISAR0.  */
546         return 0x01141110;
547     case 0xd64: /* ISAR1.  */
548         return 0x02111000;
549     case 0xd68: /* ISAR2.  */
550         return 0x21112231;
551     case 0xd6c: /* ISAR3.  */
552         return 0x01111110;
553     case 0xd70: /* ISAR4.  */
554         return 0x01310102;
555     /* TODO: Implement debug registers.  */
556     case 0xd90: /* MPU_TYPE */
557         /* Unified MPU; if the MPU is not present this value is zero */
558         return cpu->pmsav7_dregion << 8;
559         break;
560     case 0xd94: /* MPU_CTRL */
561         return cpu->env.v7m.mpu_ctrl[attrs.secure];
562     case 0xd98: /* MPU_RNR */
563         return cpu->env.pmsav7.rnr[attrs.secure];
564     case 0xd9c: /* MPU_RBAR */
565     case 0xda4: /* MPU_RBAR_A1 */
566     case 0xdac: /* MPU_RBAR_A2 */
567     case 0xdb4: /* MPU_RBAR_A3 */
568     {
569         int region = cpu->env.pmsav7.rnr[attrs.secure];
570 
571         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
572             /* PMSAv8M handling of the aliases is different from v7M:
573              * aliases A1, A2, A3 override the low two bits of the region
574              * number in MPU_RNR, and there is no 'region' field in the
575              * RBAR register.
576              */
577             int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
578             if (aliasno) {
579                 region = deposit32(region, 0, 2, aliasno);
580             }
581             if (region >= cpu->pmsav7_dregion) {
582                 return 0;
583             }
584             return cpu->env.pmsav8.rbar[attrs.secure][region];
585         }
586 
587         if (region >= cpu->pmsav7_dregion) {
588             return 0;
589         }
590         return (cpu->env.pmsav7.drbar[region] & 0x1f) | (region & 0xf);
591     }
592     case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
593     case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
594     case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
595     case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
596     {
597         int region = cpu->env.pmsav7.rnr[attrs.secure];
598 
599         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
600             /* PMSAv8M handling of the aliases is different from v7M:
601              * aliases A1, A2, A3 override the low two bits of the region
602              * number in MPU_RNR.
603              */
604             int aliasno = (offset - 0xda0) / 8; /* 0..3 */
605             if (aliasno) {
606                 region = deposit32(region, 0, 2, aliasno);
607             }
608             if (region >= cpu->pmsav7_dregion) {
609                 return 0;
610             }
611             return cpu->env.pmsav8.rlar[attrs.secure][region];
612         }
613 
614         if (region >= cpu->pmsav7_dregion) {
615             return 0;
616         }
617         return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) |
618             (cpu->env.pmsav7.drsr[region] & 0xffff);
619     }
620     case 0xdc0: /* MPU_MAIR0 */
621         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
622             goto bad_offset;
623         }
624         return cpu->env.pmsav8.mair0[attrs.secure];
625     case 0xdc4: /* MPU_MAIR1 */
626         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
627             goto bad_offset;
628         }
629         return cpu->env.pmsav8.mair1[attrs.secure];
630     default:
631     bad_offset:
632         qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
633         return 0;
634     }
635 }
636 
637 static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
638                         MemTxAttrs attrs)
639 {
640     ARMCPU *cpu = s->cpu;
641 
642     switch (offset) {
643     case 0xd04: /* Interrupt Control State.  */
644         if (value & (1 << 31)) {
645             armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI);
646         }
647         if (value & (1 << 28)) {
648             armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV);
649         } else if (value & (1 << 27)) {
650             armv7m_nvic_clear_pending(s, ARMV7M_EXCP_PENDSV);
651         }
652         if (value & (1 << 26)) {
653             armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK);
654         } else if (value & (1 << 25)) {
655             armv7m_nvic_clear_pending(s, ARMV7M_EXCP_SYSTICK);
656         }
657         break;
658     case 0xd08: /* Vector Table Offset.  */
659         cpu->env.v7m.vecbase[attrs.secure] = value & 0xffffff80;
660         break;
661     case 0xd0c: /* Application Interrupt/Reset Control.  */
662         if ((value >> 16) == 0x05fa) {
663             if (value & 4) {
664                 qemu_irq_pulse(s->sysresetreq);
665             }
666             if (value & 2) {
667                 qemu_log_mask(LOG_GUEST_ERROR,
668                               "Setting VECTCLRACTIVE when not in DEBUG mode "
669                               "is UNPREDICTABLE\n");
670             }
671             if (value & 1) {
672                 qemu_log_mask(LOG_GUEST_ERROR,
673                               "Setting VECTRESET when not in DEBUG mode "
674                               "is UNPREDICTABLE\n");
675             }
676             s->prigroup = extract32(value, 8, 3);
677             nvic_irq_update(s);
678         }
679         break;
680     case 0xd10: /* System Control.  */
681         /* TODO: Implement control registers.  */
682         qemu_log_mask(LOG_UNIMP, "NVIC: SCR unimplemented\n");
683         break;
684     case 0xd14: /* Configuration Control.  */
685         /* Enforce RAZ/WI on reserved and must-RAZ/WI bits */
686         value &= (R_V7M_CCR_STKALIGN_MASK |
687                   R_V7M_CCR_BFHFNMIGN_MASK |
688                   R_V7M_CCR_DIV_0_TRP_MASK |
689                   R_V7M_CCR_UNALIGN_TRP_MASK |
690                   R_V7M_CCR_USERSETMPEND_MASK |
691                   R_V7M_CCR_NONBASETHRDENA_MASK);
692 
693         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
694             /* v8M makes NONBASETHRDENA and STKALIGN be RES1 */
695             value |= R_V7M_CCR_NONBASETHRDENA_MASK
696                 | R_V7M_CCR_STKALIGN_MASK;
697         }
698         if (attrs.secure) {
699             /* the BFHFNMIGN bit is not banked; keep that in the NS copy */
700             cpu->env.v7m.ccr[M_REG_NS] =
701                 (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)
702                 | (value & R_V7M_CCR_BFHFNMIGN_MASK);
703             value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
704         }
705 
706         cpu->env.v7m.ccr[attrs.secure] = value;
707         break;
708     case 0xd24: /* System Handler Control.  */
709         s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;
710         s->vectors[ARMV7M_EXCP_BUS].active = (value & (1 << 1)) != 0;
711         s->vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0;
712         s->vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0;
713         s->vectors[ARMV7M_EXCP_DEBUG].active = (value & (1 << 8)) != 0;
714         s->vectors[ARMV7M_EXCP_PENDSV].active = (value & (1 << 10)) != 0;
715         s->vectors[ARMV7M_EXCP_SYSTICK].active = (value & (1 << 11)) != 0;
716         s->vectors[ARMV7M_EXCP_USAGE].pending = (value & (1 << 12)) != 0;
717         s->vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0;
718         s->vectors[ARMV7M_EXCP_BUS].pending = (value & (1 << 14)) != 0;
719         s->vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0;
720         s->vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
721         s->vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
722         s->vectors[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;
723         nvic_irq_update(s);
724         break;
725     case 0xd28: /* Configurable Fault Status.  */
726         cpu->env.v7m.cfsr[attrs.secure] &= ~value; /* W1C */
727         if (attrs.secure) {
728             /* The BFSR bits [15:8] are shared between security states
729              * and we store them in the NS copy.
730              */
731             cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
732         }
733         break;
734     case 0xd2c: /* Hard Fault Status.  */
735         cpu->env.v7m.hfsr &= ~value; /* W1C */
736         break;
737     case 0xd30: /* Debug Fault Status.  */
738         cpu->env.v7m.dfsr &= ~value; /* W1C */
739         break;
740     case 0xd34: /* Mem Manage Address.  */
741         cpu->env.v7m.mmfar[attrs.secure] = value;
742         return;
743     case 0xd38: /* Bus Fault Address.  */
744         cpu->env.v7m.bfar = value;
745         return;
746     case 0xd3c: /* Aux Fault Status.  */
747         qemu_log_mask(LOG_UNIMP,
748                       "NVIC: Aux fault status registers unimplemented\n");
749         break;
750     case 0xd90: /* MPU_TYPE */
751         return; /* RO */
752     case 0xd94: /* MPU_CTRL */
753         if ((value &
754              (R_V7M_MPU_CTRL_HFNMIENA_MASK | R_V7M_MPU_CTRL_ENABLE_MASK))
755             == R_V7M_MPU_CTRL_HFNMIENA_MASK) {
756             qemu_log_mask(LOG_GUEST_ERROR, "MPU_CTRL: HFNMIENA and !ENABLE is "
757                           "UNPREDICTABLE\n");
758         }
759         cpu->env.v7m.mpu_ctrl[attrs.secure]
760             = value & (R_V7M_MPU_CTRL_ENABLE_MASK |
761                        R_V7M_MPU_CTRL_HFNMIENA_MASK |
762                        R_V7M_MPU_CTRL_PRIVDEFENA_MASK);
763         tlb_flush(CPU(cpu));
764         break;
765     case 0xd98: /* MPU_RNR */
766         if (value >= cpu->pmsav7_dregion) {
767             qemu_log_mask(LOG_GUEST_ERROR, "MPU region out of range %"
768                           PRIu32 "/%" PRIu32 "\n",
769                           value, cpu->pmsav7_dregion);
770         } else {
771             cpu->env.pmsav7.rnr[attrs.secure] = value;
772         }
773         break;
774     case 0xd9c: /* MPU_RBAR */
775     case 0xda4: /* MPU_RBAR_A1 */
776     case 0xdac: /* MPU_RBAR_A2 */
777     case 0xdb4: /* MPU_RBAR_A3 */
778     {
779         int region;
780 
781         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
782             /* PMSAv8M handling of the aliases is different from v7M:
783              * aliases A1, A2, A3 override the low two bits of the region
784              * number in MPU_RNR, and there is no 'region' field in the
785              * RBAR register.
786              */
787             int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
788 
789             region = cpu->env.pmsav7.rnr[attrs.secure];
790             if (aliasno) {
791                 region = deposit32(region, 0, 2, aliasno);
792             }
793             if (region >= cpu->pmsav7_dregion) {
794                 return;
795             }
796             cpu->env.pmsav8.rbar[attrs.secure][region] = value;
797             tlb_flush(CPU(cpu));
798             return;
799         }
800 
801         if (value & (1 << 4)) {
802             /* VALID bit means use the region number specified in this
803              * value and also update MPU_RNR.REGION with that value.
804              */
805             region = extract32(value, 0, 4);
806             if (region >= cpu->pmsav7_dregion) {
807                 qemu_log_mask(LOG_GUEST_ERROR,
808                               "MPU region out of range %u/%" PRIu32 "\n",
809                               region, cpu->pmsav7_dregion);
810                 return;
811             }
812             cpu->env.pmsav7.rnr[attrs.secure] = region;
813         } else {
814             region = cpu->env.pmsav7.rnr[attrs.secure];
815         }
816 
817         if (region >= cpu->pmsav7_dregion) {
818             return;
819         }
820 
821         cpu->env.pmsav7.drbar[region] = value & ~0x1f;
822         tlb_flush(CPU(cpu));
823         break;
824     }
825     case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
826     case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
827     case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
828     case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
829     {
830         int region = cpu->env.pmsav7.rnr[attrs.secure];
831 
832         if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
833             /* PMSAv8M handling of the aliases is different from v7M:
834              * aliases A1, A2, A3 override the low two bits of the region
835              * number in MPU_RNR.
836              */
837             int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
838 
839             region = cpu->env.pmsav7.rnr[attrs.secure];
840             if (aliasno) {
841                 region = deposit32(region, 0, 2, aliasno);
842             }
843             if (region >= cpu->pmsav7_dregion) {
844                 return;
845             }
846             cpu->env.pmsav8.rlar[attrs.secure][region] = value;
847             tlb_flush(CPU(cpu));
848             return;
849         }
850 
851         if (region >= cpu->pmsav7_dregion) {
852             return;
853         }
854 
855         cpu->env.pmsav7.drsr[region] = value & 0xff3f;
856         cpu->env.pmsav7.dracr[region] = (value >> 16) & 0x173f;
857         tlb_flush(CPU(cpu));
858         break;
859     }
860     case 0xdc0: /* MPU_MAIR0 */
861         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
862             goto bad_offset;
863         }
864         if (cpu->pmsav7_dregion) {
865             /* Register is RES0 if no MPU regions are implemented */
866             cpu->env.pmsav8.mair0[attrs.secure] = value;
867         }
868         /* We don't need to do anything else because memory attributes
869          * only affect cacheability, and we don't implement caching.
870          */
871         break;
872     case 0xdc4: /* MPU_MAIR1 */
873         if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
874             goto bad_offset;
875         }
876         if (cpu->pmsav7_dregion) {
877             /* Register is RES0 if no MPU regions are implemented */
878             cpu->env.pmsav8.mair1[attrs.secure] = value;
879         }
880         /* We don't need to do anything else because memory attributes
881          * only affect cacheability, and we don't implement caching.
882          */
883         break;
884     case 0xf00: /* Software Triggered Interrupt Register */
885     {
886         int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ;
887         if (excnum < s->num_irq) {
888             armv7m_nvic_set_pending(s, excnum);
889         }
890         break;
891     }
892     default:
893     bad_offset:
894         qemu_log_mask(LOG_GUEST_ERROR,
895                       "NVIC: Bad write offset 0x%x\n", offset);
896     }
897 }
898 
899 static bool nvic_user_access_ok(NVICState *s, hwaddr offset, MemTxAttrs attrs)
900 {
901     /* Return true if unprivileged access to this register is permitted. */
902     switch (offset) {
903     case 0xf00: /* STIR: accessible only if CCR.USERSETMPEND permits */
904         /* For access via STIR_NS it is the NS CCR.USERSETMPEND that
905          * controls access even though the CPU is in Secure state (I_QDKX).
906          */
907         return s->cpu->env.v7m.ccr[attrs.secure] & R_V7M_CCR_USERSETMPEND_MASK;
908     default:
909         /* All other user accesses cause a BusFault unconditionally */
910         return false;
911     }
912 }
913 
914 static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
915                                     uint64_t *data, unsigned size,
916                                     MemTxAttrs attrs)
917 {
918     NVICState *s = (NVICState *)opaque;
919     uint32_t offset = addr;
920     unsigned i, startvec, end;
921     uint32_t val;
922 
923     if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
924         /* Generate BusFault for unprivileged accesses */
925         return MEMTX_ERROR;
926     }
927 
928     switch (offset) {
929     /* reads of set and clear both return the status */
930     case 0x100 ... 0x13f: /* NVIC Set enable */
931         offset += 0x80;
932         /* fall through */
933     case 0x180 ... 0x1bf: /* NVIC Clear enable */
934         val = 0;
935         startvec = offset - 0x180 + NVIC_FIRST_IRQ; /* vector # */
936 
937         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
938             if (s->vectors[startvec + i].enabled) {
939                 val |= (1 << i);
940             }
941         }
942         break;
943     case 0x200 ... 0x23f: /* NVIC Set pend */
944         offset += 0x80;
945         /* fall through */
946     case 0x280 ... 0x2bf: /* NVIC Clear pend */
947         val = 0;
948         startvec = offset - 0x280 + NVIC_FIRST_IRQ; /* vector # */
949         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
950             if (s->vectors[startvec + i].pending) {
951                 val |= (1 << i);
952             }
953         }
954         break;
955     case 0x300 ... 0x33f: /* NVIC Active */
956         val = 0;
957         startvec = offset - 0x300 + NVIC_FIRST_IRQ; /* vector # */
958 
959         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
960             if (s->vectors[startvec + i].active) {
961                 val |= (1 << i);
962             }
963         }
964         break;
965     case 0x400 ... 0x5ef: /* NVIC Priority */
966         val = 0;
967         startvec = offset - 0x400 + NVIC_FIRST_IRQ; /* vector # */
968 
969         for (i = 0; i < size && startvec + i < s->num_irq; i++) {
970             val |= s->vectors[startvec + i].prio << (8 * i);
971         }
972         break;
973     case 0xd18 ... 0xd23: /* System Handler Priority.  */
974         val = 0;
975         for (i = 0; i < size; i++) {
976             val |= s->vectors[(offset - 0xd14) + i].prio << (i * 8);
977         }
978         break;
979     case 0xfe0 ... 0xfff: /* ID.  */
980         if (offset & 3) {
981             val = 0;
982         } else {
983             val = nvic_id[(offset - 0xfe0) >> 2];
984         }
985         break;
986     default:
987         if (size == 4) {
988             val = nvic_readl(s, offset, attrs);
989         } else {
990             qemu_log_mask(LOG_GUEST_ERROR,
991                           "NVIC: Bad read of size %d at offset 0x%x\n",
992                           size, offset);
993             val = 0;
994         }
995     }
996 
997     trace_nvic_sysreg_read(addr, val, size);
998     *data = val;
999     return MEMTX_OK;
1000 }
1001 
1002 static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
1003                                      uint64_t value, unsigned size,
1004                                      MemTxAttrs attrs)
1005 {
1006     NVICState *s = (NVICState *)opaque;
1007     uint32_t offset = addr;
1008     unsigned i, startvec, end;
1009     unsigned setval = 0;
1010 
1011     trace_nvic_sysreg_write(addr, value, size);
1012 
1013     if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
1014         /* Generate BusFault for unprivileged accesses */
1015         return MEMTX_ERROR;
1016     }
1017 
1018     switch (offset) {
1019     case 0x100 ... 0x13f: /* NVIC Set enable */
1020         offset += 0x80;
1021         setval = 1;
1022         /* fall through */
1023     case 0x180 ... 0x1bf: /* NVIC Clear enable */
1024         startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ;
1025 
1026         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
1027             if (value & (1 << i)) {
1028                 s->vectors[startvec + i].enabled = setval;
1029             }
1030         }
1031         nvic_irq_update(s);
1032         return MEMTX_OK;
1033     case 0x200 ... 0x23f: /* NVIC Set pend */
1034         /* the special logic in armv7m_nvic_set_pending()
1035          * is not needed since IRQs are never escalated
1036          */
1037         offset += 0x80;
1038         setval = 1;
1039         /* fall through */
1040     case 0x280 ... 0x2bf: /* NVIC Clear pend */
1041         startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */
1042 
1043         for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
1044             if (value & (1 << i)) {
1045                 s->vectors[startvec + i].pending = setval;
1046             }
1047         }
1048         nvic_irq_update(s);
1049         return MEMTX_OK;
1050     case 0x300 ... 0x33f: /* NVIC Active */
1051         return MEMTX_OK; /* R/O */
1052     case 0x400 ... 0x5ef: /* NVIC Priority */
1053         startvec = 8 * (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
1054 
1055         for (i = 0; i < size && startvec + i < s->num_irq; i++) {
1056             set_prio(s, startvec + i, (value >> (i * 8)) & 0xff);
1057         }
1058         nvic_irq_update(s);
1059         return MEMTX_OK;
1060     case 0xd18 ... 0xd23: /* System Handler Priority.  */
1061         for (i = 0; i < size; i++) {
1062             unsigned hdlidx = (offset - 0xd14) + i;
1063             set_prio(s, hdlidx, (value >> (i * 8)) & 0xff);
1064         }
1065         nvic_irq_update(s);
1066         return MEMTX_OK;
1067     }
1068     if (size == 4) {
1069         nvic_writel(s, offset, value, attrs);
1070         return MEMTX_OK;
1071     }
1072     qemu_log_mask(LOG_GUEST_ERROR,
1073                   "NVIC: Bad write of size %d at offset 0x%x\n", size, offset);
1074     /* This is UNPREDICTABLE; treat as RAZ/WI */
1075     return MEMTX_OK;
1076 }
1077 
1078 static const MemoryRegionOps nvic_sysreg_ops = {
1079     .read_with_attrs = nvic_sysreg_read,
1080     .write_with_attrs = nvic_sysreg_write,
1081     .endianness = DEVICE_NATIVE_ENDIAN,
1082 };
1083 
1084 static MemTxResult nvic_sysreg_ns_write(void *opaque, hwaddr addr,
1085                                         uint64_t value, unsigned size,
1086                                         MemTxAttrs attrs)
1087 {
1088     if (attrs.secure) {
1089         /* S accesses to the alias act like NS accesses to the real region */
1090         attrs.secure = 0;
1091         return nvic_sysreg_write(opaque, addr, value, size, attrs);
1092     } else {
1093         /* NS attrs are RAZ/WI for privileged, and BusFault for user */
1094         if (attrs.user) {
1095             return MEMTX_ERROR;
1096         }
1097         return MEMTX_OK;
1098     }
1099 }
1100 
1101 static MemTxResult nvic_sysreg_ns_read(void *opaque, hwaddr addr,
1102                                        uint64_t *data, unsigned size,
1103                                        MemTxAttrs attrs)
1104 {
1105     if (attrs.secure) {
1106         /* S accesses to the alias act like NS accesses to the real region */
1107         attrs.secure = 0;
1108         return nvic_sysreg_read(opaque, addr, data, size, attrs);
1109     } else {
1110         /* NS attrs are RAZ/WI for privileged, and BusFault for user */
1111         if (attrs.user) {
1112             return MEMTX_ERROR;
1113         }
1114         *data = 0;
1115         return MEMTX_OK;
1116     }
1117 }
1118 
1119 static const MemoryRegionOps nvic_sysreg_ns_ops = {
1120     .read_with_attrs = nvic_sysreg_ns_read,
1121     .write_with_attrs = nvic_sysreg_ns_write,
1122     .endianness = DEVICE_NATIVE_ENDIAN,
1123 };
1124 
1125 static int nvic_post_load(void *opaque, int version_id)
1126 {
1127     NVICState *s = opaque;
1128     unsigned i;
1129 
1130     /* Check for out of range priority settings */
1131     if (s->vectors[ARMV7M_EXCP_RESET].prio != -3 ||
1132         s->vectors[ARMV7M_EXCP_NMI].prio != -2 ||
1133         s->vectors[ARMV7M_EXCP_HARD].prio != -1) {
1134         return 1;
1135     }
1136     for (i = ARMV7M_EXCP_MEM; i < s->num_irq; i++) {
1137         if (s->vectors[i].prio & ~0xff) {
1138             return 1;
1139         }
1140     }
1141 
1142     nvic_recompute_state(s);
1143 
1144     return 0;
1145 }
1146 
1147 static const VMStateDescription vmstate_VecInfo = {
1148     .name = "armv7m_nvic_info",
1149     .version_id = 1,
1150     .minimum_version_id = 1,
1151     .fields = (VMStateField[]) {
1152         VMSTATE_INT16(prio, VecInfo),
1153         VMSTATE_UINT8(enabled, VecInfo),
1154         VMSTATE_UINT8(pending, VecInfo),
1155         VMSTATE_UINT8(active, VecInfo),
1156         VMSTATE_UINT8(level, VecInfo),
1157         VMSTATE_END_OF_LIST()
1158     }
1159 };
1160 
1161 static const VMStateDescription vmstate_nvic = {
1162     .name = "armv7m_nvic",
1163     .version_id = 4,
1164     .minimum_version_id = 4,
1165     .post_load = &nvic_post_load,
1166     .fields = (VMStateField[]) {
1167         VMSTATE_STRUCT_ARRAY(vectors, NVICState, NVIC_MAX_VECTORS, 1,
1168                              vmstate_VecInfo, VecInfo),
1169         VMSTATE_UINT32(prigroup, NVICState),
1170         VMSTATE_END_OF_LIST()
1171     }
1172 };
1173 
1174 static Property props_nvic[] = {
1175     /* Number of external IRQ lines (so excluding the 16 internal exceptions) */
1176     DEFINE_PROP_UINT32("num-irq", NVICState, num_irq, 64),
1177     DEFINE_PROP_END_OF_LIST()
1178 };
1179 
1180 static void armv7m_nvic_reset(DeviceState *dev)
1181 {
1182     NVICState *s = NVIC(dev);
1183 
1184     s->vectors[ARMV7M_EXCP_NMI].enabled = 1;
1185     s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
1186     /* MEM, BUS, and USAGE are enabled through
1187      * the System Handler Control register
1188      */
1189     s->vectors[ARMV7M_EXCP_SVC].enabled = 1;
1190     s->vectors[ARMV7M_EXCP_DEBUG].enabled = 1;
1191     s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
1192     s->vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
1193 
1194     s->vectors[ARMV7M_EXCP_RESET].prio = -3;
1195     s->vectors[ARMV7M_EXCP_NMI].prio = -2;
1196     s->vectors[ARMV7M_EXCP_HARD].prio = -1;
1197 
1198     /* Strictly speaking the reset handler should be enabled.
1199      * However, we don't simulate soft resets through the NVIC,
1200      * and the reset vector should never be pended.
1201      * So we leave it disabled to catch logic errors.
1202      */
1203 
1204     s->exception_prio = NVIC_NOEXC_PRIO;
1205     s->vectpending = 0;
1206 }
1207 
1208 static void nvic_systick_trigger(void *opaque, int n, int level)
1209 {
1210     NVICState *s = opaque;
1211 
1212     if (level) {
1213         /* SysTick just asked us to pend its exception.
1214          * (This is different from an external interrupt line's
1215          * behaviour.)
1216          */
1217         armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK);
1218     }
1219 }
1220 
1221 static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
1222 {
1223     NVICState *s = NVIC(dev);
1224     SysBusDevice *systick_sbd;
1225     Error *err = NULL;
1226     int regionlen;
1227 
1228     s->cpu = ARM_CPU(qemu_get_cpu(0));
1229     assert(s->cpu);
1230 
1231     if (s->num_irq > NVIC_MAX_IRQ) {
1232         error_setg(errp, "num-irq %d exceeds NVIC maximum", s->num_irq);
1233         return;
1234     }
1235 
1236     qdev_init_gpio_in(dev, set_irq_level, s->num_irq);
1237 
1238     /* include space for internal exception vectors */
1239     s->num_irq += NVIC_FIRST_IRQ;
1240 
1241     object_property_set_bool(OBJECT(&s->systick), true, "realized", &err);
1242     if (err != NULL) {
1243         error_propagate(errp, err);
1244         return;
1245     }
1246     systick_sbd = SYS_BUS_DEVICE(&s->systick);
1247     sysbus_connect_irq(systick_sbd, 0,
1248                        qdev_get_gpio_in_named(dev, "systick-trigger", 0));
1249 
1250     /* The NVIC and System Control Space (SCS) starts at 0xe000e000
1251      * and looks like this:
1252      *  0x004 - ICTR
1253      *  0x010 - 0xff - systick
1254      *  0x100..0x7ec - NVIC
1255      *  0x7f0..0xcff - Reserved
1256      *  0xd00..0xd3c - SCS registers
1257      *  0xd40..0xeff - Reserved or Not implemented
1258      *  0xf00 - STIR
1259      *
1260      * Some registers within this space are banked between security states.
1261      * In v8M there is a second range 0xe002e000..0xe002efff which is the
1262      * NonSecure alias SCS; secure accesses to this behave like NS accesses
1263      * to the main SCS range, and non-secure accesses (including when
1264      * the security extension is not implemented) are RAZ/WI.
1265      * Note that both the main SCS range and the alias range are defined
1266      * to be exempt from memory attribution (R_BLJT) and so the memory
1267      * transaction attribute always matches the current CPU security
1268      * state (attrs.secure == env->v7m.secure). In the nvic_sysreg_ns_ops
1269      * wrappers we change attrs.secure to indicate the NS access; so
1270      * generally code determining which banked register to use should
1271      * use attrs.secure; code determining actual behaviour of the system
1272      * should use env->v7m.secure.
1273      */
1274     regionlen = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? 0x21000 : 0x1000;
1275     memory_region_init(&s->container, OBJECT(s), "nvic", regionlen);
1276     /* The system register region goes at the bottom of the priority
1277      * stack as it covers the whole page.
1278      */
1279     memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
1280                           "nvic_sysregs", 0x1000);
1281     memory_region_add_subregion(&s->container, 0, &s->sysregmem);
1282     memory_region_add_subregion_overlap(&s->container, 0x10,
1283                                         sysbus_mmio_get_region(systick_sbd, 0),
1284                                         1);
1285 
1286     if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
1287         memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
1288                               &nvic_sysreg_ns_ops, s,
1289                               "nvic_sysregs_ns", 0x1000);
1290         memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
1291     }
1292 
1293     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
1294 }
1295 
1296 static void armv7m_nvic_instance_init(Object *obj)
1297 {
1298     /* We have a different default value for the num-irq property
1299      * than our superclass. This function runs after qdev init
1300      * has set the defaults from the Property array and before
1301      * any user-specified property setting, so just modify the
1302      * value in the GICState struct.
1303      */
1304     DeviceState *dev = DEVICE(obj);
1305     NVICState *nvic = NVIC(obj);
1306     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1307 
1308     object_initialize(&nvic->systick, sizeof(nvic->systick), TYPE_SYSTICK);
1309     qdev_set_parent_bus(DEVICE(&nvic->systick), sysbus_get_default());
1310 
1311     sysbus_init_irq(sbd, &nvic->excpout);
1312     qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
1313     qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger", 1);
1314 }
1315 
1316 static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
1317 {
1318     DeviceClass *dc = DEVICE_CLASS(klass);
1319 
1320     dc->vmsd  = &vmstate_nvic;
1321     dc->props = props_nvic;
1322     dc->reset = armv7m_nvic_reset;
1323     dc->realize = armv7m_nvic_realize;
1324 }
1325 
1326 static const TypeInfo armv7m_nvic_info = {
1327     .name          = TYPE_NVIC,
1328     .parent        = TYPE_SYS_BUS_DEVICE,
1329     .instance_init = armv7m_nvic_instance_init,
1330     .instance_size = sizeof(NVICState),
1331     .class_init    = armv7m_nvic_class_init,
1332     .class_size    = sizeof(SysBusDeviceClass),
1333 };
1334 
1335 static void armv7m_nvic_register_types(void)
1336 {
1337     type_register_static(&armv7m_nvic_info);
1338 }
1339 
1340 type_init(armv7m_nvic_register_types)
1341