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