Skip over a bkpt instruction if found on resume/step.
Only software breakpoints known to openod are handled.
So this handles the special case of a user added bkpt, eg. semi-hosting.

Signed-off-by: Spencer Oliver <ntfr...@users.sourceforge.net>
---
  src/target/armv7m.c    |   31 +++++++++++++++++++++++++++++++
  src/target/armv7m.h    |    2 ++
  src/target/cortex_m3.c |   12 ++++++++++++
  3 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/src/target/armv7m.c b/src/target/armv7m.c
index 233fb95..2e21e10 100644
--- a/src/target/armv7m.c
+++ b/src/target/armv7m.c
@@ -694,6 +694,37 @@ int armv7m_blank_check_memory(struct target *target,
        return ERROR_OK;
  }

+int armv7m_check_bkpt_inst(struct target *target)
+{
+       struct armv7m_common *armv7m = target_to_armv7m(target);
+       struct reg *r = armv7m->core_cache->reg_list + 15;
+
+       /* if we halted last time due to a bkpt instruction
+        * then we have to manually step over it, otherwise
+        * the core will break again */
+
+       if (target->debug_reason == DBG_REASON_BREAKPOINT)
+       {
+               uint16_t op;
+               uint32_t pc = buf_get_u32(r->value, 0, 32);
+
+               pc &= ~1;
+               if (target_read_u16(target, pc, &op) == ERROR_OK)
+               {
+                       if ((op & 0xFF00) == 0xBE00)
+                       {
+                               pc = buf_get_u32(r->value, 0, 32) + 2;
+                               buf_set_u32(r->value, 0, 32, pc);
+                               r->dirty = true;
+                               r->valid = true;
+                               LOG_DEBUG("Skipping over BKPT instruction");
+                       }
+               }
+       }
+
+       return ERROR_OK;
+}
+
 
/*--------------------------------------------------------------------------*/

  /*
diff --git a/src/target/armv7m.h b/src/target/armv7m.h
index 86caae2..27a6577 100644
--- a/src/target/armv7m.h
+++ b/src/target/armv7m.h
@@ -171,6 +171,8 @@ int armv7m_checksum_memory(struct target *target,
  int armv7m_blank_check_memory(struct target *target,
                uint32_t address, uint32_t count, uint32_t* blank);

+int armv7m_check_bkpt_inst(struct target *target);
+
  extern const struct command_registration armv7m_command_handlers[];

  #endif /* ARMV7M_H */
diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c
index 48f8114..f2726c3 100644
--- a/src/target/cortex_m3.c
+++ b/src/target/cortex_m3.c
@@ -638,6 +638,15 @@ static int cortex_m3_resume(struct target *target, 
int current,
                r->valid = true;
        }

+       /* if we halted last time due to a bkpt instruction
+        * then we have to manually step over it, otherwise
+        * the core will break again */
+
+       if (!breakpoint_find(target, buf_get_u32(r->value, 0, 32)) && 
!debug_execution)
+       {
+               armv7m_check_bkpt_inst(target);
+       }
+
        resume_pc = buf_get_u32(r->value, 0, 32);

        armv7m_restore_context(target);
@@ -709,6 +718,8 @@ static int cortex_m3_step(struct target *target, int 
current,
                        cortex_m3_unset_breakpoint(target, breakpoint);
        }

+       armv7m_check_bkpt_inst(target);
+
        target->debug_reason = DBG_REASON_SINGLESTEP;

        armv7m_restore_context(target);
@@ -735,6 +746,7 @@ static int cortex_m3_step(struct target *target, int 
current,
        LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
                        " nvic_icsr = 0x%" PRIx32,
                        cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
+
        return ERROR_OK;
  }

-- 
1.6.5.1.1367.gcd48
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to