From c4d7232223ab6bee4261d03631117ff44258df69 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 8 Mar 2020 13:08:54 +0100 Subject: [PATCH 01/17] Export function to read out PIDR and use for samd and samx5x. --- src/target/adiv5.c | 40 +++++++++++++++++++++------------------- src/target/adiv5.h | 2 +- src/target/samd.c | 40 +++++----------------------------------- src/target/samx5x.c | 29 +++++------------------------ 4 files changed, 32 insertions(+), 79 deletions(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 38f38e4e..7cccffa6 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -210,6 +210,7 @@ static const struct { {0xc09, aa_cortexa, cidc_dc, PIDR_PN_BIT_STRINGS("Cortex-A9 Debug", "(Debug Unit)")}, {0xc0f, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-A15 Debug", "(Debug Unit)")}, /* support? */ {0xc14, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-R4 Debug", "(Debug Unit)")}, /* support? */ + {0xcd0, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Atmel DSU", "(Device Service Unit)")}, {0xd21, aa_nosupport, cidc_unknown, PIDR_PN_BIT_STRINGS("Cortex-M33", "()")}, /* support? */ {0xfff, aa_end, cidc_unknown, PIDR_PN_BIT_STRINGS("end", "end")} }; @@ -252,12 +253,29 @@ static uint32_t adiv5_mem_read32(ADIv5_AP_t *ap, uint32_t addr) return ret; } +static uint32_t adiv5_ap_read_id(ADIv5_AP_t *ap, uint32_t addr) +{ + uint32_t res = 0; + for (int i = 0; i < 4; i++) { + uint32_t x = adiv5_mem_read32(ap, addr + 4 * i); + res |= (x & 0xff) << (i * 8); + } + return res; +} + +uint64_t adiv5_ap_read_pidr(ADIv5_AP_t *ap, uint32_t addr) +{ + uint64_t pidr = adiv5_ap_read_id(ap, addr + PIDR4_OFFSET); + pidr = pidr << 32 | adiv5_ap_read_id(ap, addr + PIDR0_OFFSET); + return pidr; +} + static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, int num_entry) { (void) num_entry; addr &= ~3; - uint64_t pidr = 0; - uint32_t cidr = 0; + uint64_t pidr = adiv5_ap_read_pidr(ap, addr); + uint32_t cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET); bool res = false; #if defined(ENABLE_DEBUG) && defined(PLATFORM_HAS_DEBUG) char indent[recursion + 1]; @@ -266,22 +284,6 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, indent[recursion] = 0; #endif - /* Assemble logical Product ID register value. */ - for (int i = 0; i < 4; i++) { - uint32_t x = adiv5_mem_read32(ap, addr + PIDR0_OFFSET + 4*i); - pidr |= (x & 0xff) << (i * 8); - } - { - uint32_t x = adiv5_mem_read32(ap, addr + PIDR4_OFFSET); - pidr |= (uint64_t)x << 32; - } - - /* Assemble logical Component ID register value. */ - for (int i = 0; i < 4; i++) { - uint32_t x = adiv5_mem_read32(ap, addr + CIDR0_OFFSET + 4*i); - cidr |= ((uint64_t)(x & 0xff)) << (i * 8); - } - if (adiv5_dp_error(ap->dp)) { DEBUG("%sFault reading ID registers\n", indent); return false; @@ -376,7 +378,7 @@ static bool adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, cortexm_probe(ap, false); break; case aa_cortexa: - DEBUG("%s-> cortexa_probe\n", indent + 1); + DEBUG("\n -> cortexa_probe\n"); cortexa_probe(ap, addr); break; default: diff --git a/src/target/adiv5.h b/src/target/adiv5.h index 65f47197..60d89333 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -198,5 +198,5 @@ void adiv5_mem_read(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len); void adiv5_mem_write(ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len); void adiv5_mem_write_sized(ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len, enum align align); - +uint64_t adiv5_ap_read_pidr(ADIv5_AP_t *ap, uint32_t addr); #endif diff --git a/src/target/samd.c b/src/target/samd.c index 2a5c7e03..18da3bc4 100644 --- a/src/target/samd.c +++ b/src/target/samd.c @@ -113,10 +113,8 @@ const struct command_s samd_cmd_list[] = { #define SAMD_DSU_ADDRESS (SAMD_DSU_EXT_ACCESS + 0x4) #define SAMD_DSU_LENGTH (SAMD_DSU_EXT_ACCESS + 0x8) #define SAMD_DSU_DID (SAMD_DSU_EXT_ACCESS + 0x018) -#define SAMD_DSU_PID(n) (SAMD_DSU + 0x1FE0 + \ - (0x4 * (n % 4)) - (0x10 * (n / 4))) -#define SAMD_DSU_CID(n) (SAMD_DSU + 0x1FF0 + \ - (0x4 * (n % 4))) +#define SAMD_DSU_PID (SAMD_DSU + 0x1000) +#define SAMD_DSU_CID (SAMD_DSU + 0x1010) /* Control and Status Register (CTRLSTAT) */ #define SAMD_CTRL_CHIP_ERASE (1 << 4) @@ -221,35 +219,6 @@ static const struct samd_part samd_l22_parts[] = { {0xFF, 0, 0, 0} }; -/** - * Reads the SAM D20 Peripheral ID - */ -uint64_t samd_read_pid(target *t) -{ - uint64_t pid = 0; - uint8_t i, j; - - /* Five PID registers to read LSB first */ - for (i = 0, j = 0; i < 5; i++, j += 8) - pid |= (target_mem_read32(t, SAMD_DSU_PID(i)) & 0xFF) << j; - - return pid; -} -/** - * Reads the SAM D20 Component ID - */ -uint32_t samd_read_cid(target *t) -{ - uint64_t cid = 0; - uint8_t i, j; - - /* Four CID registers to read LSB first */ - for (i = 0, j = 0; i < 4; i++, j += 8) - cid |= (target_mem_read32(t, SAMD_DSU_CID(i)) & 0xFF) << j; - - return cid; -} - /** * Overloads the default cortexm reset function with a version that * removes the target from extended reset where required. @@ -474,8 +443,9 @@ static void samd_add_flash(target *t, uint32_t addr, size_t length) char variant_string[60]; bool samd_probe(target *t) { - uint32_t cid = samd_read_cid(t); - uint32_t pid = samd_read_pid(t); + ADIv5_AP_t *ap = cortexm_ap(t); + uint32_t cid = adiv5_ap_read_pidr(ap, SAMD_DSU_CID); + uint32_t pid = adiv5_ap_read_pidr(ap, SAMD_DSU_PID); /* Check the ARM Coresight Component and Perhiperal IDs */ if ((cid != SAMD_CID_VALUE) || diff --git a/src/target/samx5x.c b/src/target/samx5x.c index e23912c3..f8067bc3 100644 --- a/src/target/samx5x.c +++ b/src/target/samx5x.c @@ -169,11 +169,8 @@ const struct command_s samx5x_protected_cmd_list[] = { #define SAMX5X_DSU_LENGTH (SAMX5X_DSU_EXT_ACCESS + 0x08) #define SAMX5X_DSU_DATA (SAMX5X_DSU_EXT_ACCESS + 0x0C) #define SAMX5X_DSU_DID (SAMX5X_DSU_EXT_ACCESS + 0x18) -#define SAMX5X_DSU_PID(n) (SAMX5X_DSU + 0x1FE0 + \ - (0x4 * (n % 4)) - \ - (0x10 * (n / 4))) -#define SAMX5X_DSU_CID(n) (SAMX5X_DSU + 0x1FF0 + \ - (0x4 * (n % 4))) +#define SAMX5X_DSU_PID (SAMX5X_DSU + 0x1000) +#define SAMX5X_DSU_CID (SAMX5X_DSU + 0x1010) /* Control and Status Register (CTRLSTAT) */ #define SAMX5X_CTRL_CHIP_ERASE (1 << 4) @@ -219,23 +216,6 @@ const struct command_s samx5x_protected_cmd_list[] = { /* Component ID */ #define SAMX5X_CID_VALUE 0xB105100D -/** - * Reads the SAM D5x/E5x Peripheral ID - * - * (Reuses the SAM D1x/2x implementation as it is identical) - */ -extern uint64_t samd_read_pid(target *t); -#define samx5x_read_pid samd_read_pid - -/** - * Reads the SAM D5x/E5x Component ID - * - * (Reuses the SAM D1x/2x implementation as it is identical) - */ -extern uint32_t samd_read_cid(target *t); -#define samx5x_read_cid samd_read_cid - - /** * Overloads the default cortexm reset function with a version that * removes the target from extended reset where required. @@ -367,8 +347,9 @@ static void samx5x_add_flash(target *t, uint32_t addr, size_t length, char variant_string[60]; bool samx5x_probe(target *t) { - uint32_t cid = samx5x_read_cid(t); - uint32_t pid = samx5x_read_pid(t); + ADIv5_AP_t *ap = cortexm_ap(t); + uint32_t cid = adiv5_ap_read_pidr(ap, SAMX5X_DSU_CID); + uint32_t pid = adiv5_ap_read_pidr(ap, SAMX5X_DSU_PID); /* Check the ARM Coresight Component and Perhiperal IDs */ if ((cid != SAMX5X_CID_VALUE) || From 9ca401497cc00d0b4155ce3bb06b142f2fe4b515 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 27 Mar 2020 12:26:20 +0100 Subject: [PATCH 02/17] stm32/timing_stm32.c: Remove fixed constants and direct SCB access --- src/platforms/stm32/timing_stm32.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/platforms/stm32/timing_stm32.c b/src/platforms/stm32/timing_stm32.c index 234f039e..ca10de3f 100644 --- a/src/platforms/stm32/timing_stm32.c +++ b/src/platforms/stm32/timing_stm32.c @@ -20,7 +20,8 @@ #include "morse.h" #include -#include +#include +#include uint8_t running_status; static volatile uint32_t time_ms; @@ -29,9 +30,10 @@ void platform_timing_init(void) { /* Setup heartbeat timer */ systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); - systick_set_reload(900000); /* Interrupt us at 10 Hz */ - SCB_SHPR(11) &= ~((15 << 4) & 0xff); - SCB_SHPR(11) |= ((14 << 4) & 0xff); + /* Interrupt us at 10 Hz */ + systick_set_reload(rcc_ahb_frequency / (8 * 10) ); + /* SYSTICK_IRQ with low priority */ + nvic_set_priority(NVIC_SYSTICK_IRQ, 14 << 4); systick_interrupt_enable(); systick_counter_enable(); } From bd73adf9c7012179d49adb6a153d72f95787ba66 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 22 Mar 2020 19:12:49 +0100 Subject: [PATCH 03/17] bmp/pc platforms: Deduplicate code. --- src/platforms/libftdi/Makefile.inc | 2 +- src/platforms/libftdi/platform.c | 27 ------------- src/platforms/pc-hosted/Makefile.inc | 2 +- src/platforms/pc-hosted/platform.c | 26 ------------ src/platforms/pc-stlinkv2/Makefile.inc | 2 +- src/platforms/pc-stlinkv2/platform.c | 26 ------------ src/platforms/pc/utils.c | 55 ++++++++++++++++++++++++++ 7 files changed, 58 insertions(+), 82 deletions(-) create mode 100644 src/platforms/pc/utils.c diff --git a/src/platforms/libftdi/Makefile.inc b/src/platforms/libftdi/Makefile.inc index 9686050a..12c46966 100644 --- a/src/platforms/libftdi/Makefile.inc +++ b/src/platforms/libftdi/Makefile.inc @@ -8,5 +8,5 @@ else ifneq (, $(findstring cygwin, $(SYS))) LDFLAGS += -lusb-1.0 -lws2_32 endif VPATH += platforms/pc -SRC += timing.c cl_utils.c +SRC += timing.c cl_utils.c utils.c CFLAGS +=-I ./target -I./platforms/pc diff --git a/src/platforms/libftdi/platform.c b/src/platforms/libftdi/platform.c index 643304c9..8fad4ccd 100644 --- a/src/platforms/libftdi/platform.c +++ b/src/platforms/libftdi/platform.c @@ -290,34 +290,7 @@ int platform_buffer_read(uint8_t *data, int size) return size; } -#if defined(_WIN32) && !defined(__MINGW32__) -#warning "This vasprintf() is dubious!" -int vasprintf(char **strp, const char *fmt, va_list ap) -{ - int size = 128, ret = 0; - - *strp = malloc(size); - while(*strp && ((ret = vsnprintf(*strp, size, fmt, ap)) == size)) - *strp = realloc(*strp, size <<= 1); - - return ret; -} -#endif - const char *platform_target_voltage(void) { return "not supported"; } - -void platform_delay(uint32_t ms) -{ - usleep(ms * 1000); -} - -uint32_t platform_time_ms(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); -} - diff --git a/src/platforms/pc-hosted/Makefile.inc b/src/platforms/pc-hosted/Makefile.inc index 8a35408a..2ddb9fb6 100644 --- a/src/platforms/pc-hosted/Makefile.inc +++ b/src/platforms/pc-hosted/Makefile.inc @@ -11,4 +11,4 @@ else ifneq (, $(findstring cygwin, $(SYS))) LDFLAGS += -lusb-1.0 -lws2_32 endif VPATH += platforms/pc -SRC += cl_utils.c timing.c +SRC += cl_utils.c timing.c utils.c diff --git a/src/platforms/pc-hosted/platform.c b/src/platforms/pc-hosted/platform.c index d543cfb7..f95859e8 100644 --- a/src/platforms/pc-hosted/platform.c +++ b/src/platforms/pc-hosted/platform.c @@ -307,20 +307,6 @@ int platform_buffer_read(uint8_t *data, int maxsize) return 0; } -#if defined(_WIN32) && !defined(__MINGW32__) -#warning "This vasprintf() is dubious!" -int vasprintf(char **strp, const char *fmt, va_list ap) -{ - int size = 128, ret = 0; - - *strp = malloc(size); - while(*strp && ((ret = vsnprintf(*strp, size, fmt, ap)) == size)) - *strp = realloc(*strp, size <<= 1); - - return ret; -} -#endif - const char *platform_target_voltage(void) { @@ -340,15 +326,3 @@ const char *platform_target_voltage(void) return (char *)&construct[1]; } - -void platform_delay(uint32_t ms) -{ - usleep(ms * 1000); -} - -uint32_t platform_time_ms(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); -} diff --git a/src/platforms/pc-stlinkv2/Makefile.inc b/src/platforms/pc-stlinkv2/Makefile.inc index 17774743..299a8150 100644 --- a/src/platforms/pc-stlinkv2/Makefile.inc +++ b/src/platforms/pc-stlinkv2/Makefile.inc @@ -9,5 +9,5 @@ else ifneq (, $(findstring cygwin, $(SYS))) LDFLAGS += -lws2_32 endif VPATH += platforms/pc -SRC += timing.c stlinkv2.c cl_utils.c +SRC += timing.c stlinkv2.c cl_utils.c utils.c OWN_HL = 1 diff --git a/src/platforms/pc-stlinkv2/platform.c b/src/platforms/pc-stlinkv2/platform.c index 61e17965..e3f0a1f1 100644 --- a/src/platforms/pc-stlinkv2/platform.c +++ b/src/platforms/pc-stlinkv2/platform.c @@ -69,29 +69,3 @@ int platform_buffer_read(uint8_t *data, int size) (void) data; return size; } - -#if defined(_WIN32) && !defined(__MINGW32__) -#warning "This vasprintf() is dubious!" -int vasprintf(char **strp, const char *fmt, va_list ap) -{ - int size = 128, ret = 0; - - *strp = malloc(size); - while(*strp && ((ret = vsnprintf(*strp, size, fmt, ap)) == size)) - *strp = realloc(*strp, size <<= 1); - - return ret; -} -#endif - -void platform_delay(uint32_t ms) -{ - usleep(ms * 1000); -} - -uint32_t platform_time_ms(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); -} diff --git a/src/platforms/pc/utils.c b/src/platforms/pc/utils.c new file mode 100644 index 00000000..b74c8ae3 --- /dev/null +++ b/src/platforms/pc/utils.c @@ -0,0 +1,55 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de) + * Base on code: + * Copyright (C) 2011 Black Sphere Technologies Ltd. + * Written by Gareth McMullin + * and others. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* This file deduplicates codes used in several pc-hosted platforms + */ + +#include +#include +#include + +#if defined(_WIN32) && !defined(__MINGW32__) +#warning "This vasprintf() is dubious!" +int vasprintf(char **strp, const char *fmt, va_list ap) +{ + int size = 128, ret = 0; + + *strp = malloc(size); + while(*strp && ((ret = vsnprintf(*strp, size, fmt, ap)) == size)) + *strp = realloc(*strp, size <<= 1); + + return ret; +} +#endif + +void platform_delay(uint32_t ms) +{ + usleep(ms * 1000); +} + +uint32_t platform_time_ms(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); +} From 1a0cee4e9dcdb2e40f2154b87dbb6a37d9ff1f66 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 27 Mar 2020 22:49:36 +0100 Subject: [PATCH 04/17] pc-hosted: Clean up Makefile.inc. --- src/platforms/pc-hosted/Makefile.inc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/platforms/pc-hosted/Makefile.inc b/src/platforms/pc-hosted/Makefile.inc index 2ddb9fb6..3867e805 100644 --- a/src/platforms/pc-hosted/Makefile.inc +++ b/src/platforms/pc-hosted/Makefile.inc @@ -1,14 +1,11 @@ TARGET=blackmagic_hosted SYS = $(shell $(CC) -dumpmachine) -CFLAGS += -DPC_HOSTED -DNO_LIBOPENCM3 -DENABLE_DEBUG -I -CFLAGS += $(shell pkg-config --cflags libftdi1) +CFLAGS += -DPC_HOSTED -DNO_LIBOPENCM3 -DENABLE_DEBUG CFLAGS +=-I ./target -I./platforms/pc -LDFLAGS += $(shell pkg-config --libs libftdi1) ifneq (, $(findstring mingw, $(SYS))) -LDFLAGS += -lusb-1.0 -lws2_32 -CFLAGS += -Wno-cast-function-type +LDFLAGS += -lws2_32 else ifneq (, $(findstring cygwin, $(SYS))) -LDFLAGS += -lusb-1.0 -lws2_32 +LDFLAGS += -lws2_32 endif VPATH += platforms/pc SRC += cl_utils.c timing.c utils.c From 18ae2bb50de7d71c51101994efd5a8405980e2cd Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 27 Mar 2020 22:53:39 +0100 Subject: [PATCH 05/17] cl_utils.c: Include for windows builds that work on files. --- src/platforms/pc/cl_utils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index e5b55d1c..6ec5ea97 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -38,6 +38,7 @@ #define O_BINARY 0 #endif #if defined(_WIN32) || defined(__CYGWIN__) +# include #else # include #endif From b4ab9f328ed123eeaaa3dfaa4089b30f5d1d376c Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 28 Mar 2020 17:27:21 +0100 Subject: [PATCH 06/17] pc-hosted: Put serial handling in own files for unix and implement for windows. - If host provided /dev/serial/by-id, device must not be given and multiple devices may be selected with -s <(partial) serial number> - On windows, device must by specifies with -d --- src/platforms/pc-hosted/Makefile.inc | 4 + src/platforms/pc-hosted/platform.c | 169 +-------------------- src/platforms/pc-hosted/platform.h | 4 +- src/platforms/pc/cl_utils.c | 15 +- src/platforms/pc/cl_utils.h | 3 + src/platforms/pc/serial_unix.c | 215 +++++++++++++++++++++++++++ src/platforms/pc/serial_win.c | 139 +++++++++++++++++ 7 files changed, 380 insertions(+), 169 deletions(-) create mode 100644 src/platforms/pc/serial_unix.c create mode 100644 src/platforms/pc/serial_win.c diff --git a/src/platforms/pc-hosted/Makefile.inc b/src/platforms/pc-hosted/Makefile.inc index 3867e805..9493b0cf 100644 --- a/src/platforms/pc-hosted/Makefile.inc +++ b/src/platforms/pc-hosted/Makefile.inc @@ -3,9 +3,13 @@ SYS = $(shell $(CC) -dumpmachine) CFLAGS += -DPC_HOSTED -DNO_LIBOPENCM3 -DENABLE_DEBUG CFLAGS +=-I ./target -I./platforms/pc ifneq (, $(findstring mingw, $(SYS))) +SRC += serial_win.c LDFLAGS += -lws2_32 else ifneq (, $(findstring cygwin, $(SYS))) +SRC += serial_win.c LDFLAGS += -lws2_32 +else +SRC += serial_unix.c endif VPATH += platforms/pc SRC += cl_utils.c timing.c utils.c diff --git a/src/platforms/pc-hosted/platform.c b/src/platforms/pc-hosted/platform.c index f95859e8..361574d5 100644 --- a/src/platforms/pc-hosted/platform.c +++ b/src/platforms/pc-hosted/platform.c @@ -25,77 +25,16 @@ #include "remote.h" #include -#include #include -#include #include -#include -#include #include -#include #include -#include -#include #include "cl_utils.h" - -/* Allow 100mS for responses to reach us */ -#define RESP_TIMEOUT (100) - -/* Define this to see the transactions across the link */ -//#define DUMP_TRANSACTIONS - -static int f; /* File descriptor for connection to GDB remote */ - -int set_interface_attribs (int fd, int speed, int parity) - -/* A nice routine grabbed from - * https://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c - */ - -{ - struct termios tty; - memset (&tty, 0, sizeof tty); - if (tcgetattr (fd, &tty) != 0) - { - fprintf(stderr,"error %d from tcgetattr", errno); - return -1; - } - - cfsetospeed (&tty, speed); - cfsetispeed (&tty, speed); - - tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars - // disable IGNBRK for mismatched speed tests; otherwise receive break - // as \000 chars - tty.c_iflag &= ~IGNBRK; // disable break processing - tty.c_lflag = 0; // no signaling chars, no echo, - // no canonical processing - tty.c_oflag = 0; // no remapping, no delays - tty.c_cc[VMIN] = 0; // read doesn't block - tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout - - tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl - - tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, - // enable reading - tty.c_cflag &= ~(PARENB | PARODD); // shut off parity - tty.c_cflag |= parity; - tty.c_cflag &= ~CSTOPB; - tty.c_cflag &= ~CRTSCTS; - - if (tcsetattr (fd, TCSANOW, &tty) != 0) - { - fprintf(stderr,"error %d from tcsetattr", errno); - return -1; - } - return 0; -} - +static BMP_CL_OPTIONS_t cl_opts; /* Portable way to nullify the struct*/ void platform_init(int argc, char **argv) { - BMP_CL_OPTIONS_t cl_opts = {0}; cl_opts.opt_idstring = "Blackmagic Debug Probe Remote"; cl_init(&cl_opts, argc, argv); char construct[PLATFORM_MAX_MSG_SIZE]; @@ -105,18 +44,8 @@ void platform_init(int argc, char **argv) printf("License GPLv3+: GNU GPL version 3 or later " "\n\n"); - f=open(cl_opts.opt_serial,O_RDWR|O_SYNC|O_NOCTTY); - if (f<0) - { - fprintf(stderr,"Couldn't open serial port %s\n", cl_opts.opt_serial); - exit(-1); - } - - if (set_interface_attribs (f, 115000, 0)<0) - { - exit(-1); - } - + if (serial_open(&cl_opts)) + exit(-1); int c=snprintf(construct,PLATFORM_MAX_MSG_SIZE,"%s",REMOTE_START_STR); platform_buffer_write((uint8_t *)construct,c); c=platform_buffer_read((uint8_t *)construct, PLATFORM_MAX_MSG_SIZE); @@ -132,7 +61,7 @@ void platform_init(int argc, char **argv) int ret = cl_execute(&cl_opts); if (cl_opts.opt_tpwr) platform_target_set_power(0); - close(f); + serial_close(); exit(ret); } else { assert(gdb_if_init() == 0); @@ -217,96 +146,6 @@ void platform_buffer_flush(void) } -int platform_buffer_write(const uint8_t *data, int size) -{ - int s; - -#ifdef DUMP_TRANSACTIONS - printf("%s\n",data); -#endif - s=write(f,data,size); - if (s<0) - { - fprintf(stderr,"Failed to write\n"); - exit(-2); - } - - return size; -} - -int platform_buffer_read(uint8_t *data, int maxsize) - -{ - uint8_t *c; - int s; - int ret; - uint32_t endTime; - fd_set rset; - struct timeval tv; - - c=data; - tv.tv_sec=0; - - endTime=platform_time_ms()+RESP_TIMEOUT; - tv.tv_usec=1000*(endTime-platform_time_ms()); - - /* Look for start of response */ - do - { - FD_ZERO(&rset); - FD_SET(f, &rset); - - ret = select(f + 1, &rset, NULL, NULL, &tv); - if (ret < 0) - { - fprintf(stderr,"Failed on select\n"); - exit(-4); - } - if(ret == 0) - { - fprintf(stderr,"Timeout on read\n"); - exit(-3); - } - - s=read(f,c,1); - } - while ((s>0) && (*c!=REMOTE_RESP)); - - /* Now collect the response */ - do - { - FD_ZERO(&rset); - FD_SET(f, &rset); - ret = select(f + 1, &rset, NULL, NULL, &tv); - if (ret < 0) - { - fprintf(stderr,"Failed on select\n"); - exit(-4); - } - if(ret == 0) - { - fprintf(stderr,"Timeout on read\n"); - exit(-3); - } - s=read(f,c,1); - if (*c==REMOTE_EOM) - { - *c=0; -#ifdef DUMP_TRANSACTIONS - printf(" %s\n",data); -#endif - return (c-data); - } - else - c++; - } - while ((s>=0) && (c-dataopt_target_dev = 1; opt->opt_flash_start = 0x08000000; opt->opt_flash_size = 16 * 1024 *1024; - while((c = getopt(argc, argv, "Ehv::s:c:CnN:tVta:S:jprR")) != -1) { + while((c = getopt(argc, argv, "Ehv::d:s:c:CnN:tVta:S:jprR")) != -1) { switch(c) { case 'c': if (optarg) @@ -156,7 +160,9 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv) break; case 'v': if (optarg) - opt->opt_debuglevel = strtol(optarg, NULL, 0); + cl_debuglevel = strtol(optarg, NULL, 0); + else + cl_debuglevel = -1; break; case 'j': opt->opt_usejtag = true; @@ -167,6 +173,10 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv) case 'n': opt->opt_no_wait = true; break; + case 'd': + if (optarg) + opt->opt_device = optarg; + break; case 's': if (optarg) opt->opt_serial = optarg; @@ -277,7 +287,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) goto target_detach; } int read_file = -1; - struct mmap_data map = {0}; if ((opt->opt_mode == BMP_MODE_FLASH_WRITE) || (opt->opt_mode == BMP_MODE_FLASH_VERIFY)) { int mmap_res = bmp_mmap(opt->opt_flash_file, &map); diff --git a/src/platforms/pc/cl_utils.h b/src/platforms/pc/cl_utils.h index 850112b5..6e89656d 100644 --- a/src/platforms/pc/cl_utils.h +++ b/src/platforms/pc/cl_utils.h @@ -41,6 +41,7 @@ typedef struct BMP_CL_OPTIONS_s { bool opt_tpwr; bool opt_connect_under_reset; char *opt_flash_file; + char *opt_device; char *opt_serial; char *opt_cable; int opt_debuglevel; @@ -52,4 +53,6 @@ typedef struct BMP_CL_OPTIONS_s { void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv); int cl_execute(BMP_CL_OPTIONS_t *opt); +int serial_open(BMP_CL_OPTIONS_t *opt); +void serial_close(void); #endif diff --git a/src/platforms/pc/serial_unix.c b/src/platforms/pc/serial_unix.c new file mode 100644 index 00000000..c4688b08 --- /dev/null +++ b/src/platforms/pc/serial_unix.c @@ -0,0 +1,215 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2019 Dave Marples + * with additions from Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "general.h" +#include "remote.h" +#include "cl_utils.h" + +static int fd; /* File descriptor for connection to GDB remote */ +extern int cl_debuglevel; +/* A nice routine grabbed from + * https://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c + */ +static int set_interface_attribs(void) +{ + struct termios tty; + memset (&tty, 0, sizeof tty); + if (tcgetattr (fd, &tty) != 0) { + fprintf(stderr,"error %d from tcgetattr", errno); + return -1; + } + + tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars + // disable IGNBRK for mismatched speed tests; otherwise receive break + // as \000 chars + tty.c_iflag &= ~IGNBRK; // disable break processing + tty.c_lflag = 0; // no signaling chars, no echo, + // no canonical processing + tty.c_oflag = 0; // no remapping, no delays + tty.c_cc[VMIN] = 0; // read doesn't block + tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout + + tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl + + tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, + // enable reading + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CRTSCTS; + + if (tcsetattr (fd, TCSANOW, &tty) != 0) { + fprintf(stderr,"error %d from tcsetattr", errno); + return -1; + } + return 0; +} +#define BMP_IDSTRING "usb-Black_Sphere_Technologies_Black_Magic_Probe" +#define DEVICE_BY_ID "/dev/serial/by-id/" +int serial_open(BMP_CL_OPTIONS_t *opt) +{ + char name[256]; + if (!opt->opt_device) { + /* Try to find some BMP if0*/ + struct dirent *dp; + DIR *dir = opendir(DEVICE_BY_ID); + if (!dir) { + fprintf(stderr, "No serial device found\n"); + return -1; + } + int num_devices = 0; + int num_total = 0; + while ((dp = readdir(dir)) != NULL) { + if ((strstr(dp->d_name, BMP_IDSTRING)) && + (strstr(dp->d_name, "-if00"))) { + num_total++; + if (((opt->opt_serial) && + (!strstr(dp->d_name, opt->opt_serial)))) + continue; + num_devices++; + strcpy(name, DEVICE_BY_ID); + strncat(name, dp->d_name, sizeof(name) - strlen(name) - 1); + } + } + closedir(dir); + if ((num_devices == 0) && (num_total == 0)){ + fprintf(stderr, "No BMP probe found\n"); + return -1; + } else if (num_devices != 1) { + fprintf(stderr, "Available Probes:\n"); + dir = opendir(DEVICE_BY_ID); + if (dir) { + while ((dp = readdir(dir)) != NULL) { + if ((strstr(dp->d_name, BMP_IDSTRING)) && + (strstr(dp->d_name, "-if00"))) + fprintf(stderr, "%s\n", dp->d_name); + } + closedir(dir); + if (opt->opt_serial) + fprintf(stderr, "Do no match given serial \"%s\"\n", opt->opt_serial); + else + fprintf(stderr, "Select Probe with -s <(Partial) Serial Number\n"); + } else { + fprintf(stderr, "Could not opendir %s: %s\n", name, strerror(errno)); + } + return -1; + } + } else { + strncpy(name, opt->opt_device, sizeof(name) - 1); + } + fd = open(name, O_RDWR | O_SYNC | O_NOCTTY); + if (fd < 0) { + fprintf(stderr,"Couldn't open serial port %s\n", name); + return -1; + } + /* BMP only offers an USB-Serial connection with no real serial + * line in between. No need for baudrate or parity.! + */ + return set_interface_attribs(); +} + +void serial_close(void) +{ + close(fd); +} + +int platform_buffer_write(const uint8_t *data, int size) +{ + int s; + + if (cl_debuglevel) + printf("%s\n",data); + s = write(fd, data, size); + if (s < 0) { + fprintf(stderr, "Failed to write\n"); + exit(-2); + } + + return size; +} + +int platform_buffer_read(uint8_t *data, int maxsize) +{ + uint8_t *c; + int s; + int ret; + uint32_t endTime; + fd_set rset; + struct timeval tv; + + c = data; + tv.tv_sec = 0; + + endTime = platform_time_ms() + RESP_TIMEOUT; + tv.tv_usec = 1000 * (endTime - platform_time_ms()); + + /* Look for start of response */ + do { + FD_ZERO(&rset); + FD_SET(fd, &rset); + + ret = select(fd + 1, &rset, NULL, NULL, &tv); + if (ret < 0) { + fprintf(stderr,"Failed on select\n"); + exit(-4); + } + if(ret == 0) { + fprintf(stderr,"Timeout on read RESP\n"); + exit(-3); + } + + s = read(fd, c, 1); + } + while ((s > 0) && (*c != REMOTE_RESP)); + /* Now collect the response */ + do { + FD_ZERO(&rset); + FD_SET(fd, &rset); + ret = select(fd + 1, &rset, NULL, NULL, &tv); + if (ret < 0) { + fprintf(stderr,"Failed on select\n"); + exit(-4); + } + if(ret == 0) { + fprintf(stderr,"Timeout on read\n"); + exit(-3); + } + s = read(fd, c, 1); + if (*c==REMOTE_EOM) { + *c = 0; + if (cl_debuglevel) + printf(" %s\n",data); + return (c - data); + } else { + c++; + } + }while ((s >= 0) && ((c - data) < maxsize)); + + fprintf(stderr,"Failed to read\n"); + exit(-3); + return 0; +} + diff --git a/src/platforms/pc/serial_win.c b/src/platforms/pc/serial_win.c new file mode 100644 index 00000000..a39d1a1a --- /dev/null +++ b/src/platforms/pc/serial_win.c @@ -0,0 +1,139 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "general.h" +#include +#include "remote.h" +#include "cl_utils.h" + +HANDLE hComm; +extern int cl_debuglevel; + +int serial_open(BMP_CL_OPTIONS_t *opt) +{ + if (!opt->opt_device) { + fprintf(stderr,"Specify the serial device to use!\n"); + return -1; + } + char device[256]; + if (strstr(opt->opt_device, "\\\\.\\")) { + strncpy(device, opt->opt_device, sizeof(device) - 1); + } else { + strcpy(device, "\\\\.\\"); + strncat(device, opt->opt_device, sizeof(device) - strlen(device) - 1); + } + hComm = CreateFile(device, //port name + GENERIC_READ | GENERIC_WRITE, //Read/Write + 0, // No Sharing + NULL, // No Security + OPEN_EXISTING,// Open existing port only + 0, // Non Overlapped I/O + NULL); // Null for Comm Devices} + if (hComm == INVALID_HANDLE_VALUE) { + fprintf(stderr, "Could not open %s: %ld\n", device, + GetLastError()); + return -1; + } + DCB dcbSerialParams; + dcbSerialParams.DCBlength = sizeof(dcbSerialParams); + if (!GetCommState(hComm, &dcbSerialParams)) { + fprintf(stderr, "GetCommState failed %ld\n", GetLastError()); + return -1; + } + dcbSerialParams.ByteSize = 8; + if (!SetCommState(hComm, &dcbSerialParams)) { + fprintf(stderr, "SetCommState failed %ld\n", GetLastError()); + return -1; + } + COMMTIMEOUTS timeouts = {0}; + timeouts.ReadIntervalTimeout = 10; + timeouts.ReadTotalTimeoutConstant = 10; + timeouts.ReadTotalTimeoutMultiplier = 10; + timeouts.WriteTotalTimeoutConstant = 10; + timeouts.WriteTotalTimeoutMultiplier = 10; + if (!SetCommTimeouts(hComm, &timeouts)) { + fprintf(stderr, "SetCommTimeouts failed %ld\n", GetLastError()); + return -1; + } + return 0; +} + +void serial_close(void) +{ + CloseHandle(hComm); +} + +int platform_buffer_write(const uint8_t *data, int size) +{ + if (cl_debuglevel) + printf("%s\n",data); + int s = 0; + + do { + DWORD written; + if (!WriteFile(hComm, data + s, size - s, &written, NULL)) { + fprintf(stderr, "Serial write failed %ld, written %d\n", + GetLastError(), s); + return -1; + } + s += written; + } while (s < size); + return 0; +} +int platform_buffer_read(uint8_t *data, int maxsize) +{ + DWORD s; + uint8_t response = 0; + uint32_t startTime = platform_time_ms(); + uint32_t endTime = platform_time_ms() + RESP_TIMEOUT; + do { + if (!ReadFile(hComm, &response, 1, &s, NULL)) { + fprintf(stderr,"ERROR on read RESP\n"); + exit(-3); + } + if (platform_time_ms() > endTime) { + fprintf(stderr,"Timeout on read RESP\n"); + exit(-4); + } + } while (response != REMOTE_RESP); + uint8_t *c = data; + do { + if (!ReadFile(hComm, c, 1, &s, NULL)) { + fprintf(stderr,"Error on read\n"); + exit(-3); + } + if (s > 0 ) { + if (cl_debuglevel) + printf("%c", *c); + if (*c == REMOTE_EOM) { + *c = 0; + if (cl_debuglevel) + printf("\n"); + return (c - data); + } else { + c++; + } + } + } while (((c - data) < maxsize) && (platform_time_ms() < endTime)); + fprintf(stderr,"Failed to read EOM at %d\n", + platform_time_ms() - startTime); + exit(-3); + return 0; +} From 8a9980cd06d0a72d271738b96fe71ddd5a56ce12 Mon Sep 17 00:00:00 2001 From: Francesco Valla Date: Fri, 3 Apr 2020 10:50:48 +0200 Subject: [PATCH 07/17] pc/serial_unix: bump device path buffer size to 4096 bytes Since dp->d_name can be up to 255 bytes long and the 'name' buffer variable is is a superset of it, bump the size of the latter to 4096 bytes (correspoding to PATH_MAX on Linux systems). --- src/platforms/pc/serial_unix.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/platforms/pc/serial_unix.c b/src/platforms/pc/serial_unix.c index c4688b08..cc186578 100644 --- a/src/platforms/pc/serial_unix.c +++ b/src/platforms/pc/serial_unix.c @@ -71,7 +71,7 @@ static int set_interface_attribs(void) #define DEVICE_BY_ID "/dev/serial/by-id/" int serial_open(BMP_CL_OPTIONS_t *opt) { - char name[256]; + char name[4096]; if (!opt->opt_device) { /* Try to find some BMP if0*/ struct dirent *dp; @@ -212,4 +212,3 @@ int platform_buffer_read(uint8_t *data, int maxsize) exit(-3); return 0; } - From 58a8571d5b14110f8e3871ecbd72ae5e38259fd1 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 3 Apr 2020 13:49:51 +0200 Subject: [PATCH 08/17] stlink: Print Target voltage This adds about 600 bytes. --- src/platforms/pc/cl_utils.c | 1 + src/platforms/stlink/platform.c | 49 ++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index b04e89b9..f65c24cb 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -264,6 +264,7 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) platform_srst_set_val(opt->opt_connect_under_reset); if (opt->opt_mode == BMP_MODE_TEST) printf("Running in Test Mode\n"); + printf("Target voltage: %s Volt\n", platform_target_voltage()); if (opt->opt_usejtag) { num_targets = jtag_scan(NULL); } else { diff --git a/src/platforms/stlink/platform.c b/src/platforms/stlink/platform.c index df976cf5..64216e90 100644 --- a/src/platforms/stlink/platform.c +++ b/src/platforms/stlink/platform.c @@ -39,6 +39,7 @@ uint8_t running_status; uint16_t led_idle_run; uint16_t srst_pin; static uint32_t rev; +static void adc_init(void); int platform_hwversion(void) { @@ -85,6 +86,7 @@ void platform_init(void) /* Don't enable UART if we're being debugged. */ if (!(SCS_DEMCR & SCS_DEMCR_TRCENA)) usbuart_init(); + adc_init(); } void platform_srst_set_val(bool assert) @@ -105,7 +107,52 @@ bool platform_srst_get_val() return gpio_get(SRST_PORT, srst_pin) == 0; } +static void adc_init(void) +{ + rcc_periph_clock_enable(RCC_ADC1); + + gpio_set_mode(GPIOA, GPIO_MODE_INPUT, + GPIO_CNF_INPUT_ANALOG, GPIO0); + + adc_power_off(ADC1); + adc_disable_scan_mode(ADC1); + adc_set_single_conversion_mode(ADC1); + adc_disable_external_trigger_regular(ADC1); + adc_set_right_aligned(ADC1); + adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + adc_enable_temperature_sensor(); + adc_power_on(ADC1); + + /* Wait for ADC starting up. */ + for (int i = 0; i < 800000; i++) /* Wait a bit. */ + __asm__("nop"); + + adc_reset_calibration(ADC1); + adc_calibrate(ADC1); +} + const char *platform_target_voltage(void) { - return "unknown"; + static char ret[] = "0.00V"; + const uint8_t channel = 0; + adc_set_regular_sequence(ADC1, 1, (uint8_t*)&channel); + adc_start_conversion_direct(ADC1); + /* Wait for end of conversion. */ + while (!adc_eoc(ADC1)); + uint32_t platform_adc_value = adc_read_regular(ADC1); + + const uint8_t ref_channel = 17; + adc_set_regular_sequence(ADC1, 1, (uint8_t*)&ref_channel); + adc_start_conversion_direct(ADC1); + /* Wait for end of conversion. */ + while (!adc_eoc(ADC1)); + uint32_t vrefint_value = adc_read_regular(ADC1); + + /* Value in mV*/ + uint32_t val = (platform_adc_value * 2400) / vrefint_value; + ret[0] = '0' + val / 1000; + ret[2] = '0' + (val / 100) % 10; + ret[3] = '0' + (val / 10) % 10; + + return ret; } From 846dadcc39df5783988c7f030f722ab55568e6e5 Mon Sep 17 00:00:00 2001 From: Francesco Valla Date: Fri, 3 Apr 2020 17:50:32 +0200 Subject: [PATCH 09/17] lmi: add support for TM4C1294NCPDT --- src/target/lmi.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/target/lmi.c b/src/target/lmi.c index 14ae3495..fcb8a4f1 100644 --- a/src/target/lmi.c +++ b/src/target/lmi.c @@ -100,6 +100,13 @@ bool lmi_probe(target *t) lmi_add_flash(t, 0x10000); t->target_options |= CORTEXM_TOPT_INHIBIT_SRST; return true; + + case 0x101F: /* TM4C1294NCPDT */ + t->driver = lmi_driver_str; + target_add_ram(t, 0x20000000, 0x40000); + lmi_add_flash(t, 0x100000); + t->target_options |= CORTEXM_TOPT_INHIBIT_SRST; + return true; } return false; } From d1468530bd0590bd34260ffdb59a8b4685f68611 Mon Sep 17 00:00:00 2001 From: mean Date: Mon, 6 Apr 2020 13:39:34 +0200 Subject: [PATCH 10/17] add basic support for LPC11U68 (and maybe LPC11U68) --- src/target/lpc11xx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/target/lpc11xx.c b/src/target/lpc11xx.c index 43e6cd24..f93130ef 100644 --- a/src/target/lpc11xx.c +++ b/src/target/lpc11xx.c @@ -118,6 +118,11 @@ lpc11xx_probe(target *t) target_add_ram(t, 0x10000000, 0x1000); lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x1000); return true; + case 0x1000002b: // FX LPC11U6 32 kB SRAM/256 kB flash (max) + t->driver = "LPC11U6"; + target_add_ram(t, 0x10000000, 0x8000); + lpc11xx_add_flash(t, 0x00000000, 0x40000, 0x1000); + return true; case 0x3000002B: case 0x3D00002B: t->driver = "LPC1343"; From bea8436561124ab15158dfd13f5093ecd68c6363 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 14 Apr 2020 17:46:46 +0200 Subject: [PATCH 11/17] NRF5: Always set CORTEXM_TOPT_INHIBIT_SRST(#230) The problem also happens with NRF52840. Set CORTEXM_TOPT_INHIBIT_SRST for all NRF5 device. People should be more persistent! --- src/target/nrf51.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/target/nrf51.c b/src/target/nrf51.c index 41f3ffb2..17a673d1 100644 --- a/src/target/nrf51.c +++ b/src/target/nrf51.c @@ -127,6 +127,7 @@ bool nrf51_probe(target *t) if ((uid0 == 0xffffffff) || (uid1 == 0xffffffff) || (uid0 == 0) || (uid1 == 0)) return false; + t->target_options |= CORTEXM_TOPT_INHIBIT_SRST; /* Test for NRF52 device*/ uint32_t info_part = target_mem_read32(t, NRF52_PART_INFO); if ((info_part != 0xffffffff) && (info_part != 0) && @@ -150,6 +151,7 @@ bool nrf51_probe(target *t) target_add_commands(t, nrf51_cmd_list, "nRF51"); return true; } + t->target_options = 0; return false; } From 164eb43f0001849339fc3445563db2b906c4ba78 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 14 Apr 2020 18:21:42 +0200 Subject: [PATCH 12/17] NRF5: Do not reset target options. --- src/target/nrf51.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/target/nrf51.c b/src/target/nrf51.c index 17a673d1..aaaac10f 100644 --- a/src/target/nrf51.c +++ b/src/target/nrf51.c @@ -127,7 +127,6 @@ bool nrf51_probe(target *t) if ((uid0 == 0xffffffff) || (uid1 == 0xffffffff) || (uid0 == 0) || (uid1 == 0)) return false; - t->target_options |= CORTEXM_TOPT_INHIBIT_SRST; /* Test for NRF52 device*/ uint32_t info_part = target_mem_read32(t, NRF52_PART_INFO); if ((info_part != 0xffffffff) && (info_part != 0) && @@ -135,6 +134,7 @@ bool nrf51_probe(target *t) uint32_t ram_size = target_mem_read32(t, NRF52_INFO_RAM); t->idcode = info_part; t->driver = "Nordic nRF52"; + t->target_options |= CORTEXM_TOPT_INHIBIT_SRST; target_add_ram(t, 0x20000000, ram_size * 1024); nrf51_add_flash(t, 0, page_size * code_size, page_size); nrf51_add_flash(t, NRF51_UICR, page_size, page_size); @@ -146,12 +146,12 @@ bool nrf51_probe(target *t) * IDCODE is kept as '0', as deciphering is hard and * there is later no usage.*/ target_add_ram(t, 0x20000000, 0x8000); + t->target_options |= CORTEXM_TOPT_INHIBIT_SRST; nrf51_add_flash(t, 0, page_size * code_size, page_size); nrf51_add_flash(t, NRF51_UICR, page_size, page_size); target_add_commands(t, nrf51_cmd_list, "nRF51"); return true; } - t->target_options = 0; return false; } From d55cea871dc3dc9f56bdaa631da0e643a04c4949 Mon Sep 17 00:00:00 2001 From: Pieter du Preez Date: Sun, 19 Apr 2020 22:05:44 +0000 Subject: [PATCH 13/17] Fixed overrun and formatting, when dumping data in swolisten. The swolisten program failed to print the cbw buffer correctly while in dump mode. As printf() is used to print the dump, it is expected that the cbw buffer is zero-terminated, which would only be the case, if the cbw buffer is initialized with zeros, before filling it with new data. One could set the entire cbw buffer to zero, but it will be more efficient to only set the size-th byte to zero. Furthermore, if a '%' character appears in the data, printf() will attempt to format it, causing unexpected results. This patch fixes the above 2 problems, by: 1. using the size variable to set the size-th byte of the cbw buffer to zero, before passing it to printf(). 2. calling printf() with a "%s" formatting string, followed by the data buffer, cbw. --- scripts/swolisten.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/swolisten.c b/scripts/swolisten.c index 1ce141aa..f7408fd7 100644 --- a/scripts/swolisten.c +++ b/scripts/swolisten.c @@ -442,7 +442,10 @@ int usbFeeder(void) { unsigned char *c=cbw; if (options.dump) - printf(cbw); + { + cbw[size] = 0; + printf("%s", (char*)cbw); + } else while (size--) _protocolPump(c++); From ada17ada23cfde53191c806b78271a767fb87100 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 21 Apr 2020 11:43:08 +0200 Subject: [PATCH 14/17] stm32f4/7: Always use largest flashsize for device family (#633, #635, #644) Do not care for the FLASHSIZE register. Leave it up to the user to abuse flash area the ST did not announce. --- src/target/stm32f4.c | 64 +++++++++++++++++++++----------------------- src/target/stm32h7.c | 10 ++----- 2 files changed, 33 insertions(+), 41 deletions(-) diff --git a/src/target/stm32f4.c b/src/target/stm32f4.c index 68b37cdc..ff432682 100644 --- a/src/target/stm32f4.c +++ b/src/target/stm32f4.c @@ -159,31 +159,31 @@ static void stm32f4_add_flash(target *t, char *stm32f4_get_chip_name(uint32_t idcode) { switch(idcode){ - case ID_STM32F40X: + case ID_STM32F40X: /* F40XxE/G */ return "STM32F40x"; - case ID_STM32F42X: /* 427/437 */ + case ID_STM32F42X: /* F42XxG/I */ return "STM32F42x"; - case ID_STM32F46X: /* 469/479 */ + case ID_STM32F46X: /* 469/479 xG/I*/ return "STM32F47x"; - case ID_STM32F20X: /* F205 */ + case ID_STM32F20X: /* F205 xB/C/E/G*/ return "STM32F2"; - case ID_STM32F446: /* F446 */ + case ID_STM32F446: /* F446 xC/E*/ return "STM32F446"; case ID_STM32F401C: /* F401 B/C RM0368 Rev.3 */ return "STM32F401C"; - case ID_STM32F411: /* F411 RM0383 Rev.4 */ + case ID_STM32F411: /* F411 xC/E RM0383 Rev.4 */ return "STM32F411"; - case ID_STM32F412: /* F412 RM0402 Rev.4, 256 kB Ram */ + case ID_STM32F412: /* F412 xG/I RM0402 Rev.4, 256 kB Ram */ return "STM32F412"; case ID_STM32F401E: /* F401 D/E RM0368 Rev.3 */ return "STM32F401E"; - case ID_STM32F413: /* F413 RM0430 Rev.2, 320 kB Ram, 1.5 MB flash. */ + case ID_STM32F413: /* F413xG/H RM0430 Rev.2, 320 kB Ram, 1.5 MB flash. */ return "STM32F413"; - case ID_STM32F74X: /* F74x RM0385 Rev.4 */ + case ID_STM32F74X: /* F74XxG/I RM0385 Rev.4 */ return "STM32F74x"; - case ID_STM32F76X: /* F76x F77x RM0410 */ + case ID_STM32F76X: /* F76XxE/G F77x RM0410 */ return "STM32F76x"; - case ID_STM32F72X: /* F72x F73x RM0431 */ + case ID_STM32F72X: /* F72/3xC/E RM0431 */ return "STM32F72x"; default: return NULL; @@ -245,7 +245,7 @@ static bool stm32f4_attach(target *t) bool has_ccmram = false; bool is_f7 = false; bool large_sectors = false; - uint32_t flashsize_base = F4_FLASHSIZE; + uint16_t max_flashsize; if (!cortexm_attach(t)) return false; @@ -253,50 +253,53 @@ static bool stm32f4_attach(target *t) switch(t->idcode) { case ID_STM32F40X: has_ccmram = true; + max_flashsize = 1024; break; case ID_STM32F42X: /* 427/437 */ has_ccmram = true; dual_bank = true; + max_flashsize = 2048; break; case ID_STM32F46X: /* 469/479 */ has_ccmram = true; dual_bank = true; - break; - case ID_STM32F20X: /* F205 */ - break; - case ID_STM32F446: /* F446 */ + max_flashsize = 512; break; case ID_STM32F401C: /* F401 B/C RM0368 Rev.3 */ - break; - case ID_STM32F411: /* F411 RM0383 Rev.4 */ - break; - case ID_STM32F412: /* F412 RM0402 Rev.4, 256 kB Ram */ + max_flashsize = 256; break; case ID_STM32F401E: /* F401 D/E RM0368 Rev.3 */ + case ID_STM32F411: /* F411 RM0383 Rev.4 */ + case ID_STM32F446: /* F446 */ + max_flashsize = 512; + break; + case ID_STM32F20X: /* F205xB/C/E/G */ + case ID_STM32F412: /* F412xE/G RM0402 Rev.4, 256 kB Ram */ + max_flashsize = 1024; break; case ID_STM32F413: /* F413 RM0430 Rev.2, 320 kB Ram, 1.5 MB flash. */ + max_flashsize = 1536; break; case ID_STM32F74X: /* F74x RM0385 Rev.4 */ is_f7 = true; large_sectors = true; - flashsize_base = F7_FLASHSIZE; + max_flashsize = 1024; break; case ID_STM32F76X: /* F76x F77x RM0410 */ is_f7 = true; dual_bank = true; large_sectors = true; - flashsize_base = F7_FLASHSIZE; + max_flashsize = 2048; break; case ID_STM32F72X: /* F72x F73x RM0431 */ is_f7 = true; - flashsize_base = F72X_FLASHSIZE; + max_flashsize = 512; break; default: return false; } bool use_dual_bank = false; target_mem_map_free(t); - uint32_t flashsize = target_mem_read32(t, flashsize_base) & 0xffff; if (is_f7) { t->target_storage = target_mem_read32(t, DBGMCU_CR); target_mem_write32(t, DBGMCU_CR, DBG_SLEEP); @@ -314,7 +317,7 @@ static bool stm32f4_attach(target *t) target_add_ram(t, 0x20000000, 0x50000); /* 320 k RAM */ if (dual_bank) { use_dual_bank = true; - if (flashsize < 0x800) { + if (max_flashsize < 0x800) { /* Check Dual-bank on 1 Mbyte Flash memory devices*/ uint32_t optcr; optcr = target_mem_read32(t, FLASH_OPTCR); @@ -325,11 +328,11 @@ static bool stm32f4_attach(target *t) int split = 0; uint32_t banksize; if (use_dual_bank) { - banksize = flashsize << 9; /* flash split on two sectors. */ - split = (flashsize == 0x400) ? 8 : 12; + banksize = max_flashsize << 9; /* flash split on two sectors. */ + split = (max_flashsize == 0x400) ? 8 : 12; } else - banksize = flashsize << 10; + banksize = max_flashsize << 10; if (large_sectors) { uint32_t remains = banksize - 0x40000; /* 256 k in small sectors.*/ @@ -345,11 +348,6 @@ static bool stm32f4_attach(target *t) remains = banksize - 0x20000; /* 128 k in small sectors.*/ if (is_f7) { stm32f4_add_flash(t, ITCM_BASE, 0x10000, 0x4000, 0, split); - if (banksize > 0x10000) { - /* STM32F730 has only 64 kiB flash! */ - stm32f4_add_flash(t, 0x0210000, 0x10000, 0x10000, 4, split); - stm32f4_add_flash(t, 0x0220000, remains, 0x20000, 5, split); - } } stm32f4_add_flash(t, 0x8000000, 0x10000, 0x4000, 0, split); if (banksize > 0x10000) { diff --git a/src/target/stm32h7.c b/src/target/stm32h7.c index f9e0ac1f..cc617934 100644 --- a/src/target/stm32h7.c +++ b/src/target/stm32h7.c @@ -213,14 +213,8 @@ static bool stm32h7_attach(target *t) target_add_ram(t, 0x38000000, 0x01000); /* AHB SRAM4, 32 k */ /* Add the flash to memory map. */ - uint32_t flashsize = target_mem_read32(t, FLASH_SIZE_REG); - flashsize &= 0xffff; - if (flashsize == 128) { /* H750 has only 128 kByte!*/ - stm32h7_add_flash(t, 0x8000000, FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE); - } else { - stm32h7_add_flash(t, 0x8000000, 0x100000, FLASH_SECTOR_SIZE); - stm32h7_add_flash(t, 0x8100000, 0x100000, FLASH_SECTOR_SIZE); - } + stm32h7_add_flash(t, 0x8000000, 0x100000, FLASH_SECTOR_SIZE); + stm32h7_add_flash(t, 0x8100000, 0x100000, FLASH_SECTOR_SIZE); return true; } From 8851504a41e1cd80e91f4fa533cc4fc146bcbad0 Mon Sep 17 00:00:00 2001 From: Koen De Vleeschauwer Date: Wed, 15 Apr 2020 19:23:44 +0200 Subject: [PATCH 15/17] new semihosting commands --- src/gdb_main.c | 32 +++++++- src/include/target.h | 1 + src/target/cortexm.c | 147 ++++++++++++++++++++++++++++++++--- src/target/target.c | 9 +++ src/target/target_internal.h | 3 + 5 files changed, 181 insertions(+), 11 deletions(-) diff --git a/src/gdb_main.c b/src/gdb_main.c index af1edf92..c0575a6d 100644 --- a/src/gdb_main.c +++ b/src/gdb_main.c @@ -25,6 +25,7 @@ */ #include "general.h" +#include "ctype.h" #include "hex_utils.h" #include "gdb_if.h" #include "gdb_packet.h" @@ -429,9 +430,37 @@ handle_v_packet(char *packet, int plen) else gdb_putpacketz("E01"); - } else if (!strcmp(packet, "vRun;")) { + } else if (!strncmp(packet, "vRun", 4)) { + /* Parse command line for get_cmdline semihosting call */ + char cmdline[83]; + char *pbuf = cmdline; + char *tok = packet + 4; + if (*tok == ';') tok++; + *cmdline='\0'; + while(*tok != '\0') { + if(strlen(cmdline)+3 >= sizeof(cmdline)) break; + if (*tok == ';') { + *pbuf++=' '; + *pbuf='\0'; + tok++; + continue; + } + if (isxdigit(*tok) && isxdigit(*(tok+1))) { + unhexify(pbuf, tok, 2); + if ((*pbuf == ' ') || (*pbuf == '\\')) { + *(pbuf+1)=*pbuf; + *pbuf++='\\'; + } + pbuf++; + tok+=2; + *pbuf='\0'; + continue; + } + break; + } /* Run target program. For us (embedded) this means reset. */ if(cur_target) { + target_set_cmdline(cur_target, cmdline); target_reset(cur_target); gdb_putpacketz("T05"); } else if(last_target) { @@ -440,6 +469,7 @@ handle_v_packet(char *packet, int plen) /* If we were able to attach to the target again */ if (cur_target) { + target_set_cmdline(cur_target, cmdline); target_reset(cur_target); gdb_putpacketz("T05"); } else gdb_putpacketz("E01"); diff --git a/src/include/target.h b/src/include/target.h index d052ab15..35102505 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -80,6 +80,7 @@ void target_reset(target *t); void target_halt_request(target *t); enum target_halt_reason target_halt_poll(target *t, target_addr *watch); void target_halt_resume(target *t, bool step); +void target_set_cmdline(target *t, char *cmdline); /* Break-/watchpoint functions */ enum target_breakwatch { diff --git a/src/target/cortexm.c b/src/target/cortexm.c index b81b4d1d..70e38d06 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -3,10 +3,10 @@ * * Copyright (C) 2012 Black Sphere Technologies Ltd. * Written by Gareth McMullin + * and Koen De Vleeschauwer. * * This program is free software: you can redistribute it and/or modify - * it under tSchreibe Objekte: 100% (21/21), 3.20 KiB | 3.20 MiB/s, Fertig. -he terms of the GNU General Public License as published by + * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * @@ -1009,11 +1009,14 @@ static bool cortexm_vector_catch(target *t, int argc, char *argv[]) #endif /* Semihosting support */ -/* ARM Semihosting syscall numbers, from ARM doc DUI0471C, Chapter 8 */ -#define SYS_CLOSE 0x02 +/* ARM Semihosting syscall numbers, from "Semihosting for AArch32 and AArch64 Version 3.0" */ + #define SYS_CLOCK 0x10 +#define SYS_CLOSE 0x02 #define SYS_ELAPSED 0x30 #define SYS_ERRNO 0x13 +#define SYS_EXIT 0x18 +#define SYS_EXIT_EXTENDED 0x20 #define SYS_FLEN 0x0C #define SYS_GET_CMDLINE 0x15 #define SYS_HEAPINFO 0x16 @@ -1033,6 +1036,28 @@ static bool cortexm_vector_catch(target *t, int argc, char *argv[]) #define SYS_WRITEC 0x03 #define SYS_WRITE0 0x04 +#if !defined(PC_HOSTED) +/* probe memory access functions */ +static void probe_mem_read(target *t __attribute__((unused)), void *probe_dest, target_addr target_src, size_t len) +{ + uint8_t *dst = (uint8_t *)probe_dest; + uint8_t *src = (uint8_t *)target_src; + + DEBUG("probe_mem_read\n"); + while (len--) *dst++=*src++; + return; +} + +static void probe_mem_write(target *t __attribute__((unused)), target_addr target_dest, const void *probe_src, size_t len) +{ + uint8_t *dst = (uint8_t *)target_dest; + uint8_t *src = (uint8_t *)probe_src; + + DEBUG("probe_mem_write\n"); + while (len--) *dst++=*src++; + return; +} +#endif static int cortexm_hostio_request(target *t) { uint32_t arm_regs[t->regs_size]; @@ -1073,6 +1098,7 @@ static int cortexm_hostio_request(target *t) ret++; break; } + /* FIXME handle requests for special filename ':semihosting-features' */ ret = tc_open(t, params[0], params[2] + 1, pflag, 0644); if (ret != -1) @@ -1093,8 +1119,24 @@ static int cortexm_hostio_request(target *t) ret = params[2] - ret; break; case SYS_WRITEC: /* writec */ - ret = tc_write(t, 2, arm_regs[1], 1); + ret = tc_write(t, STDERR_FILENO, arm_regs[1], 1); break; + case SYS_WRITE0:{ /* write0 */ + ret = -1; + target_addr str_begin = arm_regs[1]; + target_addr str_end = str_begin; + while (target_mem_read8(t, str_end) != 0) { + if (target_check_error(t)) break; + str_end++; + } + int len = str_end - str_begin; + if (len != 0) { + int rc = tc_write(t, STDERR_FILENO, str_begin, len); + if (rc != len) break; + } + ret = 0; + break; + } case SYS_ISTTY: /* isatty */ ret = tc_isatty(t, params[0] - 1); break; @@ -1112,17 +1154,102 @@ static int cortexm_hostio_request(target *t) ret = tc_system(t, params[0] - 1, params[1] + 1); break; - case SYS_FLEN: /* Not supported, fake success */ - t->tc->errno_ = 0; - break; + case SYS_FLEN: +#if defined(PC_HOSTED) + t->tc->errno_ = 0; + break; +#else + { /* file length */ + ret = -1; + uint32_t fio_stat[16]; /* same size as fio_stat in gdb/include/gdb/fileio.h */ + //DEBUG("SYS_FLEN fio_stat addr %p\n", fio_stat); + void (*saved_mem_read)(target *t, void *dest, target_addr src, size_t len); + void (*saved_mem_write)(target *t, target_addr dest, const void *src, size_t len); + saved_mem_read = t->mem_read; + saved_mem_write = t->mem_write; + t->mem_read = probe_mem_read; + t->mem_write = probe_mem_write; + int rc = tc_fstat(t, params[0] - 1, (target_addr)fio_stat); /* write fstat() result in fio_stat[] */ + t->mem_read = saved_mem_read; + t->mem_write = saved_mem_write; + if (rc) break; /* tc_fstat() failed */ + uint32_t fst_size_msw = fio_stat[7]; /* most significant 32 bits of fst_size in fio_stat */ + uint32_t fst_size_lsw = fio_stat[8]; /* least significant 32 bits of fst_size in fio_stat */ + if (fst_size_msw != 0) break; /* file size too large for uint32_t return type */ + ret = __builtin_bswap32(fst_size_lsw); /* convert from bigendian to target order */ + break; + } + case SYS_TIME: { /* gettimeofday */ + ret = -1; + uint32_t fio_timeval[3]; /* same size as fio_timeval in gdb/include/gdb/fileio.h */ + //DEBUG("SYS_TIME fio_timeval addr %p\n", fio_timeval); + void (*saved_mem_read)(target *t, void *dest, target_addr src, size_t len); + void (*saved_mem_write)(target *t, target_addr dest, const void *src, size_t len); + saved_mem_read = t->mem_read; + saved_mem_write = t->mem_write; + t->mem_read = probe_mem_read; + t->mem_write = probe_mem_write; + int rc = tc_gettimeofday(t, (target_addr) fio_timeval, (target_addr) NULL); /* write gettimeofday() result in fio_timeval[] */ + t->mem_read = saved_mem_read; + t->mem_write = saved_mem_write; + if (rc) break; /* tc_gettimeofday() failed */ + uint32_t ftv_sec = fio_timeval[0]; /* time in seconds, first field in fio_timeval */ + ret = __builtin_bswap32(ftv_sec); /* convert from bigendian to target order */ + break; + } + + case SYS_READC: { /* readc */ + uint8_t ch; + //DEBUG("SYS_READC ch addr %p\n", &ch); + void (*saved_mem_read)(target *t, void *dest, target_addr src, size_t len); + void (*saved_mem_write)(target *t, target_addr dest, const void *src, size_t len); + saved_mem_read = t->mem_read; + saved_mem_write = t->mem_write; + t->mem_read = probe_mem_read; + t->mem_write = probe_mem_write; + int rc = tc_read(t, params[0] - 1, (target_addr) &ch, 1); /* read a character in ch */ + t->mem_read = saved_mem_read; + t->mem_write = saved_mem_write; + if (rc == 1) ret = ch; + else ret = -1; + break; + } +#endif case SYS_ERRNO: /* Return last errno from GDB */ ret = t->tc->errno_; break; - case SYS_TIME: /* gettimeofday */ - /* FIXME How do we use gdb's gettimeofday? */ + case SYS_EXIT: /* _exit() */ + tc_printf(t, "_exit(0x%x)\n", params[0]); + target_halt_resume(t, 1); + ret = 0; break; + + case SYS_GET_CMDLINE: { /* get_cmdline */ + uint32_t retval[2]; + ret = -1; + target_addr buf_ptr = params[0]; + target_addr buf_len = params[1]; + if (strlen(t->cmdline)+1 > buf_len) break; + if(target_mem_write(t, buf_ptr, t->cmdline, strlen(t->cmdline)+1)) break; + retval[0] = buf_ptr; + retval[1] = strlen(t->cmdline)+1; + if(target_mem_write(t, arm_regs[1], retval, sizeof(retval))) break; + ret = 0; + break; + } + + // not implemented yet: + case SYS_HEAPINFO: /* heapinfo */ + case SYS_CLOCK: /* clock */ + case SYS_ELAPSED: /* elapsed */ + case SYS_ISERROR: /* iserror */ + case SYS_TICKFREQ: /* tickfreq */ + case SYS_TMPNAM: /* tmpnam */ + ret = -1; + break; + } arm_regs[0] = ret; diff --git a/src/target/target.c b/src/target/target.c index 56e54b0f..5c0ca574 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -401,6 +401,15 @@ enum target_halt_reason target_halt_poll(target *t, target_addr *watch) void target_halt_resume(target *t, bool step) { t->halt_resume(t, step); } +/* Command line for semihosting get_cmdline */ +void target_set_cmdline(target *t, char *cmdline) { + uint32_t len_dst; + len_dst = sizeof(t->cmdline)-1; + strncpy(t->cmdline, cmdline, len_dst -1); + t->cmdline[strlen(t->cmdline)]='\0'; + DEBUG("cmdline: >%s<\n", t->cmdline); + } + /* Break-/watchpoint functions */ int target_breakwatch_set(target *t, enum target_breakwatch type, target_addr addr, size_t len) diff --git a/src/target/target_internal.h b/src/target/target_internal.h index 15a47293..7be19ed2 100644 --- a/src/target/target_internal.h +++ b/src/target/target_internal.h @@ -72,6 +72,8 @@ struct breakwatch { uint32_t reserved[4]; /* for use by the implementing driver */ }; +#define MAX_CMDLINE 81 + struct target_s { bool attached; struct target_controller *tc; @@ -118,6 +120,7 @@ struct target_s { /* Other stuff */ const char *driver; const char *core; + char cmdline[MAX_CMDLINE]; struct target_command_s *commands; struct target_s *next; From 08bb4d577562d7c478cb01f752417034a9ab2558 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 27 Apr 2020 20:03:50 +0200 Subject: [PATCH 16/17] pc-hosted: Make JTAG work. --- src/platforms/pc-hosted/jtagtap.c | 6 +++--- src/remote.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/platforms/pc-hosted/jtagtap.c b/src/platforms/pc-hosted/jtagtap.c index cce1c71f..86e068d2 100644 --- a/src/platforms/pc-hosted/jtagtap.c +++ b/src/platforms/pc-hosted/jtagtap.c @@ -98,7 +98,7 @@ void jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI if(!ticks || !DI) return; /* Reduce the length of DI according to the bits we're transmitting */ - DIl&=(1L<<(ticks+1))-1; + DIl &= (1LL << (ticks + 1)) - 1; s=snprintf((char *)construct,PLATFORM_MAX_MSG_SIZE,REMOTE_JTAG_TDIDO_STR,final_tms?REMOTE_TDITDO_TMS:REMOTE_TDITDO_NOTMS,ticks,DIl); platform_buffer_write(construct,s); @@ -111,8 +111,8 @@ void jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI } if (DO) { - for (unsigned int i = 1; i*8 <= (unsigned int)ticks; i++) - DO[i - 1] = remotehston(2 , (char *)&construct[s - (i * 2)]); + uint64_t DOl = remotehston(-1, (char *)&construct[1]); + *(uint64_t *)DO = DOl; } } diff --git a/src/remote.c b/src/remote.c index d54f0e22..dc44ff7d 100644 --- a/src/remote.c +++ b/src/remote.c @@ -61,7 +61,7 @@ static void _respond(char respCode, uint64_t param) /* Send response to far end */ { - char buf[34]; + char buf[35]; /*Response, code, EOM and 2*16 hex nibbles*/ char *p=buf; gdb_if_putchar(REMOTE_RESP,0); @@ -185,7 +185,7 @@ void remotePacketProcessJTAG(uint8_t i, char *packet) jtagtap_tdi_tdo_seq((void *)&DO, (packet[1]==REMOTE_TDITDO_TMS), (void *)&DI, ticks); /* Mask extra bits on return value... */ - DO&=(1<<(ticks+1))-1; + DO &= (1LL << (ticks + 1)) - 1; _respond(REMOTE_RESP_OK, DO); } From d63e870e82ecbd73af2d14e6794d2985cb9bd0ad Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Thu, 30 Apr 2020 22:04:41 +0200 Subject: [PATCH 17/17] cdcacm: Fix UART interface OUT endpoint MPS in descriptor. 3e3e450 reduced the buffer size for the UART interface OUT endpoint to 32B, but left wMaxPacketSize at 64B. This effectively configures the hardware to receive packets up to 32B in size while telling the host it can send larger packets. On reception of a larger packet, the usb core treats it as an error, drops the packet and replies with a STALL handshake. This commit fixes the issue by updating the descriptor to match the buffer configuration. Fixes #538 --- src/platforms/common/cdcacm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/common/cdcacm.c b/src/platforms/common/cdcacm.c index 8f5f779b..a063d31a 100644 --- a/src/platforms/common/cdcacm.c +++ b/src/platforms/common/cdcacm.c @@ -188,7 +188,7 @@ static const struct usb_endpoint_descriptor uart_data_endp[] = {{ .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = 0x03, .bmAttributes = USB_ENDPOINT_ATTR_BULK, - .wMaxPacketSize = CDCACM_PACKET_SIZE, + .wMaxPacketSize = CDCACM_PACKET_SIZE / 2, .bInterval = 1, }, { .bLength = USB_DT_ENDPOINT_SIZE,