aboutsummaryrefslogtreecommitdiff
path: root/hw/intc/armv7m_nvic.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-05-08 00:06:43 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-05-08 00:06:43 +0100
commit629d166994725773dea9cef843fcb0ae5f3585fe (patch)
tree266ee580fe4be6008c5d4cdf1e3bc3b467ab2dcb /hw/intc/armv7m_nvic.c
parenta6f6d24757a73f7176989134b97284a1a7df11e5 (diff)
parent63159601fb3e396b28da14cbb71e50ed3f5a0331 (diff)
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190507' into staging
target-arm queue: * Stop using variable length array in dc_zva * Implement M-profile XPSR GE bits * Don't enable ARMV7M_EXCP_DEBUG from reset * armv7m_nvic: NS BFAR and BFSR are RAZ/WI if BFHFNMINS == 0 * armv7m_nvic: Check subpriority in nvic_recompute_state_secure() * fix various minor issues to allow building for Windows-on-ARM64 * aspeed: Set SDRAM size * Allow system registers for KVM guests to be changed by QEMU code * raspi: Diagnose requests for too much RAM * virt: Support firmware configuration with -blockdev # gpg: Signature made Tue 07 May 2019 12:59:30 BST # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20190507: target/arm: Stop using variable length array in dc_zva target/arm: Implement XPSR GE bits hw/intc/armv7m_nvic: Don't enable ARMV7M_EXCP_DEBUG from reset hw/intc/armv7m_nvic: NS BFAR and BFSR are RAZ/WI if BFHFNMINS == 0 hw/arm/armv7m_nvic: Check subpriority in nvic_recompute_state_secure() osdep: Fix mingw compilation regarding stdio formats util/cacheinfo: Use uint64_t on LLP64 model to satisfy Windows ARM64 qga: Fix mingw compilation warnings on enum conversion QEMU_PACKED: Remove gcc_struct attribute in Windows non x86 targets arm: aspeed: Set SDRAM size arm: Allow system registers for KVM guests to be changed by QEMU code hw/arm/raspi: Diagnose requests for too much RAM hw/arm/virt: Support firmware configuration with -blockdev pflash_cfi01: New pflash_cfi01_legacy_drive() pc: Rearrange pc_system_firmware_init()'s legacy -drive loop Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc/armv7m_nvic.c')
-rw-r--r--hw/intc/armv7m_nvic.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index fff6e694e6..3a346a682a 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -213,6 +213,7 @@ static void nvic_recompute_state_secure(NVICState *s)
int active_prio = NVIC_NOEXC_PRIO;
int pend_irq = 0;
bool pending_is_s_banked = false;
+ int pend_subprio = 0;
/* R_CQRV: precedence is by:
* - lowest group priority; if both the same then
@@ -226,7 +227,7 @@ static void nvic_recompute_state_secure(NVICState *s)
for (i = 1; i < s->num_irq; i++) {
for (bank = M_REG_S; bank >= M_REG_NS; bank--) {
VecInfo *vec;
- int prio;
+ int prio, subprio;
bool targets_secure;
if (bank == M_REG_S) {
@@ -241,8 +242,12 @@ static void nvic_recompute_state_secure(NVICState *s)
}
prio = exc_group_prio(s, vec->prio, targets_secure);
- if (vec->enabled && vec->pending && prio < pend_prio) {
+ subprio = vec->prio & ~nvic_gprio_mask(s, targets_secure);
+ if (vec->enabled && vec->pending &&
+ ((prio < pend_prio) ||
+ (prio == pend_prio && prio >= 0 && subprio < pend_subprio))) {
pend_prio = prio;
+ pend_subprio = subprio;
pend_irq = i;
pending_is_s_banked = (bank == M_REG_S);
}
@@ -1162,6 +1167,10 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
+ if (!attrs.secure &&
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
+ return 0;
+ }
return cpu->env.v7m.bfar;
case 0xd3c: /* Aux Fault Status. */
/* TODO: Implement fault status registers. */
@@ -1641,6 +1650,10 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) {
goto bad_offset;
}
+ if (!attrs.secure &&
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
+ return;
+ }
cpu->env.v7m.bfar = value;
return;
case 0xd3c: /* Aux Fault Status. */
@@ -2125,11 +2138,18 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
val = 0;
break;
};
- /* The BFSR bits [15:8] are shared between security states
- * and we store them in the NS copy
+ /*
+ * The BFSR bits [15:8] are shared between security states
+ * and we store them in the NS copy. They are RAZ/WI for
+ * NS code if AIRCR.BFHFNMINS is 0.
*/
val = s->cpu->env.v7m.cfsr[attrs.secure];
- val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
+ if (!attrs.secure &&
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
+ val &= ~R_V7M_CFSR_BFSR_MASK;
+ } else {
+ val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
+ }
val = extract32(val, (offset - 0xd28) * 8, size * 8);
break;
case 0xfe0 ... 0xfff: /* ID. */
@@ -2244,6 +2264,12 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
*/
value <<= ((offset - 0xd28) * 8);
+ if (!attrs.secure &&
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
+ /* BFSR bits are RAZ/WI for NS if BFHFNMINS is set */
+ value &= ~R_V7M_CFSR_BFSR_MASK;
+ }
+
s->cpu->env.v7m.cfsr[attrs.secure] &= ~value;
if (attrs.secure) {
/* The BFSR bits [15:8] are shared between security states
@@ -2465,10 +2491,12 @@ static void armv7m_nvic_reset(DeviceState *dev)
* the System Handler Control register
*/
s->vectors[ARMV7M_EXCP_SVC].enabled = 1;
- s->vectors[ARMV7M_EXCP_DEBUG].enabled = 1;
s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
s->vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
+ /* DebugMonitor is enabled via DEMCR.MON_EN */
+ s->vectors[ARMV7M_EXCP_DEBUG].enabled = 0;
+
resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3;
s->vectors[ARMV7M_EXCP_RESET].prio = resetprio;
s->vectors[ARMV7M_EXCP_NMI].prio = -2;