X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farm7tdmi.c;h=e1e91c3a04b71fd6cccf4a12e61367b062087652;hp=8be8a125e475868c85c7515e36d4f8fae1caf07e;hb=a851b91c4c1db76dd1e26a7d1a99124ad456b020;hpb=aafb916bea1153b8d2f4706e4a62628f49741133 diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index 8be8a125e4..e1e91c3a04 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -19,17 +19,18 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * along with this program. If not, see . * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "arm7tdmi.h" #include "target_type.h" - +#include "register.h" +#include "arm_opcodes.h" +#include "arm_semihosting.h" /* * For information about ARM7TDMI, see ARM DDI 0210C (r4p1) @@ -48,42 +49,37 @@ static int arm7tdmi_examine_debug_reason(struct target *target) /* only check the debug reason if we don't know it already */ if ((target->debug_reason != DBG_REASON_DBGRQ) - && (target->debug_reason != DBG_REASON_SINGLESTEP)) - { + && (target->debug_reason != DBG_REASON_SINGLESTEP)) { struct scan_field fields[2]; uint8_t databus[4]; uint8_t breakpoint; - jtag_set_end_state(TAP_DRPAUSE); - - fields[0].tap = arm7_9->jtag_info.tap; fields[0].num_bits = 1; fields[0].out_value = NULL; fields[0].in_value = &breakpoint; - fields[1].tap = arm7_9->jtag_info.tap; fields[1].num_bits = 32; fields[1].out_value = NULL; fields[1].in_value = databus; - if ((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1)) != ERROR_OK) - { + retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE); + if (retval != ERROR_OK) + return retval; + retval = arm_jtag_set_instr(arm7_9->jtag_info.tap, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE); + if (retval != ERROR_OK) return retval; - } - arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL); - jtag_add_dr_scan(2, fields, jtag_set_end_state(TAP_DRPAUSE)); - if ((retval = jtag_execute_queue()) != ERROR_OK) - { + jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE); + retval = jtag_execute_queue(); + if (retval != ERROR_OK) return retval; - } fields[0].in_value = NULL; fields[0].out_value = &breakpoint; fields[1].in_value = NULL; fields[1].out_value = databus; - jtag_add_dr_scan(2, fields, jtag_set_end_state(TAP_DRPAUSE)); + jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE); if (breakpoint & 1) target->debug_reason = DBG_REASON_WATCHPOINT; @@ -96,17 +92,23 @@ static int arm7tdmi_examine_debug_reason(struct target *target) static const int arm7tdmi_num_bits[] = {1, 32}; -static __inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_t out, int breakpoint) +static inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_t out, int breakpoint) { - uint32_t values[2]={breakpoint, flip_u32(out, 32)}; + uint8_t bp = breakpoint ? 1 : 0; + uint8_t out_value[4]; + buf_set_u32(out_value, 0, 32, flip_u32(out, 32)); - jtag_add_dr_out(jtag_info->tap, + struct scan_field fields[2] = { + { .num_bits = arm7tdmi_num_bits[0], .out_value = &bp }, + { .num_bits = arm7tdmi_num_bits[1], .out_value = out_value }, + }; + + jtag_add_dr_scan(jtag_info->tap, 2, - arm7tdmi_num_bits, - values, - jtag_get_end_state()); + fields, + TAP_DRPAUSE); - jtag_add_runtest(0, jtag_get_end_state()); + jtag_add_runtest(0, TAP_DRPAUSE); return ERROR_OK; } @@ -116,12 +118,16 @@ static __inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_ * * FIXME remove the unused "deprecated" parameter */ -static __inline int arm7tdmi_clock_out(struct arm_jtag *jtag_info, +static inline int arm7tdmi_clock_out(struct arm_jtag *jtag_info, uint32_t out, uint32_t *deprecated, int breakpoint) { - jtag_set_end_state(TAP_DRPAUSE); - arm_jtag_scann(jtag_info, 0x1); - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); + int retval; + retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE); + if (retval != ERROR_OK) + return retval; + retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE); + if (retval != ERROR_OK) + return retval; return arm7tdmi_clock_out_inner(jtag_info, out, breakpoint); } @@ -132,31 +138,30 @@ static int arm7tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in) int retval = ERROR_OK; struct scan_field fields[2]; - jtag_set_end_state(TAP_DRPAUSE); - if ((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK) - { + retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE); + if (retval != ERROR_OK) + return retval; + retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE); + if (retval != ERROR_OK) return retval; - } - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); - fields[0].tap = jtag_info->tap; fields[0].num_bits = 1; fields[0].out_value = NULL; fields[0].in_value = NULL; - fields[1].tap = jtag_info->tap; fields[1].num_bits = 32; fields[1].out_value = NULL; fields[1].in_value = (uint8_t *)in; - jtag_add_dr_scan(2, fields, jtag_get_end_state()); + jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE); jtag_add_callback(arm7flip32, (jtag_callback_data_t)in); - jtag_add_runtest(0, jtag_get_end_state()); + jtag_add_runtest(0, TAP_DRPAUSE); #ifdef _DEBUG_INSTRUCTION_EXECUTION_ - if ((retval = jtag_execute_queue()) != ERROR_OK) + retval = jtag_execute_queue(); + if (retval != ERROR_OK) return retval; if (in) @@ -168,47 +173,6 @@ static int arm7tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in) return ERROR_OK; } -void arm_endianness(uint8_t *tmp, void *in, int size, int be, int flip) -{ - uint32_t readback = le_to_h_u32(tmp); - if (flip) - readback = flip_u32(readback, 32); - switch (size) - { - case 4: - if (be) - { - h_u32_to_be(((uint8_t*)in), readback); - } else - { - h_u32_to_le(((uint8_t*)in), readback); - } - break; - case 2: - if (be) - { - h_u16_to_be(((uint8_t*)in), readback & 0xffff); - } else - { - h_u16_to_le(((uint8_t*)in), readback & 0xffff); - } - break; - case 1: - *((uint8_t *)in)= readback & 0xff; - break; - } -} - -static int arm7endianness(jtag_callback_data_t arg, - jtag_callback_data_t size, jtag_callback_data_t be, - jtag_callback_data_t captured) -{ - uint8_t *in = (uint8_t *)arg; - - arm_endianness((uint8_t *)captured, in, (int)size, (int)be, 1); - return ERROR_OK; -} - /* clock the target, and read the databus * the *in pointer points to a buffer where elements of 'size' bytes * are stored in big (be == 1) or little (be == 0) endianness @@ -217,46 +181,55 @@ static int arm7tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info, void *in, int size, int be) { int retval = ERROR_OK; - struct scan_field fields[2]; + struct scan_field fields[3]; - jtag_set_end_state(TAP_DRPAUSE); - if ((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK) - { + retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE); + if (retval != ERROR_OK) + return retval; + retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE); + if (retval != ERROR_OK) return retval; - } - arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); - fields[0].tap = jtag_info->tap; fields[0].num_bits = 1; fields[0].out_value = NULL; fields[0].in_value = NULL; - fields[1].tap = jtag_info->tap; - fields[1].num_bits = 32; - fields[1].out_value = NULL; - jtag_alloc_in_value32(&fields[1]); + if (size == 4) { + fields[1].num_bits = 32; + fields[1].out_value = NULL; + fields[1].in_value = in; + } else { + /* Discard irrelevant bits of the scan, making sure we don't write more + * than size bytes to in */ + fields[1].num_bits = 32 - size * 8; + fields[1].out_value = NULL; + fields[1].in_value = NULL; + + fields[2].num_bits = size * 8; + fields[2].out_value = NULL; + fields[2].in_value = in; + } - jtag_add_dr_scan(2, fields, jtag_get_end_state()); + jtag_add_dr_scan(jtag_info->tap, size == 4 ? 2 : 3, fields, TAP_DRPAUSE); - jtag_add_callback4(arm7endianness, (jtag_callback_data_t)in, (jtag_callback_data_t)size, (jtag_callback_data_t)be, (jtag_callback_data_t)fields[1].in_value); + jtag_add_callback4(arm7_9_endianness_callback, + (jtag_callback_data_t)in, + (jtag_callback_data_t)size, + (jtag_callback_data_t)be, + (jtag_callback_data_t)1); - jtag_add_runtest(0, jtag_get_end_state()); + jtag_add_runtest(0, TAP_DRPAUSE); #ifdef _DEBUG_INSTRUCTION_EXECUTION_ { - if ((retval = jtag_execute_queue()) != ERROR_OK) - { + retval = jtag_execute_queue(); + if (retval != ERROR_OK) return retval; - } if (in) - { - LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in); - } + LOG_DEBUG("in: 0x%8.8x", *(uint32_t *)in); else - { LOG_ERROR("BUG: called with in == NULL"); - } } #endif @@ -312,7 +285,6 @@ static void arm7tdmi_change_to_arm(struct target *target, *pc -= 0xa; } - /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s? * @@ -320,7 +292,7 @@ static void arm7tdmi_change_to_arm(struct target *target, * and convert data afterwards. */ static void arm7tdmi_read_core_regs(struct target *target, - uint32_t mask, uint32_t* core_regs[16]) + uint32_t mask, uint32_t *core_regs[16]) { int i; struct arm7_9_common *arm7_9 = target_to_arm7_9(target); @@ -336,8 +308,7 @@ static void arm7tdmi_read_core_regs(struct target *target, /* fetch NOP, STM in EXECUTE stage (1st cycle) */ arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - for (i = 0; i <= 15; i++) - { + for (i = 0; i <= 15; i++) { if (mask & (1 << i)) /* nothing fetched, STM still in EXECUTE (1 + i cycle) */ arm7tdmi_clock_data_in(jtag_info, core_regs[i]); @@ -345,7 +316,7 @@ static void arm7tdmi_read_core_regs(struct target *target, } static void arm7tdmi_read_core_regs_target_buffer(struct target *target, - uint32_t mask, void* buffer, int size) + uint32_t mask, void *buffer, int size) { int i; struct arm7_9_common *arm7_9 = target_to_arm7_9(target); @@ -365,13 +336,10 @@ static void arm7tdmi_read_core_regs_target_buffer(struct target *target, /* fetch NOP, STM in EXECUTE stage (1st cycle) */ arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - for (i = 0; i <= 15; i++) - { + for (i = 0; i <= 15; i++) { /* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */ - if (mask & (1 << i)) - { - switch (size) - { + if (mask & (1 << i)) { + switch (size) { case 4: arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); break; @@ -468,8 +436,7 @@ static void arm7tdmi_write_core_regs(struct target *target, /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); - for (i = 0; i <= 15; i++) - { + for (i = 0; i <= 15; i++) { if (mask & (1 << i)) /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */ arm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0); @@ -580,7 +547,7 @@ static void arm7tdmi_branch_resume(struct target *target) static void arm7tdmi_branch_resume_thumb(struct target *target) { struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common; + struct arm *arm = &arm7_9->arm; struct arm_jtag *jtag_info = &arm7_9->jtag_info; struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; @@ -596,7 +563,8 @@ static void arm7tdmi_branch_resume_thumb(struct target *target) /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */ - arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0); + arm7tdmi_clock_out(jtag_info, + buf_get_u32(arm->pc->value, 0, 32) | 1, NULL, 0); /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */ arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); @@ -624,7 +592,7 @@ static void arm7tdmi_branch_resume_thumb(struct target *target) /* fetch NOP, LDR in Execute */ arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */ - arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0); + arm7tdmi_clock_out(jtag_info, buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32), NULL, 0); /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */ arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0); @@ -640,23 +608,21 @@ static void arm7tdmi_branch_resume_thumb(struct target *target) static void arm7tdmi_build_reg_cache(struct target *target) { struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); - struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target); + struct arm *arm = target_to_arm(target); - (*cache_p) = armv4_5_build_reg_cache(target, armv4_5); - armv4_5->core_cache = (*cache_p); + (*cache_p) = arm_build_reg_cache(target, arm); } int arm7tdmi_init_target(struct command_context *cmd_ctx, struct target *target) { arm7tdmi_build_reg_cache(target); - + arm_semihosting_init(target); return ERROR_OK; } -int arm7tdmi_init_arch_info(struct target *target, struct arm7tdmi_common *arm7tdmi, struct jtag_tap *tap) +int arm7tdmi_init_arch_info(struct target *target, + struct arm7_9_common *arm7_9, struct jtag_tap *tap) { - struct arm7_9_common *arm7_9 = &arm7tdmi->arm7_9_common; - /* prepare JTAG information for the new target */ arm7_9->jtag_info.tap = tap; arm7_9->jtag_info.scann_size = 4; @@ -687,10 +653,12 @@ int arm7tdmi_init_arch_info(struct target *target, struct arm7tdmi_common *arm7t arm7_9->enable_single_step = arm7_9_enable_eice_step; arm7_9->disable_single_step = arm7_9_disable_eice_step; + arm7_9->write_memory = arm7_9_write_memory; + arm7_9->bulk_write_memory = arm7_9_bulk_write_memory; + arm7_9->post_debug_entry = NULL; arm7_9->pre_restore_context = NULL; - arm7_9->post_restore_context = NULL; /* initialize arch-specific breakpoint handling */ arm7_9->arm_bkpt = 0xdeeedeee; @@ -705,22 +673,21 @@ int arm7tdmi_init_arch_info(struct target *target, struct arm7tdmi_common *arm7t static int arm7tdmi_target_create(struct target *target, Jim_Interp *interp) { - struct arm7tdmi_common *arm7tdmi; + struct arm7_9_common *arm7_9; - arm7tdmi = calloc(1,sizeof(struct arm7tdmi_common)); - arm7tdmi_init_arch_info(target, arm7tdmi, target->tap); - arm7tdmi->arm7_9_common.armv4_5_common.is_armv4 = true; + arm7_9 = calloc(1, sizeof(struct arm7_9_common)); + arm7tdmi_init_arch_info(target, arm7_9, target->tap); + arm7_9->arm.is_armv4 = true; return ERROR_OK; } /** Holds methods for ARM7TDMI targets. */ -struct target_type arm7tdmi_target = -{ +struct target_type arm7tdmi_target = { .name = "arm7tdmi", .poll = arm7_9_poll, - .arch_state = armv4_5_arch_state, + .arch_state = arm_arch_state, .target_request_data = arm7_9_target_request_data, @@ -732,13 +699,14 @@ struct target_type arm7tdmi_target = .deassert_reset = arm7_9_deassert_reset, .soft_reset_halt = arm7_9_soft_reset_halt, - .get_gdb_reg_list = armv4_5_get_gdb_reg_list, + .get_gdb_arch = arm_get_gdb_arch, + .get_gdb_reg_list = arm_get_gdb_reg_list, .read_memory = arm7_9_read_memory, - .write_memory = arm7_9_write_memory, - .bulk_write_memory = arm7_9_bulk_write_memory, - .checksum_memory = arm7_9_checksum_memory, - .blank_check_memory = arm7_9_blank_check_memory, + .write_memory = arm7_9_write_memory_opt, + + .checksum_memory = arm_checksum_memory, + .blank_check_memory = arm_blank_check_memory, .run_algorithm = armv4_5_run_algorithm, @@ -747,8 +715,9 @@ struct target_type arm7tdmi_target = .add_watchpoint = arm7_9_add_watchpoint, .remove_watchpoint = arm7_9_remove_watchpoint, - .register_commands = arm7_9_register_commands, + .commands = arm7_9_command_handlers, .target_create = arm7tdmi_target_create, .init_target = arm7tdmi_init_target, .examine = arm7_9_examine, + .check_reset = arm7_9_check_reset, };