X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farm9tdmi.c;h=70ee62390f2eae5917705effa23980085fb7e930;hp=595790bc9529a5c6e51b17c2fece24ea997df012;hb=503bb08f9993c59a4b3206600555a42fd18459b6;hpb=3d6bcf07921753141a3905ee5619724573460cb3 diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index 595790bc95..70ee62390f 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -2,6 +2,12 @@ * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2008 by Spencer Oliver * + * spen@spen-soft.co.uk * + * * + * Copyright (C) 2008 by Hongtao Zheng * + * hontor@126.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 * @@ -46,9 +52,10 @@ int arm9tdmi_register_commands(struct command_context_s *cmd_ctx); int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); /* forward declarations */ -int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target); +int arm9tdmi_target_create( struct target_s *target, Jim_Interp *interp ); + int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target); -int arm9tdmi_quit(); +int arm9tdmi_quit(void); target_type_t arm9tdmi_target = { @@ -66,7 +73,6 @@ target_type_t arm9tdmi_target = .assert_reset = arm7_9_assert_reset, .deassert_reset = arm7_9_deassert_reset, .soft_reset_halt = arm7_9_soft_reset_halt, - .prepare_reset_halt = arm7_9_prepare_reset_halt, .get_gdb_reg_list = armv4_5_get_gdb_reg_list, @@ -74,6 +80,7 @@ target_type_t arm9tdmi_target = .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, .run_algorithm = armv4_5_run_algorithm, @@ -83,8 +90,9 @@ target_type_t arm9tdmi_target = .remove_watchpoint = arm7_9_remove_watchpoint, .register_commands = arm9tdmi_register_commands, - .target_command = arm9tdmi_target_command, + .target_create = arm9tdmi_target_create, .init_target = arm9tdmi_init_target, + .examine = arm9tdmi_examine, .quit = arm9tdmi_quit }; @@ -103,6 +111,7 @@ arm9tdmi_vector_t arm9tdmi_vectors[] = int arm9tdmi_examine_debug_reason(target_t *target) { + int retval = ERROR_OK; /* get pointers to arch-specific information */ armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; @@ -118,7 +127,7 @@ int arm9tdmi_examine_debug_reason(target_t *target) jtag_add_end_state(TAP_PD); - fields[0].device = arm7_9->jtag_info.chain_pos; + fields[0].tap = arm7_9->jtag_info.tap; fields[0].num_bits = 32; fields[0].out_value = NULL; fields[0].out_mask = NULL; @@ -128,7 +137,7 @@ int arm9tdmi_examine_debug_reason(target_t *target) fields[0].in_handler = NULL; fields[0].in_handler_priv = NULL; - fields[1].device = arm7_9->jtag_info.chain_pos; + fields[1].tap = arm7_9->jtag_info.tap; fields[1].num_bits = 3; fields[1].out_value = NULL; fields[1].out_mask = NULL; @@ -138,7 +147,7 @@ int arm9tdmi_examine_debug_reason(target_t *target) fields[1].in_handler = NULL; fields[1].in_handler_priv = NULL; - fields[2].device = arm7_9->jtag_info.chain_pos; + fields[2].tap = arm7_9->jtag_info.tap; fields[2].num_bits = 32; fields[2].out_value = NULL; fields[2].out_mask = NULL; @@ -148,11 +157,17 @@ int arm9tdmi_examine_debug_reason(target_t *target) fields[2].in_handler = NULL; fields[2].in_handler_priv = NULL; - arm_jtag_scann(&arm7_9->jtag_info, 0x1); + if((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1)) != ERROR_OK) + { + return retval; + } arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL); jtag_add_dr_scan(3, fields, TAP_PD); - jtag_execute_queue(); + if((retval = jtag_execute_queue()) != ERROR_OK) + { + return retval; + } fields[0].in_value = NULL; fields[0].out_value = databus; @@ -178,6 +193,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) { + int retval = ERROR_OK; scan_field_t fields[3]; u8 out_buf[4]; u8 instr_buf[4]; @@ -192,11 +208,14 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s buf_set_u32(&sysspeed_buf, 2, 1, 1); jtag_add_end_state(TAP_PD); - arm_jtag_scann(jtag_info, 0x1); + if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK) + { + return retval; + } arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); - fields[0].device = jtag_info->chain_pos; + fields[0].tap = jtag_info->tap; fields[0].num_bits = 32; fields[0].out_value = out_buf; fields[0].out_mask = NULL; @@ -214,7 +233,7 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s fields[0].in_check_value = NULL; fields[0].in_check_mask = NULL; - fields[1].device = jtag_info->chain_pos; + fields[1].tap = jtag_info->tap; fields[1].num_bits = 3; fields[1].out_value = &sysspeed_buf; fields[1].out_mask = NULL; @@ -224,7 +243,7 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s fields[1].in_handler = NULL; fields[1].in_handler_priv = NULL; - fields[2].device = jtag_info->chain_pos; + fields[2].tap = jtag_info->tap; fields[2].num_bits = 32; fields[2].out_value = instr_buf; fields[2].out_mask = NULL; @@ -240,14 +259,17 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s #ifdef _DEBUG_INSTRUCTION_EXECUTION_ { - jtag_execute_queue(); + if((retval = jtag_execute_queue()) != ERROR_OK) + { + return retval; + } if (in) { - DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in); + LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in); } else - DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out); + LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out); } #endif @@ -257,14 +279,18 @@ int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int s /* just read data (instruction and data-out = don't care) */ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) { + int retval = ERROR_OK;; scan_field_t fields[3]; jtag_add_end_state(TAP_PD); - arm_jtag_scann(jtag_info, 0x1); + if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK) + { + return retval; + } arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); - fields[0].device = jtag_info->chain_pos; + fields[0].tap = jtag_info->tap; fields[0].num_bits = 32; fields[0].out_value = NULL; fields[0].out_mask = NULL; @@ -274,7 +300,7 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) fields[0].in_check_value = NULL; fields[0].in_check_mask = NULL; - fields[1].device = jtag_info->chain_pos; + fields[1].tap = jtag_info->tap; fields[1].num_bits = 3; fields[1].out_value = NULL; fields[1].out_mask = NULL; @@ -284,7 +310,7 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) fields[1].in_check_value = NULL; fields[1].in_check_mask = NULL; - fields[2].device = jtag_info->chain_pos; + fields[2].tap = jtag_info->tap; fields[2].num_bits = 32; fields[2].out_value = NULL; fields[2].out_mask = NULL; @@ -300,15 +326,18 @@ int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in) #ifdef _DEBUG_INSTRUCTION_EXECUTION_ { - jtag_execute_queue(); - + if((retval = jtag_execute_queue()) != ERROR_OK) + { + return retval; + } + if (in) { - DEBUG("in: 0x%8.8x", *in); + LOG_DEBUG("in: 0x%8.8x", *in); } else { - ERROR("BUG: called with in == NULL"); + LOG_ERROR("BUG: called with in == NULL"); } } #endif @@ -322,14 +351,18 @@ 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) { + int retval = ERROR_OK; scan_field_t fields[3]; jtag_add_end_state(TAP_PD); - arm_jtag_scann(jtag_info, 0x1); + if((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK) + { + return retval; + } arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); - fields[0].device = jtag_info->chain_pos; + fields[0].tap = jtag_info->tap; fields[0].num_bits = 32; fields[0].out_value = NULL; fields[0].out_mask = NULL; @@ -350,7 +383,7 @@ int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, fields[0].in_check_value = NULL; fields[0].in_check_mask = NULL; - fields[1].device = jtag_info->chain_pos; + fields[1].tap = jtag_info->tap; fields[1].num_bits = 3; fields[1].out_value = NULL; fields[1].out_mask = NULL; @@ -360,7 +393,7 @@ int arm9tdmi_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; - fields[2].device = jtag_info->chain_pos; + fields[2].tap = jtag_info->tap; fields[2].num_bits = 32; fields[2].out_value = NULL; fields[2].out_mask = NULL; @@ -376,15 +409,18 @@ int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, #ifdef _DEBUG_INSTRUCTION_EXECUTION_ { - jtag_execute_queue(); - + if((retval = jtag_execute_queue()) != ERROR_OK) + { + return retval; + } + if (in) { - DEBUG("in: 0x%8.8x", *in); + LOG_DEBUG("in: 0x%8.8x", *(u32*)in); } else { - ERROR("BUG: called with in == NULL"); + LOG_ERROR("BUG: called with in == NULL"); } } #endif @@ -394,6 +430,7 @@ int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc) { + int retval = ERROR_OK; /* get pointers to arch-specific information */ armv4_5_common_t *armv4_5 = target->arch_info; arm7_9_common_t *arm7_9 = armv4_5->arch_info; @@ -434,7 +471,10 @@ void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc) /* NOP fetched, BX in Execute (1) */ arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); - jtag_execute_queue(); + if((retval = jtag_execute_queue()) != ERROR_OK) + { + return; + } /* fix program counter: * MOV r0, r15 was the 5th instruction (+8) @@ -544,7 +584,7 @@ void arm9tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr) arm7_9_common_t *arm7_9 = armv4_5->arch_info; arm_jtag_t *jtag_info = &arm7_9->jtag_info; - DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr); + LOG_DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr); /* MSR1 fetched */ arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0); @@ -580,7 +620,7 @@ void arm9tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr) arm7_9_common_t *arm7_9 = armv4_5->arch_info; arm_jtag_t *jtag_info = &arm7_9->jtag_info; - DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr); + LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr); /* MSR fetched */ arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0); @@ -745,7 +785,7 @@ void arm9tdmi_branch_resume(target_t *target) void arm9tdmi_branch_resume_thumb(target_t *target) { - DEBUG("-"); + LOG_DEBUG("-"); /* get pointers to arch-specific information */ armv4_5_common_t *armv4_5 = target->arch_info; @@ -804,7 +844,7 @@ void arm9tdmi_branch_resume_thumb(target_t *target) } -void arm9tdmi_enable_single_step(target_t *target) +void arm9tdmi_enable_single_step(target_t *target, u32 next_pc) { /* get pointers to arch-specific information */ armv4_5_common_t *armv4_5 = target->arch_info; @@ -817,7 +857,7 @@ void arm9tdmi_enable_single_step(target_t *target) } else { - arm7_9_enable_eice_step(target); + arm7_9_enable_eice_step(target, next_pc); } } @@ -843,21 +883,47 @@ void arm9tdmi_build_reg_cache(target_t *target) reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache); /* get pointers to arch-specific information */ armv4_5_common_t *armv4_5 = target->arch_info; - arm7_9_common_t *arm7_9 = armv4_5->arch_info; - arm_jtag_t *jtag_info = &arm7_9->jtag_info; (*cache_p) = armv4_5_build_reg_cache(target, armv4_5); armv4_5->core_cache = (*cache_p); - - /* one extra register (vector catch) */ - (*cache_p)->next = embeddedice_build_reg_cache(target, arm7_9); - arm7_9->eice_cache = (*cache_p)->next; +} + +int arm9tdmi_examine(struct target_s *target) +{ + /* get pointers to arch-specific information */ + 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) + { + reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache); + reg_cache_t *t; + /* one extra register (vector catch) */ + t=embeddedice_build_reg_cache(target, arm7_9); + if (t==NULL) + return ERROR_FAIL; + (*cache_p) = t; + arm7_9->eice_cache = (*cache_p); + + if (arm7_9->etm_ctx) + { + arm_jtag_t *jtag_info = &arm7_9->jtag_info; + (*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; + } + if ((retval=embeddedice_setup(target))!=ERROR_OK) + return retval; + if ((retval=arm7_9_setup(target))!=ERROR_OK) + return retval; if (arm7_9->etm_ctx) { - (*cache_p)->next->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx); - arm7_9->etm_ctx->reg_cache = (*cache_p)->next->next; + if ((retval=etm_setup(target))!=ERROR_OK) + return retval; } + return ERROR_OK; } int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target) @@ -869,13 +935,13 @@ int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *tar } -int arm9tdmi_quit() +int arm9tdmi_quit(void) { return ERROR_OK; } -int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int chain_pos, char *variant) +int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, jtag_tap_t *tap, const char *variant) { armv4_5_common_t *armv4_5; arm7_9_common_t *arm7_9; @@ -884,7 +950,7 @@ int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int c armv4_5 = &arm7_9->armv4_5_common; /* prepare JTAG information for the new target */ - arm7_9->jtag_info.chain_pos = chain_pos; + arm7_9->jtag_info.tap = tap; arm7_9->jtag_info.scann_size = 5; /* register arch-specific functions */ @@ -923,8 +989,6 @@ int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int c arm7_9->arm_bkpt = 0xdeeedeee; arm7_9->thumb_bkpt = 0xdeee; - arm7_9->sw_bkpts_use_wp = 1; - arm7_9->sw_bkpts_enabled = 0; arm7_9->dbgreq_adjust_pc = 3; arm7_9->arch_info = arm9tdmi; @@ -982,25 +1046,12 @@ int arm9tdmi_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, a } -/* target arm9tdmi */ -int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target) + +int arm9tdmi_target_create(struct target_s *target, Jim_Interp *interp) { - int chain_pos; - char *variant = NULL; - arm9tdmi_common_t *arm9tdmi = malloc(sizeof(arm9tdmi_common_t)); + arm9tdmi_common_t *arm9tdmi = calloc(1,sizeof(arm9tdmi_common_t)); - if (argc < 4) - { - ERROR("'target arm9tdmi' requires at least one additional argument"); - exit(-1); - } - - chain_pos = strtoul(args[3], NULL, 0); - - if (argc >= 5) - variant = args[4]; - - arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant); + arm9tdmi_init_arch_info(target, arm9tdmi, target->tap, target->variant); return ERROR_OK; } @@ -1019,7 +1070,7 @@ int arm9tdmi_register_commands(struct command_context_s *cmd_ctx) register_command(cmd_ctx, arm9tdmi_cmd, "vector_catch", handle_arm9tdmi_catch_vectors_command, COMMAND_EXEC, "catch arm920t vectors ['all'|'none'|'']"); - return ERROR_OK; + return retval; }