X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farm7_9_common.c;h=509e91e4c8c43a9646f3dd3e7eab81d5ca787f95;hb=98f7c2127b8800e2597493eea2c7ba5c88940b86;hp=25f8cb3206e8616c76f539bfffb6ba86026aa789;hpb=c2cc677056f8b383ff8f88ed8a16f1aa4b530ae2;p=openocd.git diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 25f8cb3206..509e91e4c8 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -2,7 +2,7 @@ * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * - * Copyright (C) 2007,2008 Øyvind Harboe * + * Copyright (C) 2007-2009 Øyvind Harboe * * oyvind.harboe@zylin.com * * * * Copyright (C) 2008 by Spencer Oliver * @@ -11,6 +11,8 @@ * Copyright (C) 2008 by Hongtao Zheng * * hontor@126.com * * * + * Copyright (C) 2009 by David Brownell * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -39,6 +41,7 @@ #include "arm_semihosting.h" #include "algorithm.h" #include "register.h" +#include "armv4_5.h" /** @@ -888,34 +891,11 @@ int arm7_9_poll(struct target *target) } if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) { - int check_pc = 0; - if (target->state == TARGET_RESET) - { - if (target->reset_halt) - { - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0) - { - check_pc = 1; - } - } - } - target->state = TARGET_HALTED; if ((retval = arm7_9_debug_entry(target)) != ERROR_OK) return retval; - if (check_pc) - { - struct reg *reg = register_get_by_name(target->reg_cache, "pc", 1); - uint32_t t=*((uint32_t *)reg->value); - if (t != 0) - { - LOG_ERROR("PC was not 0. Does this target need srst_pulls_trst?"); - } - } - if (arm_semihosting(target, &retval) != 0) return retval; @@ -963,14 +943,16 @@ int arm7_9_poll(struct target *target) int arm7_9_assert_reset(struct target *target) { struct arm7_9_common *arm7_9 = target_to_arm7_9(target); + enum reset_types jtag_reset_config = jtag_get_reset_config(); + bool use_event = false; LOG_DEBUG("target->state: %s", target_state_name(target)); - enum reset_types jtag_reset_config = jtag_get_reset_config(); - if (!(jtag_reset_config & RESET_HAS_SRST)) - { - LOG_ERROR("Can't assert SRST"); + if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) + use_event = true; + else if (!(jtag_reset_config & RESET_HAS_SRST)) { + LOG_ERROR("%s: how to reset?", target_name(target)); return ERROR_FAIL; } @@ -985,7 +967,8 @@ int arm7_9_assert_reset(struct target *target) */ bool srst_asserted = false; - if (((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0) + if (!use_event + && !(jtag_reset_config & RESET_SRST_PULLS_TRST) && (jtag_reset_config & RESET_SRST_NO_GATING)) { jtag_add_reset(0, 1); @@ -995,48 +978,70 @@ int arm7_9_assert_reset(struct target *target) if (target->reset_halt) { /* - * Some targets do not support communication while SRST is asserted. We need to - * set up the reset vector catch here. + * For targets that don't support communication while SRST is + * asserted, we need to set up the reset vector catch first. * - * If TRST is asserted, then these settings will be reset anyway, so setting them - * here is harmless. + * When we use TRST+SRST and that's equivalent to a power-up + * reset, these settings may well be reset anyway; so setting + * them here won't matter. */ 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); + /* program vector catch register to catch reset */ + embeddedice_write_reg(&arm7_9->eice_cache + ->reg_list[EICE_VEC_CATCH], 0x1); - /* extra runtest added as issues were found with certain ARM9 cores (maybe more) - AT91SAM9260 and STR9 */ + /* extra runtest added as issues were found with + * certain ARM9 cores (maybe more) - AT91SAM9260 + * and STR9 + */ jtag_add_runtest(1, jtag_get_end_state()); } else { - /* program watchpoint unit to match on reset vector address */ - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], 0x0); - 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], 0xffffffff); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff); + /* program watchpoint unit to match on reset vector + * address + */ + embeddedice_write_reg(&arm7_9->eice_cache + ->reg_list[EICE_W0_ADDR_VALUE], 0x0); + 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], + 0xffffffff); + embeddedice_write_reg(&arm7_9->eice_cache + ->reg_list[EICE_W0_CONTROL_VALUE], + EICE_W_CTRL_ENABLE); + embeddedice_write_reg(&arm7_9->eice_cache + ->reg_list[EICE_W0_CONTROL_MASK], + ~EICE_W_CTRL_nOPC & 0xff); } } - /* here we should issue an SRST only, but we may have to assert TRST as well */ - if (jtag_reset_config & RESET_SRST_PULLS_TRST) - { - jtag_add_reset(1, 1); - } else if (!srst_asserted) - { - jtag_add_reset(0, 1); + if (use_event) { + target_handle_event(target, TARGET_EVENT_RESET_ASSERT); + } else { + /* If we use SRST ... we'd like to issue just SRST, but the + * board or chip may be set up so we have to assert TRST as + * well. On some chips that combination is equivalent to a + * power-up reset, and generally clobbers EICE state. + */ + if (jtag_reset_config & RESET_SRST_PULLS_TRST) + jtag_add_reset(1, 1); + else if (!srst_asserted) + jtag_add_reset(0, 1); + jtag_add_sleep(50000); } target->state = TARGET_RESET; - jtag_add_sleep(50000); - register_cache_invalidate(arm7_9->armv4_5_common.core_cache); - if ((target->reset_halt) && ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0)) + /* REVISIT why isn't standard debug entry logic sufficient?? */ + if (target->reset_halt + && (!(jtag_reset_config & RESET_SRST_PULLS_TRST) + || use_event)) { - /* debug entry was already prepared in arm7_9_assert_reset() */ + /* debug entry was prepared above */ target->debug_reason = DBG_REASON_DBGRQ; } @@ -2361,10 +2366,6 @@ int arm7_9_read_memory(struct target *target, uint32_t address, uint32_t size, u } } break; - default: - LOG_ERROR("BUG: we shouldn't get here"); - exit(-1); - break; } if (!is_arm_mode(armv4_5->core_mode)) @@ -2545,10 +2546,6 @@ int arm7_9_write_memory(struct target *target, uint32_t address, uint32_t size, num_accesses += thisrun_accesses; } break; - default: - LOG_ERROR("BUG: we shouldn't get here"); - exit(-1); - break; } /* Re-Set DBGACK */ @@ -2651,14 +2648,6 @@ static const uint32_t dcc_code[] = 0xeafffff9 /* b w */ }; -extern int armv4_5_run_algorithm_inner(struct target *target, - int num_mem_params, struct mem_param *mem_params, - int num_reg_params, struct reg_param *reg_params, - uint32_t entry_point, uint32_t exit_point, - int timeout_ms, void *arch_info, - int (*run_it)(struct target *target, uint32_t exit_point, - int timeout_ms, void *arch_info)); - int arm7_9_bulk_write_memory(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer) { int retval; @@ -2761,6 +2750,29 @@ int arm7_9_examine(struct target *target) return retval; } + +int arm7_9_check_reset(struct target *target) +{ + struct arm7_9_common *arm7_9 = target_to_arm7_9(target); + + if (get_target_reset_nag() && !arm7_9->dcc_downloads) + { + LOG_WARNING("NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'."); + } + + if (get_target_reset_nag() && (target->working_area_size == 0)) + { + LOG_WARNING("NOTE! Severe performance degradation without working memory enabled."); + } + + if (get_target_reset_nag() && !arm7_9->fast_memory_access) + { + LOG_WARNING("NOTE! Severe performance degradation without fast memory access enabled. Type 'help fast'."); + } + + return ERROR_OK; +} + COMMAND_HANDLER(handle_arm7_9_dbgrq_command) { struct target *target = get_current_target(CMD_CTX); @@ -2835,7 +2847,12 @@ COMMAND_HANDLER(handle_arm7_9_semihosting_command) COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting); - /* TODO: support other methods if vector catch is unavailable */ + if (!target_was_examined(target)) + { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } + if (arm7_9->has_vector_catch) { struct reg *vector_catch = &arm7_9->eice_cache ->reg_list[EICE_VEC_CATCH]; @@ -2844,14 +2861,17 @@ COMMAND_HANDLER(handle_arm7_9_semihosting_command) embeddedice_read_reg(vector_catch); buf_set_u32(vector_catch->value, 2, 1, semihosting); embeddedice_store_reg(vector_catch); + } else { + /* TODO: allow optional high vectors and/or BKPT_HARD */ + if (semihosting) + breakpoint_add(target, 8, 4, BKPT_SOFT); + else + breakpoint_remove(target, 8); + } - /* FIXME never let that "catch" be dropped! */ - - arm7_9->armv4_5_common.is_semihosting = semihosting; + /* FIXME never let that "catch" be dropped! */ + arm7_9->armv4_5_common.is_semihosting = semihosting; - } else if (semihosting) { - command_print(CMD_CTX, "vector catch unavailable"); - } } command_print(CMD_CTX, "semihosting is %s", @@ -2883,7 +2903,8 @@ int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9) armv4_5->write_core_reg = arm7_9_write_core_reg; armv4_5->full_context = arm7_9_full_context; - if ((retval = armv4_5_init_arch_info(target, armv4_5)) != ERROR_OK) + retval = arm_init_arch_info(target, armv4_5); + if (retval != ERROR_OK) return retval; return target_register_timer_callback(arm7_9_handle_target_request, @@ -2893,32 +2914,32 @@ int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9) static const struct command_registration arm7_9_any_command_handlers[] = { { "dbgrq", - .handler = &handle_arm7_9_dbgrq_command, + .handler = handle_arm7_9_dbgrq_command, .mode = COMMAND_ANY, - .usage = "", + .usage = "['enable'|'disable']", .help = "use EmbeddedICE dbgrq instead of breakpoint " "for target halt requests", }, { "fast_memory_access", - .handler = &handle_arm7_9_fast_memory_access_command, + .handler = handle_arm7_9_fast_memory_access_command, .mode = COMMAND_ANY, - .usage = "", + .usage = "['enable'|'disable']", .help = "use fast memory accesses instead of slower " "but potentially safer accesses", }, { "dcc_downloads", - .handler = &handle_arm7_9_dcc_downloads_command, + .handler = handle_arm7_9_dcc_downloads_command, .mode = COMMAND_ANY, - .usage = "", + .usage = "['enable'|'disable']", .help = "use DCC downloads for larger memory writes", }, { "semihosting", - .handler = &handle_arm7_9_semihosting_command, + .handler = handle_arm7_9_semihosting_command, .mode = COMMAND_EXEC, - .usage = "", + .usage = "['enable'|'disable']", .help = "activate support for semihosting operations", }, COMMAND_REGISTRATION_DONE