Hi everyone,

I tried to use a software breakpoint in thumb code on the xscale for the first
time recently, and was surprised to find that it didn't work.  The result was
this patch, which does three things:

1): fix trivial cut-n-paste error that caused thumb breakpoints to not work
2): call xscale_set_breakpoint() from xscale_add_breakpoint()
3): add ERROR_TARGET_DATA_ABORT to the errors checked by breakpoint_add()

Item 2 not only makes the xscale breakpoint code consistent with other targets,
but also alerts the user immediately if an error occurs when writing the
breakpoint instruction to target memory (previously, xscale_set_breakpoint() was
not called until execution resumed).  Also, calling xscale_breakpoint_set() as
part of the call chain starting with handle_bp_command() and propagating the
return status back up the chain avoids the situation where OpenOCD "thinks" the
breakpoint is set when in reality an error ocurred.

I sometimes forget to ensure that a region of memory containing code is mapped
with write permissions.  If it's not, a data abort is generated when the debug
handler attempts to write the bkpt instruction.  I guess this is not uncommon,
so I took the liberty of adding item 3.

This was thoroughly tested, mindful of the fact that breakpoint management is
somewhat dicey during single-stepping.

Comments and criticisms of course gratefully received.

Mike

Signed-off-by: Mike Dunn <[email protected]>
---
 src/target/breakpoints.c |    3 +++
 src/target/xscale.c      |    4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c
index dc44642..07ad9e7 100644
--- a/src/target/breakpoints.c
+++ b/src/target/breakpoints.c
@@ -86,6 +86,9 @@ int breakpoint_add(struct target *target, uint32_t address, 
uint32_t length, enu
        case ERROR_TARGET_NOT_HALTED:
                reason = "target running";
                goto fail;
+       case ERROR_TARGET_DATA_ABORT:
+               reason = "data abort";
+               goto fail;
        default:
                reason = "unknown reason";
 fail:
diff --git a/src/target/xscale.c b/src/target/xscale.c
index 2b8bff1..a678a91 100644
--- a/src/target/xscale.c
+++ b/src/target/xscale.c
@@ -2169,7 +2169,7 @@ static int xscale_set_breakpoint(struct target *target,
                                return retval;
                        }
                        /* write the bkpt instruction in target endianness 
(arm7_9->arm_bkpt is host endian) */
-                       if ((retval = target_write_u32(target, 
breakpoint->address, xscale->thumb_bkpt)) != ERROR_OK)
+                       if ((retval = target_write_u16(target, 
breakpoint->address, xscale->thumb_bkpt)) != ERROR_OK)
                        {
                                return retval;
                        }
@@ -2207,7 +2207,7 @@ static int xscale_add_breakpoint(struct target *target,
                xscale->ibcr_available--;
        }
 
-       return ERROR_OK;
+       return xscale_set_breakpoint(target, breakpoint);
 }
 
 static int xscale_unset_breakpoint(struct target *target,
-- 
1.7.1

_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to