<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>