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;
}
}
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;
}
}
/* 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++)
/* 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)
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;
}
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)
return ERROR_FAIL;
}
- if ((target->reset_mode == RESET_HALT) || (target->reset_mode == RESET_INIT))
+ if (target->reset_halt)
{
/*
* Some targets do not support communication while SRST is asserted. We need to
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], 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);
+ 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);
}
}
*/
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]);
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++)
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;
{
/* 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
{
*/
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;
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)
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++)
{
}
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);
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
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
*/
/* 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);
* - 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)
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))
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))
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;
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;
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;
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);
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;
arm7_9->dcc_working_area = NULL;
- arm7_9->fast_memory_access = 0;
- arm7_9->dcc_downloads = 0;
-
+ 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;