Feroceon has a layer 2 cache that must be invalidated after modifying an instruction in memory to set or unset a breakpoint. Otherwise, the CPU may continue to execute the original instruction out of the cache.
Added an "invalidate_l2" method to the arm7_9_common structure, in case other sub-architectures need this too. Tested on a Seagate DockStar running U-Boot. Signed-Off-By: Eric Cooper <e...@cmu.edu> --- src/target/arm7_9_common.c | 4 ++++ src/target/arm7_9_common.h | 2 ++ src/target/feroceon.c | 8 ++++++++ 3 files changed, 14 insertions(+), 0 deletions(-) diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 611d5d4..0284226 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -307,6 +307,8 @@ static int arm7_9_set_breakpoint(struct target *target, struct breakpoint *break return ERROR_OK; } } + if (arm7_9->invalidate_l2) + arm7_9->invalidate_l2(target); if ((retval = arm7_9_set_software_breakpoints(arm7_9)) != ERROR_OK) return retval; @@ -398,6 +400,8 @@ static int arm7_9_unset_breakpoint(struct target *target, struct breakpoint *bre return retval; } } + if (arm7_9->invalidate_l2) + arm7_9->invalidate_l2(target); if (--arm7_9->sw_breakpoint_count==0) { diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h index 780d6c9..21ebc7a 100644 --- a/src/target/arm7_9_common.h +++ b/src/target/arm7_9_common.h @@ -103,6 +103,8 @@ struct arm7_9_common int (*post_debug_entry)(struct target *target); /**< Callback function called after entering debug mode */ void (*pre_restore_context)(struct target *target); /**< Callback function called before restoring the processor context */ + + void (*invalidate_l2)(struct target *target); }; static inline struct arm7_9_common * diff --git a/src/target/feroceon.c b/src/target/feroceon.c index 9bd45be..902bb83 100644 --- a/src/target/feroceon.c +++ b/src/target/feroceon.c @@ -596,6 +596,11 @@ static int feroceon_init_target(struct command_context *cmd_ctx, return ERROR_OK; } +static void feroceon_invalidate_l2(struct target *target) +{ + feroceon_write_cp15(target, 1, 0, 15, 11, 0); +} + static void feroceon_common_setup(struct target *target) { struct arm *armv4_5 = target->arch_info; @@ -627,6 +632,9 @@ static void feroceon_common_setup(struct target *target) /* only one working comparator */ arm7_9->wp_available_max = 1; arm7_9->wp1_used_default = -1; + + /* layer 2 cache */ + arm7_9->invalidate_l2 = feroceon_invalidate_l2; } static int feroceon_target_create(struct target *target, Jim_Interp *interp) -- 1.7.2.5 _______________________________________________ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development