X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farm9tdmi.c;h=595790bc9529a5c6e51b17c2fece24ea997df012;hp=7584a8bbdb5893f56cffde1b592753650e19f023;hb=3d6bcf07921753141a3905ee5619724573460cb3;hpb=028f59ede54917d59f8183e6feac43cb0a6f3546 diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index 7584a8bbdb..595790bc95 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -28,6 +28,8 @@ #include "target.h" #include "armv4_5.h" #include "embeddedice.h" +#include "etm.h" +#include "etb.h" #include "log.h" #include "jtag.h" #include "arm_jtag.h" @@ -41,6 +43,7 @@ /* cli handling */ 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); @@ -54,6 +57,8 @@ target_type_t arm9tdmi_target = .poll = arm7_9_poll, .arch_state = armv4_5_arch_state, + .target_request_data = arm7_9_target_request_data, + .halt = arm7_9_halt, .resume = arm7_9_resume, .step = arm7_9_step, @@ -61,13 +66,17 @@ 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, .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, + + .run_algorithm = armv4_5_run_algorithm, + .add_breakpoint = arm7_9_add_breakpoint, .remove_breakpoint = arm7_9_remove_breakpoint, .add_watchpoint = arm7_9_add_watchpoint, @@ -79,6 +88,19 @@ target_type_t arm9tdmi_target = .quit = arm9tdmi_quit }; +arm9tdmi_vector_t arm9tdmi_vectors[] = +{ + {"reset", ARM9TDMI_RESET_VECTOR}, + {"undef", ARM9TDMI_UNDEF_VECTOR}, + {"swi", ARM9TDMI_SWI_VECTOR}, + {"pabt", ARM9TDMI_PABT_VECTOR}, + {"dabt", ARM9TDMI_DABT_VECTOR}, + {"reserved", ARM9TDMI_RESERVED_VECTOR}, + {"irq", ARM9TDMI_IRQ_VECTOR}, + {"fiq", ARM9TDMI_FIQ_VECTOR}, + {0, 0}, +}; + int arm9tdmi_examine_debug_reason(target_t *target) { /* get pointers to arch-specific information */ @@ -127,7 +149,7 @@ 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); + 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(); @@ -171,7 +193,8 @@ 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); + + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL); fields[0].device = jtag_info->chain_pos; fields[0].num_bits = 32; @@ -238,7 +261,8 @@ int arm9tdmi_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 = 32; @@ -299,10 +323,11 @@ 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]; - + 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 = 32; @@ -720,7 +745,7 @@ void arm9tdmi_branch_resume(target_t *target) void arm9tdmi_branch_resume_thumb(target_t *target) { - DEBUG(""); + DEBUG("-"); /* get pointers to arch-specific information */ armv4_5_common_t *armv4_5 = target->arch_info; @@ -784,9 +809,8 @@ void arm9tdmi_enable_single_step(target_t *target) /* 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; - arm9tdmi_common_t *arm9 = arm7_9->arch_info; - if (arm9->has_single_step) + if (arm7_9->has_single_step) { buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1); embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]); @@ -802,9 +826,8 @@ void arm9tdmi_disable_single_step(target_t *target) /* 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; - arm9tdmi_common_t *arm9 = arm7_9->arch_info; - if (arm9->has_single_step) + if (arm7_9->has_single_step) { buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0); embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]); @@ -822,34 +845,19 @@ void arm9tdmi_build_reg_cache(target_t *target) 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; - arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info; - - embeddedice_reg_t *vec_catch_arch_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, jtag_info, 1); + (*cache_p)->next = embeddedice_build_reg_cache(target, arm7_9); arm7_9->eice_cache = (*cache_p)->next; - - if (arm9tdmi->has_monitor_mode) - (*cache_p)->next->reg_list[EICE_DBG_CTRL].size = 6; - else - (*cache_p)->next->reg_list[EICE_DBG_CTRL].size = 4; - - (*cache_p)->next->reg_list[EICE_DBG_STAT].size = 5; - (*cache_p)->next->reg_list[EICE_VEC_CATCH].name = "vector catch"; - (*cache_p)->next->reg_list[EICE_VEC_CATCH].dirty = 0; - (*cache_p)->next->reg_list[EICE_VEC_CATCH].valid = 0; - (*cache_p)->next->reg_list[EICE_VEC_CATCH].bitfield_desc = NULL; - (*cache_p)->next->reg_list[EICE_VEC_CATCH].num_bitfields = 0; - (*cache_p)->next->reg_list[EICE_VEC_CATCH].size = 8; - (*cache_p)->next->reg_list[EICE_VEC_CATCH].value = calloc(1, 4); - vec_catch_arch_info = (*cache_p)->next->reg_list[EICE_VEC_CATCH].arch_info; - vec_catch_arch_info->addr = 0x2; - + 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; + } } int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target) @@ -912,8 +920,8 @@ int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int c arm7_9->post_restore_context = NULL; /* initialize arch-specific breakpoint handling */ - buf_set_u32((u8*)(&arm7_9->arm_bkpt), 0, 32, 0xdeeedeee); - buf_set_u32((u8*)(&arm7_9->thumb_bkpt), 0, 16, 0xdeee); + arm7_9->arm_bkpt = 0xdeeedeee; + arm7_9->thumb_bkpt = 0xdeee; arm7_9->sw_bkpts_use_wp = 1; arm7_9->sw_bkpts_enabled = 0; @@ -921,31 +929,59 @@ int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int c arm7_9->arch_info = arm9tdmi; arm9tdmi->common_magic = ARM9TDMI_COMMON_MAGIC; - arm9tdmi->has_monitor_mode = 0; - arm9tdmi->has_single_step = 0; arm9tdmi->arch_info = NULL; if (variant) { - if (strcmp(variant, "arm920t") == 0) - arm9tdmi->has_single_step = 1; - else if (strcmp(variant, "arm922t") == 0) - arm9tdmi->has_single_step = 1; - else if (strcmp(variant, "arm940t") == 0) - arm9tdmi->has_single_step = 1; arm9tdmi->variant = strdup(variant); } else + { arm9tdmi->variant = strdup(""); + } arm7_9_init_arch_info(target, arm7_9); /* override use of DBGRQ, this is safe on ARM9TDMI */ arm7_9->use_dbgrq = 1; + + /* all ARM9s have the vector catch register */ + arm7_9->has_vector_catch = 1; return ERROR_OK; } +int arm9tdmi_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p) +{ + armv4_5_common_t *armv4_5 = target->arch_info; + arm7_9_common_t *arm7_9; + arm9tdmi_common_t *arm9tdmi; + + if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC) + { + return -1; + } + + arm7_9 = armv4_5->arch_info; + if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC) + { + return -1; + } + + arm9tdmi = arm7_9->arch_info; + if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC) + { + return -1; + } + + *armv4_5_p = armv4_5; + *arm7_9_p = arm7_9; + *arm9tdmi_p = arm9tdmi; + + return ERROR_OK; +} + + /* target arm9tdmi */ int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target) { @@ -973,9 +1009,97 @@ int arm9tdmi_register_commands(struct command_context_s *cmd_ctx) { int retval; + command_t *arm9tdmi_cmd; + + retval = arm7_9_register_commands(cmd_ctx); + arm9tdmi_cmd = register_command(cmd_ctx, NULL, "arm9tdmi", NULL, COMMAND_ANY, "arm9tdmi specific commands"); + + register_command(cmd_ctx, arm9tdmi_cmd, "vector_catch", handle_arm9tdmi_catch_vectors_command, COMMAND_EXEC, "catch arm920t vectors ['all'|'none'|'']"); + + return ERROR_OK; } +int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + target_t *target = get_current_target(cmd_ctx); + armv4_5_common_t *armv4_5; + arm7_9_common_t *arm7_9; + arm9tdmi_common_t *arm9tdmi; + reg_t *vector_catch; + u32 vector_catch_value; + int i, j; + + if (arm9tdmi_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi) != ERROR_OK) + { + command_print(cmd_ctx, "current target isn't an ARM9TDMI based target"); + return ERROR_OK; + } + + vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH]; + + /* read the vector catch register if necessary */ + if (!vector_catch->valid) + embeddedice_read_reg(vector_catch); + + /* get the current setting */ + vector_catch_value = buf_get_u32(vector_catch->value, 0, 32); + + if (argc > 0) + { + vector_catch_value = 0x0; + if (strcmp(args[0], "all") == 0) + { + vector_catch_value = 0xdf; + } + else if (strcmp(args[0], "none") == 0) + { + /* do nothing */ + } + else + { + for (i = 0; i < argc; i++) + { + /* go through list of vectors */ + for(j = 0; arm9tdmi_vectors[j].name; j++) + { + if (strcmp(args[i], arm9tdmi_vectors[j].name) == 0) + { + vector_catch_value |= arm9tdmi_vectors[j].value; + break; + } + } + + /* complain if vector wasn't found */ + if (!arm9tdmi_vectors[j].name) + { + command_print(cmd_ctx, "vector '%s' not found, leaving current setting unchanged", args[i]); + + /* reread current setting */ + vector_catch_value = buf_get_u32(vector_catch->value, 0, 32); + + break; + } + } + } + + /* store new settings */ + buf_set_u32(vector_catch->value, 0, 32, vector_catch_value); + embeddedice_store_reg(vector_catch); + } + + /* output current settings (skip RESERVED vector) */ + for (i = 0; i < 8; i++) + { + if (i != 5) + { + command_print(cmd_ctx, "%s: %s", arm9tdmi_vectors[i].name, + (vector_catch_value & (1 << i)) ? "catch" : "don't catch"); + } + } + + return ERROR_OK; +}