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)
{
/* deassert reset lines */
jtag_add_reset(0, 0);
-
+
return ERROR_OK;
-
}
int arm7_9_clear_halt(target_t *target)
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)
+ /* we used DBGRQ only if we didn't come out of reset */
+ if (!arm7_9->debug_entry_from_reset && arm7_9->use_dbgrq)
{
/* program EmbeddedICE Debug Control Register to deassert DBGRQ
*/
}
else
{
- /* restore registers if watchpoint unit 0 was in use
- */
- if (arm7_9->wp0_used)
+ if (arm7_9->debug_entry_from_reset && arm7_9->has_vector_catch)
{
- 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]);
+ /* if we came out of reset, and vector catch is supported, we used
+ * vector catch to enter debug state
+ * restore the register in that case
+ */
+ embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH]);
+ }
+ 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]);
}
- /* 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;
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;
+
+ 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;
{
WARNING("target was already halted");
return ERROR_TARGET_ALREADY_HALTED;
- }
+ }
if (target->state == TARGET_UNKNOWN)
{
WARNING("target was in unknown state when halt was requested");
}
- if ((target->state == TARGET_RESET) && (jtag_reset_config & RESET_SRST_PULLS_TRST) && (jtag_srst))
+ if (target->state == TARGET_RESET)
{
- ERROR("can't request a halt while in reset if nSRST pulls nTRST");
- return ERROR_TARGET_FAILURE;
+ if ((jtag_reset_config & RESET_SRST_PULLS_TRST) && jtag_srst)
+ {
+ ERROR("can't request a halt while in reset if nSRST pulls nTRST");
+ return ERROR_TARGET_FAILURE;
+ }
+ else
+ {
+ /* we came here in a reset_halt or reset_init sequence
+ * debug entry was already prepared in arm7_9_prepare_reset_halt()
+ */
+ target->debug_reason = DBG_REASON_DBGRQ;
+
+ return ERROR_OK;
+ }
}
if (arm7_9->use_dbgrq)
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)
{
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->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;
+ arm7_9->debug_entry_from_reset = 0;
+
arm7_9->dcc_working_area = NULL;
arm7_9->fast_memory_access = 0;