109 uint64_t sel = (
reg & 0x000000F0) >> 4;
111 sel |= dap->
select & ~0xfULL;
172 uint32_t *dlpidr_ptr,
bool clear_sticky)
175 uint32_t dpidr, dlpidr;
224 " has version < 2. A non multidrop capable device connected?",
232 if (dlpidr != expected_dlpidr) {
233 LOG_INFO(
"Read incorrect DLPIDR 0x%08" PRIx32
234 " (possibly CTRL/STAT value)",
246 *dlpidr_ptr = dlpidr;
260 for (
unsigned int retry = 0; ; retry++) {
261 bool clear_sticky = retry > 0;
273 LOG_DEBUG(
"Failed to select multidrop %s, retrying...",
285 uint32_t dpidr = 0xdeadbeef;
286 uint32_t dlpidr = 0xdeadbeef;
312 LOG_INFO(
"SWD DPIDR 0x%08" PRIx32
", DLPIDR 0x%08" PRIx32,
321 uint32_t dpidr = 0xdeadbeef;
366 LOG_ERROR(
"Error connecting DP: cannot read IDR");
370 LOG_INFO(
"SWD DPIDR 0x%08" PRIx32, dpidr);
405 LOG_WARNING(
"\'srst_nogate\' reset_config option is required");
423 LOG_WARNING(
"Connecting DP: stalled AP operation, issuing ABORT");
506 if (sel == (dap->
select & ~0xfULL))
662 .help =
"declare a new SWD DAP"
671 .help =
"SWD command group",
697 retval = swd->
init();
struct adapter_driver * adapter_driver
static int swd_multidrop_select(struct adiv5_dap *dap)
const struct dap_ops swd_dap_ops
static int swd_connect_single(struct adiv5_dap *dap)
static int swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned reg)
Select the AP register bank matching bits 7:4 of reg.
static int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
static const struct command_registration swd_commands[]
static void swd_clear_sticky_errors(struct adiv5_dap *dap)
static int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
static int check_sync(struct adiv5_dap *dap)
static int swd_queue_ap_write(struct adiv5_ap *ap, unsigned reg, uint32_t data)
static int swd_run_inner(struct adiv5_dap *dap)
static int swd_connect(struct adiv5_dap *dap)
static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg, uint32_t *data)
static int swd_connect_multidrop(struct adiv5_dap *dap)
static int swd_init(struct command_context *ctx)
static int swd_run(struct adiv5_dap *dap)
Executes all queued DAP operations.
static int swd_select(struct command_context *ctx)
static void swd_finish_read(struct adiv5_dap *dap)
static int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned int reg)
Select the DP register bank matching bits 7:4 of reg.
static int swd_queue_dp_read_inner(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
static struct transport swd_transport
bool transport_is_swd(void)
Returns true if the current debug session is using SWD as its transport.
static int swd_queue_ap_read(struct adiv5_ap *ap, unsigned reg, uint32_t *data)
static int swd_check_reconnect(struct adiv5_dap *dap)
static int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
static void swd_quit(struct adiv5_dap *dap)
Put the SWJ-DP back to JTAG mode.
static int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg, uint32_t data)
static const struct command_registration swd_handlers[]
static struct adiv5_dap * swd_multidrop_selected_dap
static int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr, uint32_t *dlpidr_ptr, bool clear_sticky)
static void swd_constructor(void)
Holds the interface to ARM cores.
int dap_dp_init(struct adiv5_dap *dap)
Initialize a DAP.
void dap_invalidate_cache(struct adiv5_dap *dap)
Invalidate cached DP select and cached TAR and CSW of all APs.
This defines formats and data structures used to talk to ADIv5 entities.
const struct swd_driver * adiv5_dap_swd_driver(struct adiv5_dap *self)
#define DP_TARGETSEL_INSTANCEID_MASK
#define DP_SELECT_INVALID
#define DP_DLPIDR_PROTVSN
#define DP_DPIDR_VERSION_MASK
const char * adiv5_dap_name(struct adiv5_dap *self)
static bool is_adiv6(const struct adiv5_dap *dap)
Check if DAP is ADIv6.
#define DP_DPIDR_VERSION_SHIFT
static bool dap_is_multidrop(struct adiv5_dap *dap)
Check if SWD multidrop configuration is valid.
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
static int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends,...
struct esp_usb_jtag __attribute__
static enum reset_types jtag_reset_config
enum reset_types jtag_get_reset_config(void)
int adapter_assert_reset(void)
int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
void alive_sleep(uint64_t ms)
#define LOG_DEBUG_IO(expr ...)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
Represents a driver for a debugging interface.
const struct swd_driver * swd_ops
Low-level SWD APIs.
This represents an ARM Debug Interface (v5) Access Port (AP).
uint64_t ap_num
ADIv5: Number of this AP (0~255) ADIv6: Base address of this AP (4k aligned) TODO: to be more coheren...
struct adiv5_dap * dap
DAP this AP belongs to.
uint32_t memaccess_tck
Configures how many extra tck clocks are added after starting a MEM-AP access before we try to read i...
This represents an ARM Debug Interface (v5) Debug Access Port (DAP).
struct adiv5_ap ap[DP_APSEL_MAX+1]
bool do_reconnect
Signals that an attempt to reestablish communication afresh should be performed before the next acces...
uint32_t * last_read
Holds the pointer to the destination word for the last queued read, for use with posted AP read seque...
bool switch_through_dormant
Record if enter in SWD required passing through DORMANT.
uint32_t multidrop_targetsel
Value to select DP in SWD multidrop mode or DP_TARGETSEL_INVALID.
uint64_t select
Cache for DP_SELECT register.
const char * usage
a string listing the options and arguments, required or optional
Transport-neutral representation of queued DAP transactions, supporting both JTAG and SWD transports.
int(* connect)(struct adiv5_dap *dap)
connect operation for SWD
int(* switch_seq)(enum swd_special_seq seq)
Queue a special SWDIO sequence.
void(* read_reg)(uint8_t cmd, uint32_t *value, uint32_t ap_delay_hint)
Queued read of an AP or DP register.
int(* init)(void)
Initialize the debug link so it can perform SWD operations.
int(* run)(void)
Execute any queued transactions and collect the result.
void(* write_reg)(uint8_t cmd, uint32_t value, uint32_t ap_delay_hint)
Queued write of an AP or DP register.
Wrapper for transport lifecycle operations.
const char * name
Each transport has a unique name, used to select it from among the alternatives.
static uint8_t swd_cmd(bool is_read, bool is_ap, uint8_t regnum)
Construct a "cmd" byte, in lSB bit order, which swd_driver.read_reg() and swd_driver....
struct transport * get_current_transport(void)
Returns the transport currently being used by this debug or programming session.
int transport_register(struct transport *new_transport)
Registers a transport.