cortexm: use Cortex-M rather than cortex-m3 for dwt registers
[openocd.git] / src / target / cortex_m.c
index 3b4629730f27d3535a4da800bcfd45c32f70f5a9..dc8d344401abe7d83f0db75d7b379b4f45489f61 100644 (file)
 static int cortex_m_store_core_reg_u32(struct target *target,
                uint32_t num, uint32_t value);
 
-static int cortexm_dap_read_coreregister_u32(struct adiv5_dap *swjdp,
+static int cortexm_dap_read_coreregister_u32(struct target *target,
        uint32_t *value, int regnum)
 {
+       struct armv7m_common *armv7m = target_to_armv7m(target);
+       struct adiv5_dap *swjdp = armv7m->arm.dap;
        int retval;
        uint32_t dcrdr;
 
        /* because the DCB_DCRDR is used for the emulated dcc channel
         * we have to save/restore the DCB_DCRDR when used */
+       if (target->dbg_msg_enabled) {
+               retval = mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
 
-       retval = mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
-       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
-       if (retval != ERROR_OK)
-               return retval;
-       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); */
-       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
-       if (retval != ERROR_OK)
-               return retval;
-       retval = dap_queue_ap_read(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value);
+       retval = mem_ap_write_u32(swjdp, DCB_DCRSR, regnum);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = dap_run(swjdp);
+       retval = mem_ap_read_atomic_u32(swjdp, DCB_DCRDR, value);
        if (retval != ERROR_OK)
                return retval;
 
-       /* restore DCB_DCRDR - this needs to be in a seperate
-        * transaction otherwise the emulated DCC channel breaks */
-       if (retval == ERROR_OK)
-               retval = mem_ap_write_atomic_u32(swjdp, DCB_DCRDR, dcrdr);
+       if (target->dbg_msg_enabled) {
+               /* restore DCB_DCRDR - this needs to be in a separate
+                * transaction otherwise the emulated DCC channel breaks */
+               if (retval == ERROR_OK)
+                       retval = mem_ap_write_atomic_u32(swjdp, DCB_DCRDR, dcrdr);
+       }
 
        return retval;
 }
 
-static int cortexm_dap_write_coreregister_u32(struct adiv5_dap *swjdp,
+static int cortexm_dap_write_coreregister_u32(struct target *target,
        uint32_t value, int regnum)
 {
+       struct armv7m_common *armv7m = target_to_armv7m(target);
+       struct adiv5_dap *swjdp = armv7m->arm.dap;
        int retval;
        uint32_t dcrdr;
 
        /* because the DCB_DCRDR is used for the emulated dcc channel
         * we have to save/restore the DCB_DCRDR when used */
+       if (target->dbg_msg_enabled) {
+               retval = mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
 
-       retval = mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
-       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
-       if (retval != ERROR_OK)
-               return retval;
-       retval = dap_queue_ap_write(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value);
-       if (retval != ERROR_OK)
-               return retval;
-
-       /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
-       retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
-       if (retval != ERROR_OK)
-               return retval;
-       retval = dap_queue_ap_write(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum | DCRSR_WnR);
+       retval = mem_ap_write_u32(swjdp, DCB_DCRDR, value);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = dap_run(swjdp);
+       retval = mem_ap_write_atomic_u32(swjdp, DCB_DCRSR, regnum | DCRSR_WnR);
        if (retval != ERROR_OK)
                return retval;
 
-       /* restore DCB_DCRDR - this needs to be in a seperate
-        * transaction otherwise the emulated DCC channel breaks */
-       if (retval == ERROR_OK)
-               retval = mem_ap_write_atomic_u32(swjdp, DCB_DCRDR, dcrdr);
+       if (target->dbg_msg_enabled) {
+               /* restore DCB_DCRDR - this needs to be in a seperate
+                * transaction otherwise the emulated DCC channel breaks */
+               if (retval == ERROR_OK)
+                       retval = mem_ap_write_atomic_u32(swjdp, DCB_DCRDR, dcrdr);
+       }
 
        return retval;
 }
@@ -214,6 +200,24 @@ static int cortex_m_single_step_core(struct target *target)
        return ERROR_OK;
 }
 
+static int cortex_m_enable_fpb(struct target *target)
+{
+       int retval = target_write_u32(target, FP_CTRL, 3);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* check the fpb is actually enabled */
+       uint32_t fpctrl;
+       retval = target_read_u32(target, FP_CTRL, &fpctrl);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (fpctrl & 1)
+               return ERROR_OK;
+
+       return ERROR_FAIL;
+}
+
 static int cortex_m_endreset_event(struct target *target)
 {
        int i;
@@ -265,9 +269,11 @@ static int cortex_m_endreset_event(struct target *target)
         */
 
        /* Enable FPB */
-       retval = target_write_u32(target, FP_CTRL, 3);
-       if (retval != ERROR_OK)
+       retval = cortex_m_enable_fpb(target);
+       if (retval != ERROR_OK) {
+               LOG_ERROR("Failed to enable the FPB");
                return retval;
+       }
 
        cortex_m->fpb_enabled = 1;
 
@@ -751,7 +757,7 @@ static int cortex_m_resume(struct target *target, int current,
                /* Single step past breakpoint at current address */
                breakpoint = breakpoint_find(target, resume_pc);
                if (breakpoint) {
-                       LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
+                       LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %" PRIu32 ")",
                                breakpoint->address,
                                breakpoint->unique_id);
                        cortex_m_unset_breakpoint(target, breakpoint);
@@ -1109,7 +1115,7 @@ int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint
        struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;
 
        if (breakpoint->set) {
-               LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint->unique_id);
+               LOG_WARNING("breakpoint (BPID: %" PRIu32 ") already set", breakpoint->unique_id);
                return ERROR_OK;
        }
 
@@ -1134,7 +1140,13 @@ int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint
                        comparator_list[fp_num].fpcr_value);
                if (!cortex_m->fpb_enabled) {
                        LOG_DEBUG("FPB wasn't enabled, do it now");
-                       target_write_u32(target, FP_CTRL, 3);
+                       retval = cortex_m_enable_fpb(target);
+                       if (retval != ERROR_OK) {
+                               LOG_ERROR("Failed to enable the FPB");
+                               return retval;
+                       }
+
+                       cortex_m->fpb_enabled = 1;
                }
        } else if (breakpoint->type == BKPT_SOFT) {
                uint8_t code[4];
@@ -1159,7 +1171,7 @@ int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint
                breakpoint->set = true;
        }
 
-       LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
+       LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
                breakpoint->unique_id,
                (int)(breakpoint->type),
                breakpoint->address,
@@ -1180,7 +1192,7 @@ int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoi
                return ERROR_OK;
        }
 
-       LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
+       LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
                breakpoint->unique_id,
                (int)(breakpoint->type),
                breakpoint->address,
@@ -1454,8 +1466,6 @@ static int cortex_m_load_core_reg_u32(struct target *target,
                uint32_t num, uint32_t *value)
 {
        int retval;
-       struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct adiv5_dap *swjdp = armv7m->arm.dap;
 
        /* NOTE:  we "know" here that the register identifiers used
         * in the v7m header match the Cortex-M3 Debug Core Register
@@ -1464,7 +1474,7 @@ static int cortex_m_load_core_reg_u32(struct target *target,
        switch (num) {
                case 0 ... 18:
                        /* read a normal core register */
-                       retval = cortexm_dap_read_coreregister_u32(swjdp, value, num);
+                       retval = cortexm_dap_read_coreregister_u32(target, value, num);
 
                        if (retval != ERROR_OK) {
                                LOG_ERROR("JTAG failure %i", retval);
@@ -1481,7 +1491,7 @@ static int cortex_m_load_core_reg_u32(struct target *target,
                         * in one Debug Core register.  So say r0 and r2 docs;
                         * it was removed from r1 docs, but still works.
                         */
-                       cortexm_dap_read_coreregister_u32(swjdp, value, 20);
+                       cortexm_dap_read_coreregister_u32(target, value, 20);
 
                        switch (num) {
                                case ARMV7M_PRIMASK:
@@ -1517,7 +1527,6 @@ static int cortex_m_store_core_reg_u32(struct target *target,
        int retval;
        uint32_t reg;
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct adiv5_dap *swjdp = armv7m->arm.dap;
 
        /* NOTE:  we "know" here that the register identifiers used
         * in the v7m header match the Cortex-M3 Debug Core Register
@@ -1525,7 +1534,7 @@ static int cortex_m_store_core_reg_u32(struct target *target,
         */
        switch (num) {
                case 0 ... 18:
-                       retval = cortexm_dap_write_coreregister_u32(swjdp, value, num);
+                       retval = cortexm_dap_write_coreregister_u32(target, value, num);
                        if (retval != ERROR_OK) {
                                struct reg *r;
 
@@ -1545,7 +1554,7 @@ static int cortex_m_store_core_reg_u32(struct target *target,
                         * in one Debug Core register.  So say r0 and r2 docs;
                         * it was removed from r1 docs, but still works.
                         */
-                       cortexm_dap_read_coreregister_u32(swjdp, &reg, 20);
+                       cortexm_dap_read_coreregister_u32(target, &reg, 20);
 
                        switch (num) {
                                case ARMV7M_PRIMASK:
@@ -1565,7 +1574,7 @@ static int cortex_m_store_core_reg_u32(struct target *target,
                                        break;
                        }
 
-                       cortexm_dap_write_coreregister_u32(swjdp, reg, 20);
+                       cortexm_dap_write_coreregister_u32(target, reg, 20);
 
                        LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
                        break;
@@ -1719,7 +1728,7 @@ fail1:
                free(cm->dwt_comparator_list);
                goto fail0;
        }
-       cache->name = "cortex-m3 dwt registers";
+       cache->name = "Cortex-M DWT registers";
        cache->num_regs = 2 + cm->dwt_num_comp * 3;
        cache->reg_list = calloc(cache->num_regs, sizeof *cache->reg_list);
        if (!cache->reg_list) {
@@ -1853,12 +1862,19 @@ int cortex_m_examine(struct target *target)
        return ERROR_OK;
 }
 
-static int cortex_m_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *ctrl)
+static int cortex_m_dcc_read(struct target *target, uint8_t *value, uint8_t *ctrl)
 {
+       struct armv7m_common *armv7m = target_to_armv7m(target);
+       struct adiv5_dap *swjdp = armv7m->arm.dap;
        uint16_t dcrdr;
+       uint8_t buf[2];
        int retval;
 
-       mem_ap_read_buf_u16(swjdp, (uint8_t *)&dcrdr, 2, DCB_DCRDR);
+       retval = mem_ap_read(swjdp, buf, 2, 1, DCB_DCRDR, false);
+       if (retval != ERROR_OK)
+               return retval;
+
+       dcrdr = target_buffer_get_u16(target, buf);
        *ctrl = (uint8_t)dcrdr;
        *value = (uint8_t)(dcrdr >> 8);
 
@@ -1867,8 +1883,8 @@ static int cortex_m_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *c
        /* write ack back to software dcc register
         * signify we have read data */
        if (dcrdr & (1 << 0)) {
-               dcrdr = 0;
-               retval = mem_ap_write_buf_u16(swjdp, (uint8_t *)&dcrdr, 2, DCB_DCRDR);
+               target_buffer_set_u16(target, buf, 0);
+               retval = mem_ap_write(swjdp, buf, 2, 1, DCB_DCRDR, false);
                if (retval != ERROR_OK)
                        return retval;
        }
@@ -1879,14 +1895,12 @@ static int cortex_m_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *c
 static int cortex_m_target_request_data(struct target *target,
        uint32_t size, uint8_t *buffer)
 {
-       struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct adiv5_dap *swjdp = armv7m->arm.dap;
        uint8_t data;
        uint8_t ctrl;
        uint32_t i;
 
        for (i = 0; i < (size * 4); i++) {
-               cortex_m_dcc_read(swjdp, &data, &ctrl);
+               cortex_m_dcc_read(target, &data, &ctrl);
                buffer[i] = data;
        }
 
@@ -1898,8 +1912,6 @@ static int cortex_m_handle_target_request(void *priv)
        struct target *target = priv;
        if (!target_was_examined(target))
                return ERROR_OK;
-       struct armv7m_common *armv7m = target_to_armv7m(target);
-       struct adiv5_dap *swjdp = armv7m->arm.dap;
 
        if (!target->dbg_msg_enabled)
                return ERROR_OK;
@@ -1908,7 +1920,7 @@ static int cortex_m_handle_target_request(void *priv)
                uint8_t data;
                uint8_t ctrl;
 
-               cortex_m_dcc_read(swjdp, &data, &ctrl);
+               cortex_m_dcc_read(target, &data, &ctrl);
 
                /* check if we have data */
                if (ctrl & (1 << 0)) {
@@ -1916,11 +1928,11 @@ static int cortex_m_handle_target_request(void *priv)
 
                        /* we assume target is quick enough */
                        request = data;
-                       cortex_m_dcc_read(swjdp, &data, &ctrl);
+                       cortex_m_dcc_read(target, &data, &ctrl);
                        request |= (data << 8);
-                       cortex_m_dcc_read(swjdp, &data, &ctrl);
+                       cortex_m_dcc_read(target, &data, &ctrl);
                        request |= (data << 16);
-                       cortex_m_dcc_read(swjdp, &data, &ctrl);
+                       cortex_m_dcc_read(target, &data, &ctrl);
                        request |= (data << 24);
                        target_request(target, request);
                }

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)