- explicitly disable monitor mode on ARM7/9 targets
authordrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Mon, 16 Apr 2007 14:58:16 +0000 (14:58 +0000)
committerdrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Mon, 16 Apr 2007 14:58:16 +0000 (14:58 +0000)
- added "prepare_reset_halt()" to target_type_t, which allows reset_halt to be prepared before a reset is asserted, possibly preventing communication with the target
- arm7/9 devices now use a breakpoint at 0x0 or reset vector catching for debug out of reset

git-svn-id: svn://svn.berlios.de/openocd/trunk@141 b42882b7-edfa-0310-969c-e2dbd0fdcd60

12 files changed:
src/target/arm720t.c
src/target/arm7_9_common.c
src/target/arm7_9_common.h
src/target/arm7tdmi.c
src/target/arm920t.c
src/target/arm926ejs.c
src/target/arm966e.c
src/target/arm9tdmi.c
src/target/embeddedice.c
src/target/target.c
src/target/target.h
src/target/xscale.c

index 1b809e6dbf4af8dfe52f918fb572b9d622fab2c4..7aff8a7eb2373a3c890a68640b1ca2d7aaeb4b34 100644 (file)
@@ -63,6 +63,7 @@ target_type_t arm720t_target =
        .assert_reset = arm7_9_assert_reset,
        .deassert_reset = arm7_9_deassert_reset,
        .soft_reset_halt = arm720t_soft_reset_halt,
+       .prepare_reset_halt = arm7_9_prepare_reset_halt,
        
        .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
 
index 7a409b0fae10d4570da37992da556f5831c91099..3a7c80a107244f7af29ee650861653a502c2f860 100644 (file)
@@ -725,9 +725,8 @@ int arm7_9_deassert_reset(target_t *target)
        
        /* deassert reset lines */
        jtag_add_reset(0, 0);
-               
+       
        return ERROR_OK;
-
 }
 
 int arm7_9_clear_halt(target_t *target)
@@ -736,7 +735,8 @@ int arm7_9_clear_halt(target_t *target)
        arm7_9_common_t *arm7_9 = armv4_5->arch_info;
        reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
        
-       if (arm7_9->use_dbgrq)
+       /* we used DBGRQ only if we didn't come out of reset */
+       if (!arm7_9->debug_entry_from_reset && arm7_9->use_dbgrq)
        {
                /* program EmbeddedICE Debug Control Register to deassert DBGRQ
                 */
@@ -745,18 +745,29 @@ int arm7_9_clear_halt(target_t *target)
        }
        else
        {
-               /* restore registers if watchpoint unit 0 was in use
-                */
-               if (arm7_9->wp0_used)
+               if (arm7_9->debug_entry_from_reset && arm7_9->has_vector_catch)
                {
-                       embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
-                       embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
-                       embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
+                       /* if we came out of reset, and vector catch is supported, we used
+                        * vector catch to enter debug state
+                        * restore the register in that case
+                        */
+                       embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH]);
+               }
+               else
+               {
+                       /* restore registers if watchpoint unit 0 was in use
+                        */
+                       if (arm7_9->wp0_used)
+                       {
+                               embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);
+                               embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);
+                               embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);
+                       }
+                       /* control value always has to be restored, as it was either disabled, 
+                        * or enabled with possibly different bits
+                        */
+                       embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
                }
-               /* control value always has to be restored, as it was either disabled, 
-                * or enabled with possibly different bits
-                */
-               embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);
        }
        
        return ERROR_OK;
@@ -831,6 +842,28 @@ int arm7_9_soft_reset_halt(struct target_s *target)
        return ERROR_OK;
 }
 
+int arm7_9_prepare_reset_halt(target_t *target)
+{
+       armv4_5_common_t *armv4_5 = target->arch_info;
+       arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+       
+       if (arm7_9->has_vector_catch)
+       {
+               /* program vector catch register to catch reset vector */
+               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0x1);
+       }
+       else
+       {
+               /* program watchpoint unit to match on reset vector address */
+               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0x3);
+               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0x0);
+               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);
+               embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);
+       }
+       
+       return ERROR_OK;
+}
+
 int arm7_9_halt(target_t *target)
 {
        armv4_5_common_t *armv4_5 = target->arch_info;
@@ -843,17 +876,29 @@ int arm7_9_halt(target_t *target)
        {
                WARNING("target was already halted");
                return ERROR_TARGET_ALREADY_HALTED;
-       } 
+       }
        
        if (target->state == TARGET_UNKNOWN)
        {
                WARNING("target was in unknown state when halt was requested");
        }
        
-       if ((target->state == TARGET_RESET) && (jtag_reset_config & RESET_SRST_PULLS_TRST) && (jtag_srst))
+       if (target->state == TARGET_RESET) 
        {
-               ERROR("can't request a halt while in reset if nSRST pulls nTRST");
-               return ERROR_TARGET_FAILURE;
+               if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
+               {
+                       ERROR("can't request a halt while in reset if nSRST pulls nTRST");
+                       return ERROR_TARGET_FAILURE;
+               }
+               else
+               {
+                       /* we came here in a reset_halt or reset_init sequence
+                        * debug entry was already prepared in arm7_9_prepare_reset_halt()
+                        */
+                       target->debug_reason = DBG_REASON_DBGRQ;
+                       
+                       return ERROR_OK; 
+               }
        }
 
        if (arm7_9->use_dbgrq)
@@ -2477,6 +2522,8 @@ int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
        
        arm7_9->reinit_embeddedice = 0;
        
+       arm7_9->debug_entry_from_reset = 0;
+       
        arm7_9->dcc_working_area = NULL;
        
        arm7_9->fast_memory_access = 0;
index fd9a9e1bb783413ee14f44c96625c478505f0f8b..5e7d54a9ca6b050832e009942f684d27635dfed4 100644 (file)
@@ -55,6 +55,7 @@ typedef struct arm7_9_common_s
        int has_vector_catch;
        
        int reinit_embeddedice;
+       int debug_entry_from_reset;
        
        struct working_area_s *dcc_working_area;
        
@@ -108,6 +109,7 @@ int arm7_9_deassert_reset(target_t *target);
 int arm7_9_reset_request_halt(target_t *target);
 int arm7_9_early_halt(target_t *target);
 int arm7_9_soft_reset_halt(struct target_s *target);
+int arm7_9_prepare_reset_halt(struct target_s *target);
 
 int arm7_9_halt(target_t *target);
 int arm7_9_debug_entry(target_t *target);
index 3fcfa296953eec002cd465f284836eb54119200e..38917dedcd14d5a551223f0e73977958a4bfb9a2 100644 (file)
@@ -66,6 +66,7 @@ target_type_t arm7tdmi_target =
        .assert_reset = arm7_9_assert_reset,
        .deassert_reset = arm7_9_deassert_reset,
        .soft_reset_halt = arm7_9_soft_reset_halt,
+       .prepare_reset_halt = arm7_9_prepare_reset_halt,
 
        .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
        
index 1dae23192e02babf4839a6e432600fe02ec5dda3..d7fb8e11b40cce7535b72d918589975d7a4ba5d3 100644 (file)
@@ -70,6 +70,7 @@ target_type_t arm920t_target =
        .assert_reset = arm7_9_assert_reset,
        .deassert_reset = arm7_9_deassert_reset,
        .soft_reset_halt = arm920t_soft_reset_halt,
+       .prepare_reset_halt = arm7_9_prepare_reset_halt,
        
        .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
 
index ecabfcd697d9bc0b0217f27420aa4157ebcfc68c..3931e89871af8d0e3b57ae3cd7d88286118bf5eb 100644 (file)
@@ -70,6 +70,7 @@ target_type_t arm926ejs_target =
        .assert_reset = arm7_9_assert_reset,
        .deassert_reset = arm7_9_deassert_reset,
        .soft_reset_halt = arm926ejs_soft_reset_halt,
+       .prepare_reset_halt = arm7_9_prepare_reset_halt,
        
        .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
 
index d4b6cf47197d32582fb7ace461561ac141ff4c0e..8b3414ca9e15a05f6160cf2bab9bbcaaa0ce0950 100644 (file)
@@ -63,6 +63,7 @@ target_type_t arm966e_target =
        .assert_reset = arm966e_assert_reset,
        .deassert_reset = arm966e_deassert_reset,
        .soft_reset_halt = arm7_9_soft_reset_halt,
+       .prepare_reset_halt = arm7_9_prepare_reset_halt,
 
        .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
 
index dd1ee79d57f9c86cea682f3ddb8c9e43d858cb55..d21dff739f679b784fee210f4d9ed2702799203e 100644 (file)
@@ -64,6 +64,7 @@ target_type_t arm9tdmi_target =
        .assert_reset = arm7_9_assert_reset,
        .deassert_reset = arm7_9_deassert_reset,
        .soft_reset_halt = arm7_9_soft_reset_halt,
+       .prepare_reset_halt = arm7_9_prepare_reset_halt,
 
        .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
 
index 699aa96f7ac72fc22fe7efc861926941bc09a1ff..76f87410e28bac7148dbf4ee4d82efe17d7d8ed4 100644 (file)
@@ -181,6 +181,15 @@ reg_cache_t* embeddedice_build_reg_cache(target_t *target, arm7_9_common_t *arm7
                        ERROR("unknown EmbeddedICE version (comms ctrl: 0x%8.8x)", buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 0, 32));
        }
        
+       /* explicitly disable monitor mode */
+       if (arm7_9->has_monitor_mode)
+       {
+               embeddedice_read_reg(&reg_list[EICE_DBG_CTRL]);
+               jtag_execute_queue();
+               buf_set_u32(reg_list[EICE_DBG_CTRL].value, 4, 1, 0);
+               embeddedice_set_reg_w_exec(&reg_list[EICE_DBG_CTRL], reg_list[EICE_DBG_CTRL].value);
+       }
+       
        return reg_cache;
 }
 
index 548ea0c39c529ae3049f83ae9e9216e5c137afd3..050a523e712d964024ccdf57e2652ee1547f3643 100644 (file)
@@ -247,7 +247,23 @@ int target_process_reset(struct command_context_s *cmd_ctx)
 {
        int retval = ERROR_OK;
        target_t *target;
-        
+       
+       /* prepare reset_halt where necessary */
+       target = targets;
+       while (target)
+       {
+               switch (target->reset_mode)
+               {
+                       case RESET_HALT:
+                       case RESET_INIT:
+                               target->type->prepare_reset_halt(target);
+                               break;
+                       default:
+                               break;
+               }
+               target = target->next;
+       }
+       
        target = targets;
        while (target)
        {
index d340a77800d650fa9852746d59440f67396bafe8..9ab3d19adb82da28da4b31cedafbd752213bf920 100644 (file)
@@ -110,6 +110,7 @@ typedef struct target_type_s
        int (*assert_reset)(struct target_s *target);
        int (*deassert_reset)(struct target_s *target);
        int (*soft_reset_halt)(struct target_s *target);
+       int (*prepare_reset_halt)(struct target_s *target);
        
        /* target register access for gdb */
        int (*get_gdb_reg_list)(struct target_s *target, struct reg_s **reg_list[], int *reg_list_size);
index d6c9f215cd8b42edabddd6814570ff03783cc416..9bb3ca75117b43c2d5c2ccaa287dd2aad2f7bdc7 100644 (file)
@@ -58,6 +58,7 @@ int xscale_restore_context(target_t *target);
 int xscale_assert_reset(target_t *target);
 int xscale_deassert_reset(target_t *target);
 int xscale_soft_reset_halt(struct target_s *target);
+int xscale_prepare_reset_halt(struct target_s *target);
 
 int xscale_set_reg_u32(reg_t *reg, u32 value);
 
@@ -91,6 +92,7 @@ target_type_t xscale_target =
        .assert_reset = xscale_assert_reset,
        .deassert_reset = xscale_deassert_reset,
        .soft_reset_halt = xscale_soft_reset_halt,
+       .prepare_reset_halt = xscale_prepare_reset_halt,
 
        .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
        
@@ -1679,6 +1681,12 @@ int xscale_soft_reset_halt(struct target_s *target)
        return ERROR_OK;
 }
 
+int xscale_prepare_reset_halt(struct target_s *target)
+{
+       /* nothing to be done for reset_halt on XScale targets */
+       return ERROR_OK;
+}
+
 int xscale_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode)
 {