diff options
Diffstat (limited to 'src/target')
-rw-r--r-- | src/target/arm720t.c | 4 | ||||
-rw-r--r-- | src/target/arm7_9_common.c | 9 | ||||
-rw-r--r-- | src/target/arm7_9_common.h | 1 | ||||
-rw-r--r-- | src/target/arm7tdmi.c | 18 | ||||
-rw-r--r-- | src/target/arm920t.c | 14 | ||||
-rw-r--r-- | src/target/arm926ejs.c | 64 | ||||
-rw-r--r-- | src/target/arm966e.c | 10 | ||||
-rw-r--r-- | src/target/arm9tdmi.c | 47 | ||||
-rw-r--r-- | src/target/arm_jtag.c | 38 | ||||
-rw-r--r-- | src/target/arm_jtag.h | 3 | ||||
-rw-r--r-- | src/target/embeddedice.c | 29 | ||||
-rw-r--r-- | src/target/etb.c | 74 | ||||
-rw-r--r-- | src/target/etb.h | 7 | ||||
-rw-r--r-- | src/target/etm.c | 14 | ||||
-rw-r--r-- | src/target/xscale.c | 24 |
15 files changed, 266 insertions, 90 deletions
diff --git a/src/target/arm720t.c b/src/target/arm720t.c index 7aff8a7..1fa5ef1 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -97,7 +97,7 @@ int arm720t_scan_cp15(target_t *target, u32 out, u32 *in, int instruction, int c jtag_add_end_state(TAP_PD); arm_jtag_scann(jtag_info, 0xf); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 1; @@ -126,7 +126,7 @@ int arm720t_scan_cp15(target_t *target, u32 out, u32 *in, int instruction, int c fields[1].in_check_value = NULL; fields[1].in_check_mask = NULL; - jtag_add_dr_scan(2, fields, -1); + jtag_add_dr_scan(2, fields, -1, NULL); if (clock) jtag_add_runtest(0, -1); diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 3a7c80a..9cf38c3 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -55,7 +55,6 @@ int handle_arm7_9_dbgrq_command(struct command_context_s *cmd_ctx, char *cmd, ch 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) { @@ -545,7 +544,7 @@ int arm7_9_execute_sys_speed(struct target_s *target) /* set RESTART instruction */ jtag_add_end_state(TAP_RTI); - arm_jtag_set_instr(jtag_info, 0x4); + arm_jtag_set_instr(jtag_info, 0x4, NULL); for (timeout=0; timeout<50; timeout++) { @@ -578,7 +577,7 @@ int arm7_9_execute_fast_sys_speed(struct target_s *target) /* set RESTART instruction */ jtag_add_end_state(TAP_RTI); - arm_jtag_set_instr(jtag_info, 0x4); + arm_jtag_set_instr(jtag_info, 0x4, NULL); /* check for DBGACK and SYSCOMP set (others don't care) */ buf_set_u32(check_value, 0, 32, 0x9); @@ -1308,7 +1307,7 @@ int arm7_9_restart_core(struct target_s *target) /* set RESTART instruction */ jtag_add_end_state(TAP_RTI); - arm_jtag_set_instr(jtag_info, 0x4); + arm_jtag_set_instr(jtag_info, 0x4, NULL); jtag_add_runtest(1, TAP_RTI); if ((jtag_execute_queue()) != ERROR_OK) @@ -2098,7 +2097,6 @@ int arm7_9_register_commands(struct command_context_s *cmd_ctx) 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>"); @@ -2117,6 +2115,7 @@ int arm7_9_register_commands(struct command_context_s *cmd_ctx) COMMAND_ANY, "use DCC downloads for larger memory writes <enable|disable>"); armv4_5_register_commands(cmd_ctx); + etb_register_commands(cmd_ctx, arm7_9_cmd); return ERROR_OK; } diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h index 5e7d54a..e77beda 100644 --- a/src/target/arm7_9_common.h +++ b/src/target/arm7_9_common.h @@ -134,6 +134,7 @@ void arm7_9_disable_eice_step(target_t *target); int arm7_9_execute_sys_speed(struct target_s *target); int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9); +int arm7_9_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p); #endif /* ARM7_9_COMMON_H */ diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index 38917de..5dc2f20 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -124,9 +124,9 @@ int arm7tdmi_examine_debug_reason(target_t *target) fields[1].in_handler_priv = NULL; arm_jtag_scann(&arm7_9->jtag_info, 0x1); - arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr); + arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL); - jtag_add_dr_scan(2, fields, TAP_PD); + jtag_add_dr_scan(2, fields, TAP_PD, NULL); jtag_execute_queue(); fields[0].in_value = NULL; @@ -134,7 +134,7 @@ int arm7tdmi_examine_debug_reason(target_t *target) fields[1].in_value = NULL; fields[1].out_value = databus; - jtag_add_dr_scan(2, fields, TAP_PD); + jtag_add_dr_scan(2, fields, TAP_PD, NULL); if (breakpoint & 1) target->debug_reason = DBG_REASON_WATCHPOINT; @@ -157,7 +157,7 @@ int arm7tdmi_clock_out(arm_jtag_t *jtag_info, u32 out, u32 *in, int breakpoint) jtag_add_end_state(TAP_PD); arm_jtag_scann(jtag_info, 0x1); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 1; @@ -187,7 +187,7 @@ int arm7tdmi_clock_out(arm_jtag_t *jtag_info, u32 out, u32 *in, int breakpoint) fields[1].in_check_value = NULL; fields[1].in_check_mask = NULL; - jtag_add_dr_scan(2, fields, -1); + jtag_add_dr_scan(2, fields, -1, NULL); jtag_add_runtest(0, -1); @@ -214,7 +214,7 @@ int arm7tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) jtag_add_end_state(TAP_PD); arm_jtag_scann(jtag_info, 0x1); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 1; @@ -236,7 +236,7 @@ int arm7tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) fields[1].in_check_value = NULL; fields[1].in_check_mask = NULL; - jtag_add_dr_scan(2, fields, -1); + jtag_add_dr_scan(2, fields, -1, NULL); jtag_add_runtest(0, -1); @@ -268,7 +268,7 @@ int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, jtag_add_end_state(TAP_PD); arm_jtag_scann(jtag_info, 0x1); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 1; @@ -301,7 +301,7 @@ int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, fields[1].in_check_value = NULL; fields[1].in_check_mask = NULL; - jtag_add_dr_scan(2, fields, -1); + jtag_add_dr_scan(2, fields, -1, NULL); jtag_add_runtest(0, -1); diff --git a/src/target/arm920t.c b/src/target/arm920t.c index d7fb8e1..805624e 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -103,7 +103,7 @@ int arm920t_read_cp15_physical(target_t *target, int reg_addr, u32 *value) jtag_add_end_state(TAP_RTI); arm_jtag_scann(jtag_info, 0xf); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 1; @@ -145,12 +145,12 @@ int arm920t_read_cp15_physical(target_t *target, int reg_addr, u32 *value) fields[3].in_handler = NULL; fields[3].in_handler_priv = NULL; - jtag_add_dr_scan(4, fields, -1); + jtag_add_dr_scan(4, fields, -1, NULL); fields[1].in_handler_priv = value; fields[1].in_handler = arm_jtag_buf_to_u32; - jtag_add_dr_scan(4, fields, -1); + jtag_add_dr_scan(4, fields, -1, NULL); #ifdef _DEBUG_INSTRUCTION_EXECUTION_ jtag_execute_queue(); @@ -175,7 +175,7 @@ int arm920t_write_cp15_physical(target_t *target, int reg_addr, u32 value) jtag_add_end_state(TAP_RTI); arm_jtag_scann(jtag_info, 0xf); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 1; @@ -217,7 +217,7 @@ int arm920t_write_cp15_physical(target_t *target, int reg_addr, u32 value) fields[3].in_handler = NULL; fields[3].in_handler_priv = NULL; - jtag_add_dr_scan(4, fields, -1); + jtag_add_dr_scan(4, fields, -1, NULL); #ifdef _DEBUG_INSTRUCTION_EXECUTION_ DEBUG("addr: 0x%x value: %8.8x", reg_addr, value); @@ -239,7 +239,7 @@ int arm920t_execute_cp15(target_t *target, u32 cp15_opcode, u32 arm_opcode) jtag_add_end_state(TAP_RTI); arm_jtag_scann(jtag_info, 0xf); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); buf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode); @@ -283,7 +283,7 @@ int arm920t_execute_cp15(target_t *target, u32 cp15_opcode, u32 arm_opcode) fields[3].in_handler = NULL; fields[3].in_handler_priv = NULL; - jtag_add_dr_scan(4, fields, -1); + jtag_add_dr_scan(4, fields, -1, NULL); arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1); diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index 3931e89..8907e11 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -28,7 +28,7 @@ #include <stdlib.h> #include <string.h> -#if 0 +#if 1 #define _DEBUG_INSTRUCTION_EXECUTION_ #endif @@ -91,6 +91,22 @@ target_type_t arm926ejs_target = .quit = arm926ejs_quit }; +int arm926ejs_catch_broken_irscan(u8 *in_value, void *priv) +{ + /* The ARM926EJ-S' instruction register is 4 bits wide */ + *in_value &= 0xf; + + if ((*in_value == 0x0f) || (*in_value == 0x00)) + { + DEBUG("caught ARM926EJ-S invalid Capture-IR result after CP15 access"); + return ERROR_OK; + } + else + { + return ERROR_JTAG_QUEUE_FAILED; + } +} + int arm926ejs_read_cp15(target_t *target, u32 address, u32 *value) { armv4_5_common_t *armv4_5 = target->arch_info; @@ -100,12 +116,13 @@ int arm926ejs_read_cp15(target_t *target, u32 address, u32 *value) u8 address_buf[2]; u8 nr_w_buf = 0; u8 access = 1; + error_handler_t error_handler; buf_set_u32(address_buf, 0, 14, address); jtag_add_end_state(TAP_RTI); arm_jtag_scann(jtag_info, 0xf); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 32; @@ -147,17 +164,17 @@ int arm926ejs_read_cp15(target_t *target, u32 address, u32 *value) fields[3].in_handler = NULL; fields[3].in_handler_priv = NULL; - jtag_add_dr_scan(4, fields, -1); + jtag_add_dr_scan(4, fields, -1, NULL); - /* rescan with NOP, to wait for the access to complete */ - access = 0; - fields[0].in_handler_priv = value; fields[0].in_handler = arm_jtag_buf_to_u32; do { - jtag_add_dr_scan(4, fields, -1); + /* rescan with NOP, to wait for the access to complete */ + access = 0; + nr_w_buf = 0; + jtag_add_dr_scan(4, fields, -1, NULL); jtag_execute_queue(); } while (buf_get_u32(&access, 0, 1) != 1); @@ -165,6 +182,11 @@ int arm926ejs_read_cp15(target_t *target, u32 address, u32 *value) DEBUG("addr: 0x%x value: %8.8x", address, *value); #endif + error_handler.error_handler = arm926ejs_catch_broken_irscan; + error_handler.error_handler_priv = NULL; + + arm_jtag_set_instr(jtag_info, 0xc, &error_handler); + return ERROR_OK; } @@ -178,13 +200,14 @@ int arm926ejs_write_cp15(target_t *target, u32 address, u32 value) u8 address_buf[2]; u8 nr_w_buf = 1; u8 access = 1; + error_handler_t error_handler; buf_set_u32(address_buf, 0, 14, address); buf_set_u32(value_buf, 0, 32, value); jtag_add_end_state(TAP_RTI); arm_jtag_scann(jtag_info, 0xf); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 32; @@ -226,14 +249,14 @@ int arm926ejs_write_cp15(target_t *target, u32 address, u32 value) fields[3].in_handler = NULL; fields[3].in_handler_priv = NULL; - jtag_add_dr_scan(4, fields, -1); + jtag_add_dr_scan(4, fields, -1, NULL); - /* rescan with NOP, to wait for the access to complete */ - access = 0; - do { - jtag_add_dr_scan(4, fields, -1); + /* rescan with NOP, to wait for the access to complete */ + access = 0; + nr_w_buf = 0; + jtag_add_dr_scan(4, fields, -1, NULL); jtag_execute_queue(); } while (buf_get_u32(&access, 0, 1) != 1); @@ -241,6 +264,11 @@ int arm926ejs_write_cp15(target_t *target, u32 address, u32 value) DEBUG("addr: 0x%x value: %8.8x", address, value); #endif + error_handler.error_handler = arm926ejs_catch_broken_irscan; + error_handler.error_handler_priv = NULL; + + arm_jtag_set_instr(jtag_info, 0xf, &error_handler); + return ERROR_OK; } @@ -395,7 +423,7 @@ void arm926ejs_post_debug_entry(target_t *target) arm7_9_common_t *arm7_9 = armv4_5->arch_info; arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info; arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info; - + /* examine cp15 control reg */ arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 1, 0), &arm926ejs->cp15_control_reg); jtag_execute_queue(); @@ -430,7 +458,6 @@ void arm926ejs_post_debug_entry(target_t *target) arm926ejs_read_cp15(target, ARM926EJS_CP15_ADDR(7, 0, 15, 0), &cache_dbg_ctrl); cache_dbg_ctrl |= 0x7; arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(7, 0, 15, 0), cache_dbg_ctrl); - } void arm926ejs_pre_restore_context(target_t *target) @@ -439,7 +466,7 @@ void arm926ejs_pre_restore_context(target_t *target) arm7_9_common_t *arm7_9 = armv4_5->arch_info; arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info; arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info; - + /* restore i/d fault status and address register */ arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 0, 5, 0), arm926ejs->d_fsr); arm926ejs_write_cp15(target, ARM926EJS_CP15_ADDR(0, 1, 5, 0), arm926ejs->i_fsr); @@ -641,6 +668,11 @@ int arm926ejs_init_arch_info(target_t *target, arm926ejs_common_t *arm926ejs, in arm7_9->examine_debug_reason = arm926ejs_examine_debug_reason; + /* The ARM926EJ-S implements the ARMv5TE architecture which + * has the BKPT instruction, so we don't have to use a watchpoint comparator + */ + arm7_9->sw_bkpts_enabled = 1; + return ERROR_OK; } diff --git a/src/target/arm966e.c b/src/target/arm966e.c index 8b3414c..917fc4a 100644 --- a/src/target/arm966e.c +++ b/src/target/arm966e.c @@ -253,7 +253,7 @@ int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value) jtag_add_end_state(TAP_RTI); arm_jtag_scann(jtag_info, 0xf); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 32; @@ -285,11 +285,11 @@ int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); fields[0].in_value = (u8*)value; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); return ERROR_OK; } @@ -305,7 +305,7 @@ int arm966e_write_cp15(target_t *target, int reg_addr, u32 value) jtag_add_end_state(TAP_RTI); arm_jtag_scann(jtag_info, 0xf); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 32; @@ -337,7 +337,7 @@ int arm966e_write_cp15(target_t *target, int reg_addr, u32 value) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); return ERROR_OK; } diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index d21dff7..1a53d0d 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -98,6 +98,15 @@ arm9tdmi_vector_t arm9tdmi_vectors[] = {0, 0}, }; +int arm9tdmi_jtag_error_handler(u8 *in_value, void *priv) +{ + char *caller = priv; + + DEBUG("caller: %s", caller); + + return ERROR_OK; +} + int arm9tdmi_examine_debug_reason(target_t *target) { /* get pointers to arch-specific information */ @@ -108,6 +117,7 @@ int arm9tdmi_examine_debug_reason(target_t *target) if ((target->debug_reason != DBG_REASON_DBGRQ) && (target->debug_reason != DBG_REASON_SINGLESTEP)) { + error_handler_t error_handler; scan_field_t fields[3]; u8 databus[4]; u8 instructionbus[4]; @@ -146,9 +156,11 @@ int arm9tdmi_examine_debug_reason(target_t *target) fields[2].in_handler_priv = NULL; arm_jtag_scann(&arm7_9->jtag_info, 0x1); - arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr); + error_handler.error_handler = arm9tdmi_jtag_error_handler; + error_handler.error_handler_priv = "arm9tdmi_examine_debug_reason"; + arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, &error_handler); - jtag_add_dr_scan(3, fields, TAP_PD); + jtag_add_dr_scan(3, fields, TAP_PD, NULL); jtag_execute_queue(); fields[0].in_value = NULL; @@ -158,7 +170,7 @@ int arm9tdmi_examine_debug_reason(target_t *target) fields[2].in_value = NULL; fields[2].out_value = instructionbus; - jtag_add_dr_scan(3, fields, TAP_PD); + jtag_add_dr_scan(3, fields, TAP_PD, NULL); if (debug_reason & 0x4) if (debug_reason & 0x2) @@ -175,6 +187,7 @@ int arm9tdmi_examine_debug_reason(target_t *target) /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int sysspeed) { + error_handler_t error_handler; scan_field_t fields[3]; u8 out_buf[4]; u8 instr_buf[4]; @@ -190,7 +203,11 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s jtag_add_end_state(TAP_PD); arm_jtag_scann(jtag_info, 0x1); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + + error_handler.error_handler = arm9tdmi_jtag_error_handler; + error_handler.error_handler_priv = "arm9tdmi_clock_out"; + + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 32; @@ -230,7 +247,7 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); jtag_add_runtest(0, -1); @@ -254,10 +271,15 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) { scan_field_t fields[3]; + error_handler_t error_handler; jtag_add_end_state(TAP_PD); arm_jtag_scann(jtag_info, 0x1); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + + error_handler.error_handler = arm9tdmi_jtag_error_handler; + error_handler.error_handler_priv = "arm9tdmi_clock_data_in_endianness"; + + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 32; @@ -289,7 +311,7 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); jtag_add_runtest(0, -1); @@ -318,10 +340,15 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be) { scan_field_t fields[3]; - + error_handler_t error_handler; + jtag_add_end_state(TAP_PD); arm_jtag_scann(jtag_info, 0x1); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + + error_handler.error_handler = arm9tdmi_jtag_error_handler; + error_handler.error_handler_priv = "arm9tdmi_clock_data_in_endianness"; + + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, &error_handler); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 32; @@ -364,7 +391,7 @@ int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); jtag_add_runtest(0, -1); diff --git a/src/target/arm_jtag.c b/src/target/arm_jtag.c index 3bb8a32..305590c 100644 --- a/src/target/arm_jtag.c +++ b/src/target/arm_jtag.c @@ -29,7 +29,18 @@ #include <stdlib.h> -int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr) +#if 0 +#define _ARM_JTAG_SCAN_N_CHECK_ +#endif + +int arm_jtag_set_instr_error_handler(u8 *in_value, void *priv) +{ + ERROR("setting the new JTAG instruction failed, debugging is likely to be broken"); + + return ERROR_OK; +} + +int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr, error_handler_t *caller_error_handler) { jtag_device_t *device = jtag_get_device(jtag_info->chain_pos); @@ -48,7 +59,18 @@ int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr) field.in_handler = NULL; field.in_handler_priv = NULL; - jtag_add_ir_scan(1, &field, -1); + if (caller_error_handler) + { + jtag_add_ir_scan(1, &field, -1, caller_error_handler); + } + else + { + error_handler_t error_handler; + error_handler.error_handler = arm_jtag_set_instr_error_handler; + error_handler.error_handler_priv = NULL; + jtag_add_ir_scan(1, &field, -1, &error_handler); + } + free(field.out_value); } @@ -60,6 +82,9 @@ int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain) { if(jtag_info->cur_scan_chain != new_scan_chain) { +#ifdef _ARM_JTAG_SCAN_N_CHECK_ + u8 scan_n_check_value = 0x10; +#endif scan_field_t field; field.device = jtag_info->chain_pos; @@ -67,15 +92,18 @@ int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain) field.out_value = calloc(CEIL(field.num_bits, 8), 1); buf_set_u32(field.out_value, 0, field.num_bits, new_scan_chain); field.out_mask = NULL; - //field.in_value = &scan_n_capture; field.in_value = NULL; +#ifdef _ARM_JTAG_SCAN_N_CHECK_ + field.in_check_value = &scan_n_check_value; +#else field.in_check_value = NULL; +#endif field.in_check_mask = NULL; field.in_handler = NULL; field.in_handler_priv = NULL; - arm_jtag_set_instr(jtag_info, jtag_info->scann_instr); - jtag_add_dr_scan(1, &field, -1); + arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL); + jtag_add_dr_scan(1, &field, -1, NULL); jtag_info->cur_scan_chain = new_scan_chain; diff --git a/src/target/arm_jtag.h b/src/target/arm_jtag.h index 6e523fb..f2f5587 100644 --- a/src/target/arm_jtag.h +++ b/src/target/arm_jtag.h @@ -21,6 +21,7 @@ #define ARM_JTAG #include "types.h" +#include "jtag.h" typedef struct arm_jtag_s { @@ -33,7 +34,7 @@ typedef struct arm_jtag_s u32 intest_instr; } arm_jtag_t; -extern int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr); +extern int arm_jtag_set_instr(arm_jtag_t *jtag_info, u32 new_instr, error_handler_t *error_handler); extern int arm_jtag_scann(arm_jtag_t *jtag_info, u32 new_scan_chain); extern int arm_jtag_setup_connection(arm_jtag_t *jtag_info); diff --git a/src/target/embeddedice.c b/src/target/embeddedice.c index 76f8741..ef38e13 100644 --- a/src/target/embeddedice.c +++ b/src/target/embeddedice.c @@ -86,6 +86,15 @@ int embeddedice_set_reg_w_exec(reg_t *reg, u8 *buf); int embeddedice_write_reg(reg_t *reg, u32 value); int embeddedice_read_reg(reg_t *reg); +int embeddedice_jtag_error_handler(u8 *in_value, void *priv) +{ + char *caller = priv; + + DEBUG("caller: %s", caller); + + return ERROR_OK; +} + reg_cache_t* embeddedice_build_reg_cache(target_t *target, arm7_9_common_t *arm7_9) { reg_cache_t *reg_cache = malloc(sizeof(reg_cache_t)); @@ -214,12 +223,17 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) embeddedice_reg_t *ice_reg = reg->arch_info; u8 reg_addr = ice_reg->addr & 0x1f; scan_field_t fields[3]; + error_handler_t error_handler; DEBUG("%i", ice_reg->addr); jtag_add_end_state(TAP_RTI); arm_jtag_scann(ice_reg->jtag_info, 0x2); - arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr); + + error_handler.error_handler = embeddedice_jtag_error_handler; + error_handler.error_handler_priv = "embeddedice_read_reg_w_check"; + + arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, &error_handler); fields[0].device = ice_reg->jtag_info->chain_pos; fields[0].num_bits = 32; @@ -253,7 +267,7 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); fields[0].in_value = reg->value; fields[0].in_check_value = check_value; @@ -265,7 +279,7 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) */ buf_set_u32(fields[1].out_value, 0, 5, embeddedice_reg_arch_info[EICE_COMMS_CTRL]); - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); free(fields[1].out_value); free(fields[2].out_value); @@ -310,12 +324,17 @@ int embeddedice_write_reg(reg_t *reg, u32 value) embeddedice_reg_t *ice_reg = reg->arch_info; u8 reg_addr = ice_reg->addr & 0x1f; scan_field_t fields[3]; + error_handler_t error_handler; DEBUG("%i: 0x%8.8x", ice_reg->addr, value); jtag_add_end_state(TAP_RTI); arm_jtag_scann(ice_reg->jtag_info, 0x2); - arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr); + + error_handler.error_handler = embeddedice_jtag_error_handler; + error_handler.error_handler_priv = "embeddedice_write_reg"; + + arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, NULL); fields[0].device = ice_reg->jtag_info->chain_pos; fields[0].num_bits = 32; @@ -350,7 +369,7 @@ int embeddedice_write_reg(reg_t *reg, u32 value) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); free(fields[0].out_value); free(fields[1].out_value); diff --git a/src/target/etb.c b/src/target/etb.c index 3ac1adf..0b480e3 100644 --- a/src/target/etb.c +++ b/src/target/etb.c @@ -21,6 +21,7 @@ #include "config.h" #endif +#include "arm7_9_common.h" #include "etb.h" #include "log.h" @@ -54,6 +55,9 @@ int etb_set_reg_w_exec(reg_t *reg, u8 *buf); int etb_write_reg(reg_t *reg, u32 value); int etb_read_reg(reg_t *reg); +int handle_arm7_9_etb_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +int handle_arm7_9_etb_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); + int etb_set_instr(etb_t *etb, u32 new_instr) { jtag_device_t *device = jtag_get_device(etb->chain_pos); @@ -72,8 +76,8 @@ int etb_set_instr(etb_t *etb, u32 new_instr) field.in_check_mask = NULL; field.in_handler = NULL; field.in_handler_priv = NULL; - - jtag_add_ir_scan(1, &field, -1); + + jtag_add_ir_scan(1, &field, -1, NULL); free(field.out_value); } @@ -100,7 +104,7 @@ int etb_scann(etb_t *etb, u32 new_scan_chain) /* select INTEST instruction */ etb_set_instr(etb, 0x2); - jtag_add_dr_scan(1, &field, -1); + jtag_add_dr_scan(1, &field, -1, NULL); etb->cur_scan_chain = new_scan_chain; @@ -212,13 +216,17 @@ int etb_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); + /* read the identification register in the second run, to make sure we + * don't read the ETB data register twice, skipping every second entry + */ + buf_set_u32(fields[1].out_value, 0, 7, 0x0); fields[0].in_value = reg->value; fields[0].in_check_value = check_value; fields[0].in_check_mask = check_mask; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); free(fields[1].out_value); free(fields[2].out_value); @@ -303,7 +311,7 @@ int etb_write_reg(reg_t *reg, u32 value) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); free(fields[0].out_value); free(fields[1].out_value); @@ -317,3 +325,57 @@ int etb_store_reg(reg_t *reg) return etb_write_reg(reg, buf_get_u32(reg->value, 0, reg->size)); } +int etb_register_commands(struct command_context_s *cmd_ctx, command_t *arm7_9_cmd) +{ + register_command(cmd_ctx, arm7_9_cmd, "etb", handle_arm7_9_etb_command, COMMAND_CONFIG, NULL); + + register_command(cmd_ctx, arm7_9_cmd, "etb_dump", handle_arm7_9_etb_dump_command, COMMAND_EXEC, "dump current ETB content"); + + return ERROR_OK; +} + +int handle_arm7_9_etb_dump_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + int retval; + target_t *target = get_current_target(cmd_ctx); + armv4_5_common_t *armv4_5; + arm7_9_common_t *arm7_9; + int i; + + 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; + } + + if (!arm7_9->etb) + { + command_print(cmd_ctx, "no ETB configured for current target"); + return ERROR_OK; + } + + if (!(arm7_9->etb->RAM_depth && arm7_9->etb->RAM_width)) + { + /* identify ETB RAM depth and width */ + etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_DEPTH]); + etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_WIDTH]); + jtag_execute_queue(); + + arm7_9->etb->RAM_depth = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_DEPTH].value, 0, 32); + arm7_9->etb->RAM_width = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_WIDTH].value, 0, 32); + } + + /* always start reading from the beginning of the buffer */ + etb_write_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_READ_POINTER], 0x0); + for (i = 0; i < arm7_9->etb->RAM_depth; i++) + { + u32 trace_data; + etb_read_reg(&arm7_9->etb->reg_cache->reg_list[ETB_RAM_DATA]); + jtag_execute_queue(); + trace_data = buf_get_u32(arm7_9->etb->reg_cache->reg_list[ETB_RAM_DATA].value, 0, 32); + command_print(cmd_ctx, "%8.8i: %i %2.2x %2.2x %2.2x (0x%8.8x)", + i, (trace_data >> 19) & 1, (trace_data >> 11) & 0xff, (trace_data >> 3) & 0xff, trace_data & 0x7, trace_data); + } + + return ERROR_OK; +} diff --git a/src/target/etb.h b/src/target/etb.h index 55b7857..12e613f 100644 --- a/src/target/etb.h +++ b/src/target/etb.h @@ -20,6 +20,7 @@ #ifndef ETB_H
#define ETB_H
+#include "command.h"
#include "target.h"
#include "register.h"
#include "arm_jtag.h"
@@ -43,6 +44,10 @@ typedef struct etb_s int chain_pos;
int cur_scan_chain;
reg_cache_t *reg_cache;
+
+ /* ETB parameters */
+ int RAM_depth;
+ int RAM_width;
} etb_t;
typedef struct etb_reg_s
@@ -59,4 +64,6 @@ extern int etb_store_reg(reg_t *reg); extern int etb_set_reg(reg_t *reg, u32 value);
extern int etb_set_reg_w_exec(reg_t *reg, u8 *buf);
+extern int etb_register_commands(struct command_context_s *cmd_ctx, command_t *arm7_9_cmd);
+
#endif /* ETB_H */
diff --git a/src/target/etm.c b/src/target/etm.c index 9c82acc..016130d 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -64,8 +64,8 @@ int etm_reg_arch_info[] = int etm_reg_arch_size_info[] = { - 32, 32, 17, 8, 3, 9, 32, 17, - 26, 16, 25, 8, 17, 32, 32, 17, + 32, 32, 17, 8, 3, 9, 32, 16, + 17, 26, 25, 8, 17, 32, 32, 17, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 7, 7, 7, 7, 7, 7, 7, 7, @@ -271,7 +271,7 @@ int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) jtag_add_end_state(TAP_RTI); arm_jtag_scann(etm_reg->jtag_info, 0x6); - arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr); + arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL); fields[0].device = etm_reg->jtag_info->chain_pos; fields[0].num_bits = 32; @@ -305,13 +305,13 @@ int etm_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); fields[0].in_value = reg->value; fields[0].in_check_value = check_value; fields[0].in_check_mask = check_mask; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); free(fields[1].out_value); free(fields[2].out_value); @@ -361,7 +361,7 @@ int etm_write_reg(reg_t *reg, u32 value) jtag_add_end_state(TAP_RTI); arm_jtag_scann(etm_reg->jtag_info, 0x6); - arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr); + arm_jtag_set_instr(etm_reg->jtag_info, etm_reg->jtag_info->intest_instr, NULL); fields[0].device = etm_reg->jtag_info->chain_pos; fields[0].num_bits = 32; @@ -396,7 +396,7 @@ int etm_write_reg(reg_t *reg, u32 value) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); free(fields[0].out_value); free(fields[1].out_value); diff --git a/src/target/xscale.c b/src/target/xscale.c index 9bb3ca7..334924f 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -210,7 +210,7 @@ int xscale_jtag_set_instr(int chain_pos, u32 new_instr) field.in_handler = NULL; field.in_handler_priv = NULL; - jtag_add_ir_scan(1, &field, -1); + jtag_add_ir_scan(1, &field, -1, NULL); free(field.out_value); } @@ -288,7 +288,7 @@ int xscale_read_dcsr(target_t *target) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); if ((retval = jtag_execute_queue()) != ERROR_OK) { @@ -308,7 +308,7 @@ int xscale_read_dcsr(target_t *target) jtag_add_end_state(TAP_RTI); - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); return ERROR_OK; } @@ -383,7 +383,7 @@ int xscale_receive(target_t *target, u32 *buffer, int num_words) fields[1].in_handler_priv = (u8*)&field1[i]; jtag_add_pathmove(3, path); - jtag_add_dr_scan(3, fields, TAP_RTI); + jtag_add_dr_scan(3, fields, TAP_RTI, NULL); words_scheduled++; } @@ -487,7 +487,7 @@ int xscale_read_tx(target_t *target, int consume) else jtag_add_statemove(TAP_PD); - jtag_add_dr_scan(3, fields, TAP_RTI); + jtag_add_dr_scan(3, fields, TAP_RTI, NULL); if ((retval = jtag_execute_queue()) != ERROR_OK) { @@ -567,7 +567,7 @@ int xscale_write_rx(target_t *target) do { DEBUG("polling RX"); - jtag_add_dr_scan(3, fields, TAP_RTI); + jtag_add_dr_scan(3, fields, TAP_RTI, NULL); if ((retval = jtag_execute_queue()) != ERROR_OK) { @@ -585,7 +585,7 @@ int xscale_write_rx(target_t *target) /* set rx_valid */ field2 = 0x1; - jtag_add_dr_scan(3, fields, TAP_RTI); + jtag_add_dr_scan(3, fields, TAP_RTI, NULL); if ((retval = jtag_execute_queue()) != ERROR_OK) { @@ -671,7 +671,7 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size) exit(-1); } - jtag_add_dr_scan(3, fields, TAP_RTI); + jtag_add_dr_scan(3, fields, TAP_RTI, NULL); buffer += size; } @@ -750,7 +750,7 @@ int xscale_write_dcsr(target_t *target, int hold_rst, int ext_dbg_brk) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - jtag_add_dr_scan(3, fields, -1); + jtag_add_dr_scan(3, fields, -1, NULL); if ((retval = jtag_execute_queue()) != ERROR_OK) { @@ -822,7 +822,7 @@ int xscale_load_ic(target_t *target, int mini, u32 va, u32 buffer[8]) fields[1].in_handler = NULL; fields[1].in_handler_priv = NULL; - jtag_add_dr_scan(2, fields, -1); + jtag_add_dr_scan(2, fields, -1, NULL); fields[0].num_bits = 32; fields[0].out_value = packet; @@ -834,7 +834,7 @@ int xscale_load_ic(target_t *target, int mini, u32 va, u32 buffer[8]) { buf_set_u32(packet, 0, 32, buffer[word]); cmd = parity(*((u32*)packet)); - jtag_add_dr_scan(2, fields, -1); + jtag_add_dr_scan(2, fields, -1, NULL); } jtag_execute_queue(); @@ -880,7 +880,7 @@ int xscale_invalidate_ic_line(target_t *target, u32 va) fields[1].in_handler = NULL; fields[1].in_handler_priv = NULL; - jtag_add_dr_scan(2, fields, -1); + jtag_add_dr_scan(2, fields, -1, NULL); return ERROR_OK; } |