diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 8d86936..b6236d8 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -457,11 +457,6 @@ void adiv5_dp_init(ADIv5_DP_t *dp) adiv5_dp_unref(dp); } -enum align { - ALIGN_BYTE = 0, - ALIGN_HALFWORD = 1, - ALIGN_WORD = 2 -}; #define ALIGNOF(x) (((x) & 3) == 0 ? ALIGN_WORD : \ (((x) & 1) == 0 ? ALIGN_HALFWORD : ALIGN_BYTE)) @@ -477,6 +472,7 @@ static void ap_mem_access_setup(ADIv5_AP_t *ap, uint32_t addr, enum align align) case ALIGN_HALFWORD: csw |= ADIV5_AP_CSW_SIZE_HALFWORD; break; + case ALIGN_DWORD: case ALIGN_WORD: csw |= ADIV5_AP_CSW_SIZE_WORD; break; @@ -495,6 +491,7 @@ static void * extract(void *dest, uint32_t src, uint32_t val, enum align align) case ALIGN_HALFWORD: *(uint16_t *)dest = (val >> ((src & 0x2) << 3) & 0xFFFF); break; + case ALIGN_DWORD: case ALIGN_WORD: *(uint32_t *)dest = val; break; @@ -534,10 +531,10 @@ 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) +adiv5_mem_write_sized(ADIv5_AP_t *ap, uint32_t dest, const void *src, + size_t len, enum align align) { uint32_t odest = dest; - enum align align = MIN(ALIGNOF(dest), ALIGNOF(len)); len >>= align; ap_mem_access_setup(ap, dest, align); @@ -551,6 +548,7 @@ adiv5_mem_write(ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len) case ALIGN_HALFWORD: tmp = ((uint32_t)*(uint16_t *)src) << ((dest & 2) << 3); break; + case ALIGN_DWORD: case ALIGN_WORD: tmp = *(uint32_t *)src; break; @@ -568,6 +566,13 @@ adiv5_mem_write(ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len) } } +void +adiv5_mem_write(ADIv5_AP_t *ap, uint32_t dest, const void *src, size_t len) +{ + enum align align = MIN(ALIGNOF(dest), ALIGNOF(len)); + adiv5_mem_write_sized(ap, dest, src, len, align); +} + void adiv5_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value) { adiv5_dp_write(ap->dp, ADIV5_DP_SELECT, diff --git a/src/target/adiv5.h b/src/target/adiv5.h index ca81471..2929a31 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -100,6 +100,13 @@ #define ADIV5_LOW_WRITE 0 #define ADIV5_LOW_READ 1 +enum align { + ALIGN_BYTE = 0, + ALIGN_HALFWORD = 1, + ALIGN_WORD = 2, + ALIGN_DWORD = 3 +}; + /* Try to keep this somewhat absract for later adding SW-DP */ typedef struct ADIv5_DP_s { int refcnt; @@ -167,6 +174,8 @@ void adiv5_jtag_dp_handler(jtag_dev_t *dev); 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); #endif diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 33344d6..dba2349 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -459,6 +459,14 @@ static void cortexm_regs_write(target *t, const void *data) } } +int cortexm_mem_write_sized( + target *t, target_addr dest, const void *src, size_t len, enum align align) +{ + cortexm_cache_clean(t, dest, len, true); + adiv5_mem_write_sized(cortexm_ap(t), dest, src, len, align); + return target_check_error(t); +} + static uint32_t cortexm_pc_read(target *t) { target_mem_write32(t, CORTEXM_DCRSR, 0x0F); diff --git a/src/target/cortexm.h b/src/target/cortexm.h index e9bf547..9aa4733 100644 --- a/src/target/cortexm.h +++ b/src/target/cortexm.h @@ -175,6 +175,8 @@ void cortexm_detach(target *t); void cortexm_halt_resume(target *t, bool step); int cortexm_run_stub(target *t, uint32_t loadaddr, uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3); +int cortexm_mem_write_sized( + target *t, target_addr dest, const void *src, size_t len, enum align align); #endif diff --git a/src/target/flashstub/Makefile b/src/target/flashstub/Makefile index c16b3d1..abc03a4 100644 --- a/src/target/flashstub/Makefile +++ b/src/target/flashstub/Makefile @@ -11,12 +11,7 @@ endif CFLAGS=-Os -std=gnu99 -mcpu=cortex-m0 -mthumb -I../../../libopencm3/include ASFLAGS=-mcpu=cortex-m3 -mthumb -all: lmi.stub stm32f4_x8.stub stm32f4_x32.stub stm32l4.stub nrf51.stub \ - stm32f1.stub efm32.stub - -stm32f1.o: CFLAGS += -DSTM32F1 -stm32f4_x8.o: CFLAGS += -DSTM32F4 -stm32f4_x32.o: CFLAGS += -DSTM32F4 +all: lmi.stub stm32l4.stub nrf51.stub efm32.stub %.o: %.c $(Q)echo " CC $<" diff --git a/src/target/flashstub/stm32f1.c b/src/target/flashstub/stm32f1.c deleted file mode 100644 index f9ba0a1..0000000 --- a/src/target/flashstub/stm32f1.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of the Black Magic Debug project. - * - * Copyright (C) 2015 Black Sphere Technologies Ltd. - * Written by Gareth McMullin - * - * 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 "libopencm3/stm32/flash.h" -#include "stub.h" - -#define SR_ERROR_MASK 0x14 - -void __attribute__((naked)) -stm32f1_flash_write_stub(uint16_t *dest, uint16_t *src, uint32_t size) -{ - for (int i; i < size; i += 2) { - FLASH_CR = FLASH_CR_PG; - *dest++ = *src++; - while (FLASH_SR & FLASH_SR_BSY) - ; - } - - if (FLASH_SR & SR_ERROR_MASK) - stub_exit(1); - - stub_exit(0); -} - diff --git a/src/target/flashstub/stm32f1.stub b/src/target/flashstub/stm32f1.stub deleted file mode 100644 index 3fe7cd0..0000000 --- a/src/target/flashstub/stm32f1.stub +++ /dev/null @@ -1 +0,0 @@ -0x2300, 0x4C09, 0x4293, 0xD209, 0x2601, 0x4D08, 0x602E, 0x5ACD, 0x52C5, 0x6825, 0x07ED, 0xD4FC, 0x3302, 0xE7F2, 0x2314, 0x6822, 0x421A, 0xD000, 0xBE01, 0xBE00, 0x200C, 0x4002, 0x2010, 0x4002, \ No newline at end of file diff --git a/src/target/flashstub/stm32f4_x32.c b/src/target/flashstub/stm32f4_x32.c deleted file mode 100644 index 117c132..0000000 --- a/src/target/flashstub/stm32f4_x32.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of the Black Magic Debug project. - * - * Copyright (C) 2015 Black Sphere Technologies Ltd. - * Written by Gareth McMullin - * - * 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 "libopencm3/stm32/flash.h" -#include "stub.h" - -#define SR_ERROR_MASK 0xF2 - -void __attribute__((naked)) -stm32f4_flash_write_x32_stub(uint32_t *dest, uint32_t *src, uint32_t size) -{ - for (int i = 0; i < size; i += 4) { - FLASH_CR = FLASH_CR_PROGRAM_X32 | FLASH_CR_PG; - *dest++ = *src++; - __asm("dsb"); - while (FLASH_SR & FLASH_SR_BSY) - ; - } - - if (FLASH_SR & SR_ERROR_MASK) - stub_exit(1); - - stub_exit(0); -} - diff --git a/src/target/flashstub/stm32f4_x32.stub b/src/target/flashstub/stm32f4_x32.stub deleted file mode 100644 index b504ce2..0000000 --- a/src/target/flashstub/stm32f4_x32.stub +++ /dev/null @@ -1 +0,0 @@ -0x2300, 0x4C0A, 0x4293, 0xD20B, 0x4E09, 0x4D0A, 0x602E, 0x58CD, 0x50C5, 0xF3BF, 0x8F4F, 0x6825, 0x03ED, 0xD4FC, 0x3304, 0xE7F0, 0x23F2, 0x6822, 0x421A, 0xD000, 0xBE01, 0xBE00, 0x3C0C, 0x4002, 0x0201, 0x0000, 0x3C10, 0x4002, diff --git a/src/target/flashstub/stm32f4_x8.c b/src/target/flashstub/stm32f4_x8.c deleted file mode 100644 index 84f9117..0000000 --- a/src/target/flashstub/stm32f4_x8.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of the Black Magic Debug project. - * - * Copyright (C) 2017 Black Sphere Technologies Ltd. - * Written by Gordon Smith - * - * 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 "libopencm3/stm32/flash.h" -#include "stub.h" - -#define SR_ERROR_MASK 0xF2 - -void __attribute__((naked)) -stm32f4_flash_write_x8_stub(uint32_t *dest, uint32_t *src, uint32_t size) -{ - uint8_t *b_dest, *b_src; - b_dest = (void *)dest; - b_src = (void *)src; - for (int i = 0; i < size; i += 1) { - FLASH_CR = FLASH_CR_PROGRAM_X8 | FLASH_CR_PG; - *b_dest++ = *b_src++; - __asm("dsb"); - while (FLASH_SR & FLASH_SR_BSY) - ; - } - - if (FLASH_SR & SR_ERROR_MASK) - stub_exit(1); - - stub_exit(0); -} - diff --git a/src/target/flashstub/stm32f4_x8.stub b/src/target/flashstub/stm32f4_x8.stub deleted file mode 100644 index 08d17dc..0000000 --- a/src/target/flashstub/stm32f4_x8.stub +++ /dev/null @@ -1 +0,0 @@ -0x2300, 0x4C0A, 0x4293, 0xD00B, 0x2601, 0x4D09, 0x602E, 0x5CCD, 0x54C5, 0xF3BF, 0x8F4F, 0x6825, 0x03ED, 0xD4FC, 0x3301, 0xE7F0, 0x23F2, 0x6822, 0x421A, 0xD000, 0xBE01, 0xBE00, 0x3C0C, 0x4002, 0x3C10, 0x4002, diff --git a/src/target/flashstub/stm32l4.c b/src/target/flashstub/stm32l4.c deleted file mode 100644 index 820bca4..0000000 --- a/src/target/flashstub/stm32l4.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of the Black Magic Debug project. - * - * Copyright (C) 2015 Black Sphere Technologies Ltd. - * Written by Gareth McMullin - * - * 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 "stub.h" -#include - -/* No STM32L4 definitions in libopencm3 yet */ -#define FLASH_SR ((volatile uint32_t *) 0x40022010) -#define FLASH_SR_EOP (1 << 0) -#define SR_ERROR_MASK 0xC3FA -#define FLASH_SR_BSY (1 << 16) - -#define FLASH_CR ((volatile uint32_t *) 0x40022014) -#define FLASH_CR_PG (1 << 0) -#define FLASH_CR_EOPIE (1 << 24) -#define FLASH_CR_ERRIE (1 << 25) -#define FLASH_SR_EOP (1 << 0) - -void __attribute__((naked)) -stm32l4_flash_write_stub(uint32_t *dest, uint32_t *src, uint32_t size) -{ - if ((size & 7) || ((uint32_t)dest & 7)) - stub_exit(1); - for (int i = 0; i < size; i += 8) { - *FLASH_CR = FLASH_CR_EOPIE | FLASH_CR_ERRIE | FLASH_CR_PG; - *dest++ = *src++; - *dest++ = *src++; - __asm("dsb"); - while (*FLASH_SR & FLASH_SR_BSY) - ; - if ((*FLASH_SR & SR_ERROR_MASK) || !(*FLASH_SR & FLASH_SR_EOP)) - stub_exit(1); - *FLASH_SR |= FLASH_SR_EOP; - } - *FLASH_CR = 0; - stub_exit(0); -} diff --git a/src/target/flashstub/stm32l4.stub b/src/target/flashstub/stm32l4.stub deleted file mode 100644 index 73cd969..0000000 --- a/src/target/flashstub/stm32l4.stub +++ /dev/null @@ -1 +0,0 @@ -0x1C04, 0x4314, 0x2300, 0x0764, 0xD011, 0xBE01, 0xE00F, 0x4C11, 0x6825, 0x03ED, 0xD4FB, 0x6826, 0x4D0F, 0x422E, 0xD115, 0x6825, 0x07ED, 0xD512, 0x2601, 0x6825, 0x3308, 0x4335, 0x6025, 0x4C0B, 0x4293, 0xD20C, 0x4D0A, 0x6025, 0x58CC, 0x50C4, 0x18CC, 0x6865, 0x18C4, 0x6065, 0xF3BF, 0x8F4F, 0xE7E1, 0xBE01, 0xE7EA, 0x2300, 0x6023, 0xBE00, 0x2010, 0x4002, 0xC3FA, 0x0000, 0x2014, 0x4002, 0x0001, 0x0300, \ No newline at end of file diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index fcdc0c8..3394a0d 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -72,6 +72,7 @@ static int stm32f1_flash_write(struct target_flash *f, #define FLASH_CR_OPTPG (1 << 4) #define FLASH_CR_MER (1 << 2) #define FLASH_CR_PER (1 << 1) +#define FLASH_CR_PG (1 << 0) #define FLASH_OBR_RDPRT (1 << 1) @@ -93,13 +94,6 @@ static int stm32f1_flash_write(struct target_flash *f, #define FLASHSIZE 0x1FFFF7E0 #define FLASHSIZE_F0 0x1FFFF7CC -static const uint16_t stm32f1_flash_write_stub[] = { -#include "flashstub/stm32f1.stub" -}; - -#define SRAM_BASE 0x20000000 -#define STUB_BUFFER_BASE ALIGN(SRAM_BASE + sizeof(stm32f1_flash_write_stub), 4) - static void stm32f1_add_flash(target *t, uint32_t addr, size_t length, size_t erasesize) { @@ -109,6 +103,7 @@ static void stm32f1_add_flash(target *t, f->blocksize = erasesize; f->erase = stm32f1_flash_erase; f->write = stm32f1_flash_write; + f->buf_size = erasesize; f->erased = 0xff; target_add_flash(t, f); } @@ -226,11 +221,24 @@ static int stm32f1_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len) { target *t = f->t; - /* Write stub and data to target ram and set PC */ - target_mem_write(t, SRAM_BASE, stm32f1_flash_write_stub, - sizeof(stm32f1_flash_write_stub)); - target_mem_write(t, STUB_BUFFER_BASE, src, len); - return cortexm_run_stub(t, SRAM_BASE, dest, STUB_BUFFER_BASE, len, 0); + uint32_t sr; + target_mem_write32(t, FLASH_CR, FLASH_CR_PG); + cortexm_mem_write_sized(t, dest, src, len, ALIGN_HALFWORD); + /* Read FLASH_SR to poll for BSY bit */ + /* Wait for completion or an error */ + do { + sr = target_mem_read32(t, FLASH_SR); + if(target_check_error(t)) { + DEBUG("stm32f1 flash write: comm error\n"); + return -1; + } + } while (sr & FLASH_SR_BSY); + + if (sr & SR_ERROR_MASK) { + DEBUG("stm32f1 flash write error 0x%" PRIx32 "\n", sr); + return -1; + } + return 0; } static bool stm32f1_cmd_erase_mass(target *t) diff --git a/src/target/stm32f4.c b/src/target/stm32f4.c index 7f2c597..3e90bac 100644 --- a/src/target/stm32f4.c +++ b/src/target/stm32f4.c @@ -3,6 +3,8 @@ * * Copyright (C) 2011 Black Sphere Technologies Ltd. * Written by Gareth McMullin + * Copyright (C) 2017, 2018 Uwe Bonnes + * * * 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 @@ -44,7 +46,7 @@ const struct command_s stm32f4_cmd_list[] = { "Erase entire flash memory"}, {"option", (cmd_handler)stm32f4_cmd_option, "Manipulate option bytes"}, {"psize", (cmd_handler)stm32f4_cmd_psize, - "Configure flash write parallelism: (x8|x32(default))"}, + "Configure flash write parallelism: (x8|x16|x32(default)|x64)"}, {NULL, NULL, NULL} }; @@ -108,28 +110,13 @@ static int stm32f4_flash_write(struct target_flash *f, #define DBG_WWDG_STOP (1 << 11) #define DBG_IWDG_STOP (1 << 12) -/* This routine uses word access. Only usable on target voltage >2.7V */ -static const uint16_t stm32f4_flash_write_x32_stub[] = { -#include "flashstub/stm32f4_x32.stub" -}; - -/* This routine uses byte access. Usable on target voltage <2.2V */ -static const uint16_t stm32f4_flash_write_x8_stub[] = { -#include "flashstub/stm32f4_x8.stub" -}; - -#define SRAM_BASE 0x20000000 -#define STUB_BUFFER_BASE \ - ALIGN(SRAM_BASE + MAX(sizeof(stm32f4_flash_write_x8_stub), \ - sizeof(stm32f4_flash_write_x32_stub)), 4) - #define AXIM_BASE 0x8000000 #define ITCM_BASE 0x0200000 struct stm32f4_flash { struct target_flash f; + enum align psize; uint8_t base_sector; - uint8_t psize; uint8_t bank_split; }; @@ -161,10 +148,11 @@ static void stm32f4_add_flash(target *t, f->blocksize = blocksize; f->erase = stm32f4_flash_erase; f->write = stm32f4_flash_write; + f->buf_size = 1024; f->erased = 0xff; sf->base_sector = base_sector; - sf->psize = 32; sf->bank_split = split; + sf->psize = ALIGN_WORD; target_add_flash(t, f); } @@ -381,9 +369,15 @@ static int stm32f4_flash_erase(struct target_flash *f, target_addr addr, uint8_t sector = sf->base_sector + (addr - f->start)/f->blocksize; stm32f4_flash_unlock(t); + enum align psize = ALIGN_WORD; + for (struct target_flash *f = t->flash; f; f = f->next) { + if (f->write == stm32f4_flash_write) { + psize = ((struct stm32f4_flash *)f)->psize; + } + } while(len) { uint32_t cr = FLASH_CR_EOPIE | FLASH_CR_ERRIE | FLASH_CR_SER | - (sector << 3); + (psize * FLASH_CR_PSIZE16) | (sector << 3); /* Flash page erase instruction */ target_mem_write32(t, FLASH_CR, cr); /* write address to FMA */ @@ -417,17 +411,27 @@ static int stm32f4_flash_write(struct target_flash *f, if ((dest >= ITCM_BASE) && (dest < AXIM_BASE)) { dest = AXIM_BASE + (dest - ITCM_BASE); } + target *t = f->t; + uint32_t sr; + enum align psize = ((struct stm32f4_flash *)f)->psize; + target_mem_write32(t, FLASH_CR, + (psize * FLASH_CR_PSIZE16) | FLASH_CR_PG); + cortexm_mem_write_sized(t, dest, src, len, psize); + /* Read FLASH_SR to poll for BSY bit */ + /* Wait for completion or an error */ + do { + sr = target_mem_read32(t, FLASH_SR); + if(target_check_error(t)) { + DEBUG("stm32f4 flash write: comm error\n"); + return -1; + } + } while (sr & FLASH_SR_BSY); - /* Write buffer to target ram call stub */ - if (((struct stm32f4_flash *)f)->psize == 32) - target_mem_write(f->t, SRAM_BASE, stm32f4_flash_write_x32_stub, - sizeof(stm32f4_flash_write_x32_stub)); - else - target_mem_write(f->t, SRAM_BASE, stm32f4_flash_write_x8_stub, - sizeof(stm32f4_flash_write_x8_stub)); - target_mem_write(f->t, STUB_BUFFER_BASE, src, len); - return cortexm_run_stub(f->t, SRAM_BASE, dest, - STUB_BUFFER_BASE, len, 0); + if (sr & SR_ERROR_MASK) { + DEBUG("stm32f4 flash write error 0x%" PRIx32 "\n", sr); + return -1; + } + return 0; } static bool stm32f4_cmd_erase_mass(target *t) @@ -665,22 +669,28 @@ static bool stm32f4_cmd_option(target *t, int argc, char *argv[]) static bool stm32f4_cmd_psize(target *t, int argc, char *argv[]) { if (argc == 1) { - uint8_t psize = 8; + enum align psize = ALIGN_WORD; for (struct target_flash *f = t->flash; f; f = f->next) { if (f->write == stm32f4_flash_write) { psize = ((struct stm32f4_flash *)f)->psize; } } tc_printf(t, "Flash write parallelism: %s\n", - psize == 32 ? "x32" : "x8"); + psize == ALIGN_DWORD ? "x64" : + psize == ALIGN_WORD ? "x32" : + psize == ALIGN_HALFWORD ? "x16" : "x8"); } else { - uint8_t psize; + enum align psize; if (!strcmp(argv[1], "x8")) { - psize = 8; + psize = ALIGN_BYTE; + } else if (!strcmp(argv[1], "x16")) { + psize = ALIGN_HALFWORD; } else if (!strcmp(argv[1], "x32")) { - psize = 32; + psize = ALIGN_WORD; + } else if (!strcmp(argv[1], "x64")) { + psize = ALIGN_DWORD; } else { - tc_printf(t, "usage: monitor psize (x8|x32)\n"); + tc_printf(t, "usage: monitor psize (x8|x16|x32|x32)\n"); return false; } for (struct target_flash *f = t->flash; f; f = f->next) { diff --git a/src/target/stm32l4.c b/src/target/stm32l4.c index f765599..f67b858 100644 --- a/src/target/stm32l4.c +++ b/src/target/stm32l4.c @@ -1,7 +1,7 @@ /* * This file is part of the Black Magic Debug project. * - * Copyright (C) 2015, 2017 Uwe Bonnes + * Copyright (C) 2015, 2017, 2018 Uwe Bonnes * Written by Uwe Bonnes * * This program is free software: you can redistribute it and/or modify @@ -112,14 +112,6 @@ static const char stm32l4_driver_str[] = "STM32L4xx"; #define DBGMCU_IDCODE 0xE0042000 #define FLASH_SIZE_REG 0x1FFF75E0 -/* This routine is uses double word access.*/ -static const uint16_t stm32l4_flash_write_stub[] = { -#include "flashstub/stm32l4.stub" -}; - -#define SRAM_BASE 0x20000000 -#define STUB_BUFFER_BASE ALIGN(SRAM_BASE + sizeof(stm32l4_flash_write_stub), 8) - struct stm32l4_flash { struct target_flash f; uint32_t bank1_start; @@ -258,12 +250,24 @@ static int stm32l4_flash_erase(struct target_flash *f, target_addr addr, size_t static int stm32l4_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len) { - /* Write buffer to target ram call stub */ - target_mem_write(f->t, SRAM_BASE, stm32l4_flash_write_stub, - sizeof(stm32l4_flash_write_stub)); - target_mem_write(f->t, STUB_BUFFER_BASE, src, len); - return cortexm_run_stub(f->t, SRAM_BASE, dest, - STUB_BUFFER_BASE, len, 0); + target *t = f->t; + target_mem_write32(t, FLASH_CR, FLASH_CR_PG); + target_mem_write(t, dest, src, len); + /* Wait for completion or an error */ + uint32_t sr; + do { + sr = target_mem_read32(t, FLASH_SR); + if (target_check_error(t)) { + DEBUG("stm32l4 flash write: comm error\n"); + return -1; + } + } while (sr & FLASH_SR_BSY); + + if(sr & FLASH_SR_ERROR_MASK) { + DEBUG("stm32l4 flash write error: sr 0x%" PRIu32 "\n", sr); + return -1; + } + return 0; } static bool stm32l4_cmd_erase(target *t, uint32_t action)