mirror of https://github.com/xemu-project/xemu.git
nvic: Implement v8M changes to fixed priority exceptions
In v7M, the fixed-priority exceptions are: Reset: -3 NMI: -2 HardFault: -1 In v8M, this changes because Secure HardFault may need to be prioritised above NMI: Reset: -4 Secure HardFault if AIRCR.BFHFNMINS == 1: -3 NMI: -2 Secure HardFault if AIRCR.BFHFNMINS == 0: -1 NonSecure HardFault: -1 Make these changes, including support for changing the priority of Secure HardFault as AIRCR.BFHFNMINS changes. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 1505240046-11454-14-git-send-email-peter.maydell@linaro.org
This commit is contained in:
parent
94a34abe32
commit
331f4bae6c
|
@ -937,6 +937,12 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
|
||||||
(R_V7M_AIRCR_SYSRESETREQS_MASK |
|
(R_V7M_AIRCR_SYSRESETREQS_MASK |
|
||||||
R_V7M_AIRCR_BFHFNMINS_MASK |
|
R_V7M_AIRCR_BFHFNMINS_MASK |
|
||||||
R_V7M_AIRCR_PRIS_MASK);
|
R_V7M_AIRCR_PRIS_MASK);
|
||||||
|
/* BFHFNMINS changes the priority of Secure HardFault */
|
||||||
|
if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
|
||||||
|
s->sec_vectors[ARMV7M_EXCP_HARD].prio = -3;
|
||||||
|
} else {
|
||||||
|
s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nvic_irq_update(s);
|
nvic_irq_update(s);
|
||||||
}
|
}
|
||||||
|
@ -1452,9 +1458,12 @@ static int nvic_post_load(void *opaque, int version_id)
|
||||||
{
|
{
|
||||||
NVICState *s = opaque;
|
NVICState *s = opaque;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
int resetprio;
|
||||||
|
|
||||||
/* Check for out of range priority settings */
|
/* Check for out of range priority settings */
|
||||||
if (s->vectors[ARMV7M_EXCP_RESET].prio != -3 ||
|
resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3;
|
||||||
|
|
||||||
|
if (s->vectors[ARMV7M_EXCP_RESET].prio != resetprio ||
|
||||||
s->vectors[ARMV7M_EXCP_NMI].prio != -2 ||
|
s->vectors[ARMV7M_EXCP_NMI].prio != -2 ||
|
||||||
s->vectors[ARMV7M_EXCP_HARD].prio != -1) {
|
s->vectors[ARMV7M_EXCP_HARD].prio != -1) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1497,7 +1506,12 @@ static int nvic_security_post_load(void *opaque, int version_id)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Check for out of range priority settings */
|
/* Check for out of range priority settings */
|
||||||
if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1) {
|
if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1
|
||||||
|
&& s->sec_vectors[ARMV7M_EXCP_HARD].prio != -3) {
|
||||||
|
/* We can't cross-check against AIRCR.BFHFNMINS as we don't know
|
||||||
|
* if the CPU state has been migrated yet; a mismatch won't
|
||||||
|
* cause the emulation to blow up, though.
|
||||||
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
for (i = ARMV7M_EXCP_MEM; i < ARRAY_SIZE(s->sec_vectors); i++) {
|
for (i = ARMV7M_EXCP_MEM; i < ARRAY_SIZE(s->sec_vectors); i++) {
|
||||||
|
@ -1548,6 +1562,7 @@ static Property props_nvic[] = {
|
||||||
|
|
||||||
static void armv7m_nvic_reset(DeviceState *dev)
|
static void armv7m_nvic_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
|
int resetprio;
|
||||||
NVICState *s = NVIC(dev);
|
NVICState *s = NVIC(dev);
|
||||||
|
|
||||||
s->vectors[ARMV7M_EXCP_NMI].enabled = 1;
|
s->vectors[ARMV7M_EXCP_NMI].enabled = 1;
|
||||||
|
@ -1560,7 +1575,8 @@ static void armv7m_nvic_reset(DeviceState *dev)
|
||||||
s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
|
s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
|
||||||
s->vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
|
s->vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
|
||||||
|
|
||||||
s->vectors[ARMV7M_EXCP_RESET].prio = -3;
|
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;
|
s->vectors[ARMV7M_EXCP_NMI].prio = -2;
|
||||||
s->vectors[ARMV7M_EXCP_HARD].prio = -1;
|
s->vectors[ARMV7M_EXCP_HARD].prio = -1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue