X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farm7tdmi.c;h=e3185bec866fa85c15222e8fc2d2ffb586d617d2;hp=be98c8e193f310a945f841dc0d5fa0e87188ae22;hb=040e6cef41d77f6692f2f5e9c5849e6d8fbeeefd;hpb=c45de8073d027f1a4d39640dc140666f27960e3b diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index be98c8e193..e3185bec86 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -5,6 +5,9 @@ * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -25,31 +28,16 @@ #endif #include "arm7tdmi.h" +#include "target_type.h" -#include "arm7_9_common.h" -#include "register.h" -#include "target.h" -#include "armv4_5.h" -#include "embeddedice.h" -#include "etm.h" -#include "log.h" -#include "jtag.h" -#include "arm_jtag.h" - -#include -#include #if 0 #define _DEBUG_INSTRUCTION_EXECUTION_ #endif -/* cli handling */ -int arm7tdmi_register_commands(struct command_context_s *cmd_ctx); - /* forward declarations */ int arm7tdmi_target_create(struct target_s *target,Jim_Interp *interp); -int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target); int arm7tdmi_quit(void); /* target function declarations */ @@ -115,22 +103,12 @@ int arm7tdmi_examine_debug_reason(target_t *target) fields[0].tap = arm7_9->jtag_info.tap; fields[0].num_bits = 1; fields[0].out_value = NULL; - fields[0].out_mask = NULL; fields[0].in_value = &breakpoint; - fields[0].in_check_value = NULL; - fields[0].in_check_mask = NULL; - fields[0].in_handler = NULL; - fields[0].in_handler_priv = NULL; fields[1].tap = arm7_9->jtag_info.tap; fields[1].num_bits = 32; fields[1].out_value = NULL; - fields[1].out_mask = NULL; fields[1].in_value = databus; - fields[1].in_check_value = NULL; - fields[1].in_check_mask = NULL; - fields[1].in_handler = NULL; - fields[1].in_handler_priv = NULL; if((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1)) != ERROR_OK) { @@ -138,7 +116,7 @@ int arm7tdmi_examine_debug_reason(target_t *target) } arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL); - jtag_add_dr_scan(2, fields, TAP_DRPAUSE); + jtag_add_dr_scan(2, fields, jtag_add_end_state(TAP_DRPAUSE)); if((retval = jtag_execute_queue()) != ERROR_OK) { return retval; @@ -149,7 +127,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_DRPAUSE); + jtag_add_dr_scan(2, fields, jtag_add_end_state(TAP_DRPAUSE)); if (breakpoint & 1) target->debug_reason = DBG_REASON_WATCHPOINT; @@ -169,9 +147,9 @@ static __inline int arm7tdmi_clock_out_inner(arm_jtag_t *jtag_info, u32 out, int 2, arm7tdmi_num_bits, values, - -1); + jtag_add_end_state(TAP_INVALID)); - jtag_add_runtest(0, -1); + jtag_add_runtest(0, jtag_add_end_state(TAP_INVALID)); return ERROR_OK; } @@ -202,26 +180,18 @@ int arm7tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) fields[0].tap = jtag_info->tap; fields[0].num_bits = 1; fields[0].out_value = NULL; - fields[0].out_mask = NULL; fields[0].in_value = NULL; - fields[0].in_check_value = NULL; - fields[0].in_check_mask = NULL; - fields[0].in_handler = NULL; - fields[0].in_handler_priv = NULL; fields[1].tap = jtag_info->tap; fields[1].num_bits = 32; fields[1].out_value = NULL; - fields[1].out_mask = NULL; - fields[1].in_value = NULL; - fields[1].in_handler = arm_jtag_buf_to_u32_flip; - fields[1].in_handler_priv = in; - fields[1].in_check_value = NULL; - fields[1].in_check_mask = NULL; + fields[1].in_value = (u8 *)in; - jtag_add_dr_scan(2, fields, -1); + jtag_add_dr_scan(2, fields, jtag_add_end_state(TAP_INVALID)); - jtag_add_runtest(0, -1); + jtag_add_callback(arm7flip32, (u8 *)in); + + jtag_add_runtest(0, jtag_add_end_state(TAP_INVALID)); #ifdef _DEBUG_INSTRUCTION_EXECUTION_ { @@ -244,6 +214,43 @@ int arm7tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) return ERROR_OK; } +void arm_endianness(u8 *tmp, void *in, int size, int be, int flip) +{ + u32 readback=le_to_h_u32(tmp); + if (flip) + readback=flip_u32(readback, 32); + switch (size) + { + case 4: + if (be) + { + h_u32_to_be(((u8*)in), readback); + } else + { + h_u32_to_le(((u8*)in), readback); + } + break; + case 2: + if (be) + { + h_u16_to_be(((u8*)in), readback & 0xffff); + } else + { + h_u16_to_le(((u8*)in), readback & 0xffff); + } + break; + case 1: + *((u8 *)in)= readback & 0xff; + break; + } +} + +static int arm7endianness(u8 *in, jtag_callback_data_t size, jtag_callback_data_t be, jtag_callback_data_t captured) +{ + arm_endianness((u8 *)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 @@ -263,37 +270,18 @@ int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, fields[0].tap = jtag_info->tap; fields[0].num_bits = 1; fields[0].out_value = NULL; - fields[0].out_mask = NULL; fields[0].in_value = NULL; - fields[0].in_check_value = NULL; - fields[0].in_check_mask = NULL; - fields[0].in_handler = NULL; - fields[0].in_handler_priv = NULL; fields[1].tap = jtag_info->tap; fields[1].num_bits = 32; fields[1].out_value = NULL; - fields[1].out_mask = NULL; - fields[1].in_value = NULL; - switch (size) - { - case 4: - fields[1].in_handler = (be) ? arm_jtag_buf_to_be32_flip : arm_jtag_buf_to_le32_flip; - break; - case 2: - fields[1].in_handler = (be) ? arm_jtag_buf_to_be16_flip : arm_jtag_buf_to_le16_flip; - break; - case 1: - fields[1].in_handler = arm_jtag_buf_to_8_flip; - break; - } - fields[1].in_handler_priv = in; - fields[1].in_check_value = NULL; - fields[1].in_check_mask = NULL; + jtag_alloc_in_value32(&fields[1]); - jtag_add_dr_scan(2, fields, -1); + jtag_add_dr_scan(2, fields, jtag_add_end_state(TAP_INVALID)); - jtag_add_runtest(0, -1); + jtag_add_callback4(arm7endianness, in, (jtag_callback_data_t)size, (jtag_callback_data_t)be, (jtag_callback_data_t)fields[1].in_value); + + jtag_add_runtest(0, jtag_add_end_state(TAP_INVALID)); #ifdef _DEBUG_INSTRUCTION_EXECUTION_ { @@ -364,9 +352,15 @@ void arm7tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc) * reading PC in Thumb state gives address of instruction + 4 */ *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? + * + * The solution is to arrange for a large out/in scan in this loop and + * and convert data afterwards. + */ void arm7tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16]) { int i; @@ -391,7 +385,6 @@ void arm7tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16]) /* nothing fetched, STM still in EXECUTE (1+i cycle) */ arm7tdmi_clock_data_in(jtag_info, core_regs[i]); } - } void arm7tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size) @@ -435,7 +428,6 @@ void arm7tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buf } } } - } void arm7tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr) @@ -456,7 +448,6 @@ void arm7tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr) arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); /* nothing fetched, STR still in EXECUTE (2nd cycle) */ arm7tdmi_clock_data_in(jtag_info, xpsr); - } void arm7tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr) @@ -507,7 +498,6 @@ void arm7tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr) arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); /* nothing fetched, MSR in EXECUTE (2) */ arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); - } void arm7tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16]) @@ -535,7 +525,6 @@ void arm7tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16]) arm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0); } arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); - } void arm7tdmi_load_word_regs(target_t *target, u32 mask) @@ -549,7 +538,6 @@ void arm7tdmi_load_word_regs(target_t *target, u32 mask) arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), NULL, 0); - } void arm7tdmi_load_hword_reg(target_t *target, int num) @@ -563,7 +551,6 @@ void arm7tdmi_load_hword_reg(target_t *target, int num) arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), NULL, 0); - } void arm7tdmi_load_byte_reg(target_t *target, int num) @@ -577,7 +564,6 @@ void arm7tdmi_load_byte_reg(target_t *target, int num) arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), NULL, 0); - } void arm7tdmi_store_word_regs(target_t *target, u32 mask) @@ -591,7 +577,6 @@ void arm7tdmi_store_word_regs(target_t *target, u32 mask) arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), NULL, 0); - } void arm7tdmi_store_hword_reg(target_t *target, int num) @@ -605,7 +590,6 @@ void arm7tdmi_store_hword_reg(target_t *target, int num) arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); arm7tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), NULL, 0); - } void arm7tdmi_store_byte_reg(target_t *target, int num) @@ -619,7 +603,6 @@ void arm7tdmi_store_byte_reg(target_t *target, int num) arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); arm7tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), NULL, 0); - } void arm7tdmi_write_pc(target_t *target, u32 pc) @@ -658,7 +641,6 @@ void arm7tdmi_branch_resume(target_t *target) arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1); arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_B(0xfffffa, 0), 0); - } void arm7tdmi_branch_resume_thumb(target_t *target) @@ -720,7 +702,6 @@ void arm7tdmi_branch_resume_thumb(target_t *target) arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 1); arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f8), NULL, 0); - } void arm7tdmi_build_reg_cache(target_t *target) @@ -738,7 +719,7 @@ int arm7tdmi_examine(struct target_s *target) int retval; armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; - if (!target->type->examined) + if (!target_was_examined(target)) { /* get pointers to arch-specific information */ reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache); @@ -755,7 +736,7 @@ int arm7tdmi_examine(struct target_s *target) (*cache_p)->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx); arm7_9->etm_ctx->reg_cache = (*cache_p)->next; } - target->type->examined = 1; + target_set_examined(target); } if ((retval=embeddedice_setup(target))!=ERROR_OK) return retval; @@ -771,20 +752,17 @@ int arm7tdmi_examine(struct target_s *target) int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target) { - arm7tdmi_build_reg_cache(target); return ERROR_OK; - } int arm7tdmi_quit(void) { - return ERROR_OK; } -int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, jtag_tap_t *tap, const char *variant) +int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, jtag_tap_t *tap) { armv4_5_common_t *armv4_5; arm7_9_common_t *arm7_9; @@ -838,34 +816,21 @@ int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, jtag_ arm7tdmi->arch_info = NULL; arm7tdmi->common_magic = ARM7TDMI_COMMON_MAGIC; - if (variant) - { - arm7tdmi->variant = strdup(variant); - } - else - { - arm7tdmi->variant = strdup(""); - } - arm7_9_init_arch_info(target, arm7_9); return ERROR_OK; } - - int arm7tdmi_target_create( struct target_s *target, Jim_Interp *interp ) { arm7tdmi_common_t *arm7tdmi; arm7tdmi = calloc(1,sizeof(arm7tdmi_common_t)); - - arm7tdmi_init_arch_info(target, arm7tdmi, target->tap, target->variant); + arm7tdmi_init_arch_info(target, arm7tdmi, target->tap); return ERROR_OK; } - int arm7tdmi_register_commands(struct command_context_s *cmd_ctx) { int retval; @@ -873,5 +838,4 @@ int arm7tdmi_register_commands(struct command_context_s *cmd_ctx) retval = arm7_9_register_commands(cmd_ctx); return retval; - }