From 9a5b31c37bd5b55e8dc79d894f19aedd503c373c Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Mon, 9 Oct 2017 11:07:29 +1300 Subject: [PATCH 1/7] Fix fallthrough warnings on gcc 7 --- src/gdb_main.c | 5 ++--- src/platforms/common/cdcacm.c | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gdb_main.c b/src/gdb_main.c index 1a5805af..ed1f2fe0 100644 --- a/src/gdb_main.c +++ b/src/gdb_main.c @@ -155,7 +155,7 @@ int gdb_main_loop(struct target_controller *tc, bool in_syscall) } case 's': /* 's [addr]': Single step [start at addr] */ single_step = true; - // Fall through to resume target + /* fall through */ case 'c': /* 'c [addr]': Continue [at addr] */ if(!cur_target) { gdb_putpacketz("X1D"); @@ -165,7 +165,7 @@ int gdb_main_loop(struct target_controller *tc, bool in_syscall) target_halt_resume(cur_target, single_step); SET_RUN_STATE(1); single_step = false; - // Fall through to wait for target halt + /* fall through */ case '?': { /* '?': Request reason for target halt */ /* This packet isn't documented as being mandatory, * but GDB doesn't work without it. */ @@ -482,4 +482,3 @@ void gdb_main(void) { gdb_main_loop(&gdb_controller, false); } - diff --git a/src/platforms/common/cdcacm.c b/src/platforms/common/cdcacm.c index 5974cd4a..62cc419b 100644 --- a/src/platforms/common/cdcacm.c +++ b/src/platforms/common/cdcacm.c @@ -445,6 +445,7 @@ static int cdcacm_control_request(usbd_device *dev, switch(req->wIndex) { case 2: usbuart_set_line_coding((struct usb_cdc_line_coding*)*buf); + return 1; case 0: return 1; /* Ignore on GDB Port */ default: @@ -462,6 +463,7 @@ static int cdcacm_control_request(usbd_device *dev, return 1; } + return 0; case DFU_DETACH: if(req->wIndex == DFU_IF_NO) { *complete = dfu_detach_complete; @@ -561,4 +563,3 @@ void USB_ISR(void) { usbd_poll(usbdev); } - From 0e5b3ab00ea7515ec75976c9ea2bcf2a2af737f9 Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Fri, 14 Jul 2017 20:45:54 +1000 Subject: [PATCH 2/7] Make Cortex M driver write DCCIMVAC (Data cache clean and invalidate by address to the PoC=Point of Coherency) prior to reading or writing each 32 bytes of RAM --- src/target/cortexm.c | 32 ++++++++++++++++++++++++++++++++ src/target/cortexm.h | 3 +++ 2 files changed, 35 insertions(+) diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 4e941060..380f2fcc 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -181,11 +181,43 @@ ADIv5_AP_t *cortexm_ap(target *t) static void cortexm_mem_read(target *t, void *dest, target_addr src, size_t len) { + /* flush data cache for RAM regions that intersect requested region */ + target_addr src_end = src + len; /* following code is NOP if wraparound */ + /* requested region is [src, src_end) */ + for (struct target_ram *r = t->ram; r; r = r->next) { + target_addr ram = r->start; + target_addr ram_end = r->start + r->length; + /* RAM region is [ram, ram_end) */ + if (src > ram) + ram = src; + if (src_end < ram_end) + ram_end = src_end; + /* intersection is [ram, ram_end) */ + for (ram &= ~0x1f; ram < ram_end; ram += 0x20) + adiv5_mem_write(cortexm_ap(t), CORTEXM_DCCIMVAC, &ram, 4); + } + adiv5_mem_read(cortexm_ap(t), dest, src, len); } static void cortexm_mem_write(target *t, target_addr dest, const void *src, size_t len) { + /* flush data cache for RAM regions that intersect requested region */ + target_addr dest_end = dest + len; /* following code is NOP if wraparound */ + /* requested region is [dest, dest_end) */ + for (struct target_ram *r = t->ram; r; r = r->next) { + target_addr ram = r->start; + target_addr ram_end = r->start + r->length; + /* RAM region is [ram, ram_end) */ + if (dest > ram) + ram = dest; + if (dest_end < ram_end) + ram_end = dest_end; + /* intersection is [ram, ram_end) */ + for (ram &= ~0x1f; ram < ram_end; ram += 0x20) + adiv5_mem_write(cortexm_ap(t), CORTEXM_DCCIMVAC, &ram, 4); + } + adiv5_mem_write(cortexm_ap(t), dest, src, len); } diff --git a/src/target/cortexm.h b/src/target/cortexm.h index bf1d821d..ca5e10b3 100644 --- a/src/target/cortexm.h +++ b/src/target/cortexm.h @@ -37,6 +37,9 @@ #define CORTEXM_DCRDR (CORTEXM_SCS_BASE + 0xDF8) #define CORTEXM_DEMCR (CORTEXM_SCS_BASE + 0xDFC) +/* Data cache clean and invalidate by address to the PoC=Point of Coherency */ +#define CORTEXM_DCCIMVAC (CORTEXM_SCS_BASE + 0xF70) + #define CORTEXM_FPB_BASE (CORTEXM_PPB_BASE + 0x2000) /* ARM Literature uses FP_*, we use CORTEXM_FPB_* consistently */ From c53a12bfd1fc9ce4d41dd4bd3ceb87cae917c96f Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Thu, 12 Oct 2017 09:26:01 +1300 Subject: [PATCH 3/7] cortexm: Better cache support for Cortex-M7 - On probe, read CTR for cache presence and minimum line length - Make D-Cache clean a function - Clean before memory reads - Clean and invalidate before memory writes - Flush all I-Cache before resume --- src/target/cortexm.c | 58 ++++++++++++++++++++++++++------------------ src/target/cortexm.h | 10 +++++++- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 380f2fcc..abd64f4a 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -78,6 +78,9 @@ struct cortexm_priv { unsigned hw_breakpoint_max; /* Copy of DEMCR for vector-catch */ uint32_t demcr; + /* Cache parameters */ + bool has_cache; + uint32_t dcache_minline; }; /* Register number tables */ @@ -179,45 +182,40 @@ ADIv5_AP_t *cortexm_ap(target *t) return ((struct cortexm_priv *)t->priv)->ap; } -static void cortexm_mem_read(target *t, void *dest, target_addr src, size_t len) +static void cortexm_cache_clean(target *t, target_addr addr, size_t len, bool invalidate) { + struct cortexm_priv *priv = t->priv; + if (!priv->has_cache || (priv->dcache_minline == 0)) + return; + uint32_t cache_reg = invalidate ? CORTEXM_DCCIMVAC : CORTEXM_DCCMVAC; + size_t minline = priv->dcache_minline; + /* flush data cache for RAM regions that intersect requested region */ - target_addr src_end = src + len; /* following code is NOP if wraparound */ + target_addr mem_end = addr + len; /* following code is NOP if wraparound */ /* requested region is [src, src_end) */ for (struct target_ram *r = t->ram; r; r = r->next) { target_addr ram = r->start; target_addr ram_end = r->start + r->length; /* RAM region is [ram, ram_end) */ - if (src > ram) - ram = src; - if (src_end < ram_end) - ram_end = src_end; + if (addr > ram) + ram = addr; + if (mem_end < ram_end) + ram_end = mem_end; /* intersection is [ram, ram_end) */ - for (ram &= ~0x1f; ram < ram_end; ram += 0x20) - adiv5_mem_write(cortexm_ap(t), CORTEXM_DCCIMVAC, &ram, 4); + for (ram &= ~(minline-1); ram < ram_end; ram += minline) + adiv5_mem_write(cortexm_ap(t), cache_reg, &ram, 4); } +} +static void cortexm_mem_read(target *t, void *dest, target_addr src, size_t len) +{ + cortexm_cache_clean(t, src, len, false); adiv5_mem_read(cortexm_ap(t), dest, src, len); } static void cortexm_mem_write(target *t, target_addr dest, const void *src, size_t len) { - /* flush data cache for RAM regions that intersect requested region */ - target_addr dest_end = dest + len; /* following code is NOP if wraparound */ - /* requested region is [dest, dest_end) */ - for (struct target_ram *r = t->ram; r; r = r->next) { - target_addr ram = r->start; - target_addr ram_end = r->start + r->length; - /* RAM region is [ram, ram_end) */ - if (dest > ram) - ram = dest; - if (dest_end < ram_end) - ram_end = dest_end; - /* intersection is [ram, ram_end) */ - for (ram &= ~0x1f; ram < ram_end; ram += 0x20) - adiv5_mem_write(cortexm_ap(t), CORTEXM_DCCIMVAC, &ram, 4); - } - + cortexm_cache_clean(t, dest, len, true); adiv5_mem_write(cortexm_ap(t), dest, src, len); } @@ -283,6 +281,15 @@ bool cortexm_probe(ADIv5_AP_t *ap) priv->demcr = CORTEXM_DEMCR_TRCENA | CORTEXM_DEMCR_VC_HARDERR | CORTEXM_DEMCR_VC_CORERESET; + /* Check cache type */ + uint32_t ctr = target_mem_read32(t, CORTEXM_CTR); + if ((ctr >> 29) == 4) { + priv->has_cache = true; + priv->dcache_minline = 4 << (ctr & 0xf); + } else { + target_check_error(t); + } + #define PROBE(x) \ do { if ((x)(t)) return true; else target_check_error(t); } while (0) @@ -583,6 +590,9 @@ void cortexm_halt_resume(target *t, bool step) cortexm_pc_write(t, pc + 2); } + if (priv->has_cache) + target_mem_write32(t, CORTEXM_ICIALLU, 0); + target_mem_write32(t, CORTEXM_DHCSR, dhcsr); } diff --git a/src/target/cortexm.h b/src/target/cortexm.h index ca5e10b3..e9bf5476 100644 --- a/src/target/cortexm.h +++ b/src/target/cortexm.h @@ -37,7 +37,15 @@ #define CORTEXM_DCRDR (CORTEXM_SCS_BASE + 0xDF8) #define CORTEXM_DEMCR (CORTEXM_SCS_BASE + 0xDFC) -/* Data cache clean and invalidate by address to the PoC=Point of Coherency */ +/* Cache identification */ +#define CORTEXM_CLIDR (CORTEXM_SCS_BASE + 0xD78) +#define CORTEXM_CTR (CORTEXM_SCS_BASE + 0xD7C) +#define CORTEXM_CCSIDR (CORTEXM_SCS_BASE + 0xD80) +#define CORTEXM_CSSELR (CORTEXM_SCS_BASE + 0xD84) + +/* Cache maintenance operations */ +#define CORTEXM_ICIALLU (CORTEXM_SCS_BASE + 0xF50) +#define CORTEXM_DCCMVAC (CORTEXM_SCS_BASE + 0xF68) #define CORTEXM_DCCIMVAC (CORTEXM_SCS_BASE + 0xF70) #define CORTEXM_FPB_BASE (CORTEXM_PPB_BASE + 0x2000) From 1f3c2352054846a6e9825f0fc6698eb21dc035bc Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 8 Dec 2017 13:39:24 +0100 Subject: [PATCH 4/7] src/target/stm32f1.c: Add CCM Ram of STM32F303 devices. --- src/target/stm32f1.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index c9823db3..1b706599 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -136,11 +136,12 @@ bool stm32f1_probe(target *t) stm32f1_add_flash(t, 0x8000000, 0x80000, 0x800); target_add_commands(t, stm32f1_cmd_list, "STM32 HD/CL"); return true; - case 0x422: /* STM32F30x */ - case 0x432: /* STM32F37x */ case 0x438: /* STM32F303x6/8 and STM32F328 */ - case 0x439: /* STM32F302C8 */ + case 0x422: /* STM32F30x */ case 0x446: /* STM32F303xD/E and STM32F398xE */ + target_add_ram(t, 0x10000000, 0x4000); + case 0x432: /* STM32F37x */ + case 0x439: /* STM32F302C8 */ t->driver = "STM32F3"; target_add_ram(t, 0x20000000, 0x10000); stm32f1_add_flash(t, 0x8000000, 0x80000, 0x800); From 922f857de7ee6b59f128812be1e38172f3a2cada Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 18 Dec 2017 13:55:55 +0100 Subject: [PATCH 5/7] stm32f1.c: Add missing fall through statement needed by GCC7. --- src/target/stm32f1.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index 1b706599..4064e01a 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -140,6 +140,7 @@ bool stm32f1_probe(target *t) case 0x422: /* STM32F30x */ case 0x446: /* STM32F303xD/E and STM32F398xE */ target_add_ram(t, 0x10000000, 0x4000); + /* fall through */ case 0x432: /* STM32F37x */ case 0x439: /* STM32F302C8 */ t->driver = "STM32F3"; From f5cac4c78d49f91731048fc4ddc32edb0a7b833b Mon Sep 17 00:00:00 2001 From: Adam Heinrich Date: Sat, 13 Jan 2018 21:11:17 +0100 Subject: [PATCH 6/7] platforms/stm32: Ignore noise errors on USBUART --- src/platforms/stm32/usbuart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/stm32/usbuart.c b/src/platforms/stm32/usbuart.c index 0d1772a3..a466ab55 100644 --- a/src/platforms/stm32/usbuart.c +++ b/src/platforms/stm32/usbuart.c @@ -217,7 +217,7 @@ void USBUSART_ISR(void) { uint32_t err = USART_SR(USBUSART); char c = usart_recv(USBUSART); - if (err & (USART_SR_ORE | USART_SR_FE)) + if (err & (USART_SR_ORE | USART_SR_FE | USART_SR_NE)) return; /* Turn on LED */ From 0ddd8b55d756c4af3afbfbb00b4bfce4fd6ff53b Mon Sep 17 00:00:00 2001 From: jrwhite Date: Sun, 11 Mar 2018 14:35:38 -0500 Subject: [PATCH 7/7] divide-by-zero fix --- scripts/gdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gdb.py b/scripts/gdb.py index eb28ed88..286627c2 100644 --- a/scripts/gdb.py +++ b/scripts/gdb.py @@ -241,7 +241,7 @@ class Target: block = 0 for i in range(len(self.blocks)): block += 1 - if callable(progress_cb): + if callable(progress_cb) and totalblocks > 0: progress_cb(block*100/totalblocks) # Erase the block