adiv5: Rework DP/AP refcounting.

ASAN non longer reports leaks with the STM32H745.
This commit is contained in:
Uwe Bonnes 2020-10-22 15:38:50 +02:00 committed by UweBonnes
parent f76a7c4e92
commit 18673d9a56
4 changed files with 21 additions and 29 deletions

View File

@ -352,7 +352,6 @@ int platform_adiv5_swdp_scan(void)
if (target_list) if (target_list)
return 1; return 1;
} }
free(dp);
break; break;
} }
case BMP_TYPE_CMSIS_DAP: case BMP_TYPE_CMSIS_DAP:
@ -364,7 +363,6 @@ int platform_adiv5_swdp_scan(void)
if (target_list) if (target_list)
return 1; return 1;
} }
free(dp);
break; break;
} }
case BMP_TYPE_JLINK: case BMP_TYPE_JLINK:

View File

@ -494,5 +494,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
target_detach: target_detach:
if (t) if (t)
target_detach(t); target_detach(t);
target_list_free();
return res; return res;
} }

View File

@ -263,13 +263,10 @@ static const struct {
extern bool cortexa_probe(ADIv5_AP_t *apb, uint32_t debug_base); extern bool cortexa_probe(ADIv5_AP_t *apb, uint32_t debug_base);
static void adiv5_dp_ref(ADIv5_DP_t *dp)
{
dp->refcnt++;
}
void adiv5_ap_ref(ADIv5_AP_t *ap) void adiv5_ap_ref(ADIv5_AP_t *ap)
{ {
if (ap->refcnt == 0)
ap->dp->refcnt++;
ap->refcnt++; ap->refcnt++;
} }
@ -404,6 +401,7 @@ static bool cortexm_prepare(ADIv5_AP_t *ap)
return true; return true;
} }
/* Return true if we find a debuggable device.*/
static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, int num_entry) static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, int num_entry)
{ {
(void) num_entry; (void) num_entry;
@ -488,7 +486,7 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion,
} }
/* Probe recursively */ /* Probe recursively */
adiv5_component_probe( res = adiv5_component_probe(
ap, addr + (entry & ADIV5_ROM_ROMENTRY_OFFSET), ap, addr + (entry & ADIV5_ROM_ROMENTRY_OFFSET),
recursion + 1, i); recursion + 1, i);
} }
@ -543,15 +541,14 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion,
cidc_debug_strings[cid_class], cidc_debug_strings[cid_class],
cidc_debug_strings[pidr_pn_bits[i].cidc]); cidc_debug_strings[pidr_pn_bits[i].cidc]);
} }
res = true;
switch (pidr_pn_bits[i].arch) { switch (pidr_pn_bits[i].arch) {
case aa_cortexm: case aa_cortexm:
DEBUG_INFO("%s-> cortexm_probe\n", indent + 1); DEBUG_INFO("%s-> cortexm_probe\n", indent + 1);
cortexm_probe(ap); res = cortexm_probe(ap);
break; break;
case aa_cortexa: case aa_cortexa:
DEBUG_INFO("\n -> cortexa_probe\n"); DEBUG_INFO("\n -> cortexa_probe\n");
cortexa_probe(ap, addr); res = cortexa_probe(ap, addr);
break; break;
default: default:
DEBUG_INFO("\n"); DEBUG_INFO("\n");
@ -598,7 +595,6 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel)
} }
memcpy(ap, &tmpap, sizeof(*ap)); memcpy(ap, &tmpap, sizeof(*ap));
adiv5_dp_ref(dp);
ap->csw = adiv5_ap_read(ap, ADIV5_AP_CSW) & ap->csw = adiv5_ap_read(ap, ADIV5_AP_CSW) &
~(ADIV5_AP_CSW_SIZE_MASK | ADIV5_AP_CSW_ADDRINC_MASK); ~(ADIV5_AP_CSW_SIZE_MASK | ADIV5_AP_CSW_ADDRINC_MASK);
@ -620,7 +616,6 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel)
void adiv5_dp_init(ADIv5_DP_t *dp) void adiv5_dp_init(ADIv5_DP_t *dp)
{ {
volatile uint32_t ctrlstat = 0; volatile uint32_t ctrlstat = 0;
adiv5_dp_ref(dp);
#if PC_HOSTED == 1 #if PC_HOSTED == 1
platform_adiv5_dp_defaults(dp); platform_adiv5_dp_defaults(dp);
if (!dp->ap_write) if (!dp->ap_write)
@ -693,6 +688,7 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
} }
} }
bool res = false;
uint32_t dp_idcode = adiv5_dp_read(dp, ADIV5_DP_IDCODE); uint32_t dp_idcode = adiv5_dp_read(dp, ADIV5_DP_IDCODE);
if ((dp_idcode & ADIV5_DP_VERSION_MASK) == ADIV5_DPv2) { if ((dp_idcode & ADIV5_DP_VERSION_MASK) == ADIV5_DPv2) {
/* Read TargetID. Can be done with device in WFI, sleep or reset!*/ /* Read TargetID. Can be done with device in WFI, sleep or reset!*/
@ -729,7 +725,7 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
if (dp->ap_cleanup) if (dp->ap_cleanup)
dp->ap_cleanup(i); dp->ap_cleanup(i);
#endif #endif
free(ap); adiv5_ap_unref(ap);
/* FIXME: Should we expect valid APs behind duplicate ones? */ /* FIXME: Should we expect valid APs behind duplicate ones? */
return; return;
} }
@ -748,13 +744,14 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
*/ */
/* The rest should only be added after checking ROM table */ /* The rest should only be added after checking ROM table */
adiv5_component_probe(ap, ap->base, 0, 0); res = adiv5_component_probe(ap, ap->base, 0, 0);
if (!res)
adiv5_ap_unref(ap);
} }
/* We halted at least CortexM for Romtable scan. /* We halted at least CortexM for Romtable scan.
* Release the devices now. Attach() will halt them again.*/ * Release the devices now. Attach() will halt them again.*/
for (target *t = target_list; t; t = t->next) for (target *t = target_list; t; t = t->next)
target_halt_resume(t, false); target_halt_resume(t, false);
adiv5_dp_unref(dp);
} }
#define ALIGNOF(x) (((x) & 3) == 0 ? ALIGN_WORD : \ #define ALIGNOF(x) (((x) & 3) == 0 ? ALIGN_WORD : \

View File

@ -38,21 +38,12 @@ int adiv5_swdp_scan(void)
uint32_t ack; uint32_t ack;
target_list_free(); target_list_free();
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
dp->dp_jd_index = JTAG_MAX_DEVS; /* Tag for BMP_REMOTE */
if (!dp) { /* calloc failed: heap exhaustion */
DEBUG_WARN("calloc: failed in %s\n", __func__);
return -1;
}
#if PC_HOSTED == 1 #if PC_HOSTED == 1
if (platform_swdptap_init()) { if (platform_swdptap_init()) {
free(dp);
exit(-1); exit(-1);
} }
#else #else
if (swdptap_init()) { if (swdptap_init()) {
free(dp);
return -1; return -1;
} }
#endif #endif
@ -71,12 +62,19 @@ int adiv5_swdp_scan(void)
* allow the ack to be checked here. */ * allow the ack to be checked here. */
swd_proc.swdptap_seq_out(0xA5, 8); swd_proc.swdptap_seq_out(0xA5, 8);
ack = swd_proc.swdptap_seq_in(3); ack = swd_proc.swdptap_seq_in(3);
if((ack != SWDP_ACK_OK) || swd_proc.swdptap_seq_in_parity(&dp->idcode, 32)) { uint32_t idcode;
if((ack != SWDP_ACK_OK) || swd_proc.swdptap_seq_in_parity(&idcode, 32)) {
DEBUG_WARN("Read SW-DP IDCODE failed %1" PRIx32 "\n", ack); DEBUG_WARN("Read SW-DP IDCODE failed %1" PRIx32 "\n", ack);
free(dp);
return -1; return -1;
} }
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
if (!dp) { /* calloc failed: heap exhaustion */
DEBUG_WARN("calloc: failed in %s\n", __func__);
return -1;
}
dp->idcode = idcode;
dp->dp_read = firmware_swdp_read; dp->dp_read = firmware_swdp_read;
dp->error = firmware_swdp_error; dp->error = firmware_swdp_error;
dp->low_access = firmware_swdp_low_access; dp->low_access = firmware_swdp_low_access;
@ -84,8 +82,6 @@ int adiv5_swdp_scan(void)
firmware_swdp_error(dp); firmware_swdp_error(dp);
adiv5_dp_init(dp); adiv5_dp_init(dp);
if (!target_list)
free(dp);
return target_list?1:0; return target_list?1:0;
} }