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

Reply via email to