From 83440065c00cce9d36f23182b439d7bf2306cfb2 Mon Sep 17 00:00:00 2001 From: drath Date: Sun, 5 Nov 2006 17:38:35 +0000 Subject: [PATCH] - correctly enter debug state on a "soft_reset_halt" command - several small fixes - retry reading from a FT2232 device on incomplete reads git-svn-id: svn://svn.berlios.de/openocd/trunk@110 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/flash/lpc2000.c | 7 +++ src/helper/command.c | 2 +- src/jtag/ft2232.c | 27 ++++++++---- src/target/arm7_9_common.c | 88 ++++++++++++++++++++++++-------------- src/target/breakpoints.c | 4 ++ src/target/target.c | 1 - 6 files changed, 87 insertions(+), 42 deletions(-) diff --git a/src/flash/lpc2000.c b/src/flash/lpc2000.c index 9ec4165bda..16e20e2a67 100644 --- a/src/flash/lpc2000.c +++ b/src/flash/lpc2000.c @@ -46,6 +46,7 @@ * variant 2 (lpc2000_v2): * - 213x * - 214x + * - 2101|2|3 */ int lpc2000_register_commands(struct command_context_s *cmd_ctx); @@ -152,6 +153,12 @@ int lpc2000_build_sector_list(struct flash_bank_s *bank) /* variant 2 has a uniform layout, only number of sectors differs */ switch (bank->size) { + case 8 * 1024: + num_sectors = 2; + break; + case 16 * 1024: + num_sectors = 4; + break; case 32 * 1024: num_sectors = 8; break; diff --git a/src/helper/command.c b/src/helper/command.c index 9a38723c81..ca08535a40 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -400,7 +400,7 @@ int command_run_file(command_context_t *context, FILE *file, enum command_mode m break; /* run line */ - if (command_run_line(context, cmd) == ERROR_COMMAND_CLOSE_CONNECTION) + if ((retval = command_run_line(context, cmd)) == ERROR_COMMAND_CLOSE_CONNECTION) break; } diff --git a/src/jtag/ft2232.c b/src/jtag/ft2232.c index e681b3e5ad..9af57dd1b6 100644 --- a/src/jtag/ft2232.c +++ b/src/jtag/ft2232.c @@ -189,15 +189,19 @@ int ft2232_read(u8* buf, int size, u32* bytes_read) #if BUILD_FT2232_FTD2XX == 1 DWORD dw_bytes_read; FT_STATUS status; - if ((status = FT_Read(ftdih, buf, size, &dw_bytes_read)) != FT_OK) + int timeout = 5; + *bytes_read = 0; + + while ((*bytes_read < size) && timeout--) { - *bytes_read = dw_bytes_read; - ERROR("FT_Read returned: %i", status); - return ERROR_JTAG_DEVICE_ERROR; + if ((status = FT_Read(ftdih, buf, size, &dw_bytes_read)) != FT_OK) + { + *bytes_read = 0; + ERROR("FT_Read returned: %i", status); + return ERROR_JTAG_DEVICE_ERROR; + } + *bytes_read += dw_bytes_read; } - *bytes_read = dw_bytes_read; - return ERROR_OK; - #elif BUILD_FT2232_LIBFTDI == 1 int retval; int timeout = 100; @@ -213,8 +217,15 @@ int ft2232_read(u8* buf, int size, u32* bytes_read) } *bytes_read += retval; } - return ERROR_OK; #endif + + if (*bytes_read < size) + { + ERROR("couldn't read the requested number of bytes from FT2232 device (%i < %i)", *bytes_read, size); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; } int ft2232_speed(int speed) diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index c298c904e1..7bf042a91e 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -656,6 +656,9 @@ int arm7_9_assert_reset(target_t *target) if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN) { + /* if the target wasn't running, there might be working areas allocated */ + target_free_all_working_areas(target); + /* assert SRST and TRST */ /* system would get ouf sync if we didn't reset test-logic, too */ if ((retval = jtag_add_reset(1, 1)) != ERROR_OK) @@ -724,11 +727,44 @@ int arm7_9_deassert_reset(target_t *target) } +int arm7_9_clear_halt(target_t *target) +{ + armv4_5_common_t *armv4_5 = target->arch_info; + 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) + { + /* program EmbeddedICE Debug Control Register to deassert DBGRQ + */ + buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0); + embeddedice_store_reg(dbg_ctrl); + } + 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]); + } + + return ERROR_OK; +} + int arm7_9_soft_reset_halt(struct target_s *target) { armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; + reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; int i; if (target->state == TARGET_RUNNING) @@ -743,6 +779,26 @@ int arm7_9_soft_reset_halt(struct target_s *target) } target->state = TARGET_HALTED; + /* program EmbeddedICE Debug Control Register to assert DBGACK and INTDIS + * ensure that DBGRQ is cleared + */ + buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1); + buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0); + buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 1); + embeddedice_store_reg(dbg_ctrl); + + arm7_9_clear_halt(target); + + /* if the target is in Thumb state, change to ARM state */ + if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1)) + { + u32 r0_thumb, pc_thumb; + DEBUG("target entered debug from Thumb state, changing to ARM"); + /* Entered debug from Thumb mode */ + armv4_5->core_state = ARMV4_5_STATE_THUMB; + arm7_9->change_to_arm(target, &r0_thumb, &pc_thumb); + } + /* all register content is now invalid */ armv4_5_invalidate_core_regs(target); @@ -819,38 +875,6 @@ int arm7_9_halt(target_t *target) return ERROR_OK; } -int arm7_9_clear_halt(target_t *target) -{ - armv4_5_common_t *armv4_5 = target->arch_info; - 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) - { - /* program EmbeddedICE Debug Control Register to deassert DBGRQ - */ - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0); - embeddedice_store_reg(dbg_ctrl); - } - 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]); - } - - return ERROR_OK; -} - int arm7_9_debug_entry(target_t *target) { int i; diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c index 3da927386b..a30d67a4ca 100644 --- a/src/target/breakpoints.c +++ b/src/target/breakpoints.c @@ -167,6 +167,10 @@ int watchpoint_add(target_t *target, u32 address, u32 length, enum watchpoint_rw INFO("can't add %s watchpoint, resource not available", watchpoint_rw_strings[rw]); return retval; break; + case ERROR_TARGET_NOT_HALTED: + INFO("can't add watchpoint while target is running"); + return retval; + break; default: ERROR("unknown error"); exit(-1); diff --git a/src/target/target.c b/src/target/target.c index 531d632e69..732288880b 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -904,7 +904,6 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a (*last_target_p)->working_areas = NULL; (*last_target_p)->backup_working_area = 0; - (*last_target_p)->endianness = TARGET_LITTLE_ENDIAN; (*last_target_p)->state = TARGET_UNKNOWN; (*last_target_p)->reg_cache = NULL; (*last_target_p)->breakpoints = NULL; -- 2.30.2