static int kinetis_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
{
- int retval;
LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value);
- retval = dap_queue_ap_write(dap_ap(dap, MDM_AP), reg, value);
+ struct adiv5_ap *ap = dap_get_ap(dap, MDM_AP);
+ if (!ap) {
+ LOG_DEBUG("MDM: failed to get AP");
+ return ERROR_FAIL;
+ }
+
+ int retval = dap_queue_ap_write(ap, reg, value);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: failed to queue a write request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: dap_run failed");
return retval;
static int kinetis_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
{
- int retval;
+ struct adiv5_ap *ap = dap_get_ap(dap, MDM_AP);
+ if (!ap) {
+ LOG_DEBUG("MDM: failed to get AP");
+ return ERROR_FAIL;
+ }
- retval = dap_queue_ap_read(dap_ap(dap, MDM_AP), reg, result);
+ int retval = dap_queue_ap_read(ap, reg, result);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: failed to queue a read request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: dap_run failed");
return retval;
if ((val & (MDM_STAT_SYSSEC | MDM_STAT_FREADY)) != MDM_STAT_FREADY) {
uint32_t stats[32];
+ struct adiv5_ap *ap = dap_get_ap(dap, MDM_AP);
+ if (!ap) {
+ LOG_ERROR("MDM: failed to get AP");
+ return ERROR_OK;
+ }
for (unsigned int i = 0; i < 32; i++) {
stats[i] = MDM_STAT_FREADY;
- dap_queue_ap_read(dap_ap(dap, MDM_AP), MDM_REG_STAT, &stats[i]);
+ dap_queue_ap_read(ap, MDM_REG_STAT, &stats[i]);
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: dap_run failed when validating secured state");
return ERROR_OK;
static int kinetis_ke_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
{
- int retval;
LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value);
- retval = dap_queue_ap_write(dap_ap(dap, 1), reg, value);
+ struct adiv5_ap *ap = dap_get_ap(dap, 1);
+ if (!ap) {
+ LOG_DEBUG("MDM: failed to get AP");
+ return ERROR_FAIL;
+ }
+
+ int retval = dap_queue_ap_write(ap, reg, value);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: failed to queue a write request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: dap_run failed");
return retval;
static int kinetis_ke_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
{
- int retval;
- retval = dap_queue_ap_read(dap_ap(dap, 1), reg, result);
+ struct adiv5_ap *ap = dap_get_ap(dap, 1);
+ if (!ap) {
+ LOG_DEBUG("MDM: failed to get AP");
+ return ERROR_FAIL;
+ }
+
+ int retval = dap_queue_ap_read(ap, reg, result);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: failed to queue a read request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("MDM: dap_run failed");
return retval;
*/
static int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
{
- int retval;
LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32, reg, value);
- retval = dap_queue_ap_write(dap_ap(dap, SIM3X_AP), reg, value);
+ struct adiv5_ap *ap = dap_get_ap(dap, SIM3X_AP);
+ if (!ap) {
+ LOG_DEBUG("DAP: failed to get AP");
+ return ERROR_FAIL;
+ }
+
+ int retval = dap_queue_ap_write(ap, reg, value);
if (retval != ERROR_OK) {
LOG_DEBUG("DAP: failed to queue a write request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("DAP: dap_run failed");
return retval;
static int ap_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
{
- int retval;
+ struct adiv5_ap *ap = dap_get_ap(dap, SIM3X_AP);
+ if (!ap) {
+ LOG_DEBUG("DAP: failed to get AP");
+ return ERROR_FAIL;
+ }
- retval = dap_queue_ap_read(dap_ap(dap, SIM3X_AP), reg, result);
+ int retval = dap_queue_ap_read(ap, reg, result);
if (retval != ERROR_OK) {
LOG_DEBUG("DAP: failed to queue a read request");
+ dap_put_ap(ap);
return retval;
}
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK) {
LOG_DEBUG("DAP: dap_run failed");
return retval;
if (!pc)
return ERROR_FAIL;
+ if (armv8->debug_ap) {
+ dap_put_ap(armv8->debug_ap);
+ armv8->debug_ap = NULL;
+ }
+
if (pc->adiv5_config.ap_num == DP_APSEL_INVALID) {
/* Search for the APB-AB */
- retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap);
+ retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap);
if (retval != ERROR_OK) {
LOG_ERROR("Could not find APB-AP for debug access");
return retval;
}
} else {
- armv8->debug_ap = dap_ap(swjdp, pc->adiv5_config.ap_num);
+ armv8->debug_ap = dap_get_ap(swjdp, pc->adiv5_config.ap_num);
+ if (!armv8->debug_ap) {
+ LOG_ERROR("Cannot get AP");
+ return ERROR_FAIL;
+ }
}
retval = mem_ap_init(armv8->debug_ap);
struct armv8_common *armv8 = &aarch64->armv8_common;
struct arm_dpm *dpm = &armv8->dpm;
+ if (armv8->debug_ap)
+ dap_put_ap(armv8->debug_ap);
+
armv8_free_reg_cache(target);
free(aarch64->brp_list);
free(dpm->dbp);
/*
* This function checks the ID for each access port to find the requested Access Port type
+ * It also calls dap_get_ap() to increment the AP refcount
*/
-int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out)
+int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out)
{
int ap_num;
/* Maximum AP number is 255 since the SELECT register is 8 bits */
for (ap_num = 0; ap_num <= DP_APSEL_MAX; ap_num++) {
+ struct adiv5_ap *ap = dap_get_ap(dap, ap_num);
+ if (!ap)
+ continue;
/* read the IDR register of the Access Port */
uint32_t id_val = 0;
- int retval = dap_queue_ap_read(dap_ap(dap, ap_num), AP_REG_IDR, &id_val);
- if (retval != ERROR_OK)
+ int retval = dap_queue_ap_read(ap, AP_REG_IDR, &id_val);
+ if (retval != ERROR_OK) {
+ dap_put_ap(ap);
return retval;
+ }
retval = dap_run(dap);
ap_type_to_description(type_to_find),
ap_num, id_val);
- *ap_out = &dap->ap[ap_num];
+ *ap_out = ap;
return ERROR_OK;
}
+ dap_put_ap(ap);
}
LOG_DEBUG("No %s found", ap_type_to_description(type_to_find));
return ERROR_FAIL;
}
+static inline bool is_ap_in_use(struct adiv5_ap *ap)
+{
+ return ap->refcount > 0 || ap->config_ap_never_release;
+}
+
+static struct adiv5_ap *_dap_get_ap(struct adiv5_dap *dap, unsigned int ap_num)
+{
+ if (ap_num > DP_APSEL_MAX) {
+ LOG_ERROR("Invalid AP#%u", ap_num);
+ return NULL;
+ }
+ struct adiv5_ap *ap = &dap->ap[ap_num];
+ ++ap->refcount;
+ return ap;
+}
+
+/* Return AP with specified ap_num. Increment AP refcount */
+struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, unsigned int ap_num)
+{
+ struct adiv5_ap *ap = _dap_get_ap(dap, ap_num);
+ if (ap)
+ LOG_DEBUG("refcount AP#%u get %u", ap_num, ap->refcount);
+ return ap;
+}
+
+/* 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)
+{
+ struct adiv5_ap *ap = _dap_get_ap(dap, ap_num);
+ if (ap) {
+ ap->config_ap_never_release = true;
+ LOG_DEBUG("refcount AP#%u get_config %u", ap_num, ap->refcount);
+ }
+ return ap;
+}
+
+/* Decrement AP refcount and release the AP when refcount reaches zero */
+int dap_put_ap(struct adiv5_ap *ap)
+{
+ if (ap->refcount == 0) {
+ LOG_ERROR("BUG: refcount AP#%" PRIu8 " put underflow", ap->ap_num);
+ return ERROR_FAIL;
+ }
+
+ --ap->refcount;
+
+ LOG_DEBUG("refcount AP#%" PRIu8 " put %u", ap->ap_num, ap->refcount);
+ if (!is_ap_in_use(ap)) {
+ /* defaults from dap_instance_init() */
+ ap->memaccess_tck = 255;
+ ap->tar_autoincr_block = (1 << 10);
+ ap->csw_default = CSW_AHB_DEFAULT;
+ ap->cfg_reg = MEM_AP_REG_CFG_INVALID;
+ }
+ return ERROR_OK;
+}
+
static int dap_get_debugbase(struct adiv5_ap *ap,
target_addr_t *dbgbase, uint32_t *apid)
{
return ERROR_COMMAND_SYNTAX_ERROR;
}
- return dap_info_command(CMD, &dap->ap[apsel]);
+ struct adiv5_ap *ap = dap_get_ap(dap, apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+
+ int retval = dap_info_command(CMD, ap);
+ dap_put_ap(ap);
+ return retval;
}
COMMAND_HANDLER(dap_baseaddr_command)
* use the ID register to verify it's a MEM-AP.
*/
- ap = dap_ap(dap, apsel);
+ ap = dap_get_ap(dap, apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+
retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, &baseaddr_lower);
if (retval == ERROR_OK && ap->cfg_reg == MEM_AP_REG_CFG_INVALID)
if (retval == ERROR_OK)
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK)
return retval;
COMMAND_HANDLER(dap_memaccess_command)
{
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
+ struct adiv5_ap *ap;
uint32_t memaccess_tck;
switch (CMD_ARGC) {
case 0:
- memaccess_tck = dap->ap[dap->apsel].memaccess_tck;
+ ap = dap_get_ap(dap, dap->apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+ memaccess_tck = ap->memaccess_tck;
break;
case 1:
+ ap = dap_get_config_ap(dap, dap->apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck);
+ ap->memaccess_tck = memaccess_tck;
break;
default:
return ERROR_COMMAND_SYNTAX_ERROR;
}
- dap->ap[dap->apsel].memaccess_tck = memaccess_tck;
+
+ dap_put_ap(ap);
command_print(CMD, "memory bus access delay set to %" PRIu32 " tck",
- dap->ap[dap->apsel].memaccess_tck);
+ memaccess_tck);
return ERROR_OK;
}
COMMAND_HANDLER(dap_apcsw_command)
{
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
- uint32_t apcsw = dap->ap[dap->apsel].csw_default;
+ struct adiv5_ap *ap;
uint32_t csw_val, csw_mask;
switch (CMD_ARGC) {
case 0:
+ ap = dap_get_ap(dap, dap->apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
command_print(CMD, "ap %" PRIu32 " selected, csw 0x%8.8" PRIx32,
- dap->apsel, apcsw);
- return ERROR_OK;
+ dap->apsel, ap->csw_default);
+ break;
case 1:
if (strcmp(CMD_ARGV[0], "default") == 0)
csw_val = CSW_AHB_DEFAULT;
LOG_ERROR("CSW value cannot include 'Size' and 'AddrInc' bit-fields");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
- apcsw = csw_val;
+ ap = dap_get_config_ap(dap, dap->apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+ ap->csw_default = csw_val;
break;
case 2:
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], csw_val);
LOG_ERROR("CSW mask cannot include 'Size' and 'AddrInc' bit-fields");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
- apcsw = (apcsw & ~csw_mask) | (csw_val & csw_mask);
+ ap = dap_get_config_ap(dap, dap->apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+ ap->csw_default = (ap->csw_default & ~csw_mask) | (csw_val & csw_mask);
break;
default:
return ERROR_COMMAND_SYNTAX_ERROR;
}
- dap->ap[dap->apsel].csw_default = apcsw;
+ dap_put_ap(ap);
- return 0;
+ return ERROR_OK;
}
return ERROR_COMMAND_SYNTAX_ERROR;
}
- retval = dap_queue_ap_read(dap_ap(dap, apsel), AP_REG_IDR, &apid);
- if (retval != ERROR_OK)
+ struct adiv5_ap *ap = dap_get_ap(dap, apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+ retval = dap_queue_ap_read(ap, AP_REG_IDR, &apid);
+ if (retval != ERROR_OK) {
+ dap_put_ap(ap);
return retval;
+ }
retval = dap_run(dap);
+ dap_put_ap(ap);
if (retval != ERROR_OK)
return retval;
{
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
uint32_t apsel, reg, value;
- struct adiv5_ap *ap;
int retval;
if (CMD_ARGC < 2 || CMD_ARGC > 3)
return ERROR_COMMAND_ARGUMENT_INVALID;
}
- ap = dap_ap(dap, apsel);
-
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg);
if (reg >= 256 || (reg & 3)) {
command_print(CMD, "Invalid reg value (should be less than 256 and 4 bytes aligned)");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
+ struct adiv5_ap *ap = dap_get_ap(dap, apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+
if (CMD_ARGC == 3) {
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
switch (reg) {
if (retval == ERROR_OK)
retval = dap_run(dap);
+ dap_put_ap(ap);
+
if (retval != ERROR_OK)
return retval;
/* 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;
};
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 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)
struct list_head lh;
char *name;
struct adiv5_mem_ap_spot spot;
+ struct adiv5_ap *ap;
};
static LIST_HEAD(all_cti);
static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t mask, uint32_t value)
{
- struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
+ struct adiv5_ap *ap = self->ap;
uint32_t tmp;
/* Read register */
int arm_cti_enable(struct arm_cti *self, bool enable)
{
- struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
uint32_t val = enable ? 1 : 0;
- return mem_ap_write_atomic_u32(ap, self->spot.base + CTI_CTR, val);
+ return mem_ap_write_atomic_u32(self->ap, self->spot.base + CTI_CTR, val);
}
int arm_cti_ack_events(struct arm_cti *self, uint32_t event)
{
- struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
+ struct adiv5_ap *ap = self->ap;
int retval;
uint32_t tmp;
int arm_cti_write_reg(struct arm_cti *self, unsigned int reg, uint32_t value)
{
- struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
-
- return mem_ap_write_atomic_u32(ap, self->spot.base + reg, value);
+ return mem_ap_write_atomic_u32(self->ap, self->spot.base + reg, value);
}
int arm_cti_read_reg(struct arm_cti *self, unsigned int reg, uint32_t *p_value)
{
- struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
-
if (!p_value)
return ERROR_COMMAND_ARGUMENT_INVALID;
- return mem_ap_read_atomic_u32(ap, self->spot.base + reg, p_value);
+ return mem_ap_read_atomic_u32(self->ap, self->spot.base + reg, p_value);
}
int arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel)
struct arm_cti *obj, *tmp;
list_for_each_entry_safe(obj, tmp, &all_cti, lh) {
+ if (obj->ap)
+ dap_put_ap(obj->ap);
free(obj->name);
free(obj);
}
COMMAND_HANDLER(handle_cti_dump)
{
struct arm_cti *cti = CMD_DATA;
- struct adiv5_ap *ap = dap_ap(cti->spot.dap, cti->spot.ap_num);
+ struct adiv5_ap *ap = cti->ap;
int retval = ERROR_OK;
for (int i = 0; (retval == ERROR_OK) && (i < (int)ARRAY_SIZE(cti_names)); i++)
list_add_tail(&cti->lh, &all_cti);
+ cti->ap = dap_get_ap(cti->spot.dap, cti->spot.ap_num);
+ if (!cti->ap) {
+ Jim_SetResultString(goi->interp, "Cannot get AP", -1);
+ return JIM_ERR;
+ }
+
return JIM_OK;
}
/* default CSW value */
dap->ap[i].csw_default = CSW_AHB_DEFAULT;
dap->ap[i].cfg_reg = MEM_AP_REG_CFG_INVALID; /* mem_ap configuration reg (large physical addr, etc.) */
+ dap->ap[i].refcount = 0;
+ dap->ap[i].config_ap_never_release = false;
}
INIT_LIST_HEAD(&dap->cmd_journal);
INIT_LIST_HEAD(&dap->cmd_pool);
list_for_each_entry_safe(obj, tmp, &all_dap, lh) {
dap = &obj->dap;
+ for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) {
+ if (dap->ap[i].refcount != 0)
+ LOG_ERROR("BUG: refcount AP#%u still %u at exit", i, dap->ap[i].refcount);
+ }
if (dap->ops && dap->ops->quit)
dap->ops->quit(dap);
return ERROR_COMMAND_SYNTAX_ERROR;
}
- return dap_info_command(CMD, &dap->ap[apsel]);
+ struct adiv5_ap *ap = dap_get_ap(dap, apsel);
+ if (!ap) {
+ command_print(CMD, "Cannot get AP");
+ return ERROR_FAIL;
+ }
+ int retval = dap_info_command(CMD, ap);
+ dap_put_ap(ap);
+ return retval;
}
static const struct command_registration dap_subcommand_handlers[] = {
struct arm_tpiu_swo_object {
struct list_head lh;
struct adiv5_mem_ap_spot spot;
+ struct adiv5_ap *ap;
char *name;
struct arm_tpiu_swo_event_action *event_action;
/* record enable before init */
ea = next;
}
+ if (obj->ap)
+ dap_put_ap(obj->ap);
+
free(obj->name);
free(obj->out_filename);
free(obj);
struct command *c = jim_to_command(interp);
struct arm_tpiu_swo_object *obj = c->jim_handler_data;
struct command_context *cmd_ctx = current_command_context(interp);
- struct adiv5_ap *tpiu_ap = dap_ap(obj->spot.dap, obj->spot.ap_num);
uint32_t value;
int retval;
struct cortex_m_common *cm = target_to_cm(target);
obj->recheck_ap_cur_target = false;
obj->spot.ap_num = cm->armv7m.debug_ap->ap_num;
- tpiu_ap = dap_ap(obj->spot.dap, obj->spot.ap_num);
if (obj->spot.ap_num == 0)
LOG_INFO(MSG "Confirmed TPIU %s is on AP 0", obj->name);
else
}
/* END_DEPRECATED_TPIU */
+ if (!obj->ap) {
+ obj->ap = dap_get_ap(obj->spot.dap, obj->spot.ap_num);
+ if (!obj->ap) {
+ LOG_ERROR("Cannot get AP");
+ return JIM_ERR;
+ }
+ }
+
/* trigger the event before any attempt to R/W in the TPIU/SWO */
arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_ENABLE);
- retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_DEVID_OFFSET, &value);
+ retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_DEVID_OFFSET, &value);
if (retval != ERROR_OK) {
LOG_ERROR("Unable to read %s", obj->name);
return JIM_ERR;
}
if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_SYNC) {
- retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value);
+ retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value);
if (retval != ERROR_OK) {
LOG_ERROR("Cannot read TPIU register SSPSR");
return JIM_ERR;
obj->swo_pin_freq = swo_pin_freq;
}
- retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_CSPSR_OFFSET, BIT(obj->port_width - 1));
+ retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_CSPSR_OFFSET, BIT(obj->port_width - 1));
if (retval != ERROR_OK)
goto error_exit;
- retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_ACPR_OFFSET, prescaler - 1);
+ retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_ACPR_OFFSET, prescaler - 1);
if (retval != ERROR_OK)
goto error_exit;
- retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_SPPR_OFFSET, obj->pin_protocol);
+ retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_SPPR_OFFSET, obj->pin_protocol);
if (retval != ERROR_OK)
goto error_exit;
- retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_FFCR_OFFSET, &value);
+ retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, &value);
if (retval != ERROR_OK)
goto error_exit;
if (obj->en_formatter)
value |= BIT(1);
else
value &= ~BIT(1);
- retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_FFCR_OFFSET, value);
+ retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, value);
if (retval != ERROR_OK)
goto error_exit;
int retval = ERROR_OK;
uint32_t didr, cpuid, dbg_osreg, dbg_idpfr1;
+ if (armv7a->debug_ap) {
+ dap_put_ap(armv7a->debug_ap);
+ armv7a->debug_ap = NULL;
+ }
+
if (pc->ap_num == DP_APSEL_INVALID) {
/* Search for the APB-AP - it is needed for access to debug registers */
- retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap);
+ retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap);
if (retval != ERROR_OK) {
LOG_ERROR("Could not find APB-AP for debug access");
return retval;
}
} else {
- armv7a->debug_ap = dap_ap(swjdp, pc->ap_num);
+ armv7a->debug_ap = dap_get_ap(swjdp, pc->ap_num);
+ if (!armv7a->debug_ap) {
+ LOG_ERROR("Cannot get AP");
+ return ERROR_FAIL;
+ }
}
retval = mem_ap_init(armv7a->debug_ap);
dscr & ~DSCR_HALT_DBG_MODE);
}
+ if (armv7a->debug_ap)
+ dap_put_ap(armv7a->debug_ap);
+
free(cortex_a->wrp_list);
free(cortex_a->brp_list);
arm_free_reg_cache(dpm->arm);
void cortex_m_deinit_target(struct target *target)
{
struct cortex_m_common *cortex_m = target_to_cm(target);
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+
+ if (!armv7m->is_hla_target && armv7m->debug_ap)
+ dap_put_ap(armv7m->debug_ap);
free(cortex_m->fp_comparator_list);
static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp,
struct adiv5_ap **debug_ap)
{
- if (dap_find_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK)
+ if (dap_find_get_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK)
return ERROR_OK;
- return dap_find_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap);
+ return dap_find_get_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap);
}
int cortex_m_examine(struct target *target)
/* hla_target shares the examine handler but does not support
* all its calls */
if (!armv7m->is_hla_target) {
+ if (armv7m->debug_ap) {
+ dap_put_ap(armv7m->debug_ap);
+ armv7m->debug_ap = NULL;
+ }
+
if (cortex_m->apsel == DP_APSEL_INVALID) {
/* Search for the MEM-AP */
retval = cortex_m_find_mem_ap(swjdp, &armv7m->debug_ap);
return retval;
}
} else {
- armv7m->debug_ap = dap_ap(swjdp, cortex_m->apsel);
+ armv7m->debug_ap = dap_get_ap(swjdp, cortex_m->apsel);
+ if (!armv7m->debug_ap) {
+ LOG_ERROR("Cannot get AP");
+ return ERROR_FAIL;
+ }
}
armv7m->debug_ap->memaccess_tck = 8;
static void mem_ap_deinit_target(struct target *target)
{
+ struct mem_ap *mem_ap = target->arch_info;
+
LOG_DEBUG("%s", __func__);
+ if (mem_ap->ap)
+ dap_put_ap(mem_ap->ap);
+
free(target->private_config);
free(target->arch_info);
return;
struct mem_ap *mem_ap = target->arch_info;
if (!target_was_examined(target)) {
- mem_ap->ap = dap_ap(mem_ap->dap, mem_ap->ap_num);
+ if (mem_ap->ap) {
+ dap_put_ap(mem_ap->ap);
+ mem_ap->ap = NULL;
+ }
+
+ mem_ap->ap = dap_get_ap(mem_ap->dap, mem_ap->ap_num);
+ if (!mem_ap->ap) {
+ LOG_ERROR("Cannot get AP");
+ return ERROR_FAIL;
+ }
target_set_examined(target);
target->state = TARGET_UNKNOWN;
target->debug_reason = DBG_REASON_UNDEFINED;