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/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() 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, \ 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"); diff --git a/src/target/stm32f4.c b/src/target/stm32f4.c index ec5cdc7..51ee331 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,42 @@ 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; + target_add_commands(t, stm32f4_cmd_list, "stm32f4"); + 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; @@ -247,9 +274,8 @@ 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; + 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 */ 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; diff --git a/src/target/target.c b/src/target/target.c index 7ad5716..1882851 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -54,6 +54,22 @@ bool target_foreach(void (*cb)(int, target *t, void *context), void *context) return target_list != NULL; } +void target_mem_map_free(target *t) +{ + 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 +85,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); @@ -168,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 */ @@ -186,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 2b7d88c..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; @@ -124,6 +122,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);