flash/stm32l4x: switch to to c loader instead of assembly loader
authorTarek BOCHKATI <tarek.bouchkati@gmail.com>
Sat, 6 Mar 2021 21:46:35 +0000 (22:46 +0100)
committerOleksij Rempel <linux@rempel-privat.de>
Thu, 2 Sep 2021 17:21:13 +0000 (17:21 +0000)
switching to C loader instead of the assembly version will enhance readability
will reduce the maintenance effort.

besides the switch to C loader, we added a new parameters to the loader
like flash_word_size and flash_sr_bsy_mask in order to support properly
STM32U5x and STM32G0Bx/G0Cx in dual-bank mode.

Change-Id: I24cafc2ba637a065593a0506eae787b21080a0ba
Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/6109
Tested-by: jenkins
Reviewed-by: Oleksij Rempel <linux@rempel-privat.de>
contrib/loaders/flash/stm32/Makefile
contrib/loaders/flash/stm32/stm32l4x.S [deleted file]
contrib/loaders/flash/stm32/stm32l4x.c [new file with mode: 0644]
contrib/loaders/flash/stm32/stm32l4x.inc
src/flash/nor/stm32l4x.c
src/flash/nor/stm32l4x.h

index b58b412840411da88d32214c6de24f48def33c81..cee282aa3e5da87ef1c447e601ad3541c5a9b6c8 100644 (file)
@@ -6,14 +6,19 @@ CC=$(CROSS_COMPILE)gcc
 OBJCOPY=$(CROSS_COMPILE)objcopy
 OBJDUMP=$(CROSS_COMPILE)objdump
 
-CFLAGS = -static -nostartfiles -mlittle-endian -Wa,-EL
+
+AFLAGS = -static -nostartfiles -mlittle-endian -Wa,-EL
+CFLAGS = -c -mthumb -nostdlib -nostartfiles -Os -g -fPIC
 
 all: stm32f1x.inc stm32f2x.inc stm32h7x.inc stm32l4x.inc stm32lx.inc
 
 .PHONY: clean
 
 %.elf: %.S
-       $(CC) $(CFLAGS) $< -o $@
+       $(CC) $(AFLAGS) $< -o $@
+
+stm32l4x.elf: stm32l4x.c
+       $(CC) $(CFLAGS) -mcpu=cortex-m0plus -fstack-usage -Wa,-adhln=$(<:.c=.lst) $< -o $@
 
 %.lst: %.elf
        $(OBJDUMP) -S $< > $@
diff --git a/contrib/loaders/flash/stm32/stm32l4x.S b/contrib/loaders/flash/stm32/stm32l4x.S
deleted file mode 100644 (file)
index 9923ce7..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2010 by Spencer Oliver                                  *
- *   spen@spen-soft.co.uk                                                  *
- *                                                                         *
- *   Copyright (C) 2011 Ã˜yvind Harboe                                      *
- *   oyvind.harboe@zylin.com                                               *
- *                                                                         *
- *   Copyright (C) 2015 Uwe Bonnes                                         *
- *   bon@elektron.ikp.physik.tu-darmstadt.de                               *
- *                                                                         *
- *   Copyright (C) 2018 Andreas Bolsch                                     *
- *   andreas.bolsch@mni.thm.de                                             *
- *                                                                         *
- *   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 2 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, write to the                         *
- *   Free Software Foundation, Inc.                                        *
- ***************************************************************************/
-
-       .text
-       .syntax unified
-       .cpu cortex-m0
-       .thumb
-
-/*
- * Params :
- * r0 = workarea start, status (out)
- * r1 = workarea end + 1
- * r2 = target address
- * r3 = count (64bit words)
- * r4 = flash status register
- * r5 = flash control register
- *
- * Clobbered:
- * r6/7 - temp (64-bit)
- */
-
-#include "../../../../src/flash/nor/stm32l4x.h"
-
-       .thumb_func
-       .global _start
-
-_start:
-       mov             r8, r3                                          /* copy dword count */
-wait_fifo:
-       ldr             r6, [r0, #0]                            /* read wp */
-       cmp             r6, #0                                          /* if wp == 0,  */
-       beq             exit                                            /* then abort */
-       ldr             r3, [r0, #4]                            /* read rp */
-       subs    r6, r6, r3                                      /* number of bytes available for read in r6 */
-       bpl             fifo_stat                                       /* if not wrapped around, skip */
-       adds    r6, r6, r1                                      /* add end of buffer */
-       subs    r6, r6, r0                                      /* sub start of buffer */
-fifo_stat:
-       cmp             r6, #8                                          /* wait until at least one dword available */
-       bcc             wait_fifo
-
-       movs    r6, #FLASH_PG                           /* flash program enable */
-       str             r6, [r5]                                        /* write to FLASH_CR, start operation */
-       ldmia   r3!, {r6, r7}                           /* read one dword from src, increment ptr */
-       stmia   r2!, {r6, r7}                           /* write one dword to dst, increment ptr */
-       dsb
-       ldr             r7, =FLASH_BSY                          /* FLASH_BSY mask */
-busy:
-       ldr     r6, [r4]                                        /* get FLASH_SR register */
-       tst             r6, r7                                          /* BSY == 1 => operation in progress */
-       bne     busy                                            /* if still set, wait more ... */
-       movs    r7, #FLASH_ERROR                        /* all error bits */
-       tst             r6, r7                                          /* check for any error bit */
-       bne             error                                           /* fail ... */
-
-       cmp             r3, r1                                          /* rp at end of buffer? */
-       bcc             upd_rp                                          /* if no, then skip */
-       subs    r3, r3, r1                                      /* sub end of buffer */
-       adds    r3, r3, r0                                      /* add start of buffer */
-       adds    r3, r3, #8                                      /* skip wp and rp */
-upd_rp:
-       str             r3, [r0, #4]                            /* store rp */
-       mov             r7, r8                                          /* get dword count */
-       subs    r7, r7, #1                                      /* decrement dword count */
-       mov             r8, r7                                          /* save dword count */
-       beq             exit                                            /* exit if done */
-       b               wait_fifo
-
-       .pool
-
-error:
-       movs    r3, #0
-       str             r3, [r0, #4]                            /* set rp = 0 on error */
-exit:
-       mov             r0, r6                                          /* return status in r0 */
-       movs    r6, #0                                          /* flash program disable */
-       str             r6, [r5]                                        /* write to FLASH_CR */
-       movs    r6, #FLASH_ERROR                        /* all error bits */
-       str             r6, [r4]                                        /* write to FLASH_CR to clear errors */
-       bkpt    #0x00
diff --git a/contrib/loaders/flash/stm32/stm32l4x.c b/contrib/loaders/flash/stm32/stm32l4x.c
new file mode 100644 (file)
index 0000000..bcad988
--- /dev/null
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/**
+ * Copyright (C) 2021 Tarek BOCHKATI
+ *   tarek.bouchkati@st.com
+ */
+
+#include <stdint.h>
+#include "../../../../src/flash/nor/stm32l4x.h"
+
+static inline __attribute__((always_inline))
+void copy_buffer_u32(uint32_t *dst, uint32_t *src, int len)
+{
+       for (int i = 0; i < len; i++)
+               dst[i] = src[i];
+}
+
+/* this function is assumes that fifo_size is multiple of flash_word_size
+ * this condition is ensured by target_run_flash_async_algorithm
+ */
+
+void write(volatile struct stm32l4_work_area *work_area,
+                  uint8_t *fifo_end,
+                  uint8_t *target_address,
+                  uint32_t count)
+{
+       volatile uint32_t *flash_sr = (uint32_t *) work_area->params.flash_sr_addr;
+       volatile uint32_t *flash_cr = (uint32_t *) work_area->params.flash_cr_addr;
+
+       /* optimization to avoid reading from memory each time */
+       uint8_t *rp_cache  = work_area->fifo.rp;
+
+       /* fifo_start is used to wrap when we reach fifo_end */
+       uint8_t *fifo_start = rp_cache;
+
+       /* enable flash programming */
+       *flash_cr = FLASH_PG;
+
+       while (count) {
+               /* optimization to avoid reading from memory each time */
+               uint8_t *wp_cache  = work_area->fifo.wp;
+               if (wp_cache == 0)
+                       break; /* aborted by target_run_flash_async_algorithm */
+
+               int32_t fifo_size = wp_cache - rp_cache;
+               if (fifo_size < 0) {
+                       /* consider the linear fifo, we will wrap later */
+                       fifo_size = fifo_end - rp_cache;
+               }
+
+               /* wait for at least a flash word */
+               while (fifo_size >= work_area->params.flash_word_size) {
+                       copy_buffer_u32((uint32_t *)target_address,
+                                       (uint32_t *)rp_cache,
+                                       work_area->params.flash_word_size / 4);
+
+                       /* update target_address and rp_cache */
+                       target_address += work_area->params.flash_word_size;
+                       rp_cache += work_area->params.flash_word_size;
+
+                       /* wait for the busy flag */
+                       while (*flash_sr & work_area->params.flash_sr_bsy_mask)
+                               ;
+
+                       if (*flash_sr & FLASH_ERROR) {
+                               work_area->fifo.rp = 0; /* set rp to zero 0 on error */
+                               goto write_end;
+                       }
+
+                       /* wrap if reach the fifo_end, and update rp in memory */
+                       if (rp_cache >= fifo_end)
+                               rp_cache = fifo_start;
+
+                       /* flush the rp cache value,
+                        * so target_run_flash_async_algorithm can fill the circular fifo */
+                       work_area->fifo.rp = rp_cache;
+
+                       /* update fifo_size and count */
+                       fifo_size -= work_area->params.flash_word_size;
+                       count--;
+               }
+       }
+
+write_end:
+       /* disable flash programming */
+       *flash_cr = 0;
+
+       /* soft break the loader */
+       __asm("bkpt 0");
+}
+
+/* by enabling this define 'DEBUG':
+ * the main() function can help help debugging the loader algo
+ * note: the application should be linked into RAM */
+
+/* #define DEBUG */
+
+#ifdef DEBUG
+/* device selector: STM32L5 | STM32U5 | STM32WB | STM32WL | STM32WL_CPU2 | STM32G0Bx | ... */
+#define STM32U5
+
+/* when using a secure device, and want to test the secure programming enable this define */
+/* #define SECURE */
+
+#if defined(STM32U5)
+#  define FLASH_WORD_SIZE   16
+#else
+#  define FLASH_WORD_SIZE   8
+#endif
+
+#if defined(STM32WB) || defined(STM32WL)
+#  define FLASH_BASE        0x58004000
+#else
+#  define FLASH_BASE        0x40022000
+#endif
+
+#if defined(STM32G0Bx)
+#  define FLASH_BSY_MASK      (FLASH_BSY | FLASH_BSY2)
+#else
+#  define FLASH_BSY_MASK      FLASH_BSY
+#endif
+
+#if defined(STM32L5) || defined(STM32U5)
+#  ifdef SECURE
+#    define FLASH_KEYR_OFFSET 0x0c
+#    define FLASH_SR_OFFSET   0x24
+#    define FLASH_CR_OFFSET   0x2c
+#  else
+#    define FLASH_KEYR_OFFSET 0x08
+#    define FLASH_SR_OFFSET   0x20
+#    define FLASH_CR_OFFSET   0x28
+#  endif
+#elif defined(STM32WL_CPU2)
+#  define FLASH_KEYR_OFFSET 0x08
+#  define FLASH_SR_OFFSET   0x60
+#  define FLASH_CR_OFFSET   0x64
+#else
+#  define FLASH_KEYR_OFFSET 0x08
+#  define FLASH_SR_OFFSET   0x10
+#  define FLASH_CR_OFFSET   0x14
+#endif
+
+#define FLASH_KEYR        (uint32_t *)((FLASH_BASE) + (FLASH_KEYR_OFFSET))
+#define FLASH_SR          (uint32_t *)((FLASH_BASE) + (FLASH_SR_OFFSET))
+#define FLASH_CR          (uint32_t *)((FLASH_BASE) + (FLASH_CR_OFFSET))
+
+int main()
+{
+       const uint32_t count = 2;
+       const uint32_t buf_size = count * FLASH_WORD_SIZE;
+       const uint32_t work_area_size = sizeof(struct stm32l4_work_area) + buf_size;
+
+       uint8_t work_area_buf[work_area_size];
+       struct stm32l4_work_area *workarea = (struct stm32l4_work_area *)work_area_buf;
+
+       /* fill the workarea struct */
+       workarea->params.flash_sr_addr = (uint32_t)(FLASH_SR);
+       workarea->params.flash_cr_addr = (uint32_t)(FLASH_CR);
+       workarea->params.flash_word_size = FLASH_WORD_SIZE;
+       workarea->params.flash_sr_bsy_mask = FLASH_BSY_MASK;
+       /* note: the workarea->stack is not used, in this configuration */
+
+       /* programming the existing memory raw content in workarea->fifo.buf */
+       /* feel free to fill the memory with magical values ... */
+
+       workarea->fifo.wp =  (uint8_t *)(&workarea->fifo.buf + buf_size);
+       workarea->fifo.rp =  (uint8_t *)&workarea->fifo.buf;
+
+       /* unlock the flash */
+       *FLASH_KEYR = KEY1;
+       *FLASH_KEYR = KEY2;
+
+       /* erase sector 0 */
+       *FLASH_CR = FLASH_PER | FLASH_STRT;
+       while (*FLASH_SR & FLASH_BSY)
+               ;
+
+       /* flash address, should be aligned to FLASH_WORD_SIZE */
+       uint8_t *target_address = (uint8_t *) 0x8000000;
+
+       write(workarea,
+                 (uint8_t *)(workarea + work_area_size),
+                 target_address,
+                 count);
+
+       while (1)
+               ;
+}
+#endif /* DEBUG */
index df5c7edd16ee1217f96c0f5a1d47afe8b0c8a224..1ab400a0a5a7adb243ab354f9f391d8990d5a391 100644 (file)
@@ -1,7 +1,10 @@
 /* Autogenerated with ../../../../src/helper/bin2char.sh */
-0x98,0x46,0x06,0x68,0x00,0x2e,0x23,0xd0,0x43,0x68,0xf6,0x1a,0x01,0xd5,0x76,0x18,
-0x36,0x1a,0x08,0x2e,0xf5,0xd3,0x01,0x26,0x2e,0x60,0xc0,0xcb,0xc0,0xc2,0xbf,0xf3,
-0x4f,0x8f,0x09,0x4f,0x26,0x68,0x3e,0x42,0xfc,0xd1,0xfa,0x27,0x3e,0x42,0x0d,0xd1,
-0x8b,0x42,0x02,0xd3,0x5b,0x1a,0x1b,0x18,0x08,0x33,0x43,0x60,0x47,0x46,0x01,0x3f,
-0xb8,0x46,0x05,0xd0,0xdd,0xe7,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x23,0x43,0x60,
-0x30,0x46,0x00,0x26,0x2e,0x60,0xfa,0x26,0x26,0x60,0x00,0xbe,
+0xf0,0xb5,0x87,0xb0,0x07,0x68,0x01,0x93,0x43,0x68,0x04,0x91,0x02,0x93,0x83,0x6f,
+0x02,0x99,0x03,0x93,0x01,0x23,0x0b,0x60,0x03,0x9b,0x01,0x99,0x00,0x29,0x1f,0xd0,
+0x41,0x6f,0x00,0x29,0x1c,0xd0,0xc9,0x1a,0x01,0xd5,0x04,0x99,0xc9,0x1a,0x84,0x68,
+0x8c,0x42,0xf2,0xd8,0x85,0x68,0xac,0x08,0x05,0x94,0x00,0x24,0x05,0x9d,0xa5,0x42,
+0x14,0xdc,0x84,0x68,0x12,0x19,0x84,0x68,0x1b,0x19,0x3c,0x68,0xc5,0x68,0x2e,0x00,
+0x26,0x40,0x25,0x42,0xf9,0xd1,0xfa,0x25,0x3c,0x68,0x2c,0x42,0x0b,0xd0,0x86,0x67,
+0x00,0x23,0x02,0x9a,0x13,0x60,0x00,0xbe,0x07,0xb0,0xf0,0xbd,0xa6,0x00,0x9d,0x59,
+0x01,0x34,0x95,0x51,0xe2,0xe7,0x04,0x9c,0x9c,0x42,0x00,0xd8,0x03,0x9b,0x83,0x67,
+0x84,0x68,0x09,0x1b,0x01,0x9c,0x01,0x3c,0x01,0x94,0xd0,0xe7,
index 3c055616f5c1cd1a92475b7295a07a8b4a1e3683..ef15013ea45c44090af5cad928d06011f4872abd 100644 (file)
@@ -1319,11 +1319,10 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
 {
        struct target *target = bank->target;
        struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;
-       uint32_t buffer_size;
        struct working_area *write_algorithm;
        struct working_area *source;
        uint32_t address = bank->base + offset;
-       struct reg_param reg_params[6];
+       struct reg_param reg_params[5];
        struct armv7m_algorithm armv7m_info;
        int retval = ERROR_OK;
 
@@ -1345,12 +1344,13 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
                return retval;
        }
 
-       /* memory buffer, size *must* be multiple of stm32l4_info->data_width
-        * plus one dword for rp and one for wp */
-       /* FIXME, currently only STM32U5 devices do have a different data_width,
-        * but STM32U5 device flash programming does not go through this function
-        * so temporarily continue to consider the default data_width = 8 */
-       buffer_size = target_get_working_area_avail(target) & ~(2 * sizeof(uint32_t) - 1);
+       /* data_width should be multiple of double-word */
+       assert(stm32l4_info->data_width % 8 == 0);
+       const size_t extra_size = sizeof(struct stm32l4_work_area);
+       uint32_t buffer_size = target_get_working_area_avail(target) - extra_size;
+       /* buffer_size should be multiple of stm32l4_info->data_width */
+       buffer_size &= ~(stm32l4_info->data_width - 1);
+
        if (buffer_size < 256) {
                LOG_WARNING("large enough working area not available, can't do block memory writes");
                target_free_working_area(target, write_algorithm);
@@ -1360,7 +1360,7 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
                buffer_size = 16384;
        }
 
-       if (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
+       if (target_alloc_working_area_try(target, buffer_size + extra_size, &source) != ERROR_OK) {
                LOG_ERROR("allocating working area failed");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
@@ -1371,28 +1371,46 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
        init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */
        init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);    /* buffer end */
        init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);    /* target address */
-       init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);    /* count (double word-64bit) */
-       init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);    /* flash status register */
-       init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);    /* flash control register */
+       init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);    /* count (of stm32l4_info->data_width) */
+       init_reg_param(&reg_params[4], "sp", 32, PARAM_OUT);    /* write algo stack pointer */
 
        buf_set_u32(reg_params[0].value, 0, 32, source->address);
        buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
        buf_set_u32(reg_params[2].value, 0, 32, address);
        buf_set_u32(reg_params[3].value, 0, 32, count);
-       buf_set_u32(reg_params[4].value, 0, 32, stm32l4_get_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX));
-       buf_set_u32(reg_params[5].value, 0, 32, stm32l4_get_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX));
+       buf_set_u32(reg_params[4].value, 0, 32, source->address +
+                       offsetof(struct stm32l4_work_area, stack) + LDR_STACK_SIZE);
+
+       struct stm32l4_loader_params loader_extra_params;
+
+       target_buffer_set_u32(target, (uint8_t *) &loader_extra_params.flash_sr_addr,
+                       stm32l4_get_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX));
+       target_buffer_set_u32(target, (uint8_t *) &loader_extra_params.flash_cr_addr,
+                       stm32l4_get_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX));
+       target_buffer_set_u32(target, (uint8_t *) &loader_extra_params.flash_word_size,
+                       stm32l4_info->data_width);
+       target_buffer_set_u32(target, (uint8_t *) &loader_extra_params.flash_sr_bsy_mask,
+                       stm32l4_info->sr_bsy_mask);
+
+       retval = target_write_buffer(target, source->address, sizeof(loader_extra_params),
+                       (uint8_t *) &loader_extra_params);
+       if (retval != ERROR_OK)
+               return retval;
 
        retval = target_run_flash_async_algorithm(target, buffer, count, stm32l4_info->data_width,
                        0, NULL,
                        ARRAY_SIZE(reg_params), reg_params,
-                       source->address, source->size,
+                       source->address + offsetof(struct stm32l4_work_area, fifo),
+                       source->size - offsetof(struct stm32l4_work_area, fifo),
                        write_algorithm->address, 0,
                        &armv7m_info);
 
        if (retval == ERROR_FLASH_OPERATION_FAILED) {
                LOG_ERROR("error executing stm32l4 flash write algorithm");
 
-               uint32_t error = buf_get_u32(reg_params[0].value, 0, 32) & FLASH_ERROR;
+               uint32_t error;
+               stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX, &error);
+               error &= FLASH_ERROR;
 
                if (error & FLASH_WRPERR)
                        LOG_ERROR("flash memory write protected");
@@ -1413,7 +1431,6 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
        destroy_reg_param(&reg_params[2]);
        destroy_reg_param(&reg_params[3]);
        destroy_reg_param(&reg_params[4]);
-       destroy_reg_param(&reg_params[5]);
 
        return retval;
 }
@@ -1538,24 +1555,7 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer,
        if (retval != ERROR_OK)
                goto err_lock;
 
-       /**
-        * FIXME update the flash loader to use a custom FLASH_SR_BSY mask
-        * Workaround for STM32G0Bx/G0Cx devices in dual bank mode,
-        * as the flash loader does not use the SR_BSY2
-        */
-       bool use_flashloader = stm32l4_info->use_flashloader;
-       if ((stm32l4_info->part_info->id == 0x467) && stm32l4_info->dual_bank_mode) {
-               LOG_INFO("Couldn't use the flash loader in dual-bank mode");
-               use_flashloader = false;
-       } else if (stm32l4_info->part_info->id == 0x482) {
-               /**
-                * FIXME the current flashloader does not support writing in quad-words
-                * which is required for STM32U5 devices.
-                */
-               use_flashloader = false;
-       }
-
-       if (use_flashloader) {
+       if (stm32l4_info->use_flashloader) {
                /* For TrustZone enabled devices, when TZEN is set and RDP level is 0.5,
                 * the debug is possible only in non-secure state.
                 * Thus means the flashloader will run in non-secure mode,
@@ -1567,7 +1567,7 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer,
                                count / stm32l4_info->data_width);
        }
 
-       if (!use_flashloader || retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
+       if (!stm32l4_info->use_flashloader || retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
                LOG_INFO("falling back to single memory accesses");
                retval = stm32l4_write_block_without_loader(bank, buffer, offset,
                                count / stm32l4_info->data_width);
index 7b9162b08606f8658476f022058bd65515b31abd..2d19cffffbc554128e914683a62d2b34742a4e67 100644 (file)
 
 #define STM32L5_REGS_SEC_OFFSET 0x10000000
 
+/* 100 bytes as loader stack should be large enough for the loader to operate */
+#define LDR_STACK_SIZE                 100
+
+struct stm32l4_work_area {
+       struct stm32l4_loader_params {
+               uint32_t flash_sr_addr;
+               uint32_t flash_cr_addr;
+               uint32_t flash_word_size;
+               uint32_t flash_sr_bsy_mask;
+       } params;
+       uint8_t stack[LDR_STACK_SIZE];
+       struct flash_async_algorithm_circbuf {
+               uint8_t *wp;
+               uint8_t *rp;
+               uint8_t *buf;
+       } fifo;
+};
+
 #endif