13 #ifndef OPENOCD_TARGET_ARM_ADI_V5_H
14 #define OPENOCD_TARGET_ARM_ADI_V5_H
31 #define SWD_ACK_OK 0x1
32 #define SWD_ACK_WAIT 0x2
33 #define SWD_ACK_FAULT 0x4
38 #define BANK_REG(bank, reg) (((bank) << 4) | (reg))
45 #define DP_DPIDR BANK_REG(0x0, 0x0)
46 #define DP_ABORT BANK_REG(0x0, 0x0)
47 #define DP_DPIDR1 BANK_REG(0x1, 0x0)
48 #define DP_BASEPTR0 BANK_REG(0x2, 0x0)
49 #define DP_BASEPTR1 BANK_REG(0x3, 0x0)
50 #define DP_CTRL_STAT BANK_REG(0x0, 0x4)
51 #define DP_DLCR BANK_REG(0x1, 0x4)
52 #define DP_TARGETID BANK_REG(0x2, 0x4)
53 #define DP_DLPIDR BANK_REG(0x3, 0x4)
54 #define DP_EVENTSTAT BANK_REG(0x4, 0x4)
55 #define DP_SELECT1 BANK_REG(0x5, 0x4)
56 #define DP_RESEND BANK_REG(0x0, 0x8)
57 #define DP_SELECT BANK_REG(0x0, 0x8)
58 #define DP_RDBUFF BANK_REG(0x0, 0xC)
59 #define DP_TARGETSEL BANK_REG(0x0, 0xC)
61 #define DLCR_TO_TRN(dlcr) ((uint32_t)(1 + ((3 & (dlcr)) >> 8)))
64 #define DP_DPIDR_VERSION_SHIFT 12
65 #define DP_DPIDR_VERSION_MASK (0xFUL << DP_DPIDR_VERSION_SHIFT)
68 #define DAPABORT (1UL << 0)
69 #define STKCMPCLR (1UL << 1)
70 #define STKERRCLR (1UL << 2)
71 #define WDERRCLR (1UL << 3)
72 #define ORUNERRCLR (1UL << 4)
75 #define DP_DPIDR1_ASIZE_MASK (0x7F)
76 #define DP_DPIDR1_ERRMODE BIT(7)
79 #define DP_BASEPTR0_VALID BIT(0)
82 #define CORUNDETECT (1UL << 0)
83 #define SSTICKYORUN (1UL << 1)
85 #define SSTICKYCMP (1UL << 4)
86 #define SSTICKYERR (1UL << 5)
87 #define READOK (1UL << 6)
88 #define WDATAERR (1UL << 7)
91 #define CDBGRSTREQ (1UL << 26)
92 #define CDBGRSTACK (1UL << 27)
93 #define CDBGPWRUPREQ (1UL << 28)
94 #define CDBGPWRUPACK (1UL << 29)
95 #define CSYSPWRUPREQ (1UL << 30)
96 #define CSYSPWRUPACK (1UL << 31)
98 #define DP_DLPIDR_PROTVSN 1u
100 #define ADIV5_DP_SELECT_APSEL 0xFF000000
101 #define ADIV5_DP_SELECT_APBANK 0x000000F0
102 #define DP_SELECT_DPBANK 0x0000000F
107 #define SELECT_AP_MASK (~(uint64_t)DP_SELECT_DPBANK)
109 #define DP_APSEL_MAX (255)
110 #define DP_APSEL_INVALID 0xF00
112 #define DP_TARGETSEL_INVALID 0xFFFFFFFFU
113 #define DP_TARGETSEL_DPID_MASK 0x0FFFFFFFU
114 #define DP_TARGETSEL_INSTANCEID_MASK 0xF0000000U
115 #define DP_TARGETSEL_INSTANCEID_SHIFT 28
119 #define ADIV5_MEM_AP_REG_CSW (0x00)
120 #define ADIV5_MEM_AP_REG_TAR (0x04)
121 #define ADIV5_MEM_AP_REG_TAR64 (0x08)
122 #define ADIV5_MEM_AP_REG_DRW (0x0C)
123 #define ADIV5_MEM_AP_REG_BD0 (0x10)
124 #define ADIV5_MEM_AP_REG_BD1 (0x14)
125 #define ADIV5_MEM_AP_REG_BD2 (0x18)
126 #define ADIV5_MEM_AP_REG_BD3 (0x1C)
127 #define ADIV5_MEM_AP_REG_MBT (0x20)
128 #define ADIV5_MEM_AP_REG_BASE64 (0xF0)
129 #define ADIV5_MEM_AP_REG_CFG (0xF4)
130 #define ADIV5_MEM_AP_REG_BASE (0xF8)
132 #define ADIV6_MEM_AP_REG_CSW (0xD00 + ADIV5_MEM_AP_REG_CSW)
133 #define ADIV6_MEM_AP_REG_TAR (0xD00 + ADIV5_MEM_AP_REG_TAR)
134 #define ADIV6_MEM_AP_REG_TAR64 (0xD00 + ADIV5_MEM_AP_REG_TAR64)
135 #define ADIV6_MEM_AP_REG_DRW (0xD00 + ADIV5_MEM_AP_REG_DRW)
136 #define ADIV6_MEM_AP_REG_BD0 (0xD00 + ADIV5_MEM_AP_REG_BD0)
137 #define ADIV6_MEM_AP_REG_BD1 (0xD00 + ADIV5_MEM_AP_REG_BD1)
138 #define ADIV6_MEM_AP_REG_BD2 (0xD00 + ADIV5_MEM_AP_REG_BD2)
139 #define ADIV6_MEM_AP_REG_BD3 (0xD00 + ADIV5_MEM_AP_REG_BD3)
140 #define ADIV6_MEM_AP_REG_MBT (0xD00 + ADIV5_MEM_AP_REG_MBT)
141 #define ADIV6_MEM_AP_REG_BASE64 (0xD00 + ADIV5_MEM_AP_REG_BASE64)
142 #define ADIV6_MEM_AP_REG_CFG (0xD00 + ADIV5_MEM_AP_REG_CFG)
143 #define ADIV6_MEM_AP_REG_BASE (0xD00 + ADIV5_MEM_AP_REG_BASE)
145 #define MEM_AP_REG_CSW(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_CSW : ADIV5_MEM_AP_REG_CSW)
146 #define MEM_AP_REG_TAR(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_TAR : ADIV5_MEM_AP_REG_TAR)
147 #define MEM_AP_REG_TAR64(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_TAR64 : ADIV5_MEM_AP_REG_TAR64)
148 #define MEM_AP_REG_DRW(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_DRW : ADIV5_MEM_AP_REG_DRW)
149 #define MEM_AP_REG_BD0(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD0 : ADIV5_MEM_AP_REG_BD0)
150 #define MEM_AP_REG_BD1(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD1 : ADIV5_MEM_AP_REG_BD1)
151 #define MEM_AP_REG_BD2(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD2 : ADIV5_MEM_AP_REG_BD2)
152 #define MEM_AP_REG_BD3(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD3 : ADIV5_MEM_AP_REG_BD3)
153 #define MEM_AP_REG_MBT(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_MBT : ADIV5_MEM_AP_REG_MBT)
154 #define MEM_AP_REG_BASE64(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BASE64 : ADIV5_MEM_AP_REG_BASE64)
155 #define MEM_AP_REG_CFG(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_CFG : ADIV5_MEM_AP_REG_CFG)
156 #define MEM_AP_REG_BASE(dap) (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BASE : ADIV5_MEM_AP_REG_BASE)
159 #define ADIV5_AP_REG_IDR (0xFC)
160 #define ADIV6_AP_REG_IDR (0xD00 + ADIV5_AP_REG_IDR)
161 #define AP_REG_IDR(dap) (is_adiv6(dap) ? ADIV6_AP_REG_IDR : ADIV5_AP_REG_IDR)
164 #define CSW_SIZE_MASK 7
171 #define CSW_ADDRINC_MASK (3UL << 4)
172 #define CSW_ADDRINC_OFF 0UL
173 #define CSW_ADDRINC_SINGLE (1UL << 4)
174 #define CSW_ADDRINC_PACKED (2UL << 4)
175 #define CSW_DEVICE_EN (1UL << 6)
176 #define CSW_TRIN_PROG (1UL << 7)
182 #define CSW_SPIDEN (1UL << 23)
183 #define CSW_DBGSWENABLE (1UL << 31)
186 #define CSW_AHB_HPROT1 (1UL << 25)
188 #define CSW_AHB_MASTER_DEBUG (1UL << 29)
191 #define CSW_AHB_SPROT (1UL << 30)
193 #define CSW_AHB_DEFAULT (CSW_AHB_HPROT1 | CSW_AHB_MASTER_DEBUG | CSW_DBGSWENABLE)
196 #define CSW_AXI_ARPROT0_PRIV (1UL << 28)
198 #define CSW_AXI_ARPROT1_NONSEC (1UL << 29)
200 #define CSW_AXI_DEFAULT (CSW_AXI_ARPROT0_PRIV | CSW_AXI_ARPROT1_NONSEC | CSW_DBGSWENABLE)
203 #define CSW_APB_DEFAULT (CSW_DBGSWENABLE)
206 #define MEM_AP_REG_CFG_BE BIT(0)
207 #define MEM_AP_REG_CFG_LA BIT(1)
208 #define MEM_AP_REG_CFG_LD BIT(2)
209 #define MEM_AP_REG_CFG_INVALID 0xFFFFFFF8
212 #define AP_REG_IDR_REVISION_MASK (0xF0000000)
213 #define AP_REG_IDR_REVISION_SHIFT (28)
214 #define AP_REG_IDR_DESIGNER_MASK (0x0FFE0000)
215 #define AP_REG_IDR_DESIGNER_SHIFT (17)
216 #define AP_REG_IDR_CLASS_MASK (0x0001E000)
217 #define AP_REG_IDR_CLASS_SHIFT (13)
218 #define AP_REG_IDR_VARIANT_MASK (0x000000F0)
219 #define AP_REG_IDR_VARIANT_SHIFT (4)
220 #define AP_REG_IDR_TYPE_MASK (0x0000000F)
221 #define AP_REG_IDR_TYPE_SHIFT (0)
223 #define AP_REG_IDR_CLASS_NONE (0x0)
224 #define AP_REG_IDR_CLASS_COM (0x1)
225 #define AP_REG_IDR_CLASS_MEM_AP (0x8)
227 #define AP_REG_IDR_VALUE(d, c, t) (\
228 (((d) << AP_REG_IDR_DESIGNER_SHIFT) & AP_REG_IDR_DESIGNER_MASK) | \
229 (((c) << AP_REG_IDR_CLASS_SHIFT) & AP_REG_IDR_CLASS_MASK) | \
230 (((t) << AP_REG_IDR_TYPE_SHIFT) & AP_REG_IDR_TYPE_MASK) \
233 #define AP_TYPE_MASK (AP_REG_IDR_DESIGNER_MASK | AP_REG_IDR_CLASS_MASK | AP_REG_IDR_TYPE_MASK)
556 unsigned int reg, uint32_t *data)
574 unsigned int reg, uint32_t data)
591 unsigned int reg, uint32_t *data)
596 LOG_ERROR(
"BUG: refcount AP#0x%" PRIx64
" used without get", ap->
ap_num);
611 unsigned int reg, uint32_t data)
616 LOG_ERROR(
"BUG: refcount AP#0x%" PRIx64
" used without get", ap->
ap_num);
651 return dap->
ops->
run(dap);
678 assert((value &
mask) == value);
682 LOG_DEBUG(
"DAP: poll %x, mask 0x%08" PRIx32
", value 0x%08" PRIx32,
689 if ((regval &
mask) == value)
static int dap_dp_poll_register(struct adiv5_dap *dap, unsigned int reg, uint32_t mask, uint32_t value, int timeout)
const struct dap_ops jtag_dp_ops
struct adiv5_ap * dap_get_config_ap(struct adiv5_dap *dap, uint64_t ap_num)
const struct dap_ops swd_dap_ops
int dap_cleanup_all(void)
int mem_ap_read_buf(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address)
static bool is_64bit_ap(struct adiv5_ap *ap)
static int dap_queue_dp_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
Queue a DP register write.
int mem_ap_read_buf_noincr(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address)
int adiv5_verify_config(struct adiv5_private_config *pc)
static int dap_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)
Queue an AP register read.
int dap_info_command(struct command_invocation *cmd, struct adiv5_ap *ap)
#define AP_REG_IDR_CLASS_COM
int mem_ap_read_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t *value)
Asynchronous (queued) read of a word from memory or a system register.
int adiv5_mem_ap_spot_init(struct adiv5_mem_ap_spot *p)
int mem_ap_write_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t value)
Asynchronous (queued) write of a word to memory or a system register.
struct adiv5_dap * dap_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
bool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num)
static int dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
Queue an AP abort operation.
static int dap_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
Send an adi-v5 sequence to the DAP.
int adiv6_dap_read_baseptr(struct command_invocation *cmd, struct adiv5_dap *dap, target_addr_t *baseptr)
adiv5_configure_dap_optional
@ ADI_CONFIGURE_DAP_OPTIONAL
@ ADI_CONFIGURE_DAP_COMPULSORY
#define AP_REG_IDR_CLASS_MEM_AP
const struct swd_driver * adiv5_dap_swd_driver(struct adiv5_dap *self)
int adiv5_jim_configure(struct target *target, struct jim_getopt_info *goi)
int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out)
int mem_ap_write_buf_noincr(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address)
int dap_to_jtag(struct adiv5_dap *dap)
Put the debug link into JTAG mode, if the target supports it.
int adiv5_jim_configure_ext(struct target *target, struct jim_getopt_info *goi, struct adiv5_private_config *pc, enum adiv5_configure_dap_optional optional)
int dap_register_commands(struct command_context *cmd_ctx)
int dap_dp_init_or_reconnect(struct adiv5_dap *dap)
Initialize a DAP or do reconnect if DAP is not accessible.
int dap_lookup_cs_component(struct adiv5_ap *ap, uint8_t type, target_addr_t *addr, int32_t idx)
int dap_dp_init(struct adiv5_dap *dap)
Initialize a DAP.
static int dap_sync(struct adiv5_dap *dap)
struct adiv5_dap * adiv5_get_dap(struct arm_dap_object *obj)
static int dap_queue_dp_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
Queue a DP register read.
int mem_ap_read_atomic_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t *value)
Synchronous read of a word from memory or a system register.
int dap_to_swd(struct adiv5_dap *dap)
Put the debug link into SWD mode, if the target supports it.
struct adiv5_ap * dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num)
int dap_put_ap(struct adiv5_ap *ap)
#define MEM_AP_REG_CFG_LA
int mem_ap_init(struct adiv5_ap *ap)
Initialize a DAP.
static int dap_dp_read_atomic(struct adiv5_dap *dap, unsigned int reg, uint32_t *value)
int mem_ap_write_buf(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address)
static int dap_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data)
Queue an AP register write.
const char * adiv5_dap_name(struct adiv5_dap *self)
void dap_invalidate_cache(struct adiv5_dap *dap)
Invalidate cached DP select and cached TAR and CSW of all APs.
const struct command_registration dap_instance_commands[]
static bool is_adiv6(const struct adiv5_dap *dap)
Check if DAP is ADIv6.
#define AP_REG_IDR_VALUE(d, c, t)
static int dap_run(struct adiv5_dap *dap)
Perform all queued DAP operations, and clear any errors posted in the CTRL_STAT register when they ar...
static bool dap_is_multidrop(struct adiv5_dap *dap)
Check if SWD multidrop configuration is valid.
#define AP_REG_IDR_CLASS_NONE
int adiv5_jim_mem_ap_spot_configure(struct adiv5_mem_ap_spot *cfg, struct jim_getopt_info *goi)
int mem_ap_write_atomic_u32(struct adiv5_ap *ap, target_addr_t address, uint32_t value)
Synchronous write of a word to memory or a system register.
void alive_sleep(uint64_t ms)
#define LOG_ERROR(expr ...)
#define LOG_DEBUG(expr ...)
target_addr_t addr
Start address to search for the control block.
size_t size
Size of the control block search area.
This represents an ARM Debug Interface (v5) Access Port (AP).
uint32_t csw_size_supported_mask
Save the supported CSW.Size data types for the MEM-AP.
bool unaligned_access_bad
bool config_ap_never_release
bool packed_transfers_probed
bool packed_transfers_supported
uint32_t tar_autoincr_block
uint32_t csw_size_probed_mask
Probed CSW.Size data types for the MEM-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...
uint32_t csw_default
Default value for (MEM-AP) AP_REG_CSW register.
target_addr_t tar_value
Cache for (MEM-AP) AP_REG_TAR register value This is written to configure the address being read or w...
uint32_t csw_value
Cache for (MEM-AP) AP_REG_CSW register value.
This represents an ARM Debug Interface (v5) Debug Access Port (DAP).
unsigned int adi_version
Indicates ADI version (5, 6 or 0 for unknown) being used.
struct list_head cmd_journal
bool select_valid
Validity of DP SELECT cache.
struct adiv5_ap ap[DP_APSEL_MAX+1]
bool select_dpbanksel_valid
Partial DPBANKSEL validity for SWD only.
bool stlink_flush_ap_write
STLINK adapter need to know if last AP operation was read or write, and in case of write has to flush...
bool multidrop_instance_id_valid
TINSTANCE field of multidrop_targetsel has been configured.
bool do_reconnect
Signals that an attempt to reestablish communication afresh should be performed before the next acces...
const struct dap_ops * ops
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 and SELECT1 (ADIv6) register.
bool multidrop_dp_id_valid
TPARTNO and TDESIGNER fields of multidrop_targetsel have been configured.
struct list_head cmd_pool
bool ignore_syspwrupack
Flag saying whether to ignore the syspwrupack flag in DAP.
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Transport-neutral representation of queued DAP transactions, supporting both JTAG and SWD transports.
int(* connect)(struct adiv5_dap *dap)
connect operation for SWD
int(* queue_ap_abort)(struct adiv5_dap *dap, uint8_t *ack)
AP operation abort.
int(* queue_dp_write)(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
DP register write.
int(* queue_dp_read)(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
DP register read.
int(* sync)(struct adiv5_dap *dap)
Executes all queued DAP operations but doesn't check sticky error conditions.
void(* quit)(struct adiv5_dap *dap)
Optional; called at OpenOCD exit.
int(* send_sequence)(struct adiv5_dap *dap, enum swd_special_seq seq)
send a sequence to the DAP
int(* queue_ap_write)(struct adiv5_ap *ap, unsigned int reg, uint32_t data)
AP register write.
int(* run)(struct adiv5_dap *dap)
Executes all queued DAP operations.
int(* pre_connect_init)(struct adiv5_dap *dap)
Optional; called once on the first enabled dap before connecting.
int(* queue_ap_read)(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)
AP register read.
A TCL -ish GetOpt like code.