diff --git a/src/target/flashstub/Makefile b/src/target/flashstub/Makefile index c16b3d1..d6abdd1 100644 --- a/src/target/flashstub/Makefile +++ b/src/target/flashstub/Makefile @@ -11,12 +11,10 @@ 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 \ +all: lmi.stub stm32l4.stub nrf51.stub \ stm32f1.stub efm32.stub stm32f1.o: CFLAGS += -DSTM32F1 -stm32f4_x8.o: CFLAGS += -DSTM32F4 -stm32f4_x32.o: CFLAGS += -DSTM32F4 %.o: %.c $(Q)echo " CC $<" 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/stm32f4.c b/src/target/stm32f4.c index 7f2c597..2701cef 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))"}, {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); } @@ -417,17 +405,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 +663,25 @@ 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_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 { - tc_printf(t, "usage: monitor psize (x8|x32)\n"); + tc_printf(t, "usage: monitor psize (x8|x16|x32)\n"); return false; } for (struct target_flash *f = t->flash; f; f = f->next) {