From 1ee1f441d581b6473526a4870f4c3aa201a18af6 Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Mon, 27 Feb 2017 10:21:15 +0100 Subject: [PATCH 1/2] stm32f4: write flash using byte access --- src/include/general.h | 2 + src/target/flashstub/Makefile | 6 ++- .../flashstub/{stm32f4.c => stm32f4_x32.c} | 2 +- .../{stm32f4.stub => stm32f4_x32.stub} | 2 +- src/target/flashstub/stm32f4_x8.c | 44 +++++++++++++++++++ src/target/flashstub/stm32f4_x8.stub | 1 + src/target/stm32f4.c | 17 ++++--- 7 files changed, 65 insertions(+), 9 deletions(-) rename src/target/flashstub/{stm32f4.c => stm32f4_x32.c} (93%) rename src/target/flashstub/{stm32f4.stub => stm32f4_x32.stub} (85%) create mode 100644 src/target/flashstub/stm32f4_x8.c create mode 100644 src/target/flashstub/stm32f4_x8.stub diff --git a/src/include/general.h b/src/include/general.h index c82c750..23cae51 100644 --- a/src/include/general.h +++ b/src/include/general.h @@ -41,6 +41,8 @@ #define ALIGN(x, n) (((x) + (n) - 1) & ~((n) - 1)) #undef MIN #define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#undef MAX +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) #endif diff --git a/src/target/flashstub/Makefile b/src/target/flashstub/Makefile index 3b137a0..c16b3d1 100644 --- a/src/target/flashstub/Makefile +++ b/src/target/flashstub/Makefile @@ -11,10 +11,12 @@ endif CFLAGS=-Os -std=gnu99 -mcpu=cortex-m0 -mthumb -I../../../libopencm3/include ASFLAGS=-mcpu=cortex-m3 -mthumb -all: lmi.stub stm32f4.stub stm32l4.stub nrf51.stub stm32f1.stub efm32.stub +all: lmi.stub stm32f4_x8.stub stm32f4_x32.stub stm32l4.stub nrf51.stub \ + stm32f1.stub efm32.stub stm32f1.o: CFLAGS += -DSTM32F1 -stm32f4.o: CFLAGS += -DSTM32F4 +stm32f4_x8.o: CFLAGS += -DSTM32F4 +stm32f4_x32.o: CFLAGS += -DSTM32F4 %.o: %.c $(Q)echo " CC $<" diff --git a/src/target/flashstub/stm32f4.c b/src/target/flashstub/stm32f4_x32.c similarity index 93% rename from src/target/flashstub/stm32f4.c rename to src/target/flashstub/stm32f4_x32.c index 1af271a..117c132 100644 --- a/src/target/flashstub/stm32f4.c +++ b/src/target/flashstub/stm32f4_x32.c @@ -23,7 +23,7 @@ #define SR_ERROR_MASK 0xF2 void __attribute__((naked)) -stm32f4_flash_write_stub(uint32_t *dest, uint32_t *src, uint32_t size) +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; diff --git a/src/target/flashstub/stm32f4.stub b/src/target/flashstub/stm32f4_x32.stub similarity index 85% rename from src/target/flashstub/stm32f4.stub rename to src/target/flashstub/stm32f4_x32.stub index b8fc412..b504ce2 100644 --- a/src/target/flashstub/stm32f4.stub +++ b/src/target/flashstub/stm32f4_x32.stub @@ -1 +1 @@ -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, \ No newline at end of file +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 new file mode 100644 index 0000000..84f9117 --- /dev/null +++ b/src/target/flashstub/stm32f4_x8.c @@ -0,0 +1,44 @@ +/* + * 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 new file mode 100644 index 0000000..08d17dc --- /dev/null +++ b/src/target/flashstub/stm32f4_x8.stub @@ -0,0 +1 @@ +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 c530183..29dcd1e 100644 --- a/src/target/stm32f4.c +++ b/src/target/stm32f4.c @@ -103,12 +103,19 @@ static const char stm32f2_driver_str[] = "STM32F2xx"; #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_stub[] = { -#include "flashstub/stm32f4.stub" +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 + sizeof(stm32f4_flash_write_stub), 4) +#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 @@ -266,8 +273,8 @@ static int stm32f4_flash_write(struct target_flash *f, } /* Write buffer to target ram call stub */ - target_mem_write(f->t, SRAM_BASE, stm32f4_flash_write_stub, - sizeof(stm32f4_flash_write_stub)); + 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); From 3846ea47084d8f6a9ef4a5ac43a367bc7e84c1fd Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Fri, 16 Jun 2017 14:39:57 +0200 Subject: [PATCH 2/2] stm32f4: allow selection of flash programming parallelism --- src/target/stm32f4.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/target/stm32f4.c b/src/target/stm32f4.c index 29dcd1e..31bc3af 100644 --- a/src/target/stm32f4.c +++ b/src/target/stm32f4.c @@ -37,10 +37,12 @@ static bool stm32f4_cmd_erase_mass(target *t); static bool stm32f4_cmd_option(target *t, int argc, char *argv[]); +static bool stm32f4_cmd_psize(target *t, int argc, char *argv[]); const struct command_s stm32f4_cmd_list[] = { {"erase_mass", (cmd_handler)stm32f4_cmd_erase_mass, "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)"}, {NULL, NULL, NULL} }; @@ -123,6 +125,7 @@ static const uint16_t stm32f4_flash_write_x8_stub[] = { struct stm32f4_flash { struct target_flash f; uint8_t base_sector; + uint8_t psize; }; static void stm32f4_add_flash(target *t, @@ -139,6 +142,7 @@ static void stm32f4_add_flash(target *t, f->align = 4; f->erased = 0xff; sf->base_sector = base_sector; + sf->psize = 32; target_add_flash(t, f); } @@ -273,8 +277,12 @@ static int stm32f4_flash_write(struct target_flash *f, } /* Write buffer to target ram call stub */ - target_mem_write(f->t, SRAM_BASE, stm32f4_flash_write_x8_stub, - sizeof(stm32f4_flash_write_x8_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); @@ -362,3 +370,33 @@ static bool stm32f4_cmd_option(target *t, int argc, char *argv[]) } return true; } + +static bool stm32f4_cmd_psize(target *t, int argc, char *argv[]) +{ + if (argc == 1) { + uint8_t psize = 8; + 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"); + } else { + uint8_t psize; + if (!strcmp(argv[1], "x8")) { + psize = 8; + } else if (!strcmp(argv[1], "x32")) { + psize = 32; + } else { + tc_printf(t, "usage: monitor psize (x8|x32)\n"); + return false; + } + for (struct target_flash *f = t->flash; f; f = f->next) { + if (f->write == stm32f4_flash_write) { + ((struct stm32f4_flash *)f)->psize = psize; + } + } + } + return true; +}