static int swd_connect(struct adiv5_dap *dap)
{
- uint32_t idcode;
+ uint32_t dpidr;
int status;
/* FIXME validate transport config ... is the
* configured DAP present (check IDCODE)?
* Is *only* one DAP configured?
*
- * MUST READ IDCODE
+ * MUST READ DPIDR
*/
/* Note, debugport_init() does setup too */
jtag_interface->swd->switch_seq(JTAG_TO_SWD);
- /* Make sure we don't try to perform any other accesses before the DPIDR read. */
+ /* Clear link state, including the SELECT cache. */
dap->do_reconnect = false;
- dap->select = 0;
+ dap->select = DP_SELECT_INVALID;
- swd_queue_dp_read(dap, DP_IDCODE, &idcode);
+ swd_queue_dp_read(dap, DP_DPIDR, &dpidr);
/* force clear all sticky faults */
swd_clear_sticky_errors(dap);
status = swd_run_inner(dap);
if (status == ERROR_OK) {
- LOG_INFO("SWD IDCODE %#8.8" PRIx32, idcode);
+ LOG_INFO("SWD DPIDR %#8.8" PRIx32, dpidr);
dap->do_reconnect = false;
} else
dap->do_reconnect = true;
/** Select the DP register bank matching bits 7:4 of reg. */
static void swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned reg)
{
- if (reg == DP_SELECT)
+ /* Only register address 4 is banked. */
+ if ((reg & 0xf) != 4)
return;
uint32_t select_dp_bank = (reg & 0x000000F0) >> 4;
- uint32_t select = select_dp_bank
+ uint32_t sel = select_dp_bank
| (dap->select & (DP_SELECT_APSEL | DP_SELECT_APBANK));
- if (select == dap->select)
+ if (sel == dap->select)
return;
- dap->select = select;
+ dap->select = sel;
- swd_queue_dp_write(dap, DP_SELECT, select);
+ swd_queue_dp_write(dap, DP_SELECT, sel);
}
static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg,
static void swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned reg)
{
struct adiv5_dap *dap = ap->dap;
- uint32_t select = ((uint32_t)ap->ap_num << 24)
+ uint32_t sel = ((uint32_t)ap->ap_num << 24)
| (reg & 0x000000F0)
| (dap->select & DP_SELECT_DPBANK);
- if (select == dap->select)
+ if (sel == dap->select)
return;
- dap->select = select;
+ dap->select = sel;
- swd_queue_dp_write(dap, DP_SELECT, select);
+ swd_queue_dp_write(dap, DP_SELECT, sel);
}
static int swd_queue_ap_read(struct adiv5_ap *ap, unsigned reg,
return retval;
}
-COMMAND_HANDLER(handle_swd_wcr)
-{
- int retval;
- struct target *target = get_current_target(CMD_CTX);
- struct arm *arm = target_to_arm(target);
- struct adiv5_dap *dap = arm->dap;
- uint32_t wcr;
- unsigned trn, scale = 0;
-
- switch (CMD_ARGC) {
- /* no-args: just dump state */
- case 0:
- /*retval = swd_queue_dp_read(dap, DP_WCR, &wcr); */
- retval = dap_queue_dp_read(dap, DP_WCR, &wcr);
- if (retval == ERROR_OK)
- dap->ops->run(dap);
- if (retval != ERROR_OK) {
- LOG_ERROR("can't read WCR?");
- return retval;
- }
-
- command_print(CMD_CTX,
- "turnaround=%" PRIu32 ", prescale=%" PRIu32,
- WCR_TO_TRN(wcr),
- WCR_TO_PRESCALE(wcr));
- return ERROR_OK;
-
- case 2: /* TRN and prescale */
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], scale);
- if (scale > 7) {
- LOG_ERROR("prescale %d is too big", scale);
- return ERROR_FAIL;
- }
- /* FALL THROUGH */
-
- case 1: /* TRN only */
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], trn);
- if (trn < 1 || trn > 4) {
- LOG_ERROR("turnaround %d is invalid", trn);
- return ERROR_FAIL;
- }
-
- wcr = ((trn - 1) << 8) | scale;
- /* FIXME
- * write WCR ...
- * then, re-init adapter with new TRN
- */
- LOG_ERROR("can't yet modify WCR");
- return ERROR_FAIL;
-
- default: /* too many arguments */
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-}
-
static const struct command_registration swd_commands[] = {
{
/*
.mode = COMMAND_CONFIG,
.help = "declare a new SWD DAP"
},
- {
- .name = "wcr",
- .handler = handle_swd_wcr,
- .mode = COMMAND_ANY,
- .help = "display or update DAP's WCR register",
- .usage = "turnaround (1..4), prescale (0..7)",
- },
-
- /* REVISIT -- add a command for SWV trace on/off */
COMMAND_REGISTRATION_DONE
};