+ target_t *target = get_current_target(cmd_ctx);
+ struct cortex_m3_common_s *cortex_m3 = target_to_cm3(target);
+ uint32_t address;
+ unsigned long count = 1;
+ arm_instruction_t cur_instruction;
+
+ retval = cortex_m3_verify_pointer(cmd_ctx, cortex_m3);
+ if (retval != ERROR_OK)
+ return retval;
+
+ errno = 0;
+ switch (argc) {
+ case 2:
+ COMMAND_PARSE_NUMBER(ulong, args[1], count);
+ /* FALL THROUGH */
+ case 1:
+ COMMAND_PARSE_NUMBER(u32, args[0], address);
+ break;
+ default:
+ command_print(cmd_ctx,
+ "usage: cortex_m3 disassemble <address> [<count>]");
+ return ERROR_OK;
+ }
+
+ while (count--) {
+ retval = thumb2_opcode(target, address, &cur_instruction);
+ if (retval != ERROR_OK)
+ return retval;
+ command_print(cmd_ctx, "%s", cur_instruction.text);
+ address += cur_instruction.instruction_size;
+ }
+
+ return ERROR_OK;
+}
+
+static const struct {
+ char name[10];
+ unsigned mask;
+} vec_ids[] = {
+ { "hard_err", VC_HARDERR, },
+ { "int_err", VC_INTERR, },
+ { "bus_err", VC_BUSERR, },
+ { "state_err", VC_STATERR, },
+ { "chk_err", VC_CHKERR, },
+ { "nocp_err", VC_NOCPERR, },
+ { "mm_err", VC_MMERR, },
+ { "reset", VC_CORERESET, },
+};
+
+COMMAND_HANDLER(handle_cortex_m3_vector_catch_command)
+{
+ target_t *target = get_current_target(cmd_ctx);
+ struct cortex_m3_common_s *cortex_m3 = target_to_cm3(target);
+ struct armv7m_common_s *armv7m = &cortex_m3->armv7m;
+ swjdp_common_t *swjdp = &armv7m->swjdp_info;
+ uint32_t demcr = 0;
+ int retval;
+ int i;
+
+ 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) {
+ unsigned catch = 0;
+
+ if (argc == 1) {
+ if (strcmp(args[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) {
+ goto write;
+ }
+ }
+ while (argc-- > 0) {
+ for (i = 0; i < ARRAY_SIZE(vec_ids); i++) {
+ if (strcmp(args[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]);
+ return ERROR_INVALID_ARGUMENTS;
+ }
+ }
+write:
+ demcr &= ~0xffff;
+ demcr |= catch;
+
+ /* write, but don't assume it stuck */
+ mem_ap_write_u32(swjdp, DCB_DEMCR, demcr);
+ 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,
+ (demcr & vec_ids[i].mask) ? "catch" : "ignore");
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command)
+{
+ target_t *target = get_current_target(cmd_ctx);
+ struct cortex_m3_common_s *cortex_m3 = target_to_cm3(target);
+ int retval;
+
+ 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);
+ return ERROR_OK;
+ }
+
+ if (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']");
+ }
+ }
+
+ 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_s *cmd_ctx)
+{
+ int retval;
+ command_t *cortex_m3_cmd;
+