From 72c1498ae17c08577961b8aeeb32cd9b272e681f Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 15 Apr 2018 17:12:49 +0200 Subject: [PATCH 1/8] stlink: Make SWO Trace Buffer smaller. Changes for delayed memory map setup otherwise overflow SRAM silently. --- src/platforms/stlink/platform.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/stlink/platform.h b/src/platforms/stlink/platform.h index 83eb90a..cadb5d8 100644 --- a/src/platforms/stlink/platform.h +++ b/src/platforms/stlink/platform.h @@ -69,7 +69,7 @@ #define LED_UART GPIO14 #define PLATFORM_HAS_TRACESWO 1 -#define NUM_TRACE_PACKETS (192) /* This is an 12K buffer */ +#define NUM_TRACE_PACKETS (128) /* This is an 8K buffer */ #define TMS_SET_MODE() \ gpio_set_mode(TMS_PORT, GPIO_MODE_OUTPUT_50_MHZ, \ From 1fd2a24c2d0bb67d7ffec1d4feeb1c50b2b00960 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Tue, 10 Apr 2018 09:20:28 +1200 Subject: [PATCH 2/8] stm32f4: Only construct memory map at attach. --- src/target/stm32f4.c | 49 +++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/src/target/stm32f4.c b/src/target/stm32f4.c index ec5cdc7..0d1e5c3 100644 --- a/src/target/stm32f4.c +++ b/src/target/stm32f4.c @@ -48,7 +48,7 @@ const struct command_s stm32f4_cmd_list[] = { {NULL, NULL, NULL} }; - +static bool stm32f4_attach(target *t); static int stm32f4_flash_erase(struct target_flash *f, target_addr addr, size_t len); static int stm32f4_flash_write(struct target_flash *f, @@ -170,16 +170,7 @@ static void stm32f4_add_flash(target *t, bool stm32f4_probe(target *t) { - uint32_t idcode; - const char* designator = NULL; - bool dual_bank = false; - bool has_ccmram = false; - bool is_f7 = false; - bool large_sectors = false; - uint32_t flashsize_base = F4_FLASHSIZE; - - idcode = target_mem_read32(t, DBGMCU_IDCODE); - idcode &= 0xFFF; + uint32_t idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xFFF; if (idcode == ID_STM32F20X) { /* F405 revision A have a wrong IDCODE, use ARM_CPUID to make the @@ -190,6 +181,41 @@ bool stm32f4_probe(target *t) idcode = ID_STM32F40X; } switch(idcode) { + case ID_STM32F40X: + case ID_STM32F42X: /* 427/437 */ + case ID_STM32F46X: /* 469/479 */ + case ID_STM32F20X: /* F205 */ + case ID_STM32F446: /* F446 */ + case ID_STM32F401C: /* F401 B/C RM0368 Rev.3 */ + case ID_STM32F411: /* F411 RM0383 Rev.4 */ + case ID_STM32F412: /* F412 RM0402 Rev.4, 256 kB Ram */ + case ID_STM32F401E: /* F401 D/E RM0368 Rev.3 */ + case ID_STM32F413: /* F413 RM0430 Rev.2, 320 kB Ram, 1.5 MB flash. */ + case ID_STM32F74X: /* F74x RM0385 Rev.4 */ + case ID_STM32F76X: /* F76x F77x RM0410 */ + case ID_STM32F72X: /* F72x F73x RM0431 */ + t->idcode = idcode; + t->driver = "STM32F4"; + t->attach = stm32f4_attach; + return true; + default: + return false; + } +} + +static bool stm32f4_attach(target *t) +{ + const char* designator = NULL; + bool dual_bank = false; + bool has_ccmram = false; + bool is_f7 = false; + bool large_sectors = false; + uint32_t flashsize_base = F4_FLASHSIZE; + + if (!cortexm_attach(t)) + return false; + + switch(t->idcode) { case ID_STM32F40X: designator = "STM32F40x"; has_ccmram = true; @@ -248,7 +274,6 @@ bool stm32f4_probe(target *t) target_mem_write32(t, DBGMCU_CR, DBG_STANDBY| DBG_STOP | DBG_SLEEP); t->driver = designator; target_add_commands(t, stm32f4_cmd_list, designator); - t->idcode = idcode; bool use_dual_bank = false; uint32_t flashsize = target_mem_read32(t, flashsize_base) & 0xffff; if (is_f7) { From 00decb3718cc7ec1e55a6d70bd37c28bf2f746f4 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Tue, 10 Apr 2018 10:41:53 +1200 Subject: [PATCH 3/8] target: Separate function to free memory map. --- src/target/target.c | 35 +++++++++++++++++++++-------------- src/target/target_internal.h | 1 + 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index 7ad5716..37e5b6b 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -54,6 +54,26 @@ bool target_foreach(void (*cb)(int, target *t, void *context), void *context) return target_list != NULL; } +void target_mem_map_free(target *t) +{ + if (t->dyn_mem_map) { + free(t->dyn_mem_map); + t->dyn_mem_map = NULL; + } + while (t->ram) { + void * next = t->ram->next; + free(t->ram); + t->ram = next; + } + while (t->flash) { + void * next = t->flash->next; + if (t->flash->buf) + free(t->flash->buf); + free(t->flash); + t->flash = next; + } +} + void target_list_free(void) { struct target_command_s *tc; @@ -69,20 +89,7 @@ void target_list_free(void) free(target_list->commands); target_list->commands = tc; } - if (target_list->dyn_mem_map) - free(target_list->dyn_mem_map); - while (target_list->ram) { - void * next = target_list->ram->next; - free(target_list->ram); - target_list->ram = next; - } - while (target_list->flash) { - void * next = target_list->flash->next; - if (target_list->flash->buf) - free(target_list->flash->buf); - free(target_list->flash); - target_list->flash = next; - } + target_mem_map_free(target_list); while (target_list->bw_list) { void * next = target_list->bw_list->next; free(target_list->bw_list); diff --git a/src/target/target_internal.h b/src/target/target_internal.h index 2b7d88c..082b29f 100644 --- a/src/target/target_internal.h +++ b/src/target/target_internal.h @@ -124,6 +124,7 @@ struct target_s { void (*priv_free)(void *); }; +void target_mem_map_free(target *t); void target_add_commands(target *t, const struct command_s *cmds, const char *name); void target_add_ram(target *t, target_addr start, uint32_t len); void target_add_flash(target *t, struct target_flash *f); From 63967346cd34e3f5bc6dadaa566105adea6e5fcb Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Tue, 10 Apr 2018 10:43:05 +1200 Subject: [PATCH 4/8] stm32f4: Don't duplicate resources on reattach. --- src/target/stm32f4.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/target/stm32f4.c b/src/target/stm32f4.c index 0d1e5c3..51ee331 100644 --- a/src/target/stm32f4.c +++ b/src/target/stm32f4.c @@ -197,6 +197,7 @@ bool stm32f4_probe(target *t) t->idcode = idcode; t->driver = "STM32F4"; t->attach = stm32f4_attach; + target_add_commands(t, stm32f4_cmd_list, "stm32f4"); return true; default: return false; @@ -273,8 +274,8 @@ static bool stm32f4_attach(target *t) } target_mem_write32(t, DBGMCU_CR, DBG_STANDBY| DBG_STOP | DBG_SLEEP); t->driver = designator; - target_add_commands(t, stm32f4_cmd_list, designator); bool use_dual_bank = false; + target_mem_map_free(t); uint32_t flashsize = target_mem_read32(t, flashsize_base) & 0xffff; if (is_f7) { target_add_ram(t, 0x00000000, 0x4000); /* 16 k ITCM Ram */ From 6127a6431ee771125b78d050432253199661be18 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 27 Mar 2018 12:48:32 +0200 Subject: [PATCH 5/8] stlink: Check nRST line level when setting SRST. Problem: On some boards flashing hanged. Cause: Releasing SRST caused a slow rise of nRST and flashing started while the target still was in reset. Attention: platform_delay(ms) only resolved 0.1 s. Nucleo-P boards have SRST unconnected to target nRST by default. --- src/platforms/stlink/Readme | 6 ++++++ src/platforms/stlink/platform.c | 19 +++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/platforms/stlink/Readme b/src/platforms/stlink/Readme index b20a6db..ec9e05f 100644 --- a/src/platforms/stlink/Readme +++ b/src/platforms/stlink/Readme @@ -9,3 +9,9 @@ ID Pins PC13/14 unconnected PC 13 pulled low LED STLINK PA8, active High PA9, Dual Led MCO Out NA PA8 RESET(Target) T_JRST(PB1) NRST (PB0) + +On the NucleoXXXP boards, e.g. NUCLEO-L4R5ZI (144 pin) or +NUCLEO-L452RE-P (64 pins), by default nRst is not connected. To reach the +target nRST pin with the "mon connect_srst enable" option, the right NRST +jumper must be placed. On Nucleo144-P boards it is JP3, on NUCLEO64-P +boards it is JP4. diff --git a/src/platforms/stlink/platform.c b/src/platforms/stlink/platform.c index 5e2ca3b..591c2cb 100644 --- a/src/platforms/stlink/platform.c +++ b/src/platforms/stlink/platform.c @@ -90,10 +90,21 @@ void platform_init(void) void platform_srst_set_val(bool assert) { - if (assert) - gpio_clear(SRST_PORT, srst_pin); - else - gpio_set(SRST_PORT, srst_pin); + uint32_t crl = GPIOB_CRL; + uint32_t shift = (srst_pin == GPIO0) ? 0 : 4; + uint32_t mask = 0xf << shift; + crl &= ~mask; + if (assert) { + /* Set SRST as Open-Drain, 50 Mhz, low.*/ + GPIOB_BRR = srst_pin; + GPIOB_CRL = crl | (7 << shift); + } else { + /* Set SRST as input, pull-up. + * SRST might be unconnected, e.g on Nucleo-P!*/ + GPIOB_CRL = crl | (8 << shift); + GPIOB_BSRR = srst_pin; + } + while (gpio_get(SRST_PORT, srst_pin) == assert) {}; } bool platform_srst_get_val() From 5f404cdbc0ee9e6f8221746b908c9fd1b1a4b674 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 15 Apr 2018 18:03:26 +0200 Subject: [PATCH 6/8] Construct memory map on the stack The memory map uses 1k of SRAM and is only needed during attach. Release after use lowers pressure on SRAM. --- src/gdb_main.c | 4 +++- src/include/target.h | 2 +- src/target/target.c | 18 ++++-------------- src/target/target_internal.h | 2 -- 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/gdb_main.c b/src/gdb_main.c index ed1f2fe..ec6ef2f 100644 --- a/src/gdb_main.c +++ b/src/gdb_main.c @@ -354,7 +354,9 @@ handle_q_packet(char *packet, int len) gdb_putpacketz("E01"); return; } - handle_q_string_reply(target_mem_map(cur_target), packet + 23); + char buf[1024]; + target_mem_map(cur_target, buf, sizeof(buf)); /* Fixme: Check size!*/ + handle_q_string_reply(buf, packet + 23); } else if (strncmp (packet, "qXfer:features:read:target.xml:", 31) == 0) { /* Read target description */ diff --git a/src/include/target.h b/src/include/target.h index 83afb03..3ec73d5 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -45,7 +45,7 @@ bool target_attached(target *t); const char *target_driver_name(target *t); /* Memory access functions */ -const char *target_mem_map(target *t); +bool target_mem_map(target *t, char *buf, size_t len); int target_mem_read(target *t, void *dest, target_addr src, size_t len); int target_mem_write(target *t, target_addr dest, const void *src, size_t len); /* Flash memory access functions */ diff --git a/src/target/target.c b/src/target/target.c index 37e5b6b..1882851 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -56,10 +56,6 @@ bool target_foreach(void (*cb)(int, target *t, void *context), void *context) void target_mem_map_free(target *t) { - if (t->dyn_mem_map) { - free(t->dyn_mem_map); - t->dyn_mem_map = NULL; - } while (t->ram) { void * next = t->ram->next; free(t->ram); @@ -175,14 +171,8 @@ static ssize_t map_flash(char *buf, size_t len, struct target_flash *f) return i; } -const char *target_mem_map(target *t) +bool target_mem_map(target *t, char *tmp, size_t len) { - if (t->dyn_mem_map) - return t->dyn_mem_map; - - /* FIXME size buffer */ - size_t len = 1024; - char *tmp = malloc(len); size_t i = 0; i = snprintf(&tmp[i], len - i, ""); /* Map each defined RAM */ @@ -193,9 +183,9 @@ const char *target_mem_map(target *t) i += map_flash(&tmp[i], len - i, f); i += snprintf(&tmp[i], len - i, ""); - t->dyn_mem_map = tmp; - - return t->dyn_mem_map; + if (i > (len -2)) + return false; + return true; } static struct target_flash *flash_for_addr(target *t, uint32_t addr) diff --git a/src/target/target_internal.h b/src/target/target_internal.h index 082b29f..caa542a 100644 --- a/src/target/target_internal.h +++ b/src/target/target_internal.h @@ -109,8 +109,6 @@ struct target_s { unsigned target_options; uint32_t idcode; - /* Target memory map */ - char *dyn_mem_map; struct target_ram *ram; struct target_flash *flash; From a0596a0dcc270fc0c11a0892dd9e2bf1e00879ca Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 15 Apr 2018 17:39:30 +0200 Subject: [PATCH 7/8] stm32l4: Build Memory Map during attach. Reading target registers while target not halted may fail and result in invalid memory map. --- src/target/stm32l4.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/target/stm32l4.c b/src/target/stm32l4.c index 54d0e54..f765599 100644 --- a/src/target/stm32l4.c +++ b/src/target/stm32l4.c @@ -142,46 +142,65 @@ static void stm32l4_add_flash(target *t, target_add_flash(t, f); } +static bool stm32l4_attach(target *t); + bool stm32l4_probe(target *t) { uint32_t idcode; - uint32_t size; - uint32_t options; - uint32_t bank1_start = 0x08040000; idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xFFF; switch(idcode) { case 0x461: /* L496/RM0351 */ + case 0x415: /* L471/RM0392, L475/RM0395, L476/RM0351 */ + case 0x462: /* L45x L46x / RM0394 */ + case 0x435: /* L43x L44x / RM0394 */ + t->idcode = idcode; + t->driver = "STM32L4"; + t->attach = stm32l4_attach; + target_add_commands(t, stm32l4_cmd_list, "STM32L4"); + return true; + default: + return false; + } +} + +static bool stm32l4_attach(target *t) +{ + uint32_t size = (target_mem_read32(t, FLASH_SIZE_REG) & 0xffff); + uint32_t bank1_start = 0x08080000; /* default split on 1MiB devices*/ + + if (!cortexm_attach(t)) + return false; + + target_mem_map_free(t); + switch(t->idcode) { + case 0x461: /* L496/RM0351 */ case 0x415: /* L471/RM0392, L475/RM0395, L476/RM0351 */ t->driver = stm32l4_driver_str; - if (idcode == 0x415) { + if (t->idcode == 0x415) { target_add_ram(t, 0x10000000, 0x08000); target_add_ram(t, 0x20000000, 0x18000); } else { target_add_ram(t, 0x10000000, 0x10000); target_add_ram(t, 0x20000000, 0x40000); } - size = (target_mem_read32(t, FLASH_SIZE_REG) & 0xffff); - options = target_mem_read32(t, FLASH_OPTR); + uint32_t options = target_mem_read32(t, FLASH_OPTR); + /* Only 256 and 512 kiB devices evaluate OR_DUALBANK*/ if ((size < 0x400) && (options & OR_DUALBANK)) bank1_start = 0x08000000 + (size << 9); stm32l4_add_flash(t, 0x08000000, size << 10, PAGE_SIZE, bank1_start); - target_add_commands(t, stm32l4_cmd_list, "STM32L4 Dual bank"); return true; case 0x462: /* L45x L46x / RM0394 */ case 0x435: /* L43x L44x / RM0394 */ t->driver = stm32l4_driver_str; - if (idcode == 0x452) { + if (t->idcode == 0x452) { target_add_ram(t, 0x10000000, 0x08000); target_add_ram(t, 0x20000000, 0x20000); } else { target_add_ram(t, 0x10000000, 0x04000); target_add_ram(t, 0x20000000, 0x0c000); } - size = (target_mem_read32(t, FLASH_SIZE_REG) & 0xffff); - options = target_mem_read32(t, FLASH_OPTR); stm32l4_add_flash(t, 0x08000000, size << 10, PAGE_SIZE, bank1_start); - target_add_commands(t, stm32l4_cmd_list, "STM32L4"); return true; } return false; From 93f3b14b68b6938131b844ac1f1f6e7b687897b1 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 15 Apr 2018 20:08:26 +0200 Subject: [PATCH 8/8] stm32f1(f0): Do not read normal device registers during probe. Device may not be halted and memory map setup may fail. --- src/target/stm32f1.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index 9d0bf27..fcdc0c8 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -153,26 +153,30 @@ bool stm32f1_probe(target *t) switch(t->idcode) { case 0x444: /* STM32F03 RM0091 Rev.7, STM32F030x[4|6] RM0360 Rev. 4*/ t->driver = "STM32F03"; + flash_size = 0x8000; break; case 0x445: /* STM32F04 RM0091 Rev.7, STM32F070x6 RM0360 Rev. 4*/ t->driver = "STM32F04/F070x6"; + flash_size = 0x8000; break; case 0x440: /* STM32F05 RM0091 Rev.7, STM32F030x8 RM0360 Rev. 4*/ t->driver = "STM32F05/F030x8"; + flash_size = 0x10000; break; case 0x448: /* STM32F07 RM0091 Rev.7, STM32F070xB RM0360 Rev. 4*/ t->driver = "STM32F07"; + flash_size = 0x20000; block_size = 0x800; break; case 0x442: /* STM32F09 RM0091 Rev.7, STM32F030xC RM0360 Rev. 4*/ t->driver = "STM32F09/F030xC"; + flash_size = 0x40000; block_size = 0x800; break; default: /* NONE */ return false; } - flash_size = (target_mem_read32(t, FLASHSIZE_F0) & 0xffff) *0x400; target_add_ram(t, 0x20000000, 0x5000); stm32f1_add_flash(t, 0x8000000, flash_size, block_size); target_add_commands(t, stm32f1_cmd_list, "STM32F0");