Add the Configurable and Hard Fault Status registers. Note undefined instructions and escalations
Signed-off-by: Michael Davidsaver <mdavidsa...@gmail.com> --- hw/intc/armv7m_nvic.c | 10 +++++++--- target-arm/cpu.h | 2 ++ target-arm/helper.c | 1 + target-arm/machine.c | 6 ++++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 8eaf677..734f6f8 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -287,6 +287,7 @@ void armv7m_nvic_set_pending(void *opaque, int irq) } I = &s->vectors[irq]; + s->cpu->env.v7m.hfsr |= 1<<30; /* FORCED */ DPRINTF(0, "Escalate %d to %d\n", oldirq, irq); } } @@ -488,10 +489,9 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset) if (s->vectors[ARMV7M_EXCP_USAGE].enabled) val |= (1 << 18); return val; case 0xd28: /* Configurable Fault Status. */ - /* TODO: Implement Fault Status. */ - qemu_log_mask(LOG_UNIMP, "Configurable Fault Status unimplemented\n"); - return 0; + return cpu->env.v7m.cfsr; case 0xd2c: /* Hard Fault Status. */ + return cpu->env.v7m.hfsr; case 0xd30: /* Debug Fault Status. */ case 0xd34: /* Mem Manage Address. */ case 0xd38: /* Bus Fault Address. */ @@ -629,7 +629,11 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value) */ break; case 0xd28: /* Configurable Fault Status. */ + cpu->env.v7m.cfsr &= ~value; /* W1C */ + break; case 0xd2c: /* Hard Fault Status. */ + cpu->env.v7m.hfsr &= ~value; /* W1C */ + break; case 0xd30: /* Debug Fault Status. */ case 0xd34: /* Mem Manage Address. */ case 0xd38: /* Bus Fault Address. */ diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 29d89ce..e98bca0 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -396,6 +396,8 @@ typedef struct CPUARMState { uint32_t vecbase; uint32_t basepri; uint32_t control; + uint32_t cfsr; /* Configurable Fault Status */ + uint32_t hfsr; /* HardFault Status */ int current_sp; int exception; int exception_prio; diff --git a/target-arm/helper.c b/target-arm/helper.c index 2541890..5be09b8 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -5436,6 +5436,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) switch (cs->exception_index) { case EXCP_UDEF: armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); + env->v7m.cfsr |= 1<<16; /* UNDEFINSTR */ break; case EXCP_SWI: /* The PC already points to the next instruction. */ diff --git a/target-arm/machine.c b/target-arm/machine.c index 36a0d15..d7c2034 100644 --- a/target-arm/machine.c +++ b/target-arm/machine.c @@ -92,14 +92,16 @@ static bool m_needed(void *opaque) static const VMStateDescription vmstate_m = { .name = "cpu/m", - .version_id = 1, - .minimum_version_id = 1, + .version_id = 2, + .minimum_version_id = 2, .needed = m_needed, .fields = (VMStateField[]) { VMSTATE_UINT32(env.v7m.other_sp, ARMCPU), VMSTATE_UINT32(env.v7m.vecbase, ARMCPU), VMSTATE_UINT32(env.v7m.basepri, ARMCPU), VMSTATE_UINT32(env.v7m.control, ARMCPU), + VMSTATE_UINT32(env.v7m.cfsr, ARMCPU), + VMSTATE_UINT32(env.v7m.hfsr, ARMCPU), VMSTATE_INT32(env.v7m.current_sp, ARMCPU), VMSTATE_INT32(env.v7m.exception, ARMCPU), VMSTATE_END_OF_LIST() -- 2.1.4