int handle_arm7_9_dbgrq_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_arm7_9_fast_memory_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_arm7_9_dcc_downloads_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int handle_arm7_9_etm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int handle_arm7_9_etb_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int arm7_9_reinit_embeddedice(target_t *target)
{
return ERROR_OK;
}
-int arm7_9_add_breakpoint(struct target_s *target, u32 address, u32 length, enum breakpoint_type type)
+int arm7_9_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
{
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
if (arm7_9->force_hw_bkpts)
{
- type = BKPT_HARD;
+ DEBUG("forcing use of hardware breakpoint at address 0x%8.8x", breakpoint->address);
+ breakpoint->type = BKPT_HARD;
}
- if ((type == BKPT_SOFT) && (arm7_9->sw_bkpts_enabled == 0))
+ if ((breakpoint->type == BKPT_SOFT) && (arm7_9->sw_bkpts_enabled == 0))
{
INFO("sw breakpoint requested, but software breakpoints not enabled");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- if ((type == BKPT_HARD) && (arm7_9->wp_available < 1))
+ if ((breakpoint->type == BKPT_HARD) && (arm7_9->wp_available < 1))
{
INFO("no watchpoint unit available for hardware breakpoint");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- if (type == BKPT_HARD)
- arm7_9->wp_available--;
-
- if ((length != 2) && (length != 4))
+ if ((breakpoint->length != 2) && (breakpoint->length != 4))
{
INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
+ if (breakpoint->type == BKPT_HARD)
+ arm7_9->wp_available--;
+
return ERROR_OK;
}
return ERROR_OK;
}
-int arm7_9_add_watchpoint(struct target_s *target, u32 address, u32 length, enum watchpoint_rw rw)
+int arm7_9_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
{
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- if ((length != 1) && (length != 2) && (length != 4))
+ if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
{
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
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)
}
+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)
}
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);
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;
reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
#ifdef _DEBUG_ARM7_9_
- DEBUG("");
+ DEBUG("-");
#endif
if (arm7_9->pre_debug_entry)
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
- DEBUG("");
+ DEBUG("-");
if (target->state != TARGET_HALTED)
{
int dirty;
int mode_change;
- DEBUG("");
+ DEBUG("-");
if (target->state != TARGET_HALTED)
{
breakpoint_t *breakpoint = target->breakpoints;
reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
- DEBUG("");
+ DEBUG("-");
if (target->state != TARGET_HALTED)
{
{
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
- breakpoint_t *breakpoint = target->breakpoints;
+ breakpoint_t *breakpoint = NULL;
if (target->state != TARGET_HALTED)
{
int arm7_9_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode)
{
u32* reg_p[16];
+ u32 value;
int retval;
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
if ((num >= 0) && (num <= 15))
{
/* read a normal core register */
- reg_p[num] = (u32*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).value;
+ reg_p[num] = &value;
arm7_9->read_core_regs(target, 1 << num, reg_p);
}
armv4_5_core_reg_t *arch_info = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).arch_info;
int spsr = (arch_info->mode == ARMV4_5_MODE_ANY) ? 0 : 1;
- arm7_9->read_xpsr(target, (u32*)ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).value, spsr);
+ arm7_9->read_xpsr(target, &value, spsr);
}
+ if ((retval = jtag_execute_queue()) != ERROR_OK)
+ {
+ ERROR("JTAG failure");
+ exit(-1);
+ }
+
ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).valid = 1;
ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).dirty = 0;
+ buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, mode, num).value, 0, 32, value);
if ((mode != ARMV4_5_MODE_ANY)
&& (mode != armv4_5->core_mode)
arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
}
- if ((retval = jtag_execute_queue()) != ERROR_OK)
- {
- ERROR("JTAG failure");
- exit(-1);
- }
-
return ERROR_OK;
}
if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
{
- ERROR("memory read caused data abort");
+ WARNING("memory read caused data abort (address: 0x%8.8x, size: 0x%x, count: 0x%x)", address, size, count);
arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
{
- ERROR("memory write caused data abort");
+ WARNING("memory write caused data abort (address: 0x%8.8x, size: 0x%x, count: 0x%x)", address, size, count);
arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
command_t *arm7_9_cmd;
arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9", NULL, COMMAND_ANY, "arm7/9 specific commands");
+
+ register_command(cmd_ctx, arm7_9_cmd, "etm", handle_arm7_9_etm_command, COMMAND_CONFIG, NULL);
+ register_command(cmd_ctx, arm7_9_cmd, "etb", handle_arm7_9_etb_command, COMMAND_CONFIG, NULL);
register_command(cmd_ctx, arm7_9_cmd, "write_xpsr", handle_arm7_9_write_xpsr_command, COMMAND_EXEC, "write program status register <value> <not cpsr|spsr>");
register_command(cmd_ctx, arm7_9_cmd, "write_xpsr_im8", handle_arm7_9_write_xpsr_im8_command, COMMAND_EXEC, "write program status register <8bit immediate> <rotate> <not cpsr|spsr>");
return ERROR_OK;
}
+int handle_arm7_9_etm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ target_t *target;
+ armv4_5_common_t *armv4_5;
+ arm7_9_common_t *arm7_9;
+
+ if (argc != 1)
+ {
+ ERROR("incomplete 'arm7_9 etm <target>' command");
+ exit(-1);
+ }
+
+ target = get_target_by_num(strtoul(args[0], NULL, 0));
+
+ if (!target)
+ {
+ ERROR("target number '%s' not defined", args[0]);
+ exit(-1);
+ }
+
+ 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");
+ return ERROR_OK;
+ }
+
+ arm7_9->has_etm = 1;
+
+ return ERROR_OK;
+}
+
+int handle_arm7_9_etb_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ target_t *target;
+ jtag_device_t *jtag_device;
+ armv4_5_common_t *armv4_5;
+ arm7_9_common_t *arm7_9;
+
+ if (argc != 2)
+ {
+ ERROR("incomplete 'arm7_9 etb <target> <chain_pos>' command");
+ exit(-1);
+ }
+
+ target = get_target_by_num(strtoul(args[0], NULL, 0));
+
+ if (!target)
+ {
+ ERROR("target number '%s' not defined", args[0]);
+ exit(-1);
+ }
+
+ 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");
+ return ERROR_OK;
+ }
+
+ jtag_device = jtag_get_device(strtoul(args[1], NULL, 0));
+
+ if (!jtag_device)
+ {
+ ERROR("jtag device number '%s' not defined", args[1]);
+ exit(-1);
+ }
+
+ arm7_9->etb = malloc(sizeof(etb_t));
+
+ arm7_9->etb->chain_pos = strtoul(args[1], NULL, 0);
+ arm7_9->etb->cur_scan_chain = -1;
+ arm7_9->etb->reg_cache = NULL;
+
+ return ERROR_OK;
+}
+
int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
{
armv4_5_common_t *armv4_5 = &arm7_9->armv4_5_common;
arm7_9->wp1_used = 0;
arm7_9->force_hw_bkpts = 0;
arm7_9->use_dbgrq = 0;
+
arm7_9->has_etm = 0;
+ arm7_9->etb = NULL;
+ arm7_9->has_single_step = 0;
+ arm7_9->has_monitor_mode = 0;
+ arm7_9->has_vector_catch = 0;
arm7_9->reinit_embeddedice = 0;