#define DLCR_TO_TRN(dlcr) ((uint32_t)(1 + ((3 & (dlcr)) >> 8))) /* 1..4 clocks */
+/* Fields of DP_DPIDR register */
+#define DP_DPIDR_VERSION_SHIFT 12
+#define DP_DPIDR_VERSION_MASK (0xFUL << DP_DPIDR_VERSION_SHIFT)
+
/* Fields of the DP's AP ABORT register */
#define DAPABORT (1UL << 0)
#define STKCMPCLR (1UL << 1) /* SWD-only */
#define CSYSPWRUPREQ (1UL << 30)
#define CSYSPWRUPACK (1UL << 31)
+#define DP_DLPIDR_PROTVSN 1u
+
#define DP_SELECT_APSEL 0xFF000000
#define DP_SELECT_APBANK 0x000000F0
#define DP_SELECT_DPBANK 0x0000000F
/* MEM AP configuration register indicating LPAE support */
uint32_t cfg_reg;
+
+ /* references counter */
+ unsigned int refcount;
+
+ /* AP referenced during config. Never put it, even when refcount reaches zero */
+ bool config_ap_never_release;
};
bool multidrop_dp_id_valid;
/** TINSTANCE field of multidrop_targetsel has been configured */
bool multidrop_instance_id_valid;
+
+ /**
+ * Record if enter in SWD required passing through DORMANT
+ */
+ bool switch_through_dormant;
+
+ /** Indicates ADI version (5, 6 or 0 for unknown) being used */
+ unsigned int adi_version;
};
/**
return (ap->cfg_reg & MEM_AP_REG_CFG_LA) != 0;
}
+/**
+ * Check if DAP is ADIv6
+ *
+ * @param dap The DAP to test
+ *
+ * @return true for ADIv6, false for either ADIv5 or unknown version
+ */
+static inline bool is_adiv6(const struct adiv5_dap *dap)
+{
+ return dap->adi_version == 6;
+}
+
/**
* Send an adi-v5 sequence to the DAP.
*
unsigned reg, uint32_t *data)
{
assert(ap->dap->ops);
+ if (ap->refcount == 0) {
+ ap->refcount = 1;
+ LOG_ERROR("BUG: refcount AP#%" PRIu8 " used without get", ap->ap_num);
+ }
return ap->dap->ops->queue_ap_read(ap, reg, data);
}
unsigned reg, uint32_t data)
{
assert(ap->dap->ops);
+ if (ap->refcount == 0) {
+ ap->refcount = 1;
+ LOG_ERROR("BUG: refcount AP#%" PRIu8 " used without get", ap->ap_num);
+ }
return ap->dap->ops->queue_ap_write(ap, reg, data);
}
/* Invalidate cached DP select and cached TAR and CSW of all APs */
void dap_invalidate_cache(struct adiv5_dap *dap);
-/* Probe the AP for ROM Table location */
-int dap_get_debugbase(struct adiv5_ap *ap,
- target_addr_t *dbgbase, uint32_t *apid);
-
-/* Probe Access Ports to find a particular type */
-int dap_find_ap(struct adiv5_dap *dap,
+/* Probe Access Ports to find a particular type. Increment AP refcount */
+int dap_find_get_ap(struct adiv5_dap *dap,
enum ap_type type_to_find,
struct adiv5_ap **ap_out);
-static inline struct adiv5_ap *dap_ap(struct adiv5_dap *dap, uint8_t ap_num)
-{
- return &dap->ap[ap_num];
-}
+/* Return AP with specified ap_num. Increment AP refcount */
+struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, unsigned int ap_num);
+
+/* Return AP with specified ap_num. Increment AP refcount and keep it non-zero */
+struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, unsigned int ap_num);
+
+/* Decrement AP refcount and release the AP when refcount reaches zero */
+int dap_put_ap(struct adiv5_ap *ap);
/** Check if SWD multidrop configuration is valid */
static inline bool dap_is_multidrop(struct adiv5_dap *dap)
/* Lookup CoreSight component */
int dap_lookup_cs_component(struct adiv5_ap *ap,
- target_addr_t dbgbase, uint8_t type, target_addr_t *addr, int32_t *idx);
+ uint8_t type, target_addr_t *addr, int32_t idx);
struct target;