qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

armv7m_nvic.c (93708B)


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