@@ -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. */
@@ -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;
@@ -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. */
@@ -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()
Add the Configurable and Hard Fault Status registers. Note undefined instructions and escalations Signed-off-by: Michael Davidsaver <mdavidsaver@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(-)