Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix: BMDA ST-Link v3 crashes #1605

Merged
merged 25 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
eee669a
hosted/cli: Fixed the clang-tidy warnings on naming in cl_execute()
dragonmux Jun 21, 2023
aa30de1
target_internal: Reduced the padding requirements on the target struc…
dragonmux Jun 21, 2023
2048f8a
hosted/stlinkv2: Cleaned up the naming of stlink_adiv5_clear_error() …
dragonmux Jun 21, 2023
7b08293
hosted/stlinkv2: Added protocol-level debugging to stlink_raw_access(…
dragonmux Jun 21, 2023
7454bec
hosted/stlinkv2: Moved all the stlink_usb_error_check() output defini…
dragonmux Jun 21, 2023
4275ad7
hosted/stlinkv2: Fixed some of the error checking done with stlink_us…
dragonmux Jun 21, 2023
b56aaa4
hosted/stlinkv2: Cleaned up the WAIT response handling
dragonmux Jun 21, 2023
8ce6196
hosted/stlinkv2: Cleaned up the FAULT response handling, fixing a bug…
dragonmux Jun 21, 2023
a99ed70
hosted/stlinkv2: Reordered the checks in stlink_usb_error_check() so …
dragonmux Jun 21, 2023
928ea42
hosted/stlinkv2: Cleaned up the parity error response handling
dragonmux Jun 21, 2023
dbfd210
hosted/stlinkv2: Fixed the parity error handling in stlink_read_dp_re…
dragonmux Jun 21, 2023
325e2a6
hosted/stlinkv2: Cleaned up the general error response handling
dragonmux Jun 21, 2023
22620ec
hosted/stlinkv2_protocol: Cleaned up duplicated an unused error codes
dragonmux Jun 21, 2023
1ab2fad
hosted/stlinkv2: Reworked the AP handling to properly take into accou…
dragonmux Jun 21, 2023
2d65aae
hosted/stlinkv2: Implemented better handling for when stlink_ap_setup…
dragonmux Jun 21, 2023
bd440fd
hosted/stlinkv2: Cleaned up some variable naming in stlink_ap_setup()
dragonmux Jun 21, 2023
0333e56
hosted/stlinkv2: Cleaned up a couple more of the error definitions
dragonmux Jun 21, 2023
ede069c
hosted/stlinkv2: Improved the protocol-level debugging available from…
dragonmux Jun 21, 2023
9870cae
adiv5: Cleaned up adiv5_dp_recoverable_access(), fixing the parameter…
dragonmux Jun 21, 2023
85bb78d
hosted/platform: Improved the decoding of DP accesses
dragonmux Jun 21, 2023
587b793
hosted/stlinkv2_swd: Cleaned up how entry into SWD is done
dragonmux Jun 22, 2023
8900991
hosted/stlinkv2: Cleaned up the error handling and reporting
dragonmux Jul 30, 2023
8b499c7
hosted/stlinkv2: Cleaned up the error handling and reporting
dragonmux Jul 30, 2023
676419e
hosted/stlinkv2: Cleaned up the error handling and reporting
dragonmux Jul 30, 2023
53b161c
hosted/stlinkv2_jtag: Implemented adiv5_dp_read() for ST-Link JTAG
dragonmux Aug 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 28 additions & 28 deletions src/platforms/hosted/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,26 +459,26 @@ int cl_execute(bmda_cli_options_s *opt)
DEBUG_ERROR("Given target number %" PRIu32 " not available max %zu\n", opt->opt_target_dev, num_targets);
return -1;
}
target_s *t = target_attach_n(opt->opt_target_dev, &cl_controller);
target_s *target = target_attach_n(opt->opt_target_dev, &cl_controller);

int res = 0;
int read_file = -1;
if (!t) {
if (!target) {
DEBUG_ERROR("Can not attach to target %" PRIu32 "\n", opt->opt_target_dev);
res = -1;
goto target_detach;
}

/* List each defined RAM region */
size_t ram_regions = 0;
for (target_ram_s *r = t->ram; r; r = r->next)
for (target_ram_s *ram = target->ram; ram; ram = ram->next)
++ram_regions;

for (size_t region = 0; region < ram_regions; ++region) {
target_ram_s *r = t->ram;
for (size_t i = ram_regions - 1U; r; r = r->next, --i) {
target_ram_s *ram = target->ram;
for (size_t i = ram_regions - 1U; ram; ram = ram->next, --i) {
if (region == i) {
DEBUG_INFO("RAM Start: 0x%08" PRIx32 " length = 0x%zx\n", r->start, r->length);
DEBUG_INFO("RAM Start: 0x%08" PRIx32 " length = 0x%zx\n", ram->start, ram->length);
break;
}
}
Expand All @@ -490,20 +490,20 @@ int cl_execute(bmda_cli_options_s *opt)
size_t lowest_flash_size = 0;

size_t flash_regions = 0;
for (target_flash_s *f = t->flash; f; f = f->next) {
for (target_flash_s *flash = target->flash; flash; flash = flash->next) {
++flash_regions;
if (f->start < lowest_flash_start) {
lowest_flash_start = f->start;
lowest_flash_size = f->length;
if (flash->start < lowest_flash_start) {
lowest_flash_start = flash->start;
lowest_flash_size = flash->length;
}
}

for (size_t region = 0; region < flash_regions; ++region) {
target_flash_s *f = t->flash;
for (size_t i = flash_regions - 1U; f; f = f->next, --i) {
target_flash_s *flash = target->flash;
for (size_t i = flash_regions - 1U; flash; flash = flash->next, --i) {
if (region == i) {
DEBUG_INFO(
"Flash Start: 0x%08" PRIx32 " length = 0x%zx blocksize 0x%zx\n", f->start, f->length, f->blocksize);
DEBUG_INFO("Flash Start: 0x%08" PRIx32 " length = 0x%zx blocksize 0x%zx\n", flash->start, flash->length,
flash->blocksize);
break;
}
}
Expand All @@ -519,12 +519,12 @@ int cl_execute(bmda_cli_options_s *opt)
* XXX: This is bugprone - any core, even if it's not just a Cortex-M* that
* matches on the first letter triggers this
*/
if (t->core[0] == 'M') {
if (target->core[0] == 'M') {
DEBUG_WARN("Continuous read/write-back DEMCR. Abort with ^C\n");
while (true) {
uint32_t demcr;
target_mem_read(t, &demcr, CORTEXM_DEMCR, 4);
target_mem_write32(t, CORTEXM_DEMCR, demcr);
target_mem_read(target, &demcr, CORTEXM_DEMCR, 4);
target_mem_write32(target, CORTEXM_DEMCR, demcr);
platform_delay(1); /* To allow trigger */
}
} else
Expand Down Expand Up @@ -554,31 +554,31 @@ int cl_execute(bmda_cli_options_s *opt)
/* restrict to size given on command line */
map.size = opt->opt_flash_size;
if (opt->opt_monitor) {
res = command_process(t, opt->opt_monitor);
res = command_process(target, opt->opt_monitor);
if (res)
DEBUG_ERROR("Command \"%s\" failed\n", opt->opt_monitor);
}
if (opt->opt_mode == BMP_MODE_RESET)
target_reset(t);
target_reset(target);
else if (opt->opt_mode == BMP_MODE_FLASH_ERASE) {
DEBUG_INFO("Erase %zu bytes at 0x%08" PRIx32 "\n", opt->opt_flash_size, opt->opt_flash_start);
if (!target_flash_erase(t, opt->opt_flash_start, opt->opt_flash_size)) {
if (!target_flash_erase(target, opt->opt_flash_start, opt->opt_flash_size)) {
DEBUG_ERROR("Flash erase failed!\n");
res = -1;
goto free_map;
}
target_reset(t);
target_reset(target);
} else if (opt->opt_mode == BMP_MODE_FLASH_WRITE || opt->opt_mode == BMP_MODE_FLASH_WRITE_VERIFY) {
DEBUG_INFO("Erasing %zu bytes at 0x%08" PRIx32 "\n", map.size, opt->opt_flash_start);
const uint32_t start_time = platform_time_ms();
if (!target_flash_erase(t, opt->opt_flash_start, map.size)) {
if (!target_flash_erase(target, opt->opt_flash_start, map.size)) {
DEBUG_ERROR("Flash erase failed!\n");
res = -1;
goto free_map;
}
DEBUG_INFO("Flashing %zu bytes at 0x%08" PRIx32 "\n", map.size, opt->opt_flash_start);
/* Buffered write cares for padding*/
if (!target_flash_write(t, opt->opt_flash_start, map.data, map.size) || !target_flash_complete(t)) {
if (!target_flash_write(target, opt->opt_flash_start, map.data, map.size) || !target_flash_complete(target)) {
DEBUG_ERROR("Flashing failed!\n");
res = -1;
goto free_map;
Expand All @@ -588,7 +588,7 @@ int cl_execute(bmda_cli_options_s *opt)
DEBUG_WARN(
"Flash Write succeeded for %zu bytes, %8.3fkiB/s\n", map.size, (double)map.size / (end_time - start_time));
if (opt->opt_mode != BMP_MODE_FLASH_WRITE_VERIFY) {
target_reset(t);
target_reset(target);
goto free_map;
}
}
Expand All @@ -606,7 +606,7 @@ int cl_execute(bmda_cli_options_s *opt)
const uint32_t start_time = platform_time_ms();
for (size_t offset = 0; offset < size; offset += WORKSIZE) {
const size_t worksize = MIN(size - offset, WORKSIZE);
int n_read = target_mem_read(t, data, flash_src + offset, worksize);
int n_read = target_mem_read(target, data, flash_src + offset, worksize);
if (n_read) {
if (opt->opt_flash_size == 0) /* we reached end of flash */
DEBUG_INFO("Reached end of flash at size %" PRIu32 "\n", flash_src - opt->opt_flash_start);
Expand Down Expand Up @@ -642,16 +642,16 @@ int cl_execute(bmda_cli_options_s *opt)
DEBUG_WARN("Read/Verify succeeded for %zu bytes, %8.3fkiB/s\n", bytes_read,
(double)bytes_read / (end_time - start_time));
if (opt->opt_mode == BMP_MODE_FLASH_WRITE_VERIFY)
target_reset(t);
target_reset(target);
}
free_map:
if (map.size)
bmp_munmap(&map);
target_detach:
if (read_file != -1)
close(read_file);
if (t)
target_detach(t);
if (target)
target_detach(target);
target_list_free();
return res;
}
47 changes: 37 additions & 10 deletions src/platforms/hosted/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ void gdb_ident(char *p, int count)

static void exit_function(void)
{
#if HOSTED_BMP_ONLY == 0
if (bmda_probe_info.type == PROBE_TYPE_STLINK_V2)
stlink_deinit();
#endif

libusb_exit_function(&bmda_probe_info);

switch (bmda_probe_info.type) {
Expand Down Expand Up @@ -571,21 +576,43 @@ void platform_target_clk_output_enable(const bool enable)
}
}

static void decode_dp_access(const uint8_t addr, const uint8_t rnw)
static void decode_dp_access(const uint8_t addr, const uint8_t rnw, const uint32_t value)
{
/* How a DP address should be decoded depends on the bank that's presently selected, so make a note of that */
static uint8_t dp_bank = 0;
const char *reg = NULL;

/* Try to decode the requested address */
switch (addr) {
case 0x00U:
reg = rnw ? "DPIDR" : "ABORT";
break;
case 0x04U:
reg = "CTRL/STAT";
switch (dp_bank) {
case 0:
reg = rnw ? "STATUS" : "CTRL";
break;
case 1:
reg = "DLCR";
break;
case 2:
reg = "TARGETID";
break;
case 3:
reg = "DLPIDR";
break;
case 4:
reg = "EVENTSTAT";
break;
}
break;
case 0x08U:
if (!rnw)
dp_bank = value & 15U;
reg = rnw ? "RESEND" : "SELECT";
break;
case 0x0cU:
reg = "RDBUFF";
reg = rnw ? "RDBUFF" : "TARGETSEL";
break;
}

Expand Down Expand Up @@ -639,30 +666,30 @@ static void decode_ap_access(const uint8_t ap, const uint8_t addr)
DEBUG_PROTO("Reserved(%02x): ", addr);
}

static void decode_access(const uint16_t addr, const uint8_t rnw)
static void decode_access(const uint16_t addr, const uint8_t rnw, const uint32_t value)
{
if (rnw)
DEBUG_PROTO("Read ");
else
DEBUG_PROTO("Write ");

if (addr < 0x100U)
decode_dp_access(addr & 0xffU, rnw);
decode_dp_access(addr & 0xffU, rnw, value);
else
decode_ap_access(addr >> 8U, addr & 0xffU);
}

void adiv5_dp_write(adiv5_debug_port_s *dp, uint16_t addr, uint32_t value)
{
decode_access(addr, ADIV5_LOW_WRITE);
decode_access(addr, ADIV5_LOW_WRITE, value);
DEBUG_PROTO("0x%08" PRIx32 "\n", value);
dp->low_access(dp, ADIV5_LOW_WRITE, addr, value);
}

uint32_t adiv5_dp_read(adiv5_debug_port_s *dp, uint16_t addr)
{
uint32_t ret = dp->dp_read(dp, addr);
decode_access(addr, ADIV5_LOW_READ);
decode_access(addr, ADIV5_LOW_READ, 0U);
DEBUG_PROTO("0x%08" PRIx32 "\n", ret);
return ret;
}
Expand All @@ -677,22 +704,22 @@ uint32_t adiv5_dp_error(adiv5_debug_port_s *dp)
uint32_t adiv5_dp_low_access(adiv5_debug_port_s *dp, uint8_t rnw, uint16_t addr, uint32_t value)
{
uint32_t ret = dp->low_access(dp, rnw, addr, value);
decode_access(addr, rnw);
decode_access(addr, rnw, value);
DEBUG_PROTO("0x%08" PRIx32 "\n", rnw ? ret : value);
return ret;
}

uint32_t adiv5_ap_read(adiv5_access_port_s *ap, uint16_t addr)
{
uint32_t ret = ap->dp->ap_read(ap, addr);
decode_access(addr, ADIV5_LOW_READ);
decode_access(addr, ADIV5_LOW_READ, 0U);
DEBUG_PROTO("0x%08" PRIx32 "\n", ret);
return ret;
}

void adiv5_ap_write(adiv5_access_port_s *ap, uint16_t addr, uint32_t value)
{
decode_access(addr, ADIV5_LOW_WRITE);
decode_access(addr, ADIV5_LOW_WRITE, value);
DEBUG_PROTO("0x%08" PRIx32 "\n", value);
ap->dp->ap_write(ap, addr, value);
}
Expand Down
Loading