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