[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 09/26] armv7m: implement CFSR, HFSR, BFAR, and MM
From: |
Michael Davidsaver |
Subject: |
[Qemu-devel] [PATCH v2 09/26] armv7m: implement CFSR, HFSR, BFAR, and MMFAR |
Date: |
Wed, 2 Dec 2015 19:18:36 -0500 |
Add the Configurable, HardFault, BusFault and MemManage Status registers.
Note undefined instructions, violations, and escalations.
No BusFaults are raised at this point.
---
hw/intc/armv7m_nvic.c | 28 ++++++++++++++++++++++------
target-arm/cpu.h | 4 ++++
target-arm/helper.c | 3 +++
target-arm/machine.c | 8 ++++++--
4 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index ca9bd4c..619c320 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -333,6 +333,7 @@ void armv7m_nvic_set_pending(void *opaque, int irq)
irq = ARMV7M_EXCP_HARD;
vec = &s->vectors[irq];
+ s->cpu->env.v7m.hfsr |= 1<<30; /* FORCED */
DPRINTF(0, "Escalate %d to HardFault\n", oldirq);
}
}
@@ -548,16 +549,20 @@ static uint32_t nvic_readl(NVICState *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. */
+ qemu_log_mask(LOG_UNIMP, "Debug Fault status register
unimplemented\n");
+ return 0;
+ case 0xd34: /* MMFAR MemManage Fault Address */
+ return cpu->env.v7m.mmfar;
case 0xd38: /* Bus Fault Address. */
+ return cpu->env.v7m.bfar;
case 0xd3c: /* Aux Fault Status. */
/* TODO: Implement fault status registers. */
- qemu_log_mask(LOG_UNIMP, "Fault status registers unimplemented\n");
+ qemu_log_mask(LOG_UNIMP,
+ "Aux Fault status registers unimplemented\n");
return 0;
case 0xd40: /* PFR0. */
return 0x00000030;
@@ -690,13 +695,24 @@ static void nvic_writel(NVICState *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. */
+ qemu_log_mask(LOG_UNIMP,
+ "NVIC: debug fault status register unimplemented\n");
+ break;
case 0xd34: /* Mem Manage Address. */
+ cpu->env.v7m.mmfar = value;
+ return;
case 0xd38: /* Bus Fault Address. */
+ cpu->env.v7m.bfar = value;
+ return;
case 0xd3c: /* Aux Fault Status. */
qemu_log_mask(LOG_UNIMP,
- "NVIC: fault status registers unimplemented\n");
+ "NVIC: Aux fault status registers unimplemented\n");
break;
case 0xf00: /* Software Triggered Interrupt Register */
if ((value & 0x1ff) < NVIC_MAX_IRQ) {
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 4b7f78e..4262efc 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -396,6 +396,10 @@ typedef struct CPUARMState {
uint32_t vecbase;
uint32_t basepri;
uint32_t control;
+ uint32_t cfsr; /* Configurable Fault Status */
+ uint32_t hfsr; /* HardFault Status */
+ uint32_t mmfar; /* MemManage Fault Address */
+ uint32_t bfar; /* BusFault Address */
int current_sp;
int exception;
int exception_prio;
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 4490b74..d1ca011 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5454,6 +5454,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. */
@@ -5465,6 +5466,8 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
* should set the MMFAR, etc from exception.fsr and exception.vaddress.
*/
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
+ env->v7m.mmfar = env->exception.vaddress;
+ env->v7m.cfsr = (1<<1)|(1<<7); /* DACCVIOL and MMARVALID */
break;
case EXCP_BKPT:
if (semihosting_enabled()) {
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 36a0d15..14a4882 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -92,14 +92,18 @@ 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_UINT32(env.v7m.mmfar, ARMCPU),
+ VMSTATE_UINT32(env.v7m.bfar, ARMCPU),
VMSTATE_INT32(env.v7m.current_sp, ARMCPU),
VMSTATE_INT32(env.v7m.exception, ARMCPU),
VMSTATE_END_OF_LIST()
--
2.1.4
- [Qemu-devel] [PATCH v2 02/26] armv7m: Undo armv7m.hack, (continued)
[Qemu-devel] [PATCH v2 07/26] armv7m: simpler/faster exception start, Michael Davidsaver, 2015/12/02
[Qemu-devel] [PATCH v2 10/26] armv7m: auto-clear FAULTMASK, Michael Davidsaver, 2015/12/02
[Qemu-devel] [PATCH v2 09/26] armv7m: implement CFSR, HFSR, BFAR, and MMFAR,
Michael Davidsaver <=
[Qemu-devel] [PATCH v2 11/26] arm: gic: Remove references to NVIC, Michael Davidsaver, 2015/12/02
[Qemu-devel] [PATCH v2 12/26] armv7m: check exception return consistency, Michael Davidsaver, 2015/12/02
[Qemu-devel] [PATCH v2 14/26] armv7m: prevent unprivileged write to STIR, Michael Davidsaver, 2015/12/02
[Qemu-devel] [PATCH v2 13/26] armv7m: implement CCR, Michael Davidsaver, 2015/12/02
[Qemu-devel] [PATCH v2 18/26] armv7m: update base region policy, Michael Davidsaver, 2015/12/02