X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Fcortex_m3.c;h=6bc427a4389beb4cdf2281bb4bc2883f0eccec23;hb=068626fde4590a3d3e5e7a80a3ac07adb53b9b48;hp=e4949d20fa1e03f2dd06353096662e5573773b8f;hpb=8193f17c3aeb948ca8f70ed3361e8b2bccefffed;p=openocd.git diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index e4949d20fa..6bc427a438 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -37,14 +37,13 @@ #include "target_type.h" #include "arm_disassembler.h" #include "register.h" +#include "arm_opcodes.h" /* NOTE: most of this should work fine for the Cortex-M1 and * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M. */ -#define ARRAY_SIZE(x) ((int)(sizeof(x)/sizeof((x)[0]))) - /* forward declarations */ static int cortex_m3_set_breakpoint(struct target *target, struct breakpoint *breakpoint); @@ -53,11 +52,6 @@ static void cortex_m3_enable_watchpoints(struct target *target); static int cortex_m3_store_core_reg_u32(struct target *target, enum armv7m_regtype type, uint32_t num, uint32_t value); -#ifdef ARMV7_GDB_HACKS -extern uint8_t armv7m_gdb_dummy_cpsr_value[]; -extern struct reg armv7m_gdb_dummy_cpsr_reg; -#endif - static int cortexm3_dap_read_coreregister_u32(struct swjdp_common *swjdp, uint32_t *value, int regnum) { @@ -223,7 +217,7 @@ static int cortex_m3_endreset_event(struct target *target) } swjdp_transaction_endcheck(swjdp); - armv7m_invalidate_core_regs(target); + register_cache_invalidate(cortex_m3->armv7m.core_cache); /* make sure we have latest dhcsr flags */ mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); @@ -336,6 +330,9 @@ static int cortex_m3_debug_entry(struct target *target) xPSR = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32); #ifdef ARMV7_GDB_HACKS + /* FIXME this breaks on scan chains with more than one Cortex-M3. + * Instead, each CM3 should have its own dummy value... + */ /* copy real xpsr reg for gdb, setting thumb bit */ buf_set_u32(armv7m_gdb_dummy_cpsr_value, 0, 32, xPSR); buf_set_u32(armv7m_gdb_dummy_cpsr_value, 5, 1, 1); @@ -509,7 +506,7 @@ static int cortex_m3_soft_reset_halt(struct target *target) target->state = TARGET_RESET; /* registers are now invalid */ - armv7m_invalidate_core_regs(target); + register_cache_invalidate(cortex_m3->armv7m.core_cache); while (timeout < 100) { @@ -616,7 +613,8 @@ static int cortex_m3_resume(struct target *target, int current, target->debug_reason = DBG_REASON_NOTHALTED; /* registers are now invalid */ - armv7m_invalidate_core_regs(target); + register_cache_invalidate(armv7m->core_cache); + if (!debug_execution) { target->state = TARGET_RUNNING; @@ -672,7 +670,7 @@ static int cortex_m3_step(struct target *target, int current, mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); /* registers are now invalid */ - armv7m_invalidate_core_regs(target); + register_cache_invalidate(cortex_m3->armv7m.core_cache); if (breakpoint) cortex_m3_set_breakpoint(target, breakpoint); @@ -811,7 +809,7 @@ static int cortex_m3_assert_reset(struct target *target) target->state = TARGET_RESET; jtag_add_sleep(50000); - armv7m_invalidate_core_regs(target); + register_cache_invalidate(cortex_m3->armv7m.core_cache); if (target->reset_halt) { @@ -860,9 +858,8 @@ cortex_m3_set_breakpoint(struct target *target, struct breakpoint *breakpoint) fp_num++; if (fp_num >= cortex_m3->fp_num_code) { - LOG_DEBUG("ERROR Can not find free FP Comparator"); - LOG_WARNING("ERROR Can not find free FP Comparator"); - exit(-1); + LOG_ERROR("Can not find free FPB Comparator!"); + return ERROR_FAIL; } breakpoint->set = fp_num + 1; hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW; @@ -879,7 +876,7 @@ cortex_m3_set_breakpoint(struct target *target, struct breakpoint *breakpoint) else if (breakpoint->type == BKPT_SOFT) { uint8_t code[4]; - buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11)); + buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11)); if ((retval = target_read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK) { return retval; @@ -1140,13 +1137,6 @@ cortex_m3_add_watchpoint(struct target *target, struct watchpoint *watchpoint) { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - /* REVISIT why check? DWT can be updated with core running ... */ - if (target->state != TARGET_HALTED) - { - LOG_WARNING("target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - if (cortex_m3->dwt_comp_available < 1) { LOG_DEBUG("no comparators?"); @@ -1374,16 +1364,11 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address, { struct armv7m_common *armv7m = target_to_armv7m(target); struct swjdp_common *swjdp = &armv7m->swjdp_info; - int retval; - - /* sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) - return ERROR_INVALID_ARGUMENTS; + int retval = ERROR_INVALID_ARGUMENTS; /* cortex_m3 handles unaligned memory access */ - - switch (size) - { + if (count && buffer) { + switch (size) { case 4: retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address); break; @@ -1393,9 +1378,7 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address, case 1: retval = mem_ap_read_buf_u8(swjdp, buffer, count, address); break; - default: - LOG_ERROR("BUG: we shouldn't get here"); - exit(-1); + } } return retval; @@ -1406,14 +1389,10 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address, { struct armv7m_common *armv7m = target_to_armv7m(target); struct swjdp_common *swjdp = &armv7m->swjdp_info; - int retval; - - /* sanitize arguments */ - if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer)) - return ERROR_INVALID_ARGUMENTS; + int retval = ERROR_INVALID_ARGUMENTS; - switch (size) - { + if (count && buffer) { + switch (size) { case 4: retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address); break; @@ -1423,9 +1402,7 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address, case 1: retval = mem_ap_write_buf_u8(swjdp, buffer, count, address); break; - default: - LOG_ERROR("BUG: we shouldn't get here"); - exit(-1); + } } return retval; @@ -1494,7 +1471,10 @@ static struct dwt_reg dwt_comp[] = { #undef DWT_COMPARATOR }; -static int dwt_reg_type = -1; +static const struct reg_arch_type dwt_reg_type = { + .get = cortex_m3_dwt_get_reg, + .set = cortex_m3_dwt_set_reg, +}; static void cortex_m3_dwt_addreg(struct target *t, struct reg *r, struct dwt_reg *d) @@ -1511,7 +1491,7 @@ cortex_m3_dwt_addreg(struct target *t, struct reg *r, struct dwt_reg *d) r->size = d->size; r->value = &state->value; r->arch_info = state; - r->arch_type = dwt_reg_type; + r->type = &dwt_reg_type; } static void @@ -1528,10 +1508,6 @@ cortex_m3_dwt_setup(struct cortex_m3_common *cm3, struct target *target) return; } - if (dwt_reg_type < 0) - dwt_reg_type = register_reg_arch_type(cortex_m3_dwt_get_reg, - cortex_m3_dwt_set_reg); - cm3->dwt_num_comp = (dwtcr >> 28) & 0xF; cm3->dwt_comp_available = cm3->dwt_num_comp; cm3->dwt_comparator_list = calloc(cm3->dwt_num_comp, @@ -1627,6 +1603,12 @@ static int cortex_m3_examine(struct target *target) /* Setup DWT */ cortex_m3_dwt_setup(cortex_m3, target); + + /* These hardware breakpoints only work for code in flash! */ + LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints", + target_name(target), + cortex_m3->fp_num_code, + cortex_m3->dwt_num_comp); } return ERROR_OK; @@ -1786,26 +1768,26 @@ static int cortex_m3_verify_pointer(struct command_context *cmd_ctx, COMMAND_HANDLER(handle_cortex_m3_disassemble_command) { int retval; - struct target *target = get_current_target(cmd_ctx); + struct target *target = get_current_target(CMD_CTX); struct cortex_m3_common *cortex_m3 = target_to_cm3(target); uint32_t address; unsigned long count = 1; struct arm_instruction cur_instruction; - retval = cortex_m3_verify_pointer(cmd_ctx, cortex_m3); + retval = cortex_m3_verify_pointer(CMD_CTX, cortex_m3); if (retval != ERROR_OK) return retval; errno = 0; - switch (argc) { + switch (CMD_ARGC) { case 2: - COMMAND_PARSE_NUMBER(ulong, args[1], count); + COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], count); /* FALL THROUGH */ case 1: - COMMAND_PARSE_NUMBER(u32, args[0], address); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); break; default: - command_print(cmd_ctx, + command_print(CMD_CTX, "usage: cortex_m3 disassemble
[]"); return ERROR_OK; } @@ -1814,7 +1796,7 @@ COMMAND_HANDLER(handle_cortex_m3_disassemble_command) retval = thumb2_opcode(target, address, &cur_instruction); if (retval != ERROR_OK) return retval; - command_print(cmd_ctx, "%s", cur_instruction.text); + command_print(CMD_CTX, "%s", cur_instruction.text); address += cur_instruction.instruction_size; } @@ -1837,42 +1819,42 @@ static const struct { COMMAND_HANDLER(handle_cortex_m3_vector_catch_command) { - struct target *target = get_current_target(cmd_ctx); + struct target *target = get_current_target(CMD_CTX); struct cortex_m3_common *cortex_m3 = target_to_cm3(target); struct armv7m_common *armv7m = &cortex_m3->armv7m; struct swjdp_common *swjdp = &armv7m->swjdp_info; uint32_t demcr = 0; int retval; - int i; - retval = cortex_m3_verify_pointer(cmd_ctx, cortex_m3); + retval = cortex_m3_verify_pointer(CMD_CTX, cortex_m3); if (retval != ERROR_OK) return retval; mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &demcr); - if (argc > 0) { + if (CMD_ARGC > 0) { unsigned catch = 0; - if (argc == 1) { - if (strcmp(args[0], "all") == 0) { + if (CMD_ARGC == 1) { + if (strcmp(CMD_ARGV[0], "all") == 0) { catch = VC_HARDERR | VC_INTERR | VC_BUSERR | VC_STATERR | VC_CHKERR | VC_NOCPERR | VC_MMERR | VC_CORERESET; goto write; - } else if (strcmp(args[0], "none") == 0) { + } else if (strcmp(CMD_ARGV[0], "none") == 0) { goto write; } } - while (argc-- > 0) { + while (CMD_ARGC-- > 0) { + unsigned i; for (i = 0; i < ARRAY_SIZE(vec_ids); i++) { - if (strcmp(args[argc], vec_ids[i].name) != 0) + if (strcmp(CMD_ARGV[CMD_ARGC], vec_ids[i].name) != 0) continue; catch |= vec_ids[i].mask; break; } if (i == ARRAY_SIZE(vec_ids)) { - LOG_ERROR("No CM3 vector '%s'", args[argc]); + LOG_ERROR("No CM3 vector '%s'", CMD_ARGV[CMD_ARGC]); return ERROR_INVALID_ARGUMENTS; } } @@ -1885,73 +1867,82 @@ write: mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &demcr); } - for (i = 0; i < ARRAY_SIZE(vec_ids); i++) - command_print(cmd_ctx, "%9s: %s", vec_ids[i].name, + for (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++) + { + command_print(CMD_CTX, "%9s: %s", vec_ids[i].name, (demcr & vec_ids[i].mask) ? "catch" : "ignore"); + } return ERROR_OK; } COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command) { - struct target *target = get_current_target(cmd_ctx); + struct target *target = get_current_target(CMD_CTX); struct cortex_m3_common *cortex_m3 = target_to_cm3(target); int retval; - retval = cortex_m3_verify_pointer(cmd_ctx, cortex_m3); + retval = cortex_m3_verify_pointer(CMD_CTX, cortex_m3); if (retval != ERROR_OK) return retval; if (target->state != TARGET_HALTED) { - command_print(cmd_ctx, "target must be stopped for \"%s\" command", CMD_NAME); + command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); return ERROR_OK; } - if (argc > 0) + if (CMD_ARGC > 0) { - if (!strcmp(args[0], "on")) - { - cortex_m3_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0); - } - else if (!strcmp(args[0], "off")) - { - cortex_m3_write_debug_halt_mask(target, C_HALT, C_MASKINTS); - } - else - { - command_print(cmd_ctx, "usage: cortex_m3 maskisr ['on'|'off']"); - } + bool enable; + COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable); + uint32_t mask_on = C_HALT | (enable ? C_MASKINTS : 0); + uint32_t mask_off = enable ? 0 : C_MASKINTS; + cortex_m3_write_debug_halt_mask(target, mask_on, mask_off); } - command_print(cmd_ctx, "cortex_m3 interrupt mask %s", + command_print(CMD_CTX, "cortex_m3 interrupt mask %s", (cortex_m3->dcb_dhcsr & C_MASKINTS) ? "on" : "off"); return ERROR_OK; } -static int cortex_m3_register_commands(struct command_context *cmd_ctx) -{ - int retval; - struct command *cortex_m3_cmd; - - retval = armv7m_register_commands(cmd_ctx); - - cortex_m3_cmd = register_command(cmd_ctx, NULL, "cortex_m3", - NULL, COMMAND_ANY, "cortex_m3 specific commands"); - - register_command(cmd_ctx, cortex_m3_cmd, "disassemble", - handle_cortex_m3_disassemble_command, COMMAND_EXEC, - "disassemble Thumb2 instructions
[]"); - register_command(cmd_ctx, cortex_m3_cmd, "maskisr", - handle_cortex_m3_mask_interrupts_command, COMMAND_EXEC, - "mask cortex_m3 interrupts ['on'|'off']"); - register_command(cmd_ctx, cortex_m3_cmd, "vector_catch", - handle_cortex_m3_vector_catch_command, COMMAND_EXEC, - "catch hardware vectors ['all'|'none'|]"); - - return retval; -} +static const struct command_registration cortex_m3_exec_command_handlers[] = { + { + .name = "disassemble", + .handler = &handle_cortex_m3_disassemble_command, + .mode = COMMAND_EXEC, + .help = "disassemble Thumb2 instructions", + .usage = "
[]", + }, + { + .name = "maskisr", + .handler = &handle_cortex_m3_mask_interrupts_command, + .mode = COMMAND_EXEC, + .help = "mask cortex_m3 interrupts", + .usage = "['on'|'off']", + }, + { + .name = "vector_catch", + .handler = &handle_cortex_m3_vector_catch_command, + .mode = COMMAND_EXEC, + .help = "catch hardware vectors", + .usage = "['all'|'none'|]", + }, + COMMAND_REGISTRATION_DONE +}; +static const struct command_registration cortex_m3_command_handlers[] = { + { + .chain = armv7m_command_handlers, + }, + { + .name = "cortex_m3", + .mode = COMMAND_ANY, + .help = "Cortex-M3 command group", + .chain = cortex_m3_exec_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; struct target_type cortexm3_target = { @@ -1985,7 +1976,7 @@ struct target_type cortexm3_target = .add_watchpoint = cortex_m3_add_watchpoint, .remove_watchpoint = cortex_m3_remove_watchpoint, - .register_commands = cortex_m3_register_commands, + .commands = cortex_m3_command_handlers, .target_create = cortex_m3_target_create, .init_target = cortex_m3_init_target, .examine = cortex_m3_examine,