From 04dc98916d9acb57e0f5595534151a24ba4dc684 Mon Sep 17 00:00:00 2001 From: drath Date: Mon, 16 Apr 2007 14:58:16 +0000 Subject: [PATCH] - explicitly disable monitor mode on ARM7/9 targets - 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 --- src/target/arm720t.c | 1 + src/target/arm7_9_common.c | 81 ++++++++++++++++++++++++++++++-------- src/target/arm7_9_common.h | 2 + src/target/arm7tdmi.c | 1 + src/target/arm920t.c | 1 + src/target/arm926ejs.c | 1 + src/target/arm966e.c | 1 + src/target/arm9tdmi.c | 1 + src/target/embeddedice.c | 9 +++++ src/target/target.c | 18 ++++++++- src/target/target.h | 1 + src/target/xscale.c | 8 ++++ 12 files changed, 107 insertions(+), 18 deletions(-) diff --git a/src/target/arm720t.c b/src/target/arm720t.c index 1b809e6d..7aff8a7e 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -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, diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 7a409b0f..3a7c80a1 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -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; diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h index fd9a9e1b..5e7d54a9 100644 --- a/src/target/arm7_9_common.h +++ b/src/target/arm7_9_common.h @@ -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); diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index 3fcfa296..38917ded 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -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, diff --git a/src/target/arm920t.c b/src/target/arm920t.c index 1dae2319..d7fb8e11 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -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, diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index ecabfcd6..3931e898 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -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, diff --git a/src/target/arm966e.c b/src/target/arm966e.c index d4b6cf47..8b3414ca 100644 --- a/src/target/arm966e.c +++ b/src/target/arm966e.c @@ -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, diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index dd1ee79d..d21dff73 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -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, diff --git a/src/target/embeddedice.c b/src/target/embeddedice.c index 699aa96f..76f87410 100644 --- a/src/target/embeddedice.c +++ b/src/target/embeddedice.c @@ -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(®_list[EICE_DBG_CTRL]); + jtag_execute_queue(); + buf_set_u32(reg_list[EICE_DBG_CTRL].value, 4, 1, 0); + embeddedice_set_reg_w_exec(®_list[EICE_DBG_CTRL], reg_list[EICE_DBG_CTRL].value); + } + return reg_cache; } diff --git a/src/target/target.c b/src/target/target.c index 548ea0c3..050a523e 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -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) { diff --git a/src/target/target.h b/src/target/target.h index d340a778..9ab3d19a 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -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); diff --git a/src/target/xscale.c b/src/target/xscale.c index d6c9f215..9bb3ca75 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -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) { -- 2.39.5