<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><div dir="ltr"><div>I don't have something I can test this on at the moment, but I don't see anything glaring that needs to be addressed. Thanks for fixing this, Chris!</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Oct 27, 2022 at 4:34 PM <<a href="mailto:chrisj@rtems.org">chrisj@rtems.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Chris Johns <<a href="mailto:chrisj@rtems.org" target="_blank">chrisj@rtems.org</a>><br>
<br>
Closes #4744<br>
---<br>
 cpukit/libdebugger/rtems-debugger-arm.c | 808 +++++++++++++++---------<br>
 1 file changed, 495 insertions(+), 313 deletions(-)<br>
<br>
diff --git a/cpukit/libdebugger/rtems-debugger-arm.c b/cpukit/libdebugger/rtems-debugger-arm.c<br>
index ba01a860c8..cdc615ce64 100644<br>
--- a/cpukit/libdebugger/rtems-debugger-arm.c<br>
+++ b/cpukit/libdebugger/rtems-debugger-arm.c<br>
@@ -1,5 +1,5 @@<br>
 /*<br>
- * Copyright (c) 2016-2019 Chris Johns <<a href="mailto:chrisj@rtems.org" target="_blank">chrisj@rtems.org</a>>.<br>
+ * Copyright (c) 2016-2022 Chris Johns <<a href="mailto:chrisj@rtems.org" target="_blank">chrisj@rtems.org</a>>.<br>
  * All rights reserved.<br>
  *<br>
  * Redistribution and use in source and binary forms, with or without<br>
@@ -86,14 +86,26 @@<br>
   #define ARM_SWITCH_REG       uint32_t arm_switch_reg<br>
   #define ARM_SWITCH_REG_ASM   [arm_switch_reg] "=&r" (arm_switch_reg)<br>
   #define ARM_SWITCH_REG_ASM_L ARM_SWITCH_REG_ASM,<br>
+  #define ASM_ARM_ASM          ".align 2\n.arm\n"<br>
   #define ASM_ARM_MODE         ".align 2\nbx pc\n.arm\n"<br>
   #define ASM_THUMB_MODE       "add %[arm_switch_reg], pc, #1\nbx %[arm_switch_reg]\n.thumb\n"<br>
+  #define ARM_THUMB_MODE()     __asm__ volatile(ASM_THUMB_MODE : ARM_SWITCH_REG_ASM : :);<br>
+  #define ARM_ARM_MODE()       __asm__ volatile(ASM_ARM_MODE : : :);<br>
 #else<br>
   #define ARM_SWITCH_REG<br>
   #define ARM_SWITCH_REG_ASM<br>
   #define ARM_SWITCH_REG_ASM_L<br>
+  #define ASM_ARM_ASM<br>
   #define ASM_ARM_MODE<br>
   #define ASM_THUMB_MODE<br>
+  #define ARM_THUMB_MODE()<br>
+  #define ARM_ARM_MODE()<br>
+#endif<br>
+<br>
+#ifdef ARM_MULTILIB_HAS_BARRIER_INSTRUCTIONS<br>
+#define ARM_SYNC_INST  "isb\n"<br>
+#else<br>
+#define ARM_SYNC_INST<br>
 #endif<br>
<br>
 /*<br>
@@ -287,29 +299,19 @@ static const size_t exc_offsets[2][5] =<br>
 static bool debug_session_active;<br>
<br>
 /*<br>
- * ARM debug hardware.<br>
+ * ARM debug hardware. These variables are directly access<br>
+ * from assembler so do not change types.<br>
  */<br>
 static int   debug_version;<br>
 static void* debug_registers;<br>
 static int   debug_revision;<br>
-static bool  debug_disable_ints;<br>
+static int   debug_disable_ints;<br>
 static int   hw_breakpoints;<br>
 static int   hw_watchpoints;<br>
<br>
 /**<br>
  * Hardware break and watch points.<br>
  */<br>
-typedef struct<br>
-{<br>
-  bool                 enabled;<br>
-  bool                 loaded;<br>
-  void*                address;<br>
-  size_t               length;<br>
-  CPU_Exception_frame* frame;<br>
-  uint32_t             control;<br>
-  uint32_t             value;<br>
-} arm_debug_hwbreak;<br>
-<br>
 #define ARM_HW_BREAKPOINT_MAX (16)<br>
 #define ARM_HW_WATCHPOINT_MAX (16)<br>
<br>
@@ -327,8 +329,23 @@ typedef struct<br>
 #define ARM_HW_BP_PRIV_PL0_ONLY    (0x02)<br>
 #define ARM_HW_BP_PRIV_ALL_MODES   (0x03)<br>
<br>
-static arm_debug_hwbreak hw_breaks[ARM_HW_BREAKPOINT_MAX];<br>
-//static arm_debug_hwbreak hw_watches[ARM_HW_WATCHPOINT_MAX];<br>
+/*<br>
+ * A hw breakpoint has DBGBCR and DBGBVR registers. Allocate memory<br>
+ * for each.<br>
+ *<br>
+ * Maintian the values ready to load into the hardware. The loader is<br>
+ * a load of the value and then control for enabled BPs.<br>
+ */<br>
+static uint32_t hw_breaks[ARM_HW_BREAKPOINT_MAX * 2];<br>
+<br>
+/*<br>
+ * The order in the array is important<br>
+ */<br>
+#define ARM_HWB_BCR(_bp) (hw_breaks[((_bp) * 2) + 1])<br>
+#define ARM_HWB_VCR(_bp) (hw_breaks[(_bp) * 2])<br>
+#define ARM_HWB_ENALBED(_bp) ((ARM_HWB_BCR(_bp) & 1) != 0)<br>
+#define ARM_HWB_CLEAR(_bp) ARM_HWB_BCR(_bp) = 0; ARM_HWB_VCR(_bp) = 0<br>
+#define ARM_HWB_CLEAR_ALL() memset(&hw_breaks[0], 0, sizeof(hw_breaks))<br>
<br>
 /*<br>
  * Method of entry (MOE) to debug mode. Bits [5:2] of DBGDSCR.<br>
@@ -439,6 +456,7 @@ arm_moe_label(uint32_t moe)<br>
     asm volatile(                                          \<br>
       ASM_ARM_MODE                                         \<br>
       ARM_CP_INSTR(mcr, _cp, _op1, val, _CRn, _CRm, _op2)  \<br>
+      ARM_SYNC_INST                                        \<br>
       ASM_THUMB_MODE                                       \<br>
       : ARM_SWITCH_REG_ASM                                 \<br>
       : [val] "r" (_val));                                 \<br>
@@ -449,6 +467,7 @@ arm_moe_label(uint32_t moe)<br>
     ARM_SWITCH_REG;                                        \<br>
     asm volatile(                                          \<br>
       ASM_ARM_MODE                                         \<br>
+      ARM_SYNC_INST                                        \<br>
       ARM_CP_INSTR(mrc, _cp, _op1, val, _CRn, _CRm, _op2)  \<br>
       ASM_THUMB_MODE                                       \<br>
       : ARM_SWITCH_REG_ASM_L                               \<br>
@@ -491,9 +510,21 @@ arm_moe_label(uint32_t moe)<br>
  * Read and write a memory mapped debug register. The register number is a word<br>
  * offset from the base address.<br>
  */<br>
-#define ARM_MMAP_ADDR(reg)       (((volatile uint32_t*) debug_registers) + (reg))<br>
-#define ARM_MMAP_WRITE(reg, val) *ARM_MMAP_ADDR(reg) = (val); _ARM_Data_synchronization_barrier()<br>
-#define ARM_MMAP_READ(reg)       *ARM_MMAP_ADDR(reg)<br>
+#define ARM_MMAP_ADDR(reg) \<br>
+  (((volatile uint32_t*) debug_registers) + (reg))<br>
+#define ARM_MMAP_WRITE(reg, val) *ARM_MMAP_ADDR(reg) = (val)<br>
+#define ARM_MMAP_READ(reg) *ARM_MMAP_ADDR(reg)<br>
+#define ARM_MMAP_WRITE_SYNC(reg, val) \<br>
+  ARM_MMAP_WRITE(reg, val); \<br>
+  _ARM_Data_synchronization_barrier(); \<br>
+  _ARM_Instruction_synchronization_barrier()<br>
+<br>
+/*<br>
+ * Debug hardware breakpoint registers.<br>
+ */<br>
+#define ARM_MMAP_DBGDSCR 34<br>
+#define ARM_MMAP_DBGBCR  80<br>
+#define ARM_MMAP_DBGBVR  64<br>
<br>
 static bool<br>
 arm_debug_authentication(uint32_t dbgauthstatus)<br>
@@ -902,16 +933,17 @@ arm_debug_mmap_enable(rtems_debugger_target* target, uint32_t dbgdidr)<br>
        * which seems to make the debug hardware work.<br>
        */<br>
       if (ARM_MMAP_READ(1005) == 3) {<br>
-        ARM_MMAP_WRITE(1004, 0xC5ACCE55);<br>
+        ARM_MMAP_WRITE_SYNC(1004, 0xC5ACCE55);<br>
       }<br>
       /*<br>
        * Are we already in debug mode?<br>
        */<br>
-      val = ARM_MMAP_READ(34);<br>
+      val = ARM_MMAP_READ(ARM_MMAP_DBGDSCR);<br>
       if ((val & (1 << 15)) == 0) {<br>
         rtems_debugger_printf("rtems-db: arm debug: enable debug mode\n");<br>
-        val = ARM_MMAP_READ(34);<br>
-        ARM_MMAP_WRITE(34, ARM_MMAP_READ(34) | (1 << 15));<br>
+        val = ARM_MMAP_READ(ARM_MMAP_DBGDSCR);<br>
+        ARM_MMAP_WRITE_SYNC(ARM_MMAP_DBGDSCR,<br>
+                            ARM_MMAP_READ(ARM_MMAP_DBGDSCR) | (1 << 15));<br>
         arm_debug_retries = 0;<br>
       }<br>
     }<br>
@@ -1002,139 +1034,125 @@ arm_debug_probe(rtems_debugger_target* target)<br>
 }<br>
<br>
 static inline void<br>
-arm_debug_break_setup(arm_debug_hwbreak* bp,<br>
-                      uint32_t           address,<br>
-                      uint32_t           type,<br>
-                      uint32_t           byte_address_select,<br>
-                      uint32_t           privilege)<br>
+arm_debug_break_setup(int      bp,<br>
+                      uint32_t address,<br>
+                      uint32_t type,<br>
+                      uint32_t byte_address_select,<br>
+                      uint32_t privilege)<br>
 {<br>
-  bp->control = (((type & 0xf) << 20) |<br>
-                 ((byte_address_select & 0xf) << 5) |<br>
-                 ((privilege & 0x3) << 1) | 1);<br>
-  bp->value = (intptr_t) address;<br>
+  ARM_HWB_BCR(bp) = (((type & 0xf) << 20) |<br>
+                     ((byte_address_select & 0xf) << 5) |<br>
+                     ((privilege & 0x3) << 1) | 1);<br>
+  ARM_HWB_VCR(bp) = (intptr_t) (address & (~3));<br>
 }<br>
<br>
 static void<br>
-arm_debug_break_write_control(int bp, uint32_t control)<br>
+arm_debug_break_c14_write_control(int bp, uint32_t control)<br>
 {<br>
-  if (bp < 15) {<br>
-    if (debug_registers != NULL) {<br>
-      ARM_MMAP_WRITE(80 + bp, control);<br>
-    }<br>
-    else {<br>
-      switch (bp) {<br>
-      case 0:<br>
-        ARM_CP14_WRITE(control, 0, 0, 5);<br>
-        break;<br>
-      case 1:<br>
-        ARM_CP14_WRITE(control, 0, 1, 5);<br>
-        break;<br>
-      case 2:<br>
-        ARM_CP14_WRITE(control, 0, 2, 5);<br>
-        break;<br>
-      case 3:<br>
-        ARM_CP14_WRITE(control, 0, 3, 5);<br>
-        break;<br>
-      case 4:<br>
-        ARM_CP14_WRITE(control, 0, 4, 5);<br>
-        break;<br>
-      case 5:<br>
-        ARM_CP14_WRITE(control, 0, 5, 5);<br>
-        break;<br>
-      case 6:<br>
-        ARM_CP14_WRITE(control, 0, 6, 5);<br>
-        break;<br>
-      case 7:<br>
-        ARM_CP14_WRITE(control, 0, 7, 5);<br>
-        break;<br>
-      case 8:<br>
-        ARM_CP14_WRITE(control, 0, 8, 5);<br>
-        break;<br>
-      case 9:<br>
-        ARM_CP14_WRITE(control, 0, 9, 5);<br>
-        break;<br>
-      case 10:<br>
-        ARM_CP14_WRITE(control, 0, 10, 5);<br>
-        break;<br>
-      case 11:<br>
-        ARM_CP14_WRITE(control, 0, 11, 5);<br>
-        break;<br>
-      case 12:<br>
-        ARM_CP14_WRITE(control, 0, 12, 5);<br>
-        break;<br>
-      case 13:<br>
-        ARM_CP14_WRITE(control, 0, 13, 5);<br>
-        break;<br>
-      case 14:<br>
-        ARM_CP14_WRITE(control, 0, 14, 5);<br>
-        break;<br>
-      case 15:<br>
-        ARM_CP14_WRITE(control, 0, 15, 5);<br>
-        break;<br>
-      }<br>
-    }<br>
+  switch (bp) {<br>
+    case 0:<br>
+      ARM_CP14_WRITE(control, 0, 0, 5);<br>
+      break;<br>
+    case 1:<br>
+      ARM_CP14_WRITE(control, 0, 1, 5);<br>
+      break;<br>
+    case 2:<br>
+      ARM_CP14_WRITE(control, 0, 2, 5);<br>
+      break;<br>
+    case 3:<br>
+      ARM_CP14_WRITE(control, 0, 3, 5);<br>
+      break;<br>
+    case 4:<br>
+      ARM_CP14_WRITE(control, 0, 4, 5);<br>
+      break;<br>
+    case 5:<br>
+      ARM_CP14_WRITE(control, 0, 5, 5);<br>
+      break;<br>
+    case 6:<br>
+      ARM_CP14_WRITE(control, 0, 6, 5);<br>
+      break;<br>
+    case 7:<br>
+      ARM_CP14_WRITE(control, 0, 7, 5);<br>
+      break;<br>
+    case 8:<br>
+      ARM_CP14_WRITE(control, 0, 8, 5);<br>
+      break;<br>
+    case 9:<br>
+      ARM_CP14_WRITE(control, 0, 9, 5);<br>
+      break;<br>
+    case 10:<br>
+      ARM_CP14_WRITE(control, 0, 10, 5);<br>
+      break;<br>
+    case 11:<br>
+      ARM_CP14_WRITE(control, 0, 11, 5);<br>
+      break;<br>
+    case 12:<br>
+      ARM_CP14_WRITE(control, 0, 12, 5);<br>
+      break;<br>
+    case 13:<br>
+      ARM_CP14_WRITE(control, 0, 13, 5);<br>
+      break;<br>
+    case 14:<br>
+      ARM_CP14_WRITE(control, 0, 14, 5);<br>
+      break;<br>
+    case 15:<br>
+      ARM_CP14_WRITE(control, 0, 15, 5);<br>
+      break;<br>
   }<br>
 }<br>
<br>
 static void<br>
-arm_debug_break_write_value(int bp, uint32_t value)<br>
+arm_debug_break_c14_write_value(int bp, uint32_t value)<br>
 {<br>
-  if (bp < 15) {<br>
-    if (debug_registers != NULL) {<br>
-      ARM_MMAP_WRITE(64 + bp, value);<br>
-    }<br>
-    else {<br>
-      switch (bp) {<br>
-      case 0:<br>
-        ARM_CP14_WRITE(value, 0, 0, 4);<br>
-        break;<br>
-      case 1:<br>
-        ARM_CP14_WRITE(value, 0, 1, 4);<br>
-        break;<br>
-      case 2:<br>
-        ARM_CP14_WRITE(value, 0, 2, 4);<br>
-        break;<br>
-      case 3:<br>
-        ARM_CP14_WRITE(value, 0, 3, 4);<br>
-        break;<br>
-      case 4:<br>
-        ARM_CP14_WRITE(value, 0, 4, 4);<br>
-        break;<br>
-      case 5:<br>
-        ARM_CP14_WRITE(value, 0, 5, 4);<br>
-        break;<br>
-      case 6:<br>
-        ARM_CP14_WRITE(value, 0, 6, 4);<br>
-        break;<br>
-      case 7:<br>
-        ARM_CP14_WRITE(value, 0, 7, 4);<br>
-        break;<br>
-      case 8:<br>
-        ARM_CP14_WRITE(value, 0, 8, 4);<br>
-        break;<br>
-      case 9:<br>
-        ARM_CP14_WRITE(value, 0, 9, 4);<br>
-        break;<br>
-      case 10:<br>
-        ARM_CP14_WRITE(value, 0, 10, 4);<br>
-        break;<br>
-      case 11:<br>
-        ARM_CP14_WRITE(value, 0, 11, 4);<br>
-        break;<br>
-      case 12:<br>
-        ARM_CP14_WRITE(value, 0, 12, 4);<br>
-        break;<br>
-      case 13:<br>
-        ARM_CP14_WRITE(value, 0, 13, 4);<br>
-        break;<br>
-      case 14:<br>
-        ARM_CP14_WRITE(value, 0, 14, 4);<br>
-        break;<br>
-      case 15:<br>
-        ARM_CP14_WRITE(value, 0, 15, 4);<br>
-        break;<br>
-      }<br>
-    }<br>
+  switch (bp) {<br>
+    case 0:<br>
+      ARM_CP14_WRITE(value, 0, 0, 4);<br>
+      break;<br>
+    case 1:<br>
+      ARM_CP14_WRITE(value, 0, 1, 4);<br>
+      break;<br>
+    case 2:<br>
+      ARM_CP14_WRITE(value, 0, 2, 4);<br>
+      break;<br>
+    case 3:<br>
+      ARM_CP14_WRITE(value, 0, 3, 4);<br>
+      break;<br>
+    case 4:<br>
+      ARM_CP14_WRITE(value, 0, 4, 4);<br>
+      break;<br>
+    case 5:<br>
+      ARM_CP14_WRITE(value, 0, 5, 4);<br>
+      break;<br>
+    case 6:<br>
+      ARM_CP14_WRITE(value, 0, 6, 4);<br>
+      break;<br>
+    case 7:<br>
+      ARM_CP14_WRITE(value, 0, 7, 4);<br>
+      break;<br>
+    case 8:<br>
+      ARM_CP14_WRITE(value, 0, 8, 4);<br>
+      break;<br>
+    case 9:<br>
+      ARM_CP14_WRITE(value, 0, 9, 4);<br>
+      break;<br>
+    case 10:<br>
+      ARM_CP14_WRITE(value, 0, 10, 4);<br>
+      break;<br>
+    case 11:<br>
+      ARM_CP14_WRITE(value, 0, 11, 4);<br>
+      break;<br>
+    case 12:<br>
+      ARM_CP14_WRITE(value, 0, 12, 4);<br>
+      break;<br>
+    case 13:<br>
+      ARM_CP14_WRITE(value, 0, 13, 4);<br>
+      break;<br>
+    case 14:<br>
+      ARM_CP14_WRITE(value, 0, 14, 4);<br>
+      break;<br>
+    case 15:<br>
+      ARM_CP14_WRITE(value, 0, 15, 4);<br>
+      break;<br>
   }<br>
 }<br>
<br>
@@ -1143,7 +1161,7 @@ arm_debug_dbgdscr_read(void)<br>
 {<br>
   uint32_t val;<br>
   if (debug_registers != NULL) {<br>
-    val = ARM_MMAP_READ(34);<br>
+    val = ARM_MMAP_READ(ARM_MMAP_DBGDSCR);<br>
   }<br>
   else {<br>
     ARM_CP14_READ(val, 0, 1, 0);<br>
@@ -1155,7 +1173,7 @@ static void<br>
 arm_debug_dbgdscr_write(uint32_t val)<br>
 {<br>
   if (debug_registers != NULL) {<br>
-    ARM_MMAP_WRITE(34, val);<br>
+    ARM_MMAP_WRITE_SYNC(ARM_MMAP_DBGDSCR, val);<br>
   }<br>
   else {<br>
     ARM_CP14_WRITE(val, 0, 1, 0);<br>
@@ -1171,35 +1189,30 @@ arm_debug_method_of_entry(void)<br>
 static void<br>
 arm_debug_disable_interrupts(void)<br>
 {<br>
-  debug_disable_ints = true;<br>
+  debug_disable_ints = 1;<br>
 }<br>
<br>
 static void<br>
-arm_debug_commit_interrupt_disable(void)<br>
+arm_debug_enable_interrupts(void)<br>
 {<br>
-  if (debug_disable_ints) {<br>
-    arm_debug_dbgdscr_write(arm_debug_dbgdscr_read() | (1 << 11));<br>
-    debug_disable_ints = false;<br>
-  }<br>
+  arm_debug_dbgdscr_write(arm_debug_dbgdscr_read() & ~(1 << 11));<br>
 }<br>
<br>
 static void<br>
-arm_debug_enable_interrupts(void)<br>
+arm_debug_break_clear(int bp)<br>
 {<br>
-  arm_debug_dbgdscr_write(arm_debug_dbgdscr_read() & ~(1 << 11));<br>
+  rtems_interrupt_lock_context lock_context;<br>
+  rtems_interrupt_lock_acquire(&target_lock, &lock_context);<br>
+  ARM_HWB_CLEAR(bp);<br>
+  rtems_interrupt_lock_release(&target_lock, &lock_context);<br>
 }<br>
<br>
 static void<br>
-arm_debug_break_clear(void)<br>
+arm_debug_break_clear_all(void)<br>
 {<br>
   rtems_interrupt_lock_context lock_context;<br>
-  arm_debug_hwbreak*           bp = &hw_breaks[0];<br>
-  int                          i;<br>
   rtems_interrupt_lock_acquire(&target_lock, &lock_context);<br>
-  for (i = 0; i < hw_breakpoints; ++i, ++bp) {<br>
-    bp->enabled = false;<br>
-    bp->loaded = false;<br>
-  }<br>
+  ARM_HWB_CLEAR_ALL();<br>
   rtems_interrupt_lock_release(&target_lock, &lock_context);<br>
 }<br>
<br>
@@ -1211,58 +1224,81 @@ arm_debug_set_context_id(const uint32_t id)<br>
 #endif<br>
 }<br>
<br>
-/*<br>
- * You can only load the hardware breaks points when in the SVC mode or the<br>
- * single step inverted break point will trigger.<br>
- */<br>
 static void<br>
-arm_debug_break_load(void)<br>
+arm_debug_break_unload(void)<br>
 {<br>
   rtems_interrupt_lock_context lock_context;<br>
-  arm_debug_hwbreak*           bp = &hw_breaks[0];<br>
-  int                          i;<br>
+  int i;<br>
   rtems_interrupt_lock_acquire(&target_lock, &lock_context);<br>
-  if (bp->enabled && !bp->loaded) {<br>
-    arm_debug_set_context_id(0xdead1111);<br>
-    arm_debug_break_write_value(0, bp->value);<br>
-    arm_debug_break_write_control(0, bp->control);<br>
-  }<br>
-  ++bp;<br>
-  for (i = 1; i < hw_breakpoints; ++i, ++bp) {<br>
-    if (bp->enabled && !bp->loaded) {<br>
-      bp->loaded = true;<br>
-      arm_debug_break_write_value(i, bp->value);<br>
-      arm_debug_break_write_control(i, bp->control);<br>
+  if (debug_registers != NULL) {<br>
+    for (i = 0; i < hw_breakpoints; ++i) {<br>
+      ARM_MMAP_WRITE(ARM_MMAP_DBGBCR + i, 0);<br>
+      ARM_MMAP_WRITE(ARM_MMAP_DBGBVR + i, 0);<br>
+    }<br>
+  } else {<br>
+    for (i = 0; i < hw_breakpoints; ++i) {<br>
+      arm_debug_break_c14_write_control(i, 0);<br>
+      arm_debug_break_c14_write_value(i, 0);<br>
     }<br>
   }<br>
   rtems_interrupt_lock_release(&target_lock, &lock_context);<br>
 }<br>
<br>
 static void<br>
-arm_debug_break_unload(void)<br>
-{<br>
-  rtems_interrupt_lock_context lock_context;<br>
-  arm_debug_hwbreak*           bp = &hw_breaks[0];<br>
-  int                          i;<br>
-  rtems_interrupt_lock_acquire(&target_lock, &lock_context);<br>
-  arm_debug_set_context_id(0);<br>
-  for (i = 0; i < hw_breakpoints; ++i, ++bp) {<br>
-    bp->loaded = false;<br>
-    arm_debug_break_write_control(i, 0);<br>
+arm_debug_break_exec_enable(int bp, uintptr_t addr, bool thumb, bool step) {<br>
+  uint32_t bas;<br>
+<br>
+  /*<br>
+   * See table C3-2 Effect of byte address selection on Breakpoint<br>
+   * generation and "Instruction address comparision programming<br>
+   * examples.<br>
+   */<br>
+  if (thumb) {<br>
+    /*<br>
+     * Thumb<br>
+     */<br>
+    if ((addr & (1 << 1)) == 0) {<br>
+      /*<br>
+       * Instruction address: DBGBVR[31:2]:00 BAS: 0bxx11 Mismatch: Miss<br>
+       */<br>
+      bas = 0x3; /* bxx11 */<br>
+    }<br>
+    else {<br>
+      /*<br>
+       * Instruction address: DBGBVR[31:2]:10 BAS: 0b11xx Mismatch: Miss<br>
+       */<br>
+      bas = 0xc; /* b11xx */<br>
+    }<br>
   }<br>
-  rtems_interrupt_lock_release(&target_lock, &lock_context);<br>
+  else {<br>
+    /*<br>
+     * ARM<br>
+     *<br>
+     * Instruction address: DBGBVR[31:2]:00 BAS: 0b1111 Mismatch: Miss<br>
+     */<br>
+    bas = 0xf; /* b1111 */<br>
+  }<br>
+<br>
+  target_printk("[} break: addr:%08x bas:%x thumb:%s\n",<br>
+                addr, bas, thumb ? "yes" : "no");<br>
+<br>
+  arm_debug_break_setup(<br>
+    bp,<br>
+    addr,<br>
+    step ? ARM_HW_BP_UNLINKED_INSTR_MISMATCH : ARM_HW_BP_UNLINKED_INSTR_MATCH,<br>
+    bas,<br>
+    ARM_HW_BP_PRIV_PL0_SUP_SYS);<br>
 }<br>
<br>
 static void<br>
 arm_debug_break_dump(void)<br>
 {<br>
 #if TARGET_DEBUG<br>
-  arm_debug_hwbreak* bp = &hw_breaks[0];<br>
   int                i;<br>
-  for (i = 0; i < hw_breakpoints; ++i, ++bp) {<br>
-    if (bp->enabled) {<br>
+  for (i = 0; i < hw_breakpoints; ++i) {<br>
+    if (ARM_HWB_ENALBED(i)) {<br>
       target_printk("[} bp: %d: control: %08x addr: %08x\n",<br>
-                    i, bp->control, bp->value);<br>
+                    i, ARM_HWB_BCR(i), ARM_HWB_VCR(i));<br>
     }<br>
   }<br>
 #endif<br>
@@ -1314,6 +1350,8 @@ target_exception(CPU_Exception_frame* frame)<br>
 #if TARGET_DEBUG<br>
 #if ARM_CP15<br>
   const uint32_t ifsr = arm_cp15_get_instruction_fault_status();<br>
+  const uint32_t dfsr = arm_cp15_get_data_fault_status();<br>
+  const void* far = arm_cp15_get_fault_address();<br>
 #else<br>
   const uint32_t ifsr = 0;<br>
 #endif<br>
@@ -1341,18 +1379,20 @@ target_exception(CPU_Exception_frame* frame)<br>
<br>
   target_printk("[} > frame = %08" PRIx32 \<br>
                 " sig=%d vector=%u (%u) dbgdscr=%08" PRIx32 " moe=%s" \<br>
-                " ifsr=%08" PRIx32 " pra=%08x\n",<br>
-                (uint32_t) frame,<br>
+                " far=%p ifsr=%08" PRIx32 " dfsr=%08" PRIx32<br>
+                " exc-ret-pc=%08x\n", (uint32_t) frame,<br>
                 rtems_debugger_target_exception_to_signal(frame),<br>
                 frame->vector, mvector, dbgdscr, arm_moe_label(moe),<br>
-                ifsr, (intptr_t) frame->register_pc);<br>
+                far, ifsr, dfsr, (intptr_t) frame->register_pc);<br>
+<br>
+  arm_debug_break_dump();<br>
<br>
   frame->register_pc = (void*) ((intptr_t) frame->register_pc - exc_offset);<br>
<br>
   target_print_frame(frame);<br>
<br>
+  arm_debug_break_clear(0);<br>
   arm_debug_enable_interrupts();<br>
-  arm_debug_break_clear();<br>
<br>
   if (!debug_session_active)<br>
     _ARM_Exception_default(frame);<br>
@@ -1373,9 +1413,15 @@ target_exception(CPU_Exception_frame* frame)<br>
                 " PC = %08" PRIxPTR " CPSR = %08" PRIx32 "\n",<br>
                 (uint32_t) frame, (intptr_t) frame->register_pc, FRAME_SR(frame));<br>
   target_print_frame(frame);<br>
-  arm_debug_break_dump();<br>
 }<br>
<br>
+/**<br>
+ * Exception Handlers<br>
+ *<br>
+ * The entry and exit is all assembler and ARM code. This avoids any<br>
+ * compiler related optimisations effecting the various pieces.<br>
+ */<br>
+<br>
 /**<br>
  * Exception stack frame size.<br>
  *<br>
@@ -1408,15 +1454,89 @@ target_exception(CPU_Exception_frame* frame)<br>
  */<br>
 #define EXCEPTION_ENTRY_EXC()                                           \<br>
   __asm__ volatile(                                                     \<br>
-    ASM_ARM_MODE                                                        \<br>
+    ASM_ARM_MODE                 /* force ARM mode for thumb systems */ \<br>
     "sub  sp, %[frame_size]\n"           /* alloc the frame and CPSR */ \<br>
     "stm  sp, {r0-r12}\n"                            /* store r0-r12 */ \<br>
-    "sub  sp, #4\n"                                                     \<br>
-    "str  lr, [sp]\n"                           /* save the link reg */ \<br>
-    ASM_THUMB_MODE                                                      \<br>
-    : ARM_SWITCH_REG_ASM                                                \<br>
+    :                                                                   \<br>
     : [frame_size] "i" (EXCEPTION_FRAME_SIZE)                           \<br>
-    : "memory")<br>
+    : "cc", "memory")<br>
+<br>
+/**<br>
+ * Debugger entry<br>
+ *<br>
+ * Check if using debug registers else use CP14.<br>
+ *<br>
+ * Set all the break point registers to 0. Enable interrupts.<br>
+ */<br>
+#if ARM_CP15<br>
+#define ARM_HW_BP_UNLOAD(_bp)                                           \<br>
+    "cmp r0, #" #_bp "\n"                                               \<br>
+    "ble 3f\n"                                                          \<br>
+    "mcr p14, 0, r1, c0, c" #_bp ", 5\n"                                \<br>
+    "mcr p14, 0, r1, c0, c" #_bp ", 4\n"<br>
+#define ARM_DGB_ENABLE_INTS                                             \<br>
+    "mrc   p14, 0, r1, c0, c1, 0\n"               /* Get the DBGDSCR */ \<br>
+    "bic   r1, r1, #(1 << 11)\n"                /* enable interrupts */ \<br>
+    "mcr   p14, 0, r1, c0, c1, 0\n"               /* Set the DBGDSCR */<br>
+#else<br>
+#define ARM_HW_BP_UNLOAD(_bp)<br>
+#define ARM_DGB_ENABLE_INTS<br>
+#endif<br>
+<br>
+#define EXCEPTION_ENTRY_DEBUGGER()                                      \<br>
+  __asm__ volatile(                                                     \<br>
+    /* Set up r0 and r1 */                                              \<br>
+    "movw  r0, #:lower16:hw_breakpoints\n"  /* get the num hw breaks */ \<br>
+    "movt  r0, #:upper16:hw_breakpoints\n"                              \<br>
+    "ldr   r0, [r0]\n"                        /* r0 = hw_breakpoints */ \<br>
+    "mov   r1, #0\n"                                   /* write zero */ \<br>
+    /* Check if debug registers are being used */                       \<br>
+    "movw  r2, #:lower16:debug_registers\n"    /* get the debug regs */ \<br>
+    "movt  r2, #:upper16:debug_registers\n"                             \<br>
+    "ldr   r2, [r2]\n"                       /* r2 = debug_registers */ \<br>
+    "cmp   r2, #0\n"                                        /* NULL? */ \<br>
+    "beq    2f\n"                                /* if NULL use cp14 */ \<br>
+    /* Debug registers */                                               \<br>
+    "add   r3, r2, %[dbgbvr] - 4\n"        /* a3 = DBGBCR0, adjusted */ \<br>
+    "add   r2, r2, %[dbgbcr] - 4\n"        /* a2 = DBGBVR0, adjusted */ \<br>
+    "1:\n"                                                              \<br>
+    "str   r1, [r3, #4]!\n"   /* Store DBGBVR, pre-indexed, modified */ \<br>
+    "str   r1, [r2, #4]!\n"   /* Store DBGBCR, pre-indexed, modified */ \<br>
+    "sub   r0, r0, #1\n"                                 /* one less */ \<br>
+    "cmp   r0, #0\n"                                    /* all done? */ \<br>
+    "bne   1b\n"                                                        \<br>
+    "ldr   r1, [r2, %[dbgdscr]]\n"                /* Get the DBGDSCR */ \<br>
+    "bic   r1, r1, #(1 << 11)\n"                /* enable interrupts */ \<br>
+    "str   r1, [r2, %[dbgdscr]]\n"                /* Set the DBGDSCR */ \<br>
+    "b     4f\n"                                                        \<br>
+    /* CP14 */                                                          \<br>
+    "2:\n"                                                              \<br>
+    ARM_HW_BP_UNLOAD(0)                                                 \<br>
+    ARM_HW_BP_UNLOAD(1)                                                 \<br>
+    ARM_HW_BP_UNLOAD(2)                                                 \<br>
+    ARM_HW_BP_UNLOAD(3)                                                 \<br>
+    ARM_HW_BP_UNLOAD(4)                                                 \<br>
+    ARM_HW_BP_UNLOAD(5)                                                 \<br>
+    ARM_HW_BP_UNLOAD(6)                                                 \<br>
+    ARM_HW_BP_UNLOAD(7)                                                 \<br>
+    ARM_HW_BP_UNLOAD(8)                                                 \<br>
+    ARM_HW_BP_UNLOAD(9)                                                 \<br>
+    ARM_HW_BP_UNLOAD(10)                                                \<br>
+    ARM_HW_BP_UNLOAD(11)                                                \<br>
+    ARM_HW_BP_UNLOAD(12)                                                \<br>
+    ARM_HW_BP_UNLOAD(12)                                                \<br>
+    ARM_HW_BP_UNLOAD(13)                                                \<br>
+    ARM_HW_BP_UNLOAD(14)                                                \<br>
+    ARM_HW_BP_UNLOAD(15)                                                \<br>
+    "3:\n"                                                              \<br>
+    ARM_DGB_ENABLE_INTS                                                 \<br>
+    "4:\n"                                                              \<br>
+    ARM_SYNC_INST                                                       \<br>
+    :                                                                   \<br>
+    : [dbgdscr] "i" (ARM_MMAP_DBGDSCR * sizeof(uint32_t)),              \<br>
+      [dbgbcr] "i" (ARM_MMAP_DBGBCR * sizeof(uint32_t)),                \<br>
+      [dbgbvr] "i" (ARM_MMAP_DBGBVR * sizeof(uint32_t))                 \<br>
+    : "cc", "r0", "r1", "r2", "r3", "memory")<br>
<br>
 /*<br>
  * FPU entry. Conditionally D16 or D32 support.<br>
@@ -1430,10 +1550,10 @@ target_exception(CPU_Exception_frame* frame)<br>
     "mov    r3, #0\n"                                                   \<br>
     "mov    r4, #0\n"                                                   \<br>
     "adds   r6, r5, #128\n"                                             \<br>
-    "3:\n"                                                              \<br>
+    "1:\n"                                                              \<br>
     "stmia  r5!, {r3-r4}\n"                                             \<br>
     "cmp    r5, r6\n"                                                   \<br>
-    "bne    3b\n"<br>
+    "bne    1b\n"<br>
 #endif /* ARM_MULTILIB_VFP_D32 */<br>
 #define EXCEPTION_ENTRY_FPU(frame_fpu_size)                             \<br>
     "sub    sp, %[frame_fpu_size]\n" /* size includes alignment size */ \<br>
@@ -1453,9 +1573,6 @@ target_exception(CPU_Exception_frame* frame)<br>
<br>
 #define EXCEPTION_ENTRY_THREAD(_frame)                                  \<br>
   __asm__ volatile(                                                     \<br>
-    ASM_ARM_MODE                                                        \<br>
-    "ldr  lr, [sp]\n"                        /* recover the link reg */ \<br>
-    "add  sp, #4\n"                                                     \<br>
     "add  r0, sp, %[r0_r12_size]\n"       /* get the sp in the frame */ \<br>
     "mrs  r1, spsr\n"                            /* get the saved sr */ \<br>
     "mov  r6, r1\n"                            /* stash it for later */ \<br>
@@ -1468,7 +1585,7 @@ target_exception(CPU_Exception_frame* frame)<br>
     "mov  r4, lr\n"                              /* get the link reg */ \<br>
     "msr  cpsr, r2\n"                            /* back to exc mode */ \<br>
     "mov  r5, lr\n"                                   /* get the PRA */ \<br>
-    "stm  r0, {r3-r6}\n"                      /* save into the frame */ \<br>
+    "stm  r0, {r3-r6}\n"       /* save into the frame: sp,lr,pc,cpsr */ \<br>
     "sub  r4, r3, %[frame_size]\n"            /* destination address */ \<br>
     "mov  r6, r4\n"                                /* save the frame */ \<br>
     "sub  r4, #1\n"                          /* one before the start */ \<br>
@@ -1491,8 +1608,7 @@ target_exception(CPU_Exception_frame* frame)<br>
     EXCEPTION_ENTRY_FPU(frame_fpu_size)                                 \<br>
     "bic  r1, r1, %[psr_i]\n"        /* clear irq mask, debug checks */ \<br>
     "msr  cpsr, r1\n"       /* restore the state with irq mask clear */ \<br>
-    ASM_THUMB_MODE                                                      \<br>
-    : ARM_SWITCH_REG_ASM_L                                              \<br>
+    :                                                                   \<br>
       [o_frame] "=r" (_frame)                                           \<br>
     : [psr_t] "i" (ARM_PSR_T),                                          \<br>
       [psr_i] "i" (ARM_PSR_I),                                          \<br>
@@ -1501,7 +1617,7 @@ target_exception(CPU_Exception_frame* frame)<br>
       [frame_size] "i" (EXCEPTION_FRAME_SIZE),                          \<br>
       [o_frame_fpu] "i" (EXCEPTION_FRAME_FPU_OFFSET),                   \<br>
       [frame_fpu_size] "i" (EXCEPTION_FRAME_FPU_SIZE + 4)               \<br>
-    : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "memory")<br>
+    : "cc", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "memory")<br>
<br>
 /*<br>
  * FPU exit. Conditionally D16 or D32 support.<br>
@@ -1537,9 +1653,8 @@ target_exception(CPU_Exception_frame* frame)<br>
  */<br>
 #define EXCEPTION_EXIT_THREAD(_frame)                                   \<br>
   __asm__ volatile(                                                     \<br>
-    ASM_ARM_MODE                                                        \<br>
     "mov  r0, %[i_frame]\n"                         /* get the frame */ \<br>
-    "ldr  r0, [r0, %[frame_fpu]]\n"     /* recover FPU frame pointer */ \<br>
+    "ldr  r0, [r0, %[frame_fpu]]\n" /* recover aligned FPU frame ptr */ \<br>
     EXCEPTION_EXIT_FPU(frame_fpu_size)                                  \<br>
     "ldr  r2, [sp, %[frame_cpsr]]\n" /* recover exc CPSR from thread */ \<br>
     "mov  r0, sp\n"                  /* get the thread frame pointer */ \<br>
@@ -1562,11 +1677,8 @@ target_exception(CPU_Exception_frame* frame)<br>
     "mov  lr, r4\n"                              /* set the link reg */ \<br>
     "msr  cpsr, r2\n"            /* switch back to the exc's context */ \<br>
     "msr  spsr, r6\n"                       /* set the thread's CPSR */ \<br>
-    "sub  sp, #4\n"                                                     \<br>
     "mov  lr, r5\n"                                    /* get the PC */ \<br>
-    "str  lr, [sp]\n"                           /* save the link reg */ \<br>
-    ASM_THUMB_MODE                                                      \<br>
-    : ARM_SWITCH_REG_ASM                                                \<br>
+    :                                                                   \<br>
     : [psr_i] "i" (ARM_PSR_I),                                          \<br>
       [r0_r12_size] "i" (13 * sizeof(uint32_t)),                        \<br>
       [frame_cpsr] "i" (EXCEPTION_FRAME_SIZE - sizeof(uint32_t)),       \<br>
@@ -1574,19 +1686,135 @@ target_exception(CPU_Exception_frame* frame)<br>
       [frame_fpu] "i" (EXCEPTION_FRAME_FPU_OFFSET),                     \<br>
       [frame_fpu_size] "i" (EXCEPTION_FRAME_FPU_SIZE + 4),              \<br>
       [i_frame] "r" (_frame)                                            \<br>
-    : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "memory")<br>
+    : "cc", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "memory")<br>
+<br>
+/*<br>
+ * Debugger exit<br>
+ *<br>
+ * Check if using debug registers else use CP14.<br>
+ *<br>
+ * Set all the break point registers to settgins. Disable interrupts<br>
+ * if debug_disable_ints is true. Clear debug_disable_ints.<br>
+ */<br>
+#if ARM_CP15<br>
+#define ARM_HW_BP_LOAD(_bp)                                             \<br>
+    "cmp r0, #" #_bp "\n"                                               \<br>
+    "ble 5f\n"                                                          \<br>
+    "ldm r1!, {r2-r3}\n"                                                \<br>
+    "mcr p14, 0, r2, c0, c" #_bp ", 4\n"                    /* value */ \<br>
+    "mcr p14, 0, r3, c0, c" #_bp ", 5\n"                  /* control */<br>
+#define ARM_DGB_DISABLE_INTS                                            \<br>
+    "mrc   p14, 0, r4, c0, c1, 0\n"               /* Get the DBGDSCR */ \<br>
+    "orr   r4, r4, #(1 << 11)\n"               /* disable interrupts */ \<br>
+    "mcr   p14, 0, r4, c0, c1, 0\n"               /* Set the DBGDSCR */<br>
+#else<br>
+#define ARM_HW_BP_LOAD(_bp)<br>
+#define ARM_DGB_DISABLE_INTS<br>
+#endif<br>
+<br>
+#define EXCEPTION_EXIT_DEBUGGER()                                       \<br>
+  __asm__ volatile(                                                     \<br>
+    /* Set up r0, r1, r4 and r5 */                                      \<br>
+    "movw  r0, #:lower16:hw_breakpoints\n"  /* get the num hw breaks */ \<br>
+    "movt  r0, #:upper16:hw_breakpoints\n"                              \<br>
+    "ldr   r0, [r0]\n"                        /* r0 = hw_breakpoints */ \<br>
+    "movw  r1, #:lower16:hw_breaks\n"   /* get the hw_breaks pointer */ \<br>
+    "movt  r1, #:upper16:hw_breaks\n"                                   \<br>
+    "movw  r4, #:lower16:debug_disable_ints\n"   /* get disable ints */ \<br>
+    "movt  r4, #:upper16:debug_disable_ints\n"                          \<br>
+    "ldr   r5, [r4]\n"                                                  \<br>
+    "mov   r3, #0\n"                             /* clear debug ints */ \<br>
+    "str   r3, [r4]\n"                                                  \<br>
+    /* Check if debug registers are being used */                       \<br>
+    "movw  r2, #:lower16:debug_registers\n"    /* get the debug regs */ \<br>
+    "movt  r2, #:upper16:debug_registers\n"                             \<br>
+    "ldr   r2, [r2]\n"                       /* r2 = debug_registers */ \<br>
+    "cmp   r2, #0\n"                                        /* NULL? */ \<br>
+    "beq   3f\n"                                 /* if NULL use cp14 */ \<br>
+    /* Debug registers */                                               \<br>
+    "cmp   r5, #0\n"                                       /* false? */ \<br>
+    "beq   1f\n"                 /* if false do not set ints disable */ \<br>
+    "ldr   r4, [r2, %[dbgdscr]]\n"                /* Get the DBGDSCR */ \<br>
+    "orr   r4, r4, #(1 << 11)\n"               /* disable interrupts */ \<br>
+    "str   r4, [r2, %[dbgdscr]]\n"                /* Set the DBGDSCR */ \<br>
+    "1:\n"                                                              \<br>
+    "add   r3, r2, %[dbgbvr] - 4\n"        /* a3 = DBGBCR0, adjusted */ \<br>
+    "add   r2, r2, %[dbgbcr] - 4\n"        /* a2 = DBGBVR0, adjusted */ \<br>
+    "2:\n"                                                              \<br>
+    "ldm   r1!, {r4-r5}\n"                         /* load vr and cr */ \<br>
+    "str   r4, [r3, #4]!\n"   /* Store DBGBVR, pre-indexed, modified */ \<br>
+    "str   r5, [r2, #4]!\n"   /* Store DBGBCR, pre-indexed, modified */ \<br>
+    "sub   r0, r0, #1\n"                                /* one less? */ \<br>
+    "cmp   r0, #1\n"                                    /* all done? */ \<br>
+    "bne   2b\n"                                                        \<br>
+    "b     5f\n"                                                        \<br>
+    /* CP14 */                                                          \<br>
+    "3:\n"                                                              \<br>
+    "cmp   r5, #0\n"                                       /* false? */ \<br>
+    "beq   4f\n"                 /* if false do not set ints disable */ \<br>
+    ARM_DGB_DISABLE_INTS                                                \<br>
+    "4:\n"                                                              \<br>
+    ARM_HW_BP_LOAD(0)                                                   \<br>
+    ARM_HW_BP_LOAD(1)                                                   \<br>
+    ARM_HW_BP_LOAD(2)                                                   \<br>
+    ARM_HW_BP_LOAD(3)                                                   \<br>
+    ARM_HW_BP_LOAD(4)                                                   \<br>
+    ARM_HW_BP_LOAD(5)                                                   \<br>
+    ARM_HW_BP_LOAD(6)                                                   \<br>
+    ARM_HW_BP_LOAD(7)                                                   \<br>
+    ARM_HW_BP_LOAD(8)                                                   \<br>
+    ARM_HW_BP_LOAD(9)                                                   \<br>
+    ARM_HW_BP_LOAD(10)                                                  \<br>
+    ARM_HW_BP_LOAD(11)                                                  \<br>
+    ARM_HW_BP_LOAD(12)                                                  \<br>
+    ARM_HW_BP_LOAD(13)                                                  \<br>
+    ARM_HW_BP_LOAD(14)                                                  \<br>
+    ARM_HW_BP_LOAD(15)                                                  \<br>
+    "5:\n"                                                              \<br>
+     ARM_SYNC_INST                                                      \<br>
+    :                                                                   \<br>
+    : [disints] "X" (debug_disable_ints),  /* make the sym available */ \<br>
+      [dbgdscr] "i" (ARM_MMAP_DBGDSCR * sizeof(uint32_t)),              \<br>
+      [dbgbcr] "i" (ARM_MMAP_DBGBCR * sizeof(uint32_t)),                \<br>
+      [dbgbvr] "i" (ARM_MMAP_DBGBVR * sizeof(uint32_t))                 \<br>
+    : "cc", "r0", "r1", "r2", "r3", "r4", "r5", "memory")<br>
<br>
 #define EXCEPTION_EXIT_EXC()                                            \<br>
   __asm__ volatile(                                                     \<br>
-    ASM_ARM_MODE                                                        \<br>
-    "ldr  lr, [sp]\n"                        /* recover the link reg */ \<br>
-    "add  sp, #4\n"                                                     \<br>
     "ldm  sp, {r0-r12}\n"            /* restore the thread's context */ \<br>
     "add  sp, %[frame_size]\n"                     /* free the frame */ \<br>
     "subs pc, lr, #0\n"                       /* return from the exc */ \<br>
+    ARM_SYNC_INST                                                       \<br>
     :                                                                   \<br>
     : [frame_size] "i" (EXCEPTION_FRAME_SIZE)                           \<br>
-    : "memory")<br>
+    : "cc", "memory")<br>
+<br>
+#define ARM_PUSH_LR()                                                   \<br>
+  __asm__ volatile(                                                     \<br>
+    "push {lr}\n"                                                       \<br>
+    : : : )<br>
+<br>
+#define ARM_POP_LR()                                                    \<br>
+  __asm__ volatile(                                                     \<br>
+    "pop {lr}\n"                                                        \<br>
+    : : : )<br>
+<br>
+/*<br>
+ * Entry and exit stacks<br>
+ */<br>
+#define EXCEPTION_ENTRY(_frame)                   \<br>
+  EXCEPTION_ENTRY_EXC();                          \<br>
+  EXCEPTION_ENTRY_DEBUGGER();                     \<br>
+  EXCEPTION_ENTRY_THREAD(_frame);                 \<br>
+  ARM_THUMB_MODE()                                \<br>
+  ARM_PUSH_LR()<br>
+<br>
+#define EXCEPTION_EXIT(_frame)                    \<br>
+  ARM_POP_LR();                                   \<br>
+  ARM_ARM_MODE();                                 \<br>
+  EXCEPTION_EXIT_THREAD(_frame);                  \<br>
+  EXCEPTION_EXIT_DEBUGGER();                      \<br>
+  EXCEPTION_EXIT_EXC()<br>
<br>
 /*<br>
  * This is used to catch faulting accesses.<br>
@@ -1596,9 +1824,10 @@ static void __attribute__((naked))<br>
 arm_debug_unlock_abort(void)<br>
 {<br>
   CPU_Exception_frame* frame;<br>
-  ARM_SWITCH_REG;<br>
+  ARM_SWITCH_REGISTERS;<br>
   EXCEPTION_ENTRY_EXC();<br>
   EXCEPTION_ENTRY_THREAD(frame);<br>
+  ARM_SWITCH_BACK;<br>
   longjmp(unlock_abort_jmpbuf, -1);<br>
 }<br>
 #endif<br>
@@ -1608,16 +1837,10 @@ target_exception_undefined_instruction(void)<br>
 {<br>
   CPU_Exception_frame* frame;<br>
   ARM_SWITCH_REG;<br>
-  EXCEPTION_ENTRY_EXC();<br>
-  arm_debug_break_unload();<br>
-  arm_debug_enable_interrupts();<br>
-  EXCEPTION_ENTRY_THREAD(frame);<br>
+  EXCEPTION_ENTRY(frame);<br>
   frame->vector = 1;<br>
   target_exception(frame);<br>
-  EXCEPTION_EXIT_THREAD(frame);<br>
-  arm_debug_commit_interrupt_disable();<br>
-  arm_debug_break_load();<br>
-  EXCEPTION_EXIT_EXC();<br>
+  EXCEPTION_EXIT(frame);<br>
 }<br>
<br>
 static void __attribute__((naked))<br>
@@ -1631,16 +1854,10 @@ target_exception_supervisor_call(void)<br>
    * this exception is used by the BKPT instruction in the prefetch abort<br>
    * handler to signal a TRAP.<br>
    */<br>
-  EXCEPTION_ENTRY_EXC();<br>
-  arm_debug_break_unload();<br>
-  arm_debug_enable_interrupts();<br>
-  EXCEPTION_ENTRY_THREAD(frame);<br>
+  EXCEPTION_ENTRY(frame);<br>
   frame->vector = 2;<br>
   target_exception(frame);<br>
-  EXCEPTION_EXIT_THREAD(frame);<br>
-  arm_debug_commit_interrupt_disable();<br>
-  arm_debug_break_load();<br>
-  EXCEPTION_EXIT_EXC();<br>
+  EXCEPTION_EXIT(frame);<br>
 }<br>
<br>
 static void __attribute__((naked))<br>
@@ -1648,16 +1865,10 @@ target_exception_prefetch_abort(void)<br>
 {<br>
   CPU_Exception_frame* frame;<br>
   ARM_SWITCH_REG;<br>
-  EXCEPTION_ENTRY_EXC();<br>
-  arm_debug_break_unload();<br>
-  arm_debug_enable_interrupts();<br>
-  EXCEPTION_ENTRY_THREAD(frame);<br>
+  EXCEPTION_ENTRY(frame);<br>
   frame->vector = 3;<br>
   target_exception(frame);<br>
-  EXCEPTION_EXIT_THREAD(frame);<br>
-  arm_debug_commit_interrupt_disable();<br>
-  arm_debug_break_load();<br>
-  EXCEPTION_EXIT_EXC();<br>
+  EXCEPTION_EXIT(frame);<br>
 }<br>
<br>
 static void __attribute__((naked))<br>
@@ -1665,16 +1876,10 @@ target_exception_data_abort(void)<br>
 {<br>
   CPU_Exception_frame* frame;<br>
   ARM_SWITCH_REG;<br>
-  EXCEPTION_ENTRY_EXC();<br>
-  arm_debug_break_unload();<br>
-  arm_debug_enable_interrupts();<br>
-  EXCEPTION_ENTRY_THREAD(frame);<br>
+  EXCEPTION_ENTRY(frame);<br>
   frame->vector = 4;<br>
   target_exception(frame);<br>
-  EXCEPTION_EXIT_THREAD(frame);<br>
-  arm_debug_commit_interrupt_disable();<br>
-  arm_debug_break_load();<br>
-  EXCEPTION_EXIT_EXC();<br>
+  EXCEPTION_EXIT(frame);<br>
 }<br>
<br>
 #if ARM_CP15<br>
@@ -1776,13 +1981,13 @@ int<br>
 rtems_debugger_target_enable(void)<br>
 {<br>
   rtems_interrupt_lock_context lock_context;<br>
-  debug_session_active = true;<br>
   arm_debug_break_unload();<br>
-  arm_debug_break_clear();<br>
+  arm_debug_break_clear_all();<br>
   rtems_interrupt_lock_acquire(&target_lock, &lock_context);<br>
   rtems_debugger_target_set_mmu();<br>
   rtems_debugger_target_set_vectors();<br>
   rtems_interrupt_lock_release(&target_lock, &lock_context);<br>
+  debug_session_active = true;<br>
   return 0;<br>
 }<br>
<br>
@@ -1795,8 +2000,9 @@ rtems_debugger_target_disable(void)<br>
   void*                        text_end;<br>
 #endif<br>
   arm_debug_break_unload();<br>
-  arm_debug_break_clear();<br>
+  arm_debug_break_clear_all();<br>
   rtems_interrupt_lock_acquire(&target_lock, &lock_context);<br>
+  debug_disable_ints = 0;<br>
   debug_session_active = false;<br>
 #if DOES_NOT_WORK<br>
   text_begin = &bsp_section_text_begin[0];<br>
@@ -1979,57 +2185,13 @@ rtems_debugger_target_thread_stepping(rtems_debugger_thread* thread)<br>
      * 0. This is reserved for single stepping.<br>
      */<br>
     CPU_Exception_frame* frame = thread->frame;<br>
-    arm_debug_hwbreak*   bp = &hw_breaks[0];<br>
<br>
-    target_printk("[} stepping: %s\n", bp->enabled ? "yes" : "no");<br>
+    target_printk("[} stepping: hbp[0] enabled: %s\n", ARM_HWB_ENALBED(0) ? "yes" : "no");<br>
<br>
-    if (!bp->enabled) {<br>
+    if (!ARM_HWB_ENALBED(0)) {<br>
       const uint32_t addr = (intptr_t) frame->register_pc;<br>
       const bool     thumb = (FRAME_SR(frame) & (1 << 5)) != 0 ? true : false;<br>
-      uint32_t       bas;<br>
-<br>
-      bp->enabled = true;<br>
-      bp->loaded = false;<br>
-      bp->address = frame->register_pc;<br>
-      bp->frame = frame;<br>
-      bp->length = sizeof(uint32_t);<br>
-<br>
-      if (thumb) {<br>
-        uint16_t instr = *((uint16_t*) frame->register_pc);<br>
-        switch (instr & 0xf800) {<br>
-        case 0xe800:<br>
-        case 0xf000:<br>
-        case 0xf800:<br>
-          break;<br>
-        default:<br>
-          bp->length = sizeof(uint16_t);<br>
-          break;<br>
-        }<br>
-      }<br>
-<br>
-      /*<br>
-       * See table C3-2 Effect of byte address selection on Breakpoint<br>
-       * generation and "Instruction address comparision programming<br>
-       * examples.<br>
-       */<br>
-      if (thumb) {<br>
-        if ((addr & (1 << 1)) == 0) {<br>
-          bas = 0x3; /* b0011 */<br>
-        }<br>
-        else {<br>
-          bas = 0xc; /* b1100 */<br>
-        }<br>
-      }<br>
-      else {<br>
-        bas = 0xf; /* b1111 */<br>
-      }<br>
-<br>
-      arm_debug_break_setup(bp,<br>
-                            addr & ~0x3,<br>
-                            ARM_HW_BP_UNLINKED_INSTR_MISMATCH,<br>
-                            bas,<br>
-                            ARM_HW_BP_PRIV_PL0_SUP_SYS);<br>
-<br>
+      arm_debug_break_exec_enable(0, addr, thumb, true);<br>
       arm_debug_disable_interrupts();<br>
     }<br>
   }<br>
@@ -2085,6 +2247,7 @@ rtems_debugger_target_hwbreak_insert(void)<br>
 int<br>
 rtems_debugger_target_hwbreak_remove(void)<br>
 {<br>
+  target_printk("[} hbreak: remove: unload\n");<br>
   arm_debug_break_unload();<br>
   return 0;<br>
 }<br>
@@ -2095,15 +2258,34 @@ rtems_debugger_target_hwbreak_control(rtems_debugger_target_watchpoint wp,<br>
                                       DB_UINT                          addr,<br>
                                       DB_UINT                          kind)<br>
 {<br>
-  /*<br>
-   * To do.<br>
-   */<br>
+  rtems_interrupt_lock_context lock_context;<br>
+  int                          i;<br>
+  if (wp != rtems_debugger_target_hw_execute) {<br>
+    errno = EIO;<br>
+    return -1;<br>
+  }<br>
+  rtems_interrupt_lock_acquire(&target_lock, &lock_context);<br>
+  for (i = 1; i < hw_breakpoints; ++i) {<br>
+    if (insert && !ARM_HWB_ENALBED(i)) {<br>
+      arm_debug_break_exec_enable(i, addr, kind == 1, false);<br>
+      break;<br>
+    } else if (!insert && ARM_HWB_ENALBED(i) && ARM_HWB_VCR(i) == (addr & ~3)) {<br>
+      arm_debug_break_clear(i);<br>
+      break;<br>
+    }<br>
+  }<br>
+  rtems_interrupt_lock_release(&target_lock, &lock_context);<br>
+  if (!insert && i == hw_breakpoints) {<br>
+    errno = EIO;<br>
+    return -1;<br>
+  }<br>
   return 0;<br>
 }<br>
<br>
 int<br>
 rtems_debugger_target_cache_sync(rtems_debugger_target_swbreak* swbreak)<br>
 {<br>
+  target_printk("[} cache: sync: %p\n", swbreak->address);<br>
   /*<br>
    * Flush the data cache and invalidate the instruction cache.<br>
    */<br>
-- <br>
2.37.1<br>
<br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org" target="_blank">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</blockquote></div>