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