X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farm7_9_common.c;h=cf5f2b369afba752e62e79a0d3c6d3fd1852d7b0;hb=e2b6de3d66bae70cb08fea17f5b66ee875dbb636;hp=4b393cc2b0fb8f583332f95b5c01099cf5513ac7;hpb=d47e1b8f362379d8a2307f49e2b42115a3f40524;p=openocd.git diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 4b393cc2b0..cf5f2b369a 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -2,6 +2,9 @@ * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * * 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 * @@ -84,27 +87,17 @@ int arm7_9_reinit_embeddedice(target_t *target) arm7_9_enable_sw_bkpts(target); } - arm7_9->reinit_embeddedice = 0; - return ERROR_OK; } -int arm7_9_jtag_callback(enum jtag_event event, void *priv) +/* set things up after a reset / on startup */ +int arm7_9_setup(target_t *target) { - target_t *target = priv; - armv4_5_common_t *armv4_5 = target->arch_info; - arm7_9_common_t *arm7_9 = armv4_5->arch_info; - - /* a test-logic reset occured + /* a test-logic reset have occured * the EmbeddedICE registers have been reset * hardware breakpoints have been cleared */ - if (event == JTAG_TRST_ASSERTED) - { - arm7_9->reinit_embeddedice = 1; - } - - return ERROR_OK; + return arm7_9_reinit_embeddedice(target); } int arm7_9_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p) @@ -195,7 +188,7 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint) target->type->read_memory(target, breakpoint->address, 4, 1, (u8 *)&verify); if (verify != arm7_9->arm_bkpt) { - LOG_ERROR("Unable to set 32 bit software breakpoint at address %08x", breakpoint->address); + LOG_ERROR("Unable to set 32 bit software breakpoint at address %08x - check that memory is read/writable", breakpoint->address); return ERROR_OK; } } @@ -210,7 +203,7 @@ int arm7_9_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint) target->type->read_memory(target, breakpoint->address, 2, 1, (u8 *)&verify); if (verify != arm7_9->thumb_bkpt) { - LOG_ERROR("Unable to set thumb software breakpoint at address %08x", breakpoint->address); + LOG_ERROR("Unable to set thumb software breakpoint at address %08x - check that memory is read/writable", breakpoint->address); return ERROR_OK; } } @@ -519,13 +512,13 @@ int arm7_9_enable_sw_bkpts(struct target_s *target) else { LOG_ERROR("BUG: both watchpoints used, but wp_available >= 1"); - exit(-1); + return ERROR_FAIL; } if ((retval = jtag_execute_queue()) != ERROR_OK) { LOG_ERROR("error writing EmbeddedICE registers to enable sw breakpoints"); - exit(-1); + return ERROR_FAIL; }; return ERROR_OK; @@ -569,6 +562,10 @@ int arm7_9_execute_sys_speed(struct target_s *target) /* set RESTART instruction */ jtag_add_end_state(TAP_RTI); + if (arm7_9->need_bypass_before_restart) { + arm7_9->need_bypass_before_restart = 0; + arm_jtag_set_instr(jtag_info, 0xf, NULL); + } arm_jtag_set_instr(jtag_info, 0x4, NULL); for (timeout=0; timeout<50; timeout++) @@ -603,6 +600,10 @@ int arm7_9_execute_fast_sys_speed(struct target_s *target) /* set RESTART instruction */ jtag_add_end_state(TAP_RTI); + if (arm7_9->need_bypass_before_restart) { + arm7_9->need_bypass_before_restart = 0; + arm_jtag_set_instr(jtag_info, 0xf, NULL); + } arm_jtag_set_instr(jtag_info, 0x4, NULL); if (!set) @@ -649,11 +650,14 @@ int arm7_9_target_request_data(target_t *target, u32 size, u8 *buffer) int arm7_9_handle_target_request(void *priv) { target_t *target = priv; + if (!target->type->examined) + return ERROR_OK; armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; arm_jtag_t *jtag_info = &arm7_9->jtag_info; reg_t *dcc_control = &arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL]; + if (!target->dbg_msg_enabled) return ERROR_OK; @@ -683,11 +687,6 @@ int arm7_9_poll(target_t *target) arm7_9_common_t *arm7_9 = armv4_5->arch_info; reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; - if (arm7_9->reinit_embeddedice) - { - arm7_9_reinit_embeddedice(target); - } - /* read debug status register */ embeddedice_read_reg(dbg_stat); if ((retval = jtag_execute_queue()) != ERROR_OK) @@ -697,7 +696,7 @@ int arm7_9_poll(target_t *target) if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1)) { - LOG_DEBUG("DBGACK set, dbg_state->value: 0x%x", buf_get_u32(dbg_stat->value, 0, 32)); +/* LOG_DEBUG("DBGACK set, dbg_state->value: 0x%x", buf_get_u32(dbg_stat->value, 0, 32));*/ if (target->state == TARGET_UNKNOWN) { target->state = TARGET_RUNNING; @@ -705,10 +704,33 @@ int arm7_9_poll(target_t *target) } if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) { + int check_pc=0; + if (target->state == TARGET_RESET) + { + if (target->reset_halt) + { + 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) + { + reg_t *reg = register_get_by_name(target->reg_cache, "pc", 1); + u32 t=*((u32 *)reg->value); + if (t!=0) + { + LOG_ERROR("PC was not 0. Does this target need srst_pulls_trst?"); + } + } + target_call_event_callbacks(target, TARGET_EVENT_HALTED); } if (target->state == TARGET_DEBUG_RUNNING) @@ -733,64 +755,64 @@ int arm7_9_poll(target_t *target) return ERROR_OK; } +/* + Some -S targets (ARM966E-S in the STR912 isn't affected, ARM926EJ-S + in the LPC3180 and AT91SAM9260 is affected) completely stop the JTAG clock + while the core is held in reset(SRST). It isn't possible to program the halt + condition once reset was asserted, hence a hook that allows the target to set + up its reset-halt condition prior to asserting reset. +*/ + int arm7_9_assert_reset(target_t *target) { - int retval; - + armv4_5_common_t *armv4_5 = target->arch_info; + arm7_9_common_t *arm7_9 = armv4_5->arch_info; LOG_DEBUG("target->state: %s", target_state_strings[target->state]); - if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN) + if (!(jtag_reset_config & RESET_HAS_SRST)) { - /* 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) + LOG_ERROR("Can't assert SRST"); + return ERROR_FAIL; + } + + if (target->reset_halt) + { + /* + * Some targets do not support communication while SRST is asserted. We need to + * set up the reset vector catch here. + * + * If TRST is asserted, then these settings will be reset anyway, so setting them + * here is harmless. + */ + if (arm7_9->has_vector_catch) { - if (retval == ERROR_JTAG_RESET_CANT_SRST) - { - return retval; - } - else - { - LOG_ERROR("unknown error"); - exit(-1); - } + /* program vector catch register to catch reset vector */ + embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0x1); } - jtag_add_sleep(5000); - if ((retval = jtag_add_reset(0, 1)) != ERROR_OK) + else { - if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST) - { - retval = jtag_add_reset(1, 1); - } + /* 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); } } - else + + /* here we should issue a srst only, but we may have to assert trst as well */ + if (jtag_reset_config & RESET_SRST_PULLS_TRST) { - if ((retval = jtag_add_reset(0, 1)) != ERROR_OK) - { - if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST) - { - retval = jtag_add_reset(1, 1); - } - - if (retval == ERROR_JTAG_RESET_CANT_SRST) - { - return retval; - } - else if (retval != ERROR_OK) - { - LOG_ERROR("unknown error"); - exit(-1); - } - } + jtag_add_reset(1, 1); + } else + { + jtag_add_reset(0, 1); } + target->state = TARGET_RESET; jtag_add_sleep(50000); - + armv4_5_invalidate_core_regs(target); return ERROR_OK; @@ -837,6 +859,10 @@ int arm7_9_clear_halt(target_t *target) */ if (arm7_9->wp0_used) { + if (arm7_9->debug_entry_from_reset) + { + embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE]); + } 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]); @@ -860,7 +886,7 @@ int arm7_9_soft_reset_halt(struct target_s *target) int i; int retval; - if ((retval=target->type->halt(target))!=ERROR_OK) + if ((retval=target_halt(target))!=ERROR_OK) return retval; for (i=0; i<10; i++) @@ -916,6 +942,9 @@ int arm7_9_soft_reset_halt(struct target_s *target) armv4_5->core_mode = ARMV4_5_MODE_SVC; armv4_5->core_state = ARMV4_5_STATE_ARM; + + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; /* reset registers */ for (i = 0; i <= 14; i++) @@ -930,35 +959,6 @@ 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; - - /* poll the target, and resume if it was currently halted */ - arm7_9_poll(target); - if (target->state == TARGET_HALTED) - { - arm7_9_resume(target, 1, 0x0, 0, 1); - } - - 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; @@ -969,7 +969,7 @@ int arm7_9_halt(target_t *target) if (target->state == TARGET_HALTED) { - LOG_WARNING("target was already halted"); + LOG_DEBUG("target was already halted"); return ERROR_OK; } @@ -988,7 +988,7 @@ int arm7_9_halt(target_t *target) else { /* we came here in a reset_halt or reset_init sequence - * debug entry was already prepared in arm7_9_prepare_reset_halt() + * debug entry was already prepared in arm7_9_assert_reset() */ target->debug_reason = DBG_REASON_DBGRQ; @@ -1000,8 +1000,12 @@ int arm7_9_halt(target_t *target) { /* program EmbeddedICE Debug Control Register to assert DBGRQ */ - buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 1); - embeddedice_store_reg(dbg_ctrl); + if (arm7_9->set_special_dbgrq) { + arm7_9->set_special_dbgrq(target); + } else { + buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 1); + embeddedice_store_reg(dbg_ctrl); + } } else { @@ -1009,8 +1013,8 @@ int arm7_9_halt(target_t *target) */ embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff); 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], 0x100); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7); + 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); } target->debug_reason = DBG_REASON_DBGRQ; @@ -1051,15 +1055,7 @@ int arm7_9_debug_entry(target_t *target) if ((retval = jtag_execute_queue()) != ERROR_OK) { - switch (retval) - { - case ERROR_JTAG_QUEUE_FAILED: - LOG_ERROR("JTAG queue failed while writing EmbeddedICE control register"); - exit(-1); - break; - default: - break; - } + return retval; } if ((retval = arm7_9->examine_debug_reason(target)) != ERROR_OK) @@ -1141,6 +1137,8 @@ int arm7_9_debug_entry(target_t *target) LOG_ERROR("unknown debug reason: %i", target->debug_reason); } + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; for (i=0; i<=15; i++) { @@ -1151,9 +1149,12 @@ int arm7_9_debug_entry(target_t *target) } LOG_DEBUG("entered debug state at PC 0x%x", context[15]); + + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; /* exceptions other than USR & SYS have a saved program status register */ - if ((armv4_5_mode_to_number(armv4_5->core_mode) != ARMV4_5_MODE_USR) && (armv4_5_mode_to_number(armv4_5->core_mode) != ARMV4_5_MODE_SYS)) + if ((armv4_5->core_mode != ARMV4_5_MODE_USR) && (armv4_5->core_mode != ARMV4_5_MODE_SYS)) { u32 spsr; arm7_9->read_xpsr(target, &spsr, 1); @@ -1190,6 +1191,9 @@ int arm7_9_full_context(target_t *target) LOG_WARNING("target not halted"); return ERROR_TARGET_NOT_HALTED; } + + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND) * SYS shares registers with User, so we don't touch SYS @@ -1249,8 +1253,7 @@ int arm7_9_full_context(target_t *target) if ((retval = jtag_execute_queue()) != ERROR_OK) { - LOG_ERROR("JTAG failure"); - exit(-1); + return retval; } return ERROR_OK; } @@ -1277,6 +1280,9 @@ int arm7_9_restore_context(target_t *target) if (arm7_9->pre_restore_context) arm7_9->pre_restore_context(target); + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; + /* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND) * SYS shares registers with User, so we don't touch SYS */ @@ -1402,15 +1408,14 @@ int arm7_9_restart_core(struct target_s *target) /* set RESTART instruction */ jtag_add_end_state(TAP_RTI); + if (arm7_9->need_bypass_before_restart) { + arm7_9->need_bypass_before_restart = 0; + arm_jtag_set_instr(jtag_info, 0xf, NULL); + } arm_jtag_set_instr(jtag_info, 0x4, NULL); jtag_add_runtest(1, TAP_RTI); - if ((jtag_execute_queue()) != ERROR_OK) - { - exit(-1); - } - - return ERROR_OK; + return jtag_execute_queue(); } void arm7_9_enable_watchpoints(struct target_s *target) @@ -1508,7 +1513,7 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_ else { LOG_ERROR("unhandled core state"); - exit(-1); + return ERROR_FAIL; } buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0); @@ -1550,7 +1555,7 @@ int arm7_9_resume(struct target_s *target, int current, u32 address, int handle_ else { LOG_ERROR("unhandled core state"); - exit(-1); + return ERROR_FAIL; } /* deassert DBGACK and INTDIS */ @@ -1593,13 +1598,13 @@ void arm7_9_enable_eice_step(target_t *target) * - comparator 0 matches any address, as long as rangein is low */ embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff); 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], 0x100); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0x77); + 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_RANGE|EICE_W_CTRL_nOPC) & 0xff); embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0); embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffff); embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0); - embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], 0xf7); + embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], ~EICE_W_CTRL_nOPC & 0xff); } void arm7_9_disable_eice_step(target_t *target) @@ -1657,7 +1662,7 @@ int arm7_9_step(struct target_s *target, int current, u32 address, int handle_br else { LOG_ERROR("unhandled core state"); - exit(-1); + return ERROR_FAIL; } target_call_event_callbacks(target, TARGET_EVENT_RESUMED); @@ -1691,6 +1696,10 @@ int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mod int retval; armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; + + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; + enum armv4_5_mode reg_mode = ((armv4_5_core_reg_t*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode; if ((num < 0) || (num > 16)) @@ -1729,8 +1738,7 @@ int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mod if ((retval = jtag_execute_queue()) != ERROR_OK) { - LOG_ERROR("JTAG failure"); - exit(-1); + return retval; } ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1; @@ -1753,6 +1761,10 @@ int arm7_9_write_core_reg(struct target_s *target, int num, enum armv4_5_mode mo u32 reg[16]; armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; + + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; + enum armv4_5_mode reg_mode = ((armv4_5_core_reg_t*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info)->mode; if ((num < 0) || (num > 16)) @@ -1928,6 +1940,9 @@ int arm7_9_read_memory(struct target_s *target, u32 address, u32 size, u32 count break; } + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; + for (i=0; i<=last_reg; i++) ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid; @@ -2095,6 +2110,9 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1); embeddedice_store_reg(dbg_ctrl); + if (armv4_5_mode_to_number(armv4_5->core_mode)==-1) + return ERROR_FAIL; + for (i=0; i<=last_reg; i++) ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid; @@ -2117,6 +2135,12 @@ int arm7_9_write_memory(struct target_s *target, u32 address, u32 size, u32 coun return ERROR_OK; } +static const u32 dcc_code[] = +{ + /* MRC TST BNE MRC STR B */ + 0xee101e10, 0xe3110001, 0x0afffffc, 0xee111e10, 0xe4801004, 0xeafffff9 +}; + int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer) { armv4_5_common_t *armv4_5 = target->arch_info; @@ -2127,12 +2151,6 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe u32 pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); int i; - u32 dcc_code[] = - { - /* MRC TST BNE MRC STR B */ - 0xee101e10, 0xe3110001, 0x0afffffc, 0xee111e10, 0xe4801004, 0xeafffff9 - }; - if (!arm7_9->dcc_downloads) return target->type->write_memory(target, address, 4, count, buffer); @@ -2205,11 +2223,11 @@ int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffe } } - target->type->halt(target); + target_halt(target); for (i=0; i<100; i++) { - target->type->poll(target); + target_poll(target); if (target->state == TARGET_HALTED) break; usleep(1000); /* sleep 1ms */ @@ -2311,6 +2329,69 @@ int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32* return ERROR_OK; } +int arm7_9_blank_check_memory(struct target_s *target, u32 address, u32 count, u32* blank) +{ + working_area_t *erase_check_algorithm; + reg_param_t reg_params[3]; + armv4_5_algorithm_t armv4_5_info; + int retval; + int i; + + u32 erase_check_code[] = + { + /* loop: */ + 0xe4d03001, /* ldrb r3, [r0], #1 */ + 0xe0022003, /* and r2, r2, r3 */ + 0xe2511001, /* subs r1, r1, #1 */ + 0x1afffffb, /* bne loop */ + /* end: */ + 0xeafffffe /* b end */ + }; + + /* make sure we have a working area */ + if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK) + { + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + /* convert flash writing code into a buffer in target endianness */ + for (i = 0; i < (sizeof(erase_check_code)/sizeof(u32)); i++) + target_write_u32(target, erase_check_algorithm->address + i*sizeof(u32), erase_check_code[i]); + + armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC; + armv4_5_info.core_mode = ARMV4_5_MODE_SVC; + armv4_5_info.core_state = ARMV4_5_STATE_ARM; + + init_reg_param(®_params[0], "r0", 32, PARAM_OUT); + buf_set_u32(reg_params[0].value, 0, 32, address); + + init_reg_param(®_params[1], "r1", 32, PARAM_OUT); + buf_set_u32(reg_params[1].value, 0, 32, count); + + init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT); + buf_set_u32(reg_params[2].value, 0, 32, 0xff); + + if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params, + erase_check_algorithm->address, erase_check_algorithm->address + (sizeof(erase_check_code) - 4), 10000, &armv4_5_info)) != ERROR_OK) + { + destroy_reg_param(®_params[0]); + destroy_reg_param(®_params[1]); + destroy_reg_param(®_params[2]); + target_free_working_area(target, erase_check_algorithm); + return 0; + } + + *blank = buf_get_u32(reg_params[2].value, 0, 32); + + destroy_reg_param(®_params[0]); + destroy_reg_param(®_params[1]); + destroy_reg_param(®_params[2]); + + target_free_working_area(target, erase_check_algorithm); + + return ERROR_OK; +} + int arm7_9_register_commands(struct command_context_s *cmd_ctx) { command_t *arm7_9_cmd; @@ -2468,6 +2549,12 @@ int handle_arm7_9_sw_bkpts_command(struct command_context_s *cmd_ctx, char *cmd, armv4_5_common_t *armv4_5; arm7_9_common_t *arm7_9; + if (target->state != TARGET_HALTED) + { + LOG_ERROR("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK) { command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target"); @@ -2663,17 +2750,15 @@ int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9) arm7_9->has_monitor_mode = 0; arm7_9->has_vector_catch = 0; - arm7_9->reinit_embeddedice = 0; - arm7_9->debug_entry_from_reset = 0; arm7_9->dcc_working_area = NULL; - arm7_9->fast_memory_access = 0; - arm7_9->dcc_downloads = 0; - - jtag_register_event_callback(arm7_9_jtag_callback, target); - + arm7_9->fast_memory_access = fast_and_dangerous; + arm7_9->dcc_downloads = fast_and_dangerous; + + arm7_9->need_bypass_before_restart = 0; + armv4_5->arch_info = arm7_9; armv4_5->read_core_reg = arm7_9_read_core_reg; armv4_5->write_core_reg = arm7_9_write_core_reg;