From 217403ce096627fec035b79f9464e5bfc09e8f06 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Thu, 29 Jan 2015 13:58:45 +0300 Subject: [PATCH] armv7m: do not access FPU registers when not present This is runtime and valgrind tested with l0, l1 and f3 hla boards. Change-Id: I49b0b042253d5f3bf216997f0203583db319fe23 Signed-off-by: Paul Fertser Reviewed-on: http://openocd.zylin.com/2516 Tested-by: jenkins Reviewed-by: Spencer Oliver --- src/target/armv7m.c | 8 ++++---- src/target/armv7m.h | 1 + src/target/cortex_m.c | 11 +++++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/target/armv7m.c b/src/target/armv7m.c index ee96f0e2b3..01fb69ac93 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -148,7 +148,7 @@ int armv7m_restore_context(struct target *target) if (armv7m->pre_restore_context) armv7m->pre_restore_context(target); - for (i = ARMV7M_NUM_REGS - 1; i >= 0; i--) { + for (i = cache->num_regs - 1; i >= 0; i--) { if (cache->reg_list[i].dirty) { armv7m->arm.write_core_reg(target, &cache->reg_list[i], i, ARM_MODE_ANY, cache->reg_list[i].value); @@ -302,7 +302,7 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int i; if (reg_class == REG_CLASS_ALL) - *reg_list_size = ARMV7M_NUM_REGS; + *reg_list_size = armv7m->arm.core_cache->num_regs; else *reg_list_size = ARMV7M_NUM_CORE_REGS; @@ -368,7 +368,7 @@ int armv7m_start_algorithm(struct target *target, /* refresh core register cache * Not needed if core register cache is always consistent with target process state */ - for (unsigned i = 0; i < ARMV7M_NUM_REGS; i++) { + for (unsigned i = 0; i < armv7m->arm.core_cache->num_regs; i++) { armv7m_algorithm_info->context[i] = buf_get_u32( armv7m->arm.core_cache->reg_list[i].value, @@ -503,7 +503,7 @@ int armv7m_wait_algorithm(struct target *target, } } - for (int i = ARMV7M_NUM_REGS - 1; i >= 0; i--) { + for (int i = armv7m->arm.core_cache->num_regs - 1; i >= 0; i--) { uint32_t regvalue; regvalue = buf_get_u32(armv7m->arm.core_cache->reg_list[i].value, 0, 32); if (regvalue != armv7m_algorithm_info->context[i]) { diff --git a/src/target/armv7m.h b/src/target/armv7m.h index 86c9aee221..d28977edf3 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -136,6 +136,7 @@ enum { }; #define ARMV7M_NUM_CORE_REGS (ARMV7M_xPSR + 1) +#define ARMV7M_NUM_CORE_REGS_NOFP (ARMV7M_NUM_CORE_REGS + 6) #define ARMV7M_COMMON_MAGIC 0x2A452A45 diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index b194c33e6f..38ed4c3a1f 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -1885,6 +1885,17 @@ int cortex_m_examine(struct target *target) armv7m->arm.is_armv6m = true; } + if (armv7m->fp_feature != FPv4_SP && + armv7m->arm.core_cache->num_regs > ARMV7M_NUM_CORE_REGS_NOFP) { + /* free unavailable FPU registers */ + size_t idx; + for (idx = ARMV7M_NUM_CORE_REGS_NOFP; + idx < armv7m->arm.core_cache->num_regs; + idx++) + free(armv7m->arm.core_cache->reg_list[idx].value); + armv7m->arm.core_cache->num_regs = ARMV7M_NUM_CORE_REGS_NOFP; + } + if (i == 4 || i == 3) { /* Cortex-M3/M4 has 4096 bytes autoincrement range */ armv7m->dap.tar_autoincr_block = (1 << 12); -- 2.30.2