Lines Matching +full:non +full:- +full:secure

4  * Copyright (c) 2006-2007 CodeSourcery.
20 #include "hw/qdev-properties.h"
24 #include "target/arm/cpu-features.h"
25 #include "exec/exec-all.h"
33 * the num-irq property counts the number of external IRQ lines
44 * for (i = 1; i < s->num_irq; i++) to avoid the unused slot 0.
56 #define NVIC_MAX_IRQ (NVIC_MAX_VECTORS - NVIC_FIRST_IRQ)
62 /* Maximum priority of non-secure exceptions when AIRCR.PRIS is set */
71 if (qemu_irq_is_connected(s->sysresetreq)) { in signal_sysresetreq()
72 qemu_irq_pulse(s->sysresetreq); in signal_sysresetreq()
88 return s->vectpending_prio; in nvic_pending_prio()
95 * which matches the choice Cortex-M3 is documented as making).
101 * to fail an exception-return integrity check. The definition
103 * with the behaviour documented for the Cortex-M3.
108 bool check_sec = arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY); in nvic_rettobase()
110 for (irq = ARMV7M_EXCP_RESET; irq < s->num_irq; irq++) { in nvic_rettobase()
111 if (s->vectors[irq].active || in nvic_rettobase()
113 s->sec_vectors[irq].active)) { in nvic_rettobase()
137 if (s->vectpending > NVIC_FIRST_IRQ) { in nvic_isrpending()
141 for (irq = NVIC_FIRST_IRQ; irq < s->num_irq; irq++) { in nvic_isrpending()
142 if (s->vectors[irq].pending) { in nvic_isrpending()
163 * a priority value for an M-profile exception, leaving only
166 static inline uint32_t nvic_gprio_mask(NVICState *s, bool secure) in nvic_gprio_mask() argument
168 return ~0U << (s->prigroup[secure] + 1); in nvic_gprio_mask()
173 /* Return true if this non-banked exception targets Secure state. */ in exc_targets_secure()
174 if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) { in exc_targets_secure()
179 return !s->itns[exc]; in exc_targets_secure()
188 return !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK); in exc_targets_secure()
198 * non-existent exceptions will never be pended or active. in exc_targets_secure()
207 * (group-and-subgroup) priority value and whether it is targeting in exc_group_prio()
208 * secure state or not. in exc_group_prio()
218 (s->cpu->env.v7m.aircr & R_V7M_AIRCR_PRIS_MASK)) { in exc_group_prio()
237 * - lowest group priority; if both the same then in nvic_recompute_state_secure()
238 * - lowest subpriority; if both the same then in nvic_recompute_state_secure()
239 * - lowest exception number; if both the same (ie banked) then in nvic_recompute_state_secure()
240 * - secure exception takes precedence in nvic_recompute_state_secure()
245 for (i = 1; i < s->num_irq; i++) { in nvic_recompute_state_secure()
246 for (bank = M_REG_S; bank >= M_REG_NS; bank--) { in nvic_recompute_state_secure()
255 vec = &s->sec_vectors[i]; in nvic_recompute_state_secure()
258 vec = &s->vectors[i]; in nvic_recompute_state_secure()
262 prio = exc_group_prio(s, vec->prio, targets_secure); in nvic_recompute_state_secure()
263 subprio = vec->prio & ~nvic_gprio_mask(s, targets_secure); in nvic_recompute_state_secure()
264 if (vec->enabled && vec->pending && in nvic_recompute_state_secure()
272 if (vec->active && prio < active_prio) { in nvic_recompute_state_secure()
278 s->vectpending_is_s_banked = pending_is_s_banked; in nvic_recompute_state_secure()
279 s->vectpending = pend_irq; in nvic_recompute_state_secure()
280 s->vectpending_prio = pend_prio; in nvic_recompute_state_secure()
281 s->exception_prio = active_prio; in nvic_recompute_state_secure()
283 trace_nvic_recompute_state_secure(s->vectpending, in nvic_recompute_state_secure()
284 s->vectpending_is_s_banked, in nvic_recompute_state_secure()
285 s->vectpending_prio, in nvic_recompute_state_secure()
286 s->exception_prio); in nvic_recompute_state_secure()
301 * would be even worse, so we retain a separate non-secure-only in nvic_recompute_state()
304 if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) { in nvic_recompute_state()
309 for (i = 1; i < s->num_irq; i++) { in nvic_recompute_state()
310 VecInfo *vec = &s->vectors[i]; in nvic_recompute_state()
312 if (vec->enabled && vec->pending && vec->prio < pend_prio) { in nvic_recompute_state()
313 pend_prio = vec->prio; in nvic_recompute_state()
316 if (vec->active && vec->prio < active_prio) { in nvic_recompute_state()
317 active_prio = vec->prio; in nvic_recompute_state()
329 s->vectpending = pend_irq; in nvic_recompute_state()
330 s->vectpending_prio = pend_prio; in nvic_recompute_state()
331 s->exception_prio = active_prio; in nvic_recompute_state()
333 trace_nvic_recompute_state(s->vectpending, in nvic_recompute_state()
334 s->vectpending_prio, in nvic_recompute_state()
335 s->exception_prio); in nvic_recompute_state()
340 * This is a value between -2 (NMI priority) and NVIC_NOEXC_PRIO.
344 CPUARMState *env = &s->cpu->env; in nvic_exec_prio()
347 if (env->v7m.basepri[M_REG_NS] > 0) { in nvic_exec_prio()
348 running = exc_group_prio(s, env->v7m.basepri[M_REG_NS], M_REG_NS); in nvic_exec_prio()
351 if (env->v7m.basepri[M_REG_S] > 0) { in nvic_exec_prio()
352 int basepri = exc_group_prio(s, env->v7m.basepri[M_REG_S], M_REG_S); in nvic_exec_prio()
358 if (env->v7m.primask[M_REG_NS]) { in nvic_exec_prio()
359 if (env->v7m.aircr & R_V7M_AIRCR_PRIS_MASK) { in nvic_exec_prio()
368 if (env->v7m.primask[M_REG_S]) { in nvic_exec_prio()
372 if (env->v7m.faultmask[M_REG_NS]) { in nvic_exec_prio()
373 if (env->v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) { in nvic_exec_prio()
374 running = -1; in nvic_exec_prio()
376 if (env->v7m.aircr & R_V7M_AIRCR_PRIS_MASK) { in nvic_exec_prio()
386 if (env->v7m.faultmask[M_REG_S]) { in nvic_exec_prio()
387 running = (env->v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) ? -3 : -1; in nvic_exec_prio()
391 return MIN(running, s->exception_prio); in nvic_exec_prio()
394 bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure) in armv7m_nvic_neg_prio_requested() argument
404 if (s->cpu->env.v7m.faultmask[secure]) { in armv7m_nvic_neg_prio_requested()
408 if (secure ? s->sec_vectors[ARMV7M_EXCP_HARD].active : in armv7m_nvic_neg_prio_requested()
409 s->vectors[ARMV7M_EXCP_HARD].active) { in armv7m_nvic_neg_prio_requested()
413 if (s->vectors[ARMV7M_EXCP_NMI].active && in armv7m_nvic_neg_prio_requested()
414 exc_targets_secure(s, ARMV7M_EXCP_NMI) == secure) { in armv7m_nvic_neg_prio_requested()
428 return s->exception_prio; in armv7m_nvic_raw_execution_priority()
432 * secure indicates the bank to use for banked exceptions (we assert if
433 * we are passed secure=true for a non-banked exception).
435 static void set_prio(NVICState *s, unsigned irq, bool secure, uint8_t prio) in set_prio() argument
438 assert(irq < s->num_irq); in set_prio()
440 prio &= MAKE_64BIT_MASK(8 - s->num_prio_bits, s->num_prio_bits); in set_prio()
442 if (secure) { in set_prio()
444 s->sec_vectors[irq].prio = prio; in set_prio()
446 s->vectors[irq].prio = prio; in set_prio()
449 trace_nvic_set_prio(irq, secure, prio); in set_prio()
453 * secure indicates the bank to use for banked exceptions (we assert if
454 * we are passed secure=true for a non-banked exception).
456 static int get_prio(NVICState *s, unsigned irq, bool secure) in get_prio() argument
459 assert(irq < s->num_irq); in get_prio()
461 if (secure) { in get_prio()
463 return s->sec_vectors[irq].prio; in get_prio()
465 return s->vectors[irq].prio; in get_prio()
471 * vec->active, vec->enabled, vec->pending or vec->prio for any vector
488 lvl = (pend_prio < s->exception_prio); in nvic_irq_update()
489 trace_nvic_irq_update(s->vectpending, pend_prio, s->exception_prio, lvl); in nvic_irq_update()
490 qemu_set_irq(s->excpout, lvl); in nvic_irq_update()
497 * @secure: false for non-banked exceptions or for the nonsecure
498 * version of a banked exception, true for the secure version of a banked
502 * if @secure is true and @irq does not specify one of the fixed set
505 static void armv7m_nvic_clear_pending(NVICState *s, int irq, bool secure) in armv7m_nvic_clear_pending() argument
509 assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); in armv7m_nvic_clear_pending()
511 if (secure) { in armv7m_nvic_clear_pending()
513 vec = &s->sec_vectors[irq]; in armv7m_nvic_clear_pending()
515 vec = &s->vectors[irq]; in armv7m_nvic_clear_pending()
517 trace_nvic_clear_pending(irq, secure, vec->enabled, vec->prio); in armv7m_nvic_clear_pending()
518 if (vec->pending) { in armv7m_nvic_clear_pending()
519 vec->pending = 0; in armv7m_nvic_clear_pending()
524 static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure, in do_armv7m_nvic_set_pending() argument
536 * - s->vectpending is the "original exception" we were trying to take in do_armv7m_nvic_set_pending()
537 * - irq is the "derived exception" in do_armv7m_nvic_set_pending()
538 * - nvic_exec_prio(s) gives the priority before exception entry in do_armv7m_nvic_set_pending()
548 assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); in do_armv7m_nvic_set_pending()
549 assert(!secure || banked); in do_armv7m_nvic_set_pending()
551 vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq]; in do_armv7m_nvic_set_pending()
553 targets_secure = banked ? secure : exc_targets_secure(s, irq); in do_armv7m_nvic_set_pending()
555 trace_nvic_set_pending(irq, secure, targets_secure, in do_armv7m_nvic_set_pending()
556 derived, vec->enabled, vec->prio); in do_armv7m_nvic_set_pending()
563 exc_group_prio(s, vec->prio, secure) >= nvic_exec_prio(s)) { in do_armv7m_nvic_set_pending()
570 if (irq == ARMV7M_EXCP_HARD && vec->prio >= s->vectpending_prio) { in do_armv7m_nvic_set_pending()
582 cpu_abort(CPU(s->cpu), in do_armv7m_nvic_set_pending()
585 s->vectpending_prio); in do_armv7m_nvic_set_pending()
619 if (exc_group_prio(s, vec->prio, secure) >= running) { in do_armv7m_nvic_set_pending()
620 trace_nvic_escalate_prio(irq, vec->prio, running); in do_armv7m_nvic_set_pending()
622 } else if (!vec->enabled) { in do_armv7m_nvic_set_pending()
632 * we take a Secure HardFault. in do_armv7m_nvic_set_pending()
635 if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) && in do_armv7m_nvic_set_pending()
637 !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) { in do_armv7m_nvic_set_pending()
638 vec = &s->sec_vectors[irq]; in do_armv7m_nvic_set_pending()
640 vec = &s->vectors[irq]; in do_armv7m_nvic_set_pending()
642 if (running <= vec->prio) { in do_armv7m_nvic_set_pending()
648 cpu_abort(CPU(s->cpu), in do_armv7m_nvic_set_pending()
654 s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK; in do_armv7m_nvic_set_pending()
658 if (!vec->pending) { in do_armv7m_nvic_set_pending()
659 vec->pending = 1; in do_armv7m_nvic_set_pending()
664 void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure) in armv7m_nvic_set_pending() argument
666 do_armv7m_nvic_set_pending(s, irq, secure, false); in armv7m_nvic_set_pending()
669 void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure) in armv7m_nvic_set_pending_derived() argument
671 do_armv7m_nvic_set_pending(s, irq, secure, true); in armv7m_nvic_set_pending_derived()
674 void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure) in armv7m_nvic_set_pending_lazyfp() argument
688 * (in which case 'secure' tells us whether it is the S or NS version). in armv7m_nvic_set_pending_lazyfp()
689 * All the bits for the non-banked exceptions are in fpccr_s. in armv7m_nvic_set_pending_lazyfp()
691 uint32_t fpccr_s = s->cpu->env.v7m.fpccr[M_REG_S]; in armv7m_nvic_set_pending_lazyfp()
692 uint32_t fpccr = s->cpu->env.v7m.fpccr[secure]; in armv7m_nvic_set_pending_lazyfp()
694 assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); in armv7m_nvic_set_pending_lazyfp()
695 assert(!secure || banked); in armv7m_nvic_set_pending_lazyfp()
697 vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq]; in armv7m_nvic_set_pending_lazyfp()
699 targets_secure = banked ? secure : exc_targets_secure(s, irq); in armv7m_nvic_set_pending_lazyfp()
726 * Escalate to HardFault: faults that initially targeted Secure in armv7m_nvic_set_pending_lazyfp()
730 if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) && in armv7m_nvic_set_pending_lazyfp()
732 !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) { in armv7m_nvic_set_pending_lazyfp()
733 vec = &s->sec_vectors[irq]; in armv7m_nvic_set_pending_lazyfp()
735 vec = &s->vectors[irq]; in armv7m_nvic_set_pending_lazyfp()
739 if (!vec->enabled || in armv7m_nvic_set_pending_lazyfp()
740 nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) { in armv7m_nvic_set_pending_lazyfp()
744 * FP state belongs to prevents the exception pre-empting. in armv7m_nvic_set_pending_lazyfp()
746 cpu_abort(CPU(s->cpu), in armv7m_nvic_set_pending_lazyfp()
753 s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK; in armv7m_nvic_set_pending_lazyfp()
755 if (!vec->pending) { in armv7m_nvic_set_pending_lazyfp()
756 vec->pending = 1; in armv7m_nvic_set_pending_lazyfp()
772 CPUARMState *env = &s->cpu->env; in armv7m_nvic_acknowledge_irq()
773 const int pending = s->vectpending; in armv7m_nvic_acknowledge_irq()
777 assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq); in armv7m_nvic_acknowledge_irq()
779 if (s->vectpending_is_s_banked) { in armv7m_nvic_acknowledge_irq()
780 vec = &s->sec_vectors[pending]; in armv7m_nvic_acknowledge_irq()
782 vec = &s->vectors[pending]; in armv7m_nvic_acknowledge_irq()
785 assert(vec->enabled); in armv7m_nvic_acknowledge_irq()
786 assert(vec->pending); in armv7m_nvic_acknowledge_irq()
788 assert(s->vectpending_prio < running); in armv7m_nvic_acknowledge_irq()
790 trace_nvic_acknowledge_irq(pending, s->vectpending_prio); in armv7m_nvic_acknowledge_irq()
792 vec->active = 1; in armv7m_nvic_acknowledge_irq()
793 vec->pending = 0; in armv7m_nvic_acknowledge_irq()
795 write_v7m_exception(env, s->vectpending); in armv7m_nvic_acknowledge_irq()
802 /* Return true if s->vectpending targets Secure state */ in vectpending_targets_secure()
803 if (s->vectpending_is_s_banked) { in vectpending_targets_secure()
806 return !exc_is_banked(s->vectpending) && in vectpending_targets_secure()
807 exc_targets_secure(s, s->vectpending); in vectpending_targets_secure()
813 const int pending = s->vectpending; in armv7m_nvic_get_pending_irq_info()
816 assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq); in armv7m_nvic_get_pending_irq_info()
826 int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure) in armv7m_nvic_complete_irq() argument
831 assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); in armv7m_nvic_complete_irq()
833 trace_nvic_complete_irq(irq, secure); in armv7m_nvic_complete_irq()
835 if (secure && exc_is_banked(irq)) { in armv7m_nvic_complete_irq()
836 vec = &s->sec_vectors[irq]; in armv7m_nvic_complete_irq()
838 vec = &s->vectors[irq]; in armv7m_nvic_complete_irq()
846 if (!exc_is_banked(irq) && exc_targets_secure(s, irq) != secure) { in armv7m_nvic_complete_irq()
853 ret = -1; in armv7m_nvic_complete_irq()
855 } else if (!vec->active) { in armv7m_nvic_complete_irq()
857 ret = -1; in armv7m_nvic_complete_irq()
868 * IPSR and leaving the CPU in a negative-priority state. in armv7m_nvic_complete_irq()
871 if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) { in armv7m_nvic_complete_irq()
873 case -1: in armv7m_nvic_complete_irq()
874 if (s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) { in armv7m_nvic_complete_irq()
875 vec = &s->vectors[ARMV7M_EXCP_HARD]; in armv7m_nvic_complete_irq()
877 vec = &s->sec_vectors[ARMV7M_EXCP_HARD]; in armv7m_nvic_complete_irq()
880 case -2: in armv7m_nvic_complete_irq()
881 vec = &s->vectors[ARMV7M_EXCP_NMI]; in armv7m_nvic_complete_irq()
883 case -3: in armv7m_nvic_complete_irq()
884 vec = &s->sec_vectors[ARMV7M_EXCP_HARD]; in armv7m_nvic_complete_irq()
895 vec->active = 0; in armv7m_nvic_complete_irq()
896 if (vec->level) { in armv7m_nvic_complete_irq()
897 /* Re-pend the exception if it's still held high; only in armv7m_nvic_complete_irq()
901 vec->pending = 1; in armv7m_nvic_complete_irq()
909 bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure) in armv7m_nvic_get_ready_status() argument
916 * irq and secure have the same semantics as for armv7m_nvic_set_pending(): in armv7m_nvic_get_ready_status()
917 * for non-banked exceptions secure is always false; for banked exceptions in armv7m_nvic_get_ready_status()
924 assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); in armv7m_nvic_get_ready_status()
925 assert(!secure || banked); in armv7m_nvic_get_ready_status()
928 * HardFault is an odd special case: we always check against -1, in armv7m_nvic_get_ready_status()
929 * even if we're secure and HardFault has priority -3; we never in armv7m_nvic_get_ready_status()
933 return running > -1; in armv7m_nvic_get_ready_status()
936 vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq]; in armv7m_nvic_get_ready_status()
938 return vec->enabled && in armv7m_nvic_get_ready_status()
939 exc_group_prio(s, vec->prio, secure) < running; in armv7m_nvic_get_ready_status()
950 assert(n >= NVIC_FIRST_IRQ && n < s->num_irq); in set_irq_level()
958 * once, and the handler will re-run until the in set_irq_level()
961 vec = &s->vectors[n]; in set_irq_level()
962 if (level != vec->level) { in set_irq_level()
963 vec->level = level; in set_irq_level()
979 * the normal-interrupt behaviour of being resampled on in nvic_nmi_trigger()
990 ARMCPU *cpu = s->cpu; in nvic_readl()
995 if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) { in nvic_readl()
998 return ((s->num_irq - NVIC_FIRST_IRQ) / 32) - 1; in nvic_readl()
1000 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1004 * non-retentive power state, which allows us to RAZ/WI this. in nvic_readl()
1009 int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ; in nvic_readl()
1012 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1015 if (!attrs.secure) { in nvic_readl()
1019 for (i = 0; i < 32 && startvec + i < s->num_irq; i++) { in nvic_readl()
1020 if (s->itns[startvec + i]) { in nvic_readl()
1027 if (!arm_feature(&cpu->env, ARM_FEATURE_V8_1M)) { in nvic_readl()
1030 return cpu->revidr; in nvic_readl()
1032 return cpu->midr; in nvic_readl()
1035 val = cpu->env.v7m.exception; in nvic_readl()
1037 if (s->vectpending) { in nvic_readl()
1041 * exception targets Secure. in nvic_readl()
1043 int vp = s->vectpending; in nvic_readl()
1044 if (!attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_V8_1M) && in nvic_readl()
1050 /* ISRPENDING - set if any external IRQ is pending */ in nvic_readl()
1054 /* RETTOBASE - set if only one handler is active */ in nvic_readl()
1058 if (attrs.secure) { in nvic_readl()
1060 if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].pending) { in nvic_readl()
1064 if (s->sec_vectors[ARMV7M_EXCP_PENDSV].pending) { in nvic_readl()
1069 if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) { in nvic_readl()
1073 if (s->vectors[ARMV7M_EXCP_PENDSV].pending) { in nvic_readl()
1078 if ((attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) in nvic_readl()
1079 && s->vectors[ARMV7M_EXCP_NMI].pending) { in nvic_readl()
1086 return cpu->env.v7m.vecbase[attrs.secure]; in nvic_readl()
1088 val = 0xfa050000 | (s->prigroup[attrs.secure] << 8); in nvic_readl()
1089 if (attrs.secure) { in nvic_readl()
1090 /* s->aircr stores PRIS, BFHFNMINS, SYSRESETREQS */ in nvic_readl()
1091 val |= cpu->env.v7m.aircr; in nvic_readl()
1093 if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1098 val |= cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK; in nvic_readl()
1103 if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) { in nvic_readl()
1106 return cpu->env.v7m.scr[attrs.secure]; in nvic_readl()
1109 * Non-banked bits: BFHFNMIGN (stored in the NS copy of the register) in nvic_readl()
1112 val = cpu->env.v7m.ccr[attrs.secure]; in nvic_readl()
1113 val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK; in nvic_readl()
1115 if (!attrs.secure) { in nvic_readl()
1116 if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { in nvic_readl()
1122 if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) { in nvic_readl()
1126 if (attrs.secure) { in nvic_readl()
1127 if (s->sec_vectors[ARMV7M_EXCP_MEM].active) { in nvic_readl()
1130 if (s->sec_vectors[ARMV7M_EXCP_HARD].active) { in nvic_readl()
1133 if (s->sec_vectors[ARMV7M_EXCP_USAGE].active) { in nvic_readl()
1136 if (s->sec_vectors[ARMV7M_EXCP_SVC].active) { in nvic_readl()
1139 if (s->sec_vectors[ARMV7M_EXCP_PENDSV].active) { in nvic_readl()
1142 if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].active) { in nvic_readl()
1145 if (s->sec_vectors[ARMV7M_EXCP_USAGE].pending) { in nvic_readl()
1148 if (s->sec_vectors[ARMV7M_EXCP_MEM].pending) { in nvic_readl()
1151 if (s->sec_vectors[ARMV7M_EXCP_SVC].pending) { in nvic_readl()
1154 if (s->sec_vectors[ARMV7M_EXCP_MEM].enabled) { in nvic_readl()
1157 if (s->sec_vectors[ARMV7M_EXCP_USAGE].enabled) { in nvic_readl()
1160 if (s->sec_vectors[ARMV7M_EXCP_HARD].pending) { in nvic_readl()
1164 if (s->vectors[ARMV7M_EXCP_SECURE].active) { in nvic_readl()
1167 if (s->vectors[ARMV7M_EXCP_SECURE].enabled) { in nvic_readl()
1170 if (s->vectors[ARMV7M_EXCP_SECURE].pending) { in nvic_readl()
1174 if (s->vectors[ARMV7M_EXCP_MEM].active) { in nvic_readl()
1177 if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1179 if (s->vectors[ARMV7M_EXCP_HARD].active) { in nvic_readl()
1182 if (s->vectors[ARMV7M_EXCP_HARD].pending) { in nvic_readl()
1186 if (s->vectors[ARMV7M_EXCP_USAGE].active) { in nvic_readl()
1189 if (s->vectors[ARMV7M_EXCP_SVC].active) { in nvic_readl()
1192 if (s->vectors[ARMV7M_EXCP_PENDSV].active) { in nvic_readl()
1195 if (s->vectors[ARMV7M_EXCP_SYSTICK].active) { in nvic_readl()
1198 if (s->vectors[ARMV7M_EXCP_USAGE].pending) { in nvic_readl()
1201 if (s->vectors[ARMV7M_EXCP_MEM].pending) { in nvic_readl()
1204 if (s->vectors[ARMV7M_EXCP_SVC].pending) { in nvic_readl()
1207 if (s->vectors[ARMV7M_EXCP_MEM].enabled) { in nvic_readl()
1210 if (s->vectors[ARMV7M_EXCP_USAGE].enabled) { in nvic_readl()
1214 if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { in nvic_readl()
1215 if (s->vectors[ARMV7M_EXCP_BUS].active) { in nvic_readl()
1218 if (s->vectors[ARMV7M_EXCP_BUS].pending) { in nvic_readl()
1221 if (s->vectors[ARMV7M_EXCP_BUS].enabled) { in nvic_readl()
1224 if (arm_feature(&cpu->env, ARM_FEATURE_V8) && in nvic_readl()
1225 s->vectors[ARMV7M_EXCP_NMI].active) { in nvic_readl()
1232 if (s->vectors[ARMV7M_EXCP_DEBUG].active) { in nvic_readl()
1237 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1240 return cpu->env.v7m.hfsr; in nvic_readl()
1242 return cpu->env.v7m.dfsr; in nvic_readl()
1244 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1247 return cpu->env.v7m.mmfar[attrs.secure]; in nvic_readl()
1249 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1252 if (!attrs.secure && in nvic_readl()
1253 !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { in nvic_readl()
1256 return cpu->env.v7m.bfar; in nvic_readl()
1263 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1266 return cpu->isar.id_pfr0; in nvic_readl()
1268 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1271 return cpu->isar.id_pfr1; in nvic_readl()
1273 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1276 return cpu->isar.id_dfr0; in nvic_readl()
1278 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1281 return cpu->id_afr0; in nvic_readl()
1283 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1286 return cpu->isar.id_mmfr0; in nvic_readl()
1288 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1291 return cpu->isar.id_mmfr1; in nvic_readl()
1293 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1296 return cpu->isar.id_mmfr2; in nvic_readl()
1298 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1301 return cpu->isar.id_mmfr3; in nvic_readl()
1303 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1306 return cpu->isar.id_isar0; in nvic_readl()
1308 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1311 return cpu->isar.id_isar1; in nvic_readl()
1313 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1316 return cpu->isar.id_isar2; in nvic_readl()
1318 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1321 return cpu->isar.id_isar3; in nvic_readl()
1323 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1326 return cpu->isar.id_isar4; in nvic_readl()
1328 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_readl()
1331 return cpu->isar.id_isar5; in nvic_readl()
1333 return cpu->clidr; in nvic_readl()
1335 return cpu->ctr; in nvic_readl()
1338 int idx = cpu->env.v7m.csselr[attrs.secure] & R_V7M_CSSELR_INDEX_MASK; in nvic_readl()
1339 return cpu->ccsidr[idx]; in nvic_readl()
1342 return cpu->env.v7m.csselr[attrs.secure]; in nvic_readl()
1347 return cpu->env.v7m.cpacr[attrs.secure]; in nvic_readl()
1349 if (!attrs.secure || !cpu_isar_feature(aa32_vfp_simd, cpu)) { in nvic_readl()
1352 return cpu->env.v7m.nsacr; in nvic_readl()
1356 return cpu->pmsav7_dregion << 8; in nvic_readl()
1358 return cpu->env.v7m.mpu_ctrl[attrs.secure]; in nvic_readl()
1360 return cpu->env.pmsav7.rnr[attrs.secure]; in nvic_readl()
1366 int region = cpu->env.pmsav7.rnr[attrs.secure]; in nvic_readl()
1368 if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1374 int aliasno = (offset - 0xd9c) / 8; /* 0..3 */ in nvic_readl()
1378 if (region >= cpu->pmsav7_dregion) { in nvic_readl()
1381 return cpu->env.pmsav8.rbar[attrs.secure][region]; in nvic_readl()
1384 if (region >= cpu->pmsav7_dregion) { in nvic_readl()
1387 return (cpu->env.pmsav7.drbar[region] & ~0x1f) | (region & 0xf); in nvic_readl()
1394 int region = cpu->env.pmsav7.rnr[attrs.secure]; in nvic_readl()
1396 if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1401 int aliasno = (offset - 0xda0) / 8; /* 0..3 */ in nvic_readl()
1405 if (region >= cpu->pmsav7_dregion) { in nvic_readl()
1408 return cpu->env.pmsav8.rlar[attrs.secure][region]; in nvic_readl()
1411 if (region >= cpu->pmsav7_dregion) { in nvic_readl()
1414 return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) | in nvic_readl()
1415 (cpu->env.pmsav7.drsr[region] & 0xffff); in nvic_readl()
1418 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1421 return cpu->env.pmsav8.mair0[attrs.secure]; in nvic_readl()
1423 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1426 return cpu->env.pmsav8.mair1[attrs.secure]; in nvic_readl()
1428 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1431 if (!attrs.secure) { in nvic_readl()
1434 return cpu->env.sau.ctrl; in nvic_readl()
1436 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1439 if (!attrs.secure) { in nvic_readl()
1442 return cpu->sau_sregion; in nvic_readl()
1444 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1447 if (!attrs.secure) { in nvic_readl()
1450 return cpu->env.sau.rnr; in nvic_readl()
1453 int region = cpu->env.sau.rnr; in nvic_readl()
1455 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1458 if (!attrs.secure) { in nvic_readl()
1461 if (region >= cpu->sau_sregion) { in nvic_readl()
1464 return cpu->env.sau.rbar[region]; in nvic_readl()
1468 int region = cpu->env.sau.rnr; in nvic_readl()
1470 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1473 if (!attrs.secure) { in nvic_readl()
1476 if (region >= cpu->sau_sregion) { in nvic_readl()
1479 return cpu->env.sau.rlar[region]; in nvic_readl()
1482 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1485 if (!attrs.secure) { in nvic_readl()
1488 return cpu->env.v7m.sfsr; in nvic_readl()
1490 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_readl()
1493 if (!attrs.secure) { in nvic_readl()
1496 return cpu->env.v7m.sfar; in nvic_readl()
1501 /* We provide minimal-RAS only: RFSR is RAZ/WI */ in nvic_readl()
1507 if (attrs.secure) { in nvic_readl()
1508 return cpu->env.v7m.fpccr[M_REG_S]; in nvic_readl()
1513 * other non-banked bits RAZ. in nvic_readl()
1516 uint32_t value = cpu->env.v7m.fpccr[M_REG_S]; in nvic_readl()
1521 if (s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) { in nvic_readl()
1527 value |= cpu->env.v7m.fpccr[M_REG_NS]; in nvic_readl()
1534 return cpu->env.v7m.fpcar[attrs.secure]; in nvic_readl()
1539 return cpu->env.v7m.fpdscr[attrs.secure]; in nvic_readl()
1541 return cpu->isar.mvfr0; in nvic_readl()
1543 return cpu->isar.mvfr1; in nvic_readl()
1545 return cpu->isar.mvfr2; in nvic_readl()
1556 ARMCPU *cpu = s->cpu; in nvic_writel()
1560 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1567 int startvec = 8 * (offset - 0x380) + NVIC_FIRST_IRQ; in nvic_writel()
1570 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1573 if (!attrs.secure) { in nvic_writel()
1576 for (i = 0; i < 32 && startvec + i < s->num_irq; i++) { in nvic_writel()
1577 s->itns[startvec + i] = (value >> i) & 1; in nvic_writel()
1583 if (attrs.secure || cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) { in nvic_writel()
1587 arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1593 armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure); in nvic_writel()
1595 armv7m_nvic_clear_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure); in nvic_writel()
1598 armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure); in nvic_writel()
1600 armv7m_nvic_clear_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure); in nvic_writel()
1604 cpu->env.v7m.vecbase[attrs.secure] = value & 0xffffff80; in nvic_writel()
1609 if (attrs.secure || in nvic_writel()
1610 !(cpu->env.v7m.aircr & R_V7M_AIRCR_SYSRESETREQS_MASK)) { in nvic_writel()
1625 if (arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_writel()
1626 s->prigroup[attrs.secure] = in nvic_writel()
1632 if (attrs.secure) { in nvic_writel()
1633 /* These bits are only writable by secure */ in nvic_writel()
1634 cpu->env.v7m.aircr = value & in nvic_writel()
1638 /* BFHFNMINS changes the priority of Secure HardFault, and in nvic_writel()
1639 * allows a pending Non-secure HardFault to preempt (which in nvic_writel()
1642 if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) { in nvic_writel()
1643 s->sec_vectors[ARMV7M_EXCP_HARD].prio = -3; in nvic_writel()
1644 s->vectors[ARMV7M_EXCP_HARD].enabled = 1; in nvic_writel()
1646 s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1; in nvic_writel()
1647 s->vectors[ARMV7M_EXCP_HARD].enabled = 0; in nvic_writel()
1654 if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) { in nvic_writel()
1657 /* We don't implement deep-sleep so these bits are RAZ/WI. in nvic_writel()
1663 cpu->env.v7m.scr[attrs.secure] = value; in nvic_writel()
1669 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_writel()
1673 /* Enforce RAZ/WI on reserved and must-RAZ/WI bits */ in nvic_writel()
1680 if (arm_feature(&cpu->env, ARM_FEATURE_V8_1M) && attrs.secure) { in nvic_writel()
1686 if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1691 if (attrs.secure) { in nvic_writel()
1693 cpu->env.v7m.ccr[M_REG_NS] = in nvic_writel()
1694 (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK) in nvic_writel()
1702 if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { in nvic_writel()
1704 value |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK; in nvic_writel()
1708 cpu->env.v7m.ccr[attrs.secure] = value; in nvic_writel()
1712 if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) { in nvic_writel()
1715 if (attrs.secure) { in nvic_writel()
1716 s->sec_vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0; in nvic_writel()
1717 /* Secure HardFault active bit cannot be written */ in nvic_writel()
1718 s->sec_vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0; in nvic_writel()
1719 s->sec_vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0; in nvic_writel()
1720 s->sec_vectors[ARMV7M_EXCP_PENDSV].active = in nvic_writel()
1722 s->sec_vectors[ARMV7M_EXCP_SYSTICK].active = in nvic_writel()
1724 s->sec_vectors[ARMV7M_EXCP_USAGE].pending = in nvic_writel()
1726 s->sec_vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0; in nvic_writel()
1727 s->sec_vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0; in nvic_writel()
1728 s->sec_vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0; in nvic_writel()
1729 s->sec_vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0; in nvic_writel()
1730 s->sec_vectors[ARMV7M_EXCP_USAGE].enabled = in nvic_writel()
1732 s->sec_vectors[ARMV7M_EXCP_HARD].pending = (value & (1 << 21)) != 0; in nvic_writel()
1734 s->vectors[ARMV7M_EXCP_SECURE].active = (value & (1 << 4)) != 0; in nvic_writel()
1735 s->vectors[ARMV7M_EXCP_SECURE].enabled = (value & (1 << 19)) != 0; in nvic_writel()
1736 s->vectors[ARMV7M_EXCP_SECURE].pending = (value & (1 << 20)) != 0; in nvic_writel()
1738 s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0; in nvic_writel()
1739 if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1741 s->vectors[ARMV7M_EXCP_HARD].pending = (value & (1 << 21)) != 0; in nvic_writel()
1743 s->vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0; in nvic_writel()
1744 s->vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0; in nvic_writel()
1745 s->vectors[ARMV7M_EXCP_PENDSV].active = (value & (1 << 10)) != 0; in nvic_writel()
1746 s->vectors[ARMV7M_EXCP_SYSTICK].active = (value & (1 << 11)) != 0; in nvic_writel()
1747 s->vectors[ARMV7M_EXCP_USAGE].pending = (value & (1 << 12)) != 0; in nvic_writel()
1748 s->vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0; in nvic_writel()
1749 s->vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0; in nvic_writel()
1750 s->vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0; in nvic_writel()
1751 s->vectors[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0; in nvic_writel()
1753 if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { in nvic_writel()
1754 s->vectors[ARMV7M_EXCP_BUS].active = (value & (1 << 1)) != 0; in nvic_writel()
1755 s->vectors[ARMV7M_EXCP_BUS].pending = (value & (1 << 14)) != 0; in nvic_writel()
1756 s->vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0; in nvic_writel()
1759 * BFHFNMINS 1, and by the CPU in secure state via the NS alias. in nvic_writel()
1761 if (!attrs.secure && cpu->env.v7m.secure && in nvic_writel()
1762 (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) && in nvic_writel()
1764 s->vectors[ARMV7M_EXCP_NMI].active = 0; in nvic_writel()
1767 * to the non-secure HardFault state by the CPU in secure state. in nvic_writel()
1768 * The only case where we can be targeting the non-secure HF state in nvic_writel()
1769 * when in secure state is if this is a write via the NS alias in nvic_writel()
1772 if (!attrs.secure && cpu->env.v7m.secure && in nvic_writel()
1773 (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) && in nvic_writel()
1775 s->vectors[ARMV7M_EXCP_HARD].active = 0; in nvic_writel()
1779 s->vectors[ARMV7M_EXCP_DEBUG].active = (value & (1 << 8)) != 0; in nvic_writel()
1783 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_writel()
1786 cpu->env.v7m.hfsr &= ~value; /* W1C */ in nvic_writel()
1789 cpu->env.v7m.dfsr &= ~value; /* W1C */ in nvic_writel()
1792 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_writel()
1795 cpu->env.v7m.mmfar[attrs.secure] = value; in nvic_writel()
1798 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_writel()
1801 if (!attrs.secure && in nvic_writel()
1802 !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { in nvic_writel()
1805 cpu->env.v7m.bfar = value; in nvic_writel()
1813 cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK; in nvic_writel()
1819 cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20); in nvic_writel()
1823 if (attrs.secure && cpu_isar_feature(aa32_vfp_simd, cpu)) { in nvic_writel()
1825 cpu->env.v7m.nsacr = value & (3 << 10); in nvic_writel()
1837 cpu->env.v7m.mpu_ctrl[attrs.secure] in nvic_writel()
1844 if (value >= cpu->pmsav7_dregion) { in nvic_writel()
1847 value, cpu->pmsav7_dregion); in nvic_writel()
1849 cpu->env.pmsav7.rnr[attrs.secure] = value; in nvic_writel()
1859 if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1865 int aliasno = (offset - 0xd9c) / 8; /* 0..3 */ in nvic_writel()
1867 region = cpu->env.pmsav7.rnr[attrs.secure]; in nvic_writel()
1871 if (region >= cpu->pmsav7_dregion) { in nvic_writel()
1874 cpu->env.pmsav8.rbar[attrs.secure][region] = value; in nvic_writel()
1884 if (region >= cpu->pmsav7_dregion) { in nvic_writel()
1887 region, cpu->pmsav7_dregion); in nvic_writel()
1890 cpu->env.pmsav7.rnr[attrs.secure] = region; in nvic_writel()
1892 region = cpu->env.pmsav7.rnr[attrs.secure]; in nvic_writel()
1895 if (region >= cpu->pmsav7_dregion) { in nvic_writel()
1899 cpu->env.pmsav7.drbar[region] = value & ~0x1f; in nvic_writel()
1908 int region = cpu->env.pmsav7.rnr[attrs.secure]; in nvic_writel()
1910 if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1915 int aliasno = (offset - 0xd9c) / 8; /* 0..3 */ in nvic_writel()
1917 region = cpu->env.pmsav7.rnr[attrs.secure]; in nvic_writel()
1921 if (region >= cpu->pmsav7_dregion) { in nvic_writel()
1924 cpu->env.pmsav8.rlar[attrs.secure][region] = value; in nvic_writel()
1929 if (region >= cpu->pmsav7_dregion) { in nvic_writel()
1933 cpu->env.pmsav7.drsr[region] = value & 0xff3f; in nvic_writel()
1934 cpu->env.pmsav7.dracr[region] = (value >> 16) & 0x173f; in nvic_writel()
1939 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1942 if (cpu->pmsav7_dregion) { in nvic_writel()
1944 cpu->env.pmsav8.mair0[attrs.secure] = value; in nvic_writel()
1951 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1954 if (cpu->pmsav7_dregion) { in nvic_writel()
1956 cpu->env.pmsav8.mair1[attrs.secure] = value; in nvic_writel()
1963 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1966 if (!attrs.secure) { in nvic_writel()
1969 cpu->env.sau.ctrl = value & 3; in nvic_writel()
1972 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1977 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1980 if (!attrs.secure) { in nvic_writel()
1983 if (value >= cpu->sau_sregion) { in nvic_writel()
1986 value, cpu->sau_sregion); in nvic_writel()
1988 cpu->env.sau.rnr = value; in nvic_writel()
1993 int region = cpu->env.sau.rnr; in nvic_writel()
1995 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
1998 if (!attrs.secure) { in nvic_writel()
2001 if (region >= cpu->sau_sregion) { in nvic_writel()
2004 cpu->env.sau.rbar[region] = value & ~0x1f; in nvic_writel()
2010 int region = cpu->env.sau.rnr; in nvic_writel()
2012 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
2015 if (!attrs.secure) { in nvic_writel()
2018 if (region >= cpu->sau_sregion) { in nvic_writel()
2021 cpu->env.sau.rlar[region] = value & ~0x1c; in nvic_writel()
2026 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
2029 if (!attrs.secure) { in nvic_writel()
2032 cpu->env.v7m.sfsr &= ~value; /* W1C */ in nvic_writel()
2035 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
2038 if (!attrs.secure) { in nvic_writel()
2041 cpu->env.v7m.sfsr = value; in nvic_writel()
2047 if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_writel()
2051 if (excnum < s->num_irq) { in nvic_writel()
2060 /* We provide minimal-RAS only: RFSR is RAZ/WI */ in nvic_writel()
2067 if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { in nvic_writel()
2081 if (!attrs.secure) { in nvic_writel()
2082 /* Some non-banked bits are configurably writable by NS */ in nvic_writel()
2083 fpccr_s = cpu->env.v7m.fpccr[M_REG_S]; in nvic_writel()
2092 if ((s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { in nvic_writel()
2105 * All other non-banked bits are RAZ/WI from NS; write in nvic_writel()
2109 cpu->env.v7m.fpccr[M_REG_NS] = value; in nvic_writel()
2113 cpu->env.v7m.fpccr[M_REG_S] = fpccr_s; in nvic_writel()
2119 cpu->env.v7m.fpcar[attrs.secure] = value; in nvic_writel()
2132 cpu->env.v7m.fpdscr[attrs.secure] = value; in nvic_writel()
2160 * controls access even though the CPU is in Secure state (I_QDKX). in nvic_user_access_ok()
2162 return s->cpu->env.v7m.ccr[attrs.secure] & R_V7M_CCR_USERSETMPEND_MASK; in nvic_user_access_ok()
2173 * non-banked exceptions), M_REG_S for the secure version of in shpr_bank()
2174 * a banked exception, and -1 if this field should RAZ/WI. in shpr_bank()
2183 return attrs.secure; in shpr_bank()
2186 if (!attrs.secure && in shpr_bank()
2187 !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { in shpr_bank()
2188 return -1; in shpr_bank()
2193 if (!attrs.secure) { in shpr_bank()
2194 return -1; in shpr_bank()
2203 return -1; in shpr_bank()
2231 startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ; /* vector # */ in nvic_sysreg_read()
2233 for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { in nvic_sysreg_read()
2234 if (s->vectors[startvec + i].enabled && in nvic_sysreg_read()
2235 (attrs.secure || s->itns[startvec + i])) { in nvic_sysreg_read()
2245 startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */ in nvic_sysreg_read()
2246 for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { in nvic_sysreg_read()
2247 if (s->vectors[startvec + i].pending && in nvic_sysreg_read()
2248 (attrs.secure || s->itns[startvec + i])) { in nvic_sysreg_read()
2256 if (!arm_feature(&s->cpu->env, ARM_FEATURE_V7)) { in nvic_sysreg_read()
2260 startvec = 8 * (offset - 0x300) + NVIC_FIRST_IRQ; /* vector # */ in nvic_sysreg_read()
2262 for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { in nvic_sysreg_read()
2263 if (s->vectors[startvec + i].active && in nvic_sysreg_read()
2264 (attrs.secure || s->itns[startvec + i])) { in nvic_sysreg_read()
2271 startvec = offset - 0x400 + NVIC_FIRST_IRQ; /* vector # */ in nvic_sysreg_read()
2273 for (i = 0; i < size && startvec + i < s->num_irq; i++) { in nvic_sysreg_read()
2274 if (attrs.secure || s->itns[startvec + i]) { in nvic_sysreg_read()
2275 val |= s->vectors[startvec + i].prio << (8 * i); in nvic_sysreg_read()
2280 if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_sysreg_read()
2288 unsigned hdlidx = (offset - 0xd14) + i; in nvic_sysreg_read()
2298 if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_sysreg_read()
2307 val = s->cpu->env.v7m.cfsr[attrs.secure]; in nvic_sysreg_read()
2308 if (!attrs.secure && in nvic_sysreg_read()
2309 !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { in nvic_sysreg_read()
2312 val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK; in nvic_sysreg_read()
2314 val = extract32(val, (offset - 0xd28) * 8, size * 8); in nvic_sysreg_read()
2320 val = nvic_id[(offset - 0xfe0) >> 2]; in nvic_sysreg_read()
2361 startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ; in nvic_sysreg_write()
2363 for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { in nvic_sysreg_write()
2365 (attrs.secure || s->itns[startvec + i])) { in nvic_sysreg_write()
2366 s->vectors[startvec + i].enabled = setval; in nvic_sysreg_write()
2379 startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */ in nvic_sysreg_write()
2381 for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { in nvic_sysreg_write()
2388 (attrs.secure || s->itns[startvec + i]) && in nvic_sysreg_write()
2389 !(setval == 0 && s->vectors[startvec + i].level && in nvic_sysreg_write()
2390 !s->vectors[startvec + i].active)) { in nvic_sysreg_write()
2391 s->vectors[startvec + i].pending = setval; in nvic_sysreg_write()
2399 startvec = (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */ in nvic_sysreg_write()
2401 for (i = 0; i < size && startvec + i < s->num_irq; i++) { in nvic_sysreg_write()
2402 if (attrs.secure || s->itns[startvec + i]) { in nvic_sysreg_write()
2409 if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_sysreg_write()
2415 unsigned hdlidx = (offset - 0xd14) + i; in nvic_sysreg_write()
2427 if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) { in nvic_sysreg_write()
2433 value <<= ((offset - 0xd28) * 8); in nvic_sysreg_write()
2435 if (!attrs.secure && in nvic_sysreg_write()
2436 !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { in nvic_sysreg_write()
2441 s->cpu->env.v7m.cfsr[attrs.secure] &= ~value; in nvic_sysreg_write()
2442 if (attrs.secure) { in nvic_sysreg_write()
2446 s->cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK); in nvic_sysreg_write()
2461 arm_rebuild_hflags(&s->cpu->env); in nvic_sysreg_write()
2479 resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3; in nvic_post_load()
2481 if (s->vectors[ARMV7M_EXCP_RESET].prio != resetprio || in nvic_post_load()
2482 s->vectors[ARMV7M_EXCP_NMI].prio != -2 || in nvic_post_load()
2483 s->vectors[ARMV7M_EXCP_HARD].prio != -1) { in nvic_post_load()
2486 for (i = ARMV7M_EXCP_MEM; i < s->num_irq; i++) { in nvic_post_load()
2487 if (s->vectors[i].prio & ~0xff) { in nvic_post_load()
2515 return arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY); in nvic_security_needed()
2524 if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1 in nvic_security_post_load()
2525 && s->sec_vectors[ARMV7M_EXCP_HARD].prio != -3) { in nvic_security_post_load()
2526 /* We can't cross-check against AIRCR.BFHFNMINS as we don't know in nvic_security_post_load()
2532 for (i = ARMV7M_EXCP_MEM; i < ARRAY_SIZE(s->sec_vectors); i++) { in nvic_security_post_load()
2533 if (s->sec_vectors[i].prio & ~0xff) { in nvic_security_post_load()
2541 .name = "armv7m_nvic/m-security",
2574 DEFINE_PROP_UINT32("num-irq", NVICState, num_irq, 64),
2579 DEFINE_PROP_UINT8("num-prio-bits", NVICState, num_prio_bits, 0),
2588 memset(s->vectors, 0, sizeof(s->vectors)); in armv7m_nvic_reset()
2589 memset(s->sec_vectors, 0, sizeof(s->sec_vectors)); in armv7m_nvic_reset()
2590 s->prigroup[M_REG_NS] = 0; in armv7m_nvic_reset()
2591 s->prigroup[M_REG_S] = 0; in armv7m_nvic_reset()
2593 s->vectors[ARMV7M_EXCP_NMI].enabled = 1; in armv7m_nvic_reset()
2597 s->vectors[ARMV7M_EXCP_SVC].enabled = 1; in armv7m_nvic_reset()
2598 s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1; in armv7m_nvic_reset()
2599 s->vectors[ARMV7M_EXCP_SYSTICK].enabled = 1; in armv7m_nvic_reset()
2602 s->vectors[ARMV7M_EXCP_DEBUG].enabled = 0; in armv7m_nvic_reset()
2604 resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3; in armv7m_nvic_reset()
2605 s->vectors[ARMV7M_EXCP_RESET].prio = resetprio; in armv7m_nvic_reset()
2606 s->vectors[ARMV7M_EXCP_NMI].prio = -2; in armv7m_nvic_reset()
2607 s->vectors[ARMV7M_EXCP_HARD].prio = -1; in armv7m_nvic_reset()
2609 if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) { in armv7m_nvic_reset()
2610 s->sec_vectors[ARMV7M_EXCP_HARD].enabled = 1; in armv7m_nvic_reset()
2611 s->sec_vectors[ARMV7M_EXCP_SVC].enabled = 1; in armv7m_nvic_reset()
2612 s->sec_vectors[ARMV7M_EXCP_PENDSV].enabled = 1; in armv7m_nvic_reset()
2613 s->sec_vectors[ARMV7M_EXCP_SYSTICK].enabled = 1; in armv7m_nvic_reset()
2615 /* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC) */ in armv7m_nvic_reset()
2616 s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1; in armv7m_nvic_reset()
2618 s->vectors[ARMV7M_EXCP_HARD].enabled = 0; in armv7m_nvic_reset()
2620 s->vectors[ARMV7M_EXCP_HARD].enabled = 1; in armv7m_nvic_reset()
2629 s->exception_prio = NVIC_NOEXC_PRIO; in armv7m_nvic_reset()
2630 s->vectpending = 0; in armv7m_nvic_reset()
2631 s->vectpending_is_s_banked = false; in armv7m_nvic_reset()
2632 s->vectpending_prio = NVIC_NOEXC_PRIO; in armv7m_nvic_reset()
2634 if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) { in armv7m_nvic_reset()
2635 memset(s->itns, 0, sizeof(s->itns)); in armv7m_nvic_reset()
2637 /* This state is constant and not guest accessible in a non-security in armv7m_nvic_reset()
2643 for (i = NVIC_FIRST_IRQ; i < ARRAY_SIZE(s->itns); i++) { in armv7m_nvic_reset()
2644 s->itns[i] = true; in armv7m_nvic_reset()
2654 arm_rebuild_hflags(&s->cpu->env); in armv7m_nvic_reset()
2667 * n == 1 : Secure systick in nvic_systick_trigger()
2678 if (!s->cpu || !arm_feature(&s->cpu->env, ARM_FEATURE_M)) { in armv7m_nvic_realize()
2679 error_setg(errp, "The NVIC can only be used with a Cortex-M CPU"); in armv7m_nvic_realize()
2683 if (s->num_irq > NVIC_MAX_IRQ) { in armv7m_nvic_realize()
2684 error_setg(errp, "num-irq %d exceeds NVIC maximum", s->num_irq); in armv7m_nvic_realize()
2688 qdev_init_gpio_in(dev, set_irq_level, s->num_irq); in armv7m_nvic_realize()
2691 s->num_irq += NVIC_FIRST_IRQ; in armv7m_nvic_realize()
2693 if (s->num_prio_bits == 0) { in armv7m_nvic_realize()
2695 * If left unspecified, use 2 bits by default on Cortex-M0/M0+/M1 in armv7m_nvic_realize()
2698 s->num_prio_bits = arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 8 : 2; in armv7m_nvic_realize()
2701 arm_feature(&s->cpu->env, ARM_FEATURE_V7) ? 3 : 2; in armv7m_nvic_realize()
2702 if (s->num_prio_bits < min_prio_bits || s->num_prio_bits > 8) { in armv7m_nvic_realize()
2704 "num-prio-bits %d is outside " in armv7m_nvic_realize()
2705 "NVIC acceptable range [%d-8]", in armv7m_nvic_realize()
2706 s->num_prio_bits, min_prio_bits); in armv7m_nvic_realize()
2716 memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s, in armv7m_nvic_realize()
2718 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->sysregmem); in armv7m_nvic_realize()
2727 sysbus_init_irq(sbd, &nvic->excpout); in armv7m_nvic_instance_init()
2728 qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1); in armv7m_nvic_instance_init()
2729 qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger", in armv7m_nvic_instance_init()
2738 dc->vmsd = &vmstate_nvic; in armv7m_nvic_class_init()
2741 dc->realize = armv7m_nvic_realize; in armv7m_nvic_class_init()