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