+ 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);
+ if (retval != ERROR_OK)
+ return retval;
+
+ errno = 0;
+ switch (CMD_ARGC) {
+ case 2:
+ COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], count);
+ /* FALL THROUGH */
+ case 1:
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[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)
+{
+ 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;
+
+ 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 (CMD_ARGC > 0) {
+ unsigned catch = 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(CMD_ARGV[0], "none") == 0) {
+ goto write;
+ }
+ }
+ while (CMD_ARGC-- > 0) {
+ unsigned i;
+ for (i = 0; i < ARRAY_SIZE(vec_ids); i++) {
+ 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'", CMD_ARGV[CMD_ARGC]);
+ return ERROR_INVALID_ARGUMENTS;
+ }
+ }
+write:
+ /* For now, armv7m->demcr only stores vector catch flags. */
+ armv7m->demcr = catch;
+
+ demcr &= ~0xffff;
+ demcr |= catch;
+
+ /* write, but don't assume it stuck (why not??) */
+ mem_ap_write_u32(swjdp, DCB_DEMCR, demcr);
+ mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &demcr);
+
+ /* FIXME be sure to clear DEMCR on clean server shutdown.
+ * Otherwise the vector catch hardware could fire when there's
+ * no debugger hooked up, causing much confusion...
+ */
+ }
+
+ 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;