X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fcortex_m.c;h=dc8d344401abe7d83f0db75d7b379b4f45489f61;hp=3b4629730f27d3535a4da800bcfd45c32f70f5a9;hb=c46dd490d1a26fee57ff1f32781175ad64b72e86;hpb=1c975fe30b8fb380907133462cc38a0b2e9de565 diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 3b4629730f..dc8d344401 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -62,84 +62,70 @@ 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, ®, 20); + cortexm_dap_read_coreregister_u32(target, ®, 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); }