* This file implements support for the ARM Debug Interface version 5 (ADIv5)
* debugging architecture. Compared with previous versions, this includes
* a low pin-count Serial Wire Debug (SWD) alternative to JTAG for message
- * transport, and focusses on memory mapped resources as defined by the
+ * transport, and focuses on memory mapped resources as defined by the
* CoreSight architecture.
*
* A key concept in ADIv5 is the Debug Access Port, or DAP. A DAP has two
* @param buffer The data buffer to receive the data. No particular alignment is assumed.
* @param size Which access size to use, in bytes. 1, 2 or 4.
* @param count The number of reads to do (in size units, not bytes).
- * @param address Address to be read; it must be readable by the currently selected MEM-AP.
+ * @param adr Address to be read; it must be readable by the currently selected MEM-AP.
* @param addrinc Whether the target address should be increased after each read or not. This
* should normally be true, except when reading from e.g. a FIFO.
* @return ERROR_OK on success, otherwise an error code.
LOG_DEBUG("%s", adiv5_dap_name(dap));
+ dap->do_reconnect = false;
dap_invalidate_cache(dap);
/*
* Early initialize dap->dp_ctrl_stat.
- * In jtag mode only, if the following atomic reads fail and set the
- * sticky error, it will trigger the clearing of the sticky. Without this
- * initialization system and debug power would be disabled while clearing
- * the sticky error bit.
+ * In jtag mode only, if the following queue run (in dap_dp_poll_register)
+ * fails and sets the sticky error, it will trigger the clearing
+ * of the sticky. Without this initialization system and debug power
+ * would be disabled while clearing the sticky error bit.
*/
dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;
- for (size_t i = 0; i < 30; i++) {
- /* DP initialization */
-
- retval = dap_dp_read_atomic(dap, DP_CTRL_STAT, NULL);
- if (retval == ERROR_OK)
- break;
- }
-
/*
* This write operation clears the sticky error bit in jtag mode only and
* is ignored in swd mode. It also powers-up system and debug domains in
* both jtag and swd modes, if not done before.
- * Actually we do not need to clear the sticky error here because it has
- * been already cleared (if it was set) in the previous atomic read. This
- * write could be removed, but this initial part of dap_dp_init() is the
- * result of years of fine tuning and there are strong concerns about any
- * unnecessary code change. It doesn't harm, so let's keep it here and
- * preserve the historical sequence of read/write operations!
*/
retval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat | SSTICKYERR);
if (retval != ERROR_OK)
return retval;
}
+/**
+ * Initialize a DAP or do reconnect if DAP is not accessible.
+ *
+ * @param dap The DAP being initialized.
+ */
+int dap_dp_init_or_reconnect(struct adiv5_dap *dap)
+{
+ LOG_DEBUG("%s", adiv5_dap_name(dap));
+
+ /*
+ * Early initialize dap->dp_ctrl_stat.
+ * In jtag mode only, if the following atomic reads fail and set the
+ * sticky error, it will trigger the clearing of the sticky. Without this
+ * initialization system and debug power would be disabled while clearing
+ * the sticky error bit.
+ */
+ dap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;
+
+ dap->do_reconnect = false;
+
+ dap_dp_read_atomic(dap, DP_CTRL_STAT, NULL);
+ if (dap->do_reconnect) {
+ /* dap connect calls dap_dp_init() after transport dependent initialization */
+ return dap->ops->connect(dap);
+ } else {
+ return dap_dp_init(dap);
+ }
+}
+
/**
* Initialize a DAP. This sets up the power domains, prepares the DP
* for further use, and arranges to use AP #0 for all AP operations
CFG_DAP,
CFG_AP_NUM,
CFG_BASEADDR,
+ CFG_CTIBASE, /* DEPRECATED */
};
-static const Jim_Nvp nvp_config_opts[] = {
+static const struct jim_nvp nvp_config_opts[] = {
{ .name = "-dap", .value = CFG_DAP },
{ .name = "-ap-num", .value = CFG_AP_NUM },
{ .name = "-baseaddr", .value = CFG_BASEADDR },
+ { .name = "-ctibase", .value = CFG_CTIBASE }, /* DEPRECATED */
{ .name = NULL, .value = -1 }
};
-static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi,
+static int adiv5_jim_spot_configure(struct jim_getopt_info *goi,
struct adiv5_dap **dap_p, int *ap_num_p, uint32_t *base_p)
{
if (!goi->argc)
Jim_SetEmptyResult(goi->interp);
- Jim_Nvp *n;
- int e = Jim_Nvp_name2value_obj(goi->interp, nvp_config_opts,
+ struct jim_nvp *n;
+ int e = jim_nvp_name2value_obj(goi->interp, nvp_config_opts,
goi->argv[0], &n);
if (e != JIM_OK)
return JIM_CONTINUE;
/* base_p can be NULL, then '-baseaddr' option is treated as unknown */
- if (!base_p && n->value == CFG_BASEADDR)
+ if (!base_p && (n->value == CFG_BASEADDR || n->value == CFG_CTIBASE))
return JIM_CONTINUE;
- e = Jim_GetOpt_Obj(goi, NULL);
+ e = jim_getopt_obj(goi, NULL);
if (e != JIM_OK)
return e;
if (goi->isconfigure) {
Jim_Obj *o_t;
struct adiv5_dap *dap;
- e = Jim_GetOpt_Obj(goi, &o_t);
+ e = jim_getopt_obj(goi, &o_t);
if (e != JIM_OK)
return e;
dap = dap_instance_by_jim_obj(goi->interp, o_t);
case CFG_AP_NUM:
if (goi->isconfigure) {
jim_wide ap_num;
- e = Jim_GetOpt_Wide(goi, &ap_num);
+ e = jim_getopt_wide(goi, &ap_num);
if (e != JIM_OK)
return e;
if (ap_num < 0 || ap_num > DP_APSEL_MAX) {
}
break;
+ case CFG_CTIBASE:
+ LOG_WARNING("DEPRECATED! use \'-baseaddr' not \'-ctibase\'");
+ /* fall through */
case CFG_BASEADDR:
if (goi->isconfigure) {
jim_wide base;
- e = Jim_GetOpt_Wide(goi, &base);
+ e = jim_getopt_wide(goi, &base);
if (e != JIM_OK)
return e;
*base_p = (uint32_t)base;
return JIM_ERR;
}
-int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi)
+int adiv5_jim_configure(struct target *target, struct jim_getopt_info *goi)
{
struct adiv5_private_config *pc;
int e;
}
int adiv5_jim_mem_ap_spot_configure(struct adiv5_mem_ap_spot *cfg,
- Jim_GetOptInfo *goi)
+ struct jim_getopt_info *goi)
{
return adiv5_jim_spot_configure(goi, &cfg->dap, &cfg->ap_num, &cfg->base);
}