diff --git a/src/platforms/hosted/platform.c b/src/platforms/hosted/platform.c index f1f88b8a..4d2fd9e5 100644 --- a/src/platforms/hosted/platform.c +++ b/src/platforms/hosted/platform.c @@ -352,7 +352,6 @@ int platform_adiv5_swdp_scan(void) if (target_list) return 1; } - free(dp); break; } case BMP_TYPE_CMSIS_DAP: @@ -364,7 +363,6 @@ int platform_adiv5_swdp_scan(void) if (target_list) return 1; } - free(dp); break; } case BMP_TYPE_JLINK: diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index 545e102c..7af20b5d 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -494,5 +494,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) target_detach: if (t) target_detach(t); + target_list_free(); return res; } diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 21fcad3f..7190b494 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -263,13 +263,10 @@ static const struct { 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) { + if (ap->refcnt == 0) + ap->dp->refcnt++; ap->refcnt++; } @@ -404,6 +401,7 @@ static bool cortexm_prepare(ADIv5_AP_t *ap) 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) { (void) num_entry; @@ -488,7 +486,7 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, } /* Probe recursively */ - adiv5_component_probe( + res = adiv5_component_probe( ap, addr + (entry & ADIV5_ROM_ROMENTRY_OFFSET), 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[pidr_pn_bits[i].cidc]); } - res = true; switch (pidr_pn_bits[i].arch) { case aa_cortexm: DEBUG_INFO("%s-> cortexm_probe\n", indent + 1); - cortexm_probe(ap); + res = cortexm_probe(ap); break; case aa_cortexa: DEBUG_INFO("\n -> cortexa_probe\n"); - cortexa_probe(ap, addr); + res = cortexa_probe(ap, addr); break; default: 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)); - adiv5_dp_ref(dp); ap->csw = adiv5_ap_read(ap, ADIV5_AP_CSW) & ~(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) { volatile uint32_t ctrlstat = 0; - adiv5_dp_ref(dp); #if PC_HOSTED == 1 platform_adiv5_dp_defaults(dp); 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); if ((dp_idcode & ADIV5_DP_VERSION_MASK) == ADIV5_DPv2) { /* 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) dp->ap_cleanup(i); #endif - free(ap); + adiv5_ap_unref(ap); /* FIXME: Should we expect valid APs behind duplicate ones? */ return; } @@ -748,13 +744,14 @@ void adiv5_dp_init(ADIv5_DP_t *dp) */ /* 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. * Release the devices now. Attach() will halt them again.*/ for (target *t = target_list; t; t = t->next) target_halt_resume(t, false); - adiv5_dp_unref(dp); } #define ALIGNOF(x) (((x) & 3) == 0 ? ALIGN_WORD : \ diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index 457b35fa..69c771f9 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -38,21 +38,12 @@ int adiv5_swdp_scan(void) uint32_t ack; 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 (platform_swdptap_init()) { - free(dp); exit(-1); } #else if (swdptap_init()) { - free(dp); return -1; } #endif @@ -71,12 +62,19 @@ int adiv5_swdp_scan(void) * allow the ack to be checked here. */ swd_proc.swdptap_seq_out(0xA5, 8); 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); - free(dp); 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->error = firmware_swdp_error; dp->low_access = firmware_swdp_low_access; @@ -84,8 +82,6 @@ int adiv5_swdp_scan(void) firmware_swdp_error(dp); adiv5_dp_init(dp); - if (!target_list) - free(dp); return target_list?1:0; }