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 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 127a2c56..a6931ee2 100644 --- a/src/platforms/common/cdcacm.c +++ b/src/platforms/common/cdcacm.c @@ -449,6 +449,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: @@ -466,6 +467,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; @@ -566,4 +568,3 @@ void USB_ISR(void) { usbd_poll(usbdev); } - 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 */ diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 4e941060..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,13 +182,40 @@ ADIv5_AP_t *cortexm_ap(target *t) return ((struct cortexm_priv *)t->priv)->ap; } +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 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 (addr > ram) + ram = addr; + if (mem_end < ram_end) + ram_end = mem_end; + /* intersection is [ram, ram_end) */ + 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) { + cortexm_cache_clean(t, dest, len, true); adiv5_mem_write(cortexm_ap(t), dest, src, len); } @@ -251,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) @@ -551,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 bf1d821d..e9bf5476 100644 --- a/src/target/cortexm.h +++ b/src/target/cortexm.h @@ -37,6 +37,17 @@ #define CORTEXM_DCRDR (CORTEXM_SCS_BASE + 0xDF8) #define CORTEXM_DEMCR (CORTEXM_SCS_BASE + 0xDFC) +/* 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) /* ARM Literature uses FP_*, we use CORTEXM_FPB_* consistently */ diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index c9823db3..4064e01a 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -136,11 +136,13 @@ 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); + /* fall through */ + case 0x432: /* STM32F37x */ + case 0x439: /* STM32F302C8 */ t->driver = "STM32F3"; target_add_ram(t, 0x20000000, 0x10000); stm32f1_add_flash(t, 0x8000000, 0x80000, 0x800);