PIC32: add software reset support
[openocd.git] / src / target / cortex_m3.c
index 762e3184c901151aedc230f8011919c3f07def2e..7f6cbafa522b3f2ccd062a933bfe9211e2932c50 100644 (file)
@@ -38,7 +38,7 @@
 #include "arm_disassembler.h"
 #include "register.h"
 #include "arm_opcodes.h"
-
+#include "arm_semihosting.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.
@@ -59,7 +59,7 @@ 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);
 
-static int cortexm3_dap_read_coreregister_u32(struct swjdp_common *swjdp,
+static int cortexm3_dap_read_coreregister_u32(struct adiv5_dap *swjdp,
                uint32_t *value, int regnum)
 {
        int retval;
@@ -70,17 +70,21 @@ static int cortexm3_dap_read_coreregister_u32(struct swjdp_common *swjdp,
 
        mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
 
-       swjdp->trans_mode = TRANS_MODE_COMPOSITE;
-
        /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
        dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
-       dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum);
+       retval = dap_queue_ap_write(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
        dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
-       dap_ap_read_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value);
+       retval = dap_queue_ap_read(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value);
+       if (retval != ERROR_OK)
+               return retval;
 
-       retval = swjdp_transaction_endcheck(swjdp);
+       retval = dap_run(swjdp);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* restore DCB_DCRDR - this needs to be in a seperate
         * transaction otherwise the emulated DCC channel breaks */
@@ -90,7 +94,7 @@ static int cortexm3_dap_read_coreregister_u32(struct swjdp_common *swjdp,
        return retval;
 }
 
-static int cortexm3_dap_write_coreregister_u32(struct swjdp_common *swjdp,
+static int cortexm3_dap_write_coreregister_u32(struct adiv5_dap *swjdp,
                uint32_t value, int regnum)
 {
        int retval;
@@ -101,17 +105,17 @@ static int cortexm3_dap_write_coreregister_u32(struct swjdp_common *swjdp,
 
        mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
 
-       swjdp->trans_mode = TRANS_MODE_COMPOSITE;
-
        /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
        dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
-       dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value);
+       retval = dap_queue_ap_write(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value);
+       // XXX check retval
 
        /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
        dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
-       dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum | DCRSR_WnR);
+       retval = dap_queue_ap_write(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum | DCRSR_WnR);
+       // XXX check retval
 
-       retval = swjdp_transaction_endcheck(swjdp);
+       retval = dap_run(swjdp);
 
        /* restore DCB_DCRDR - this needs to be in a seperate
         * transaction otherwise the emulated DCC channel breaks */
@@ -125,7 +129,7 @@ static int cortex_m3_write_debug_halt_mask(struct target *target,
                uint32_t mask_on, uint32_t mask_off)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info;
+       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
 
        /* mask off status bits */
        cortex_m3->dcb_dhcsr &= ~((0xFFFF << 16) | mask_off);
@@ -138,7 +142,7 @@ static int cortex_m3_write_debug_halt_mask(struct target *target,
 static int cortex_m3_clear_halt(struct target *target)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info;
+       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
 
        /* clear step if any */
        cortex_m3_write_debug_halt_mask(target, C_HALT, C_STEP);
@@ -156,7 +160,7 @@ static int cortex_m3_clear_halt(struct target *target)
 static int cortex_m3_single_step_core(struct target *target)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info;
+       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
        uint32_t dhcsr_save;
 
        /* backup dhcsr reg */
@@ -183,10 +187,11 @@ static int cortex_m3_single_step_core(struct target *target)
 static int cortex_m3_endreset_event(struct target *target)
 {
        int i;
+       int retval;
        uint32_t dcb_demcr;
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct armv7m_common *armv7m = &cortex_m3->armv7m;
-       struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info;
+       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
        struct cortex_m3_fp_comparator *fp_list = cortex_m3->fp_comparator_list;
        struct cortex_m3_dwt_comparator *dwt_list = cortex_m3->dwt_comparator_list;
 
@@ -238,14 +243,16 @@ static int cortex_m3_endreset_event(struct target *target)
                target_write_u32(target, dwt_list[i].dwt_comparator_address + 8,
                                dwt_list[i].function);
        }
-       swjdp_transaction_endcheck(swjdp);
+       retval = dap_run(swjdp);
+       if (retval != ERROR_OK)
+               return retval;
 
        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);
 
-       return ERROR_OK;
+       return retval;
 }
 
 static int cortex_m3_examine_debug_reason(struct target *target)
@@ -279,7 +286,8 @@ static int cortex_m3_examine_exception_reason(struct target *target)
 {
        uint32_t shcsr, except_sr, cfsr = -1, except_ar = -1;
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct swjdp_common *swjdp = &armv7m->swjdp_info;
+       struct adiv5_dap *swjdp = &armv7m->dap;
+       int retval;
 
        mem_ap_read_u32(swjdp, NVIC_SHCSR, &shcsr);
        switch (armv7m->exception_number)
@@ -317,12 +325,33 @@ static int cortex_m3_examine_exception_reason(struct target *target)
                        except_sr = 0;
                        break;
        }
-       swjdp_transaction_endcheck(swjdp);
-       LOG_DEBUG("%s SHCSR 0x%" PRIx32 ", SR 0x%" PRIx32 ", CFSR 0x%" PRIx32 ", AR 0x%" PRIx32 "", armv7m_exception_string(armv7m->exception_number), \
-               shcsr, except_sr, cfsr, except_ar);
-       return ERROR_OK;
+       retval = dap_run(swjdp);
+       if (retval == ERROR_OK)
+               LOG_DEBUG("%s SHCSR 0x%" PRIx32 ", SR 0x%" PRIx32
+                       ", CFSR 0x%" PRIx32 ", AR 0x%" PRIx32,
+                       armv7m_exception_string(armv7m->exception_number),
+                       shcsr, except_sr, cfsr, except_ar);
+       return retval;
 }
 
+/* PSP is used in some thread modes */
+static const int armv7m_psp_reg_map[17] = {
+       ARMV7M_R0, ARMV7M_R1, ARMV7M_R2, ARMV7M_R3,
+       ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7,
+       ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11,
+       ARMV7M_R12, ARMV7M_PSP, ARMV7M_R14, ARMV7M_PC,
+       ARMV7M_xPSR,
+};
+
+/* MSP is used in handler and some thread modes */
+static const int armv7m_msp_reg_map[17] = {
+       ARMV7M_R0, ARMV7M_R1, ARMV7M_R2, ARMV7M_R3,
+       ARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7,
+       ARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11,
+       ARMV7M_R12, ARMV7M_MSP, ARMV7M_R14, ARMV7M_PC,
+       ARMV7M_xPSR,
+};
+
 static int cortex_m3_debug_entry(struct target *target)
 {
        int i;
@@ -330,7 +359,8 @@ static int cortex_m3_debug_entry(struct target *target)
        int retval;
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct armv7m_common *armv7m = &cortex_m3->armv7m;
-       struct swjdp_common *swjdp = &armv7m->swjdp_info;
+       struct arm *arm = &armv7m->arm;
+       struct adiv5_dap *swjdp = &armv7m->dap;
        struct reg *r;
 
        LOG_DEBUG(" ");
@@ -377,11 +407,27 @@ static int cortex_m3_debug_entry(struct target *target)
        {
                armv7m->core_mode = ARMV7M_MODE_HANDLER;
                armv7m->exception_number = (xPSR & 0x1FF);
+
+               arm->core_mode = ARM_MODE_HANDLER;
+               arm->map = armv7m_msp_reg_map;
        }
        else
        {
-               armv7m->core_mode = buf_get_u32(armv7m->core_cache
-                               ->reg_list[ARMV7M_CONTROL].value, 0, 1);
+               unsigned control = buf_get_u32(armv7m->core_cache
+                               ->reg_list[ARMV7M_CONTROL].value, 0, 2);
+
+               /* is this thread privileged? */
+               armv7m->core_mode = control & 1;
+               arm->core_mode = armv7m->core_mode
+                               ? ARM_MODE_USER_THREAD
+                               : ARM_MODE_THREAD;
+
+               /* which stack is it using? */
+               if (control & 2)
+                       arm->map = armv7m_psp_reg_map;
+               else
+                       arm->map = armv7m_msp_reg_map;
+
                armv7m->exception_number = 0;
        }
 
@@ -392,7 +438,7 @@ static int cortex_m3_debug_entry(struct target *target)
 
        LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s",
                armv7m_mode_strings[armv7m->core_mode],
-               *(uint32_t*)(armv7m->core_cache->reg_list[15].value),
+               *(uint32_t*)(arm->pc->value),
                target_state_name(target));
 
        if (armv7m->post_debug_entry)
@@ -406,7 +452,7 @@ static int cortex_m3_poll(struct target *target)
        int retval;
        enum target_state prev_target_state = target->state;
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info;
+       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
 
        /* Read from Debug Halting Control and Status Register */
        retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
@@ -416,6 +462,21 @@ static int cortex_m3_poll(struct target *target)
                return retval;
        }
 
+       /* Recover from lockup.  See ARMv7-M architecture spec,
+        * section B1.5.15 "Unrecoverable exception cases".
+        *
+        * REVISIT Is there a better way to report and handle this?
+        */
+       if (cortex_m3->dcb_dhcsr & S_LOCKUP) {
+               LOG_WARNING("%s -- clearing lockup after double fault",
+                               target_name(target));
+               cortex_m3_write_debug_halt_mask(target, C_HALT, 0);
+               target->debug_reason = DBG_REASON_DBGRQ;
+
+               /* refresh status bits */
+               mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
+       }
+
        if (cortex_m3->dcb_dhcsr & S_RESET_ST)
        {
                /* check if still in reset */
@@ -449,6 +510,9 @@ static int cortex_m3_poll(struct target *target)
                        if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
                                return retval;
 
+                       if (arm_semihosting(target, &retval) != 0)
+                               return retval;
+
                        target_call_event_callbacks(target, TARGET_EVENT_HALTED);
                }
                if (prev_target_state == TARGET_DEBUG_RUNNING)
@@ -523,7 +587,7 @@ static int cortex_m3_halt(struct target *target)
 static int cortex_m3_soft_reset_halt(struct target *target)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info;
+       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
        uint32_t dcb_dhcsr = 0;
        int retval, timeout = 0;
 
@@ -630,7 +694,7 @@ static int cortex_m3_resume(struct target *target, int current,
        }
 
        /* current = 1: continue on current pc, otherwise continue at <address> */
-       r = armv7m->core_cache->reg_list + 15;
+       r = armv7m->arm.pc;
        if (!current)
        {
                buf_set_u32(r->value, 0, 32, address);
@@ -697,9 +761,9 @@ static int cortex_m3_step(struct target *target, int current,
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
        struct armv7m_common *armv7m = &cortex_m3->armv7m;
-       struct swjdp_common *swjdp = &armv7m->swjdp_info;
+       struct adiv5_dap *swjdp = &armv7m->dap;
        struct breakpoint *breakpoint = NULL;
-       struct reg *pc = armv7m->core_cache->reg_list + 15;
+       struct reg *pc = armv7m->arm.pc;
        bool bkpt_inst_found = false;
 
        if (target->state != TARGET_HALTED)
@@ -762,7 +826,7 @@ static int cortex_m3_step(struct target *target, int current,
 static int cortex_m3_assert_reset(struct target *target)
 {
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info;
+       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
        int assert_srst = 1;
 
        LOG_DEBUG("target->state: %s",
@@ -1312,7 +1376,7 @@ static int cortex_m3_load_core_reg_u32(struct target *target,
 {
        int retval;
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct swjdp_common *swjdp = &armv7m->swjdp_info;
+       struct adiv5_dap *swjdp = &armv7m->dap;
 
        /* NOTE:  we "know" here that the register identifiers used
         * in the v7m header match the Cortex-M3 Debug Core Register
@@ -1376,7 +1440,7 @@ static int cortex_m3_store_core_reg_u32(struct target *target,
        int retval;
        uint32_t reg;
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct swjdp_common *swjdp = &armv7m->swjdp_info;
+       struct adiv5_dap *swjdp = &armv7m->dap;
 
 #ifdef ARMV7_GDB_HACKS
        /* If the LR register is being modified, make sure it will put us
@@ -1454,7 +1518,7 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address,
                uint32_t size, uint32_t count, uint8_t *buffer)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct swjdp_common *swjdp = &armv7m->swjdp_info;
+       struct adiv5_dap *swjdp = &armv7m->dap;
        int retval = ERROR_INVALID_ARGUMENTS;
 
        /* cortex_m3 handles unaligned memory access */
@@ -1479,7 +1543,7 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address,
                uint32_t size, uint32_t count, uint8_t *buffer)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct swjdp_common *swjdp = &armv7m->swjdp_info;
+       struct adiv5_dap *swjdp = &armv7m->dap;
        int retval = ERROR_INVALID_ARGUMENTS;
 
        if (count && buffer) {
@@ -1660,7 +1724,7 @@ static int cortex_m3_examine(struct target *target)
        uint32_t cpuid, fpcr;
        int i;
        struct cortex_m3_common *cortex_m3 = target_to_cm3(target);
-       struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info;
+       struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap;
 
        if ((retval = ahbap_debugport_init(swjdp)) != ERROR_OK)
                return retval;
@@ -1675,8 +1739,8 @@ static int cortex_m3_examine(struct target *target)
                        return retval;
 
                if (((cpuid >> 4) & 0xc3f) == 0xc23)
-                       LOG_DEBUG("Cortex-M3 r%dp%d processor detected",
-                               (cpuid >> 20) & 0xf, (cpuid >> 0) & 0xf);
+                       LOG_DEBUG("Cortex-M3 r%" PRId8 "p%" PRId8 " processor detected",
+                               (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf));
                LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
 
                /* NOTE: FPB and DWT are both optional. */
@@ -1709,7 +1773,7 @@ static int cortex_m3_examine(struct target *target)
        return ERROR_OK;
 }
 
-static int cortex_m3_dcc_read(struct swjdp_common *swjdp, uint8_t *value, uint8_t *ctrl)
+static int cortex_m3_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *ctrl)
 {
        uint16_t dcrdr;
 
@@ -1734,7 +1798,7 @@ static int cortex_m3_target_request_data(struct target *target,
                uint32_t size, uint8_t *buffer)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct swjdp_common *swjdp = &armv7m->swjdp_info;
+       struct adiv5_dap *swjdp = &armv7m->dap;
        uint8_t data;
        uint8_t ctrl;
        uint32_t i;
@@ -1754,7 +1818,7 @@ static int cortex_m3_handle_target_request(void *priv)
        if (!target_was_examined(target))
                return ERROR_OK;
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct swjdp_common *swjdp = &armv7m->swjdp_info;
+       struct adiv5_dap *swjdp = &armv7m->dap;
 
        if (!target->dbg_msg_enabled)
                return ERROR_OK;
@@ -1798,12 +1862,13 @@ static int cortex_m3_init_arch_info(struct target *target,
        cortex_m3->jtag_info.tap = tap;
        cortex_m3->jtag_info.scann_size = 4;
 
-       armv7m->swjdp_info.dp_select_value = -1;
-       armv7m->swjdp_info.ap_csw_value = -1;
-       armv7m->swjdp_info.ap_tar_value = -1;
-       armv7m->swjdp_info.jtag_info = &cortex_m3->jtag_info;
-       armv7m->swjdp_info.memaccess_tck = 8;
-       armv7m->swjdp_info.tar_autoincr_block = (1 << 12);      /* Cortex-M3 has 4096 bytes autoincrement range */
+       armv7m->arm.dap = &armv7m->dap;
+
+       /* Leave (only) generic DAP stuff for debugport_init(); */
+       armv7m->dap.jtag_info = &cortex_m3->jtag_info;
+       armv7m->dap.memaccess_tck = 8;
+       /* Cortex-M3 has 4096 bytes autoincrement range */
+       armv7m->dap.tar_autoincr_block = (1 << 12);
 
        /* register arch-specific functions */
        armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
@@ -1811,7 +1876,6 @@ static int cortex_m3_init_arch_info(struct target *target,
        armv7m->post_debug_entry = NULL;
 
        armv7m->pre_restore_context = NULL;
-       armv7m->post_restore_context = NULL;
 
        armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
        armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
@@ -1854,50 +1918,6 @@ static int cortex_m3_verify_pointer(struct command_context *cmd_ctx,
  * cortexm3_target structure, which is only used with CM3 targets.
  */
 
-/*
- * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well
- * as at least ARM-1156T2.  The interesting thing about Cortex-M is
- * that *only* Thumb2 disassembly matters.  There are also some small
- * additions to Thumb2 that are specific to ARMv7-M.
- */
-COMMAND_HANDLER(handle_cortex_m3_disassemble_command)
-{
-       int retval;
-       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;
@@ -1917,7 +1937,7 @@ 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;
+       struct adiv5_dap *swjdp = &armv7m->dap;
        uint32_t demcr = 0;
        int retval;
 
@@ -2011,13 +2031,6 @@ COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command)
 }
 
 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 = "address [count]",
-       },
        {
                .name = "maskisr",
                .handler = handle_cortex_m3_mask_interrupts_command,

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)