Skip to content

Commit 81187ff

Browse files
committed
STM32H5: DUAL BANK update
1 parent 19fdbb8 commit 81187ff

File tree

4 files changed

+111
-40
lines changed

4 files changed

+111
-40
lines changed
File renamed without changes.

docs/Targets.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ This README describes configuration of supported targets.
2323
* [STM32L5](#stm32l5)
2424
* [STM32G0](#stm32g0)
2525
* [STM32C0](#stm32c0)
26+
* [STM32H5](#stm32h5)
2627
* [STM32H7](#stm32h7)
2728
* [STM32U5](#stm32u5)
2829
* [STM32WB55](#stm32wb55)
@@ -807,6 +808,59 @@ arm-none-eabi-gdb
807808
(gdb) target remote:3333
808809
```
809810

811+
## STM32H5
812+
813+
### DUALBANK mode (Trustzone disabled)
814+
815+
The STM32H5 can be configured to use hardware-assisted bank swapping to facilitate the update.
816+
The configuration file to copy into `.config` is `config/examples/stm32h5-dualbank.config`.
817+
818+
DUALBANK configuration (Tested on NUCLEO-STM32H563ZI):
819+
820+
BANK A: 0x08000000 to 0x080FFFFFF (1MB)
821+
BANK B: 0x08100000 to 0x081FFFFFF (1MB)
822+
823+
First of all, ensure that the `SWAP_BANK` option byte is off when running wolfBoot
824+
for the first time:
825+
826+
```
827+
STM32_Programmer_CLI -c port=swd -ob SWAP_BANK=0
828+
```
829+
830+
It is a good idea to start with an empty flash, by erasing all sectors via:
831+
832+
```
833+
STM32_Programmer_CLI -c port=swd -e 0 255
834+
```
835+
Compile wolfBoot with `make`. The file `factory.bin` contains both wolfboot and the
836+
version 1 of the application, and can be uploaded to the board at the beginning
837+
of the first bank using `STM32_Programmer_CLI` tool:
838+
839+
```
840+
STM32_Programmer_CLI -c port=swd -d factory.bin 0x08000000
841+
```
842+
843+
Optionally, you can upload another copy of wolfboot.bin to the beginning of the second bank.
844+
Wolfboot should take care of copying itself to the second bank upon first boot if you don't.:
845+
846+
```
847+
STM32_Programmer_CLI -c port=swd -d wolfboot.bin 0x08100000
848+
```
849+
850+
After uploading the images, reboot your board. The green LED should indicate that v1 of the
851+
test application is running.
852+
853+
To initiate an update, sign a new version of the app and upload the v3 to the update partition
854+
on the second bank:
855+
856+
```
857+
tools/keytools/sign --ecc256 test-app/image.bin wolfboot_signing_private_key.der 3
858+
STM32_Programmer_CLI -c port=swd -d test-app/image_v3_signed.bin 0x08110000
859+
```
860+
861+
Reboot the board to initiate an update via DUALBANK hw-assisted swap.
862+
Any version except the first one will also turn on the orange LED.
863+
810864

811865
## STM32H7
812866

hal/stm32h5.c

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ static void RAMFUNCTION flash_set_waitstates(unsigned int waitstates)
3131
uint32_t reg = FLASH_ACR;
3232
if ((reg & FLASH_ACR_LATENCY_MASK) < waitstates)
3333
do {
34-
FLASH_ACR = (reg & ~FLASH_ACR_LATENCY_MASK) | waitstates ;
34+
FLASH_ACR = (reg & ~(FLASH_ACR_LATENCY_MASK | (FLASH_ACR_WRHIGHFREQ_MASK << FLASH_ACR_WRHIGHFREQ_SHIFT))) |
35+
waitstates | (0x02 << FLASH_ACR_WRHIGHFREQ_SHIFT) ;
3536
}
3637
while ((FLASH_ACR & FLASH_ACR_LATENCY_MASK) != waitstates);
3738
}
@@ -49,11 +50,9 @@ void RAMFUNCTION hal_flash_wait_complete(uint8_t bank)
4950

5051
void RAMFUNCTION hal_flash_clear_errors(uint8_t bank)
5152
{
52-
FLASH_SR |= ( FLASH_SR_WBNE | FLASH_SR_DBNE );
53-
54-
#if (TZ_SECURE())
55-
FLASH_NS_SR |= ( FLASH_SR_WBNE | FLASH_SR_DBNE );
56-
#endif
53+
FLASH_CCR |= ( FLASH_CCR_CLR_WBNE | FLASH_CCR_CLR_DBNE | FLASH_CCR_CLR_INCE|
54+
FLASH_CCR_CLR_PGSE | FLASH_CCR_CLR_OPTE | FLASH_CCR_CLR_OPTWE |
55+
FLASH_CCR_CLR_WRPE | FLASH_CCR_CLR_EOP);
5756

5857
}
5958

@@ -156,25 +155,23 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
156155
for (p = address; p < end_address; p += FLASH_PAGE_SIZE) {
157156
uint32_t reg;
158157
uint32_t base;
159-
uint32_t bker = 0;
160-
if ((((FLASH_OPTCR & FLASH_OPTCR_SWAP_BANK) == 0) && (p <= FLASH_TOP)) ||
161-
(p < FLASH_BANK2_BASE)) {
162-
base = FLASHMEM_ADDRESS_SPACE;
163-
}
164-
else if(p >= (FLASH_BANK2_BASE) && (p <= (FLASH_TOP) ))
158+
uint32_t bnksel = 0;
159+
base = FLASHMEM_ADDRESS_SPACE;
160+
reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT) | FLASH_CR_BER));
161+
162+
if(p >= (FLASH_BANK2_BASE) && (p <= (FLASH_TOP) ))
165163
{
166164
#if TZ_SECURE()
167165
/* When in secure mode, skip erasing non-secure pages: will be erased upon claim */
168166
return 0;
169167
#endif
170-
bker = FLASH_CR_BER;
171168
base = FLASH_BANK2_BASE;
169+
bnksel = 1;
172170
} else {
173171
FLASH_CR &= ~FLASH_CR_SER ;
174172
return 0; /* Address out of range */
175173
}
176-
reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT) | FLASH_CR_BER));
177-
reg |= ((((p - base) >> 11) << FLASH_CR_PNB_SHIFT) | FLASH_CR_SER | bker );
174+
reg |= ((((p - base) >> 13) << FLASH_CR_PNB_SHIFT) | FLASH_CR_SER | (bnksel << 31));
178175
FLASH_CR = reg;
179176
DMB();
180177
FLASH_CR |= FLASH_CR_STRT;
@@ -336,8 +333,6 @@ static void periph_unsecure()
336333
#endif
337334

338335

339-
#define OPTR_SWAP_BANK (1 << 20)
340-
341336
#define AIRCR *(volatile uint32_t *)(0xE000ED0C)
342337
#define AIRCR_VKEY (0x05FA << 16)
343338
#define AIRCR_SYSRESETREQ (1 << 2)
@@ -356,29 +351,33 @@ static void RAMFUNCTION stm32h5_reboot(void)
356351
void RAMFUNCTION hal_flash_dualbank_swap(void)
357352
{
358353
uint32_t cur_opts;
354+
cur_opts = (FLASH_OPTSR_CUR & FLASH_OPTSR_SWAP_BANK) >> 31;
355+
hal_flash_clear_errors(0);
359356
hal_flash_unlock();
360357
hal_flash_opt_unlock();
361-
cur_opts = (FLASH_OPTCR & FLASH_OPTCR_SWAP_BANK) >> 31;
362358
if (cur_opts)
363-
FLASH_SECCR &= ~(FLASH_SECCR_BKSEL);
359+
FLASH_OPTSR_PRG &= ~(FLASH_OPTSR_SWAP_BANK);
364360
else
365-
FLASH_SECCR |= FLASH_SECCR_BKSEL;
361+
FLASH_OPTSR_PRG |= FLASH_OPTSR_SWAP_BANK;
362+
363+
FLASH_OPTCR |= FLASH_OPTCR_OPTSTRT;
364+
DMB();
366365
hal_flash_opt_lock();
367366
hal_flash_lock();
368367
stm32h5_reboot();
369368
}
370369

371370
static uint8_t bootloader_copy_mem[BOOTLOADER_SIZE];
372371

373-
static void RAMFUNCTION fork_bootloader(void)
372+
static void fork_bootloader(void)
374373
{
375374
uint8_t *data = (uint8_t *) FLASHMEM_ADDRESS_SPACE;
376375
uint32_t dst = FLASH_BANK2_BASE;
377376
uint32_t r = 0, w = 0;
378377
int i;
379378

380379
/* Return if content already matches */
381-
if (memcmp(data, (void *)FLASH_BANK2_BASE, BOOTLOADER_SIZE) == 0)
380+
if (memcmp(data, (const char*)FLASH_BANK2_BASE, BOOTLOADER_SIZE) == 0)
382381
return;
383382

384383
/* Read the wolfBoot image in RAM */
@@ -395,16 +394,16 @@ static void RAMFUNCTION fork_bootloader(void)
395394
void hal_init(void)
396395
{
397396

397+
#if defined(DUALBANK_SWAP) && defined(__WOLFBOOT)
398+
if ((FLASH_OPTSR_CUR & (FLASH_OPTSR_SWAP_BANK)) == 0)
399+
fork_bootloader();
400+
#endif
398401

399402
#if TZ_SECURE()
400403
hal_tz_sau_init();
401404
hal_gtzc_init();
402405
#endif
403406
clock_pll_on();
404-
#if defined(DUALBANK_SWAP) && defined(__WOLFBOOT)
405-
if ((FLASH_OPTSR_CUR & (FLASH_OPTSR_CUR_SWAP_BANK)) == 0)
406-
fork_bootloader();
407-
#endif
408407

409408
}
410409

hal/stm32h5.h

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -213,21 +213,27 @@
213213

214214
#define FLASH_NS_BASE (0x40022000) //RM0481 - Table 3
215215
#define FLASH_NS_KEYR (*(volatile uint32_t *)(FLASH_NS_BASE + 0x08))
216-
#define FLASH_NS_OPTKEYR (*(volatile uint32_t *)(FLASH_NS_BASE + 0x10))
216+
#define FLASH_NS_OPTKEYR (*(volatile uint32_t *)(FLASH_NS_BASE + 0x0C))
217217
#define FLASH_NS_SR (*(volatile uint32_t *)(FLASH_NS_BASE + 0x20))
218218
#define FLASH_NS_CR (*(volatile uint32_t *)(FLASH_NS_BASE + 0x28))
219219

220-
#define TZSC_PRIVCFGR2 *((uint32_t *)(0x50036424))
220+
#define TZSC_PRIVCFGR2 *((volatile uint32_t *)(0x50036424))
221221
#define TZSC_PRIVCFG2_LPUARTPRIV (1 << 25) /* LPUART1 */
222222

223+
/* Mapping FLASH_SECCR for bank swapping */
224+
#define FLASH_CCR (*(volatile uint32_t *)(FLASH_BASE + 0x34))
223225

224226
#else
225227
/* Non-Secure only */
226228
#define FLASH_BASE (0x40022000) //RM0481 - Table 3
227229
#define FLASH_KEYR (*(volatile uint32_t *)(FLASH_BASE + 0x04))
228-
#define FLASH_OPTKEYR (*(volatile uint32_t *)(FLASH_BASE + 0x10))
230+
#define FLASH_OPTKEYR (*(volatile uint32_t *)(FLASH_BASE + 0x0C))
229231
#define FLASH_SR (*(volatile uint32_t *)(FLASH_BASE + 0x20))
230232
#define FLASH_CR (*(volatile uint32_t *)(FLASH_BASE + 0x28))
233+
234+
/* Mapping FLASH_NSCCR for bank swapping */
235+
#define FLASH_CCR (*(volatile uint32_t *)(FLASH_BASE + 0x30))
236+
231237
#endif
232238

233239
/* Both secure + non secure */
@@ -252,11 +258,9 @@
252258

253259

254260
#if defined(DUALBANK_SWAP) && defined (__WOLFBOOT)
255-
/* Mapping FLASH_SECCR for bank swapping */
256261
#define FLASH_OPTSR_CUR (*(volatile uint32_t *)(FLASH_BASE + 0x50))
257-
#define FLASH_SECCR (*(volatile uint32_t *)(FLASH_BASE + 0x2C))
258-
#define FLASH_SECCR_BKSEL (1 << 31)
259-
#define FLASH_OPTSR_CUR_SWAP_BANK (1 << 31)
262+
#define FLASH_OPTSR_PRG (*(volatile uint32_t *)(FLASH_BASE + 0x54))
263+
#define FLASH_OPTSR_SWAP_BANK (1 << 31)
260264
#endif
261265

262266
/* Register values (for both secure and non secure registers)
@@ -266,12 +270,23 @@
266270
#define FLASH_SR_WBNE (1 << 1)
267271
#define FLASH_SR_DBNE (1 << 3)
268272
#define FLASH_SR_EOP (1 << 16)
269-
#define FLASH_SR_WRPERR (1 << 17)
270-
#define FLASH_SR_PGSERR (1 << 18)
271-
#define FLASH_SR_STRBERR (1 << 19)
272-
#define FLASH_SR_INCERR (1 << 20)
273-
#define FLASH_SR_OPTERR (1 << 21)
274-
#define FLASH_SR_OPTWERR (1 << 22)
273+
#define FLASH_SR_WRPE (1 << 17)
274+
#define FLASH_SR_PGSE (1 << 18)
275+
#define FLASH_SR_STRBE (1 << 19)
276+
#define FLASH_SR_INCE (1 << 20)
277+
#define FLASH_SR_OPTE (1 << 21)
278+
#define FLASH_SR_OPTWE (1 << 22)
279+
280+
#define FLASH_CCR_CLR_BUSY (1 << 0)
281+
#define FLASH_CCR_CLR_WBNE (1 << 1)
282+
#define FLASH_CCR_CLR_DBNE (1 << 3)
283+
#define FLASH_CCR_CLR_EOP (1 << 16)
284+
#define FLASH_CCR_CLR_WRPE (1 << 17)
285+
#define FLASH_CCR_CLR_PGSE (1 << 18)
286+
#define FLASH_CCR_CLR_STRBE (1 << 19)
287+
#define FLASH_CCR_CLR_INCE (1 << 20)
288+
#define FLASH_CCR_CLR_OPTE (1 << 21)
289+
#define FLASH_CCR_CLR_OPTWE (1 << 22)
275290

276291
#define FLASH_CR_LOCK (1 << 0)
277292
#define FLASH_CR_PG (1 << 1)
@@ -295,6 +310,9 @@
295310

296311
#define FLASH_ACR (*(volatile uint32_t *)(FLASH_BASE + 0x00))
297312
#define FLASH_ACR_LATENCY_MASK (0x0F)
313+
#define FLASH_ACR_WRHIGHFREQ_MASK (0x03)
314+
#define FLASH_ACR_WRHIGHFREQ_SHIFT (4)
315+
298316

299317
#define FLASH_OPTCR (*(volatile uint32_t *)(FLASH_BASE + 0x1C))
300318
#define FLASH_OPTCR_OPTSTRT (1 << 1)
@@ -305,7 +323,7 @@
305323
#define FLASH_PAGE_SIZE (0x2000) /* 8KB */
306324
#define FLASH_BANK2_BASE (0x08100000) /*!< Base address of Flash Bank2 */
307325
#define BOOTLOADER_SIZE (0x8000)
308-
#define FLASH_TOP (0x080FFFFF) /*!< FLASH end address (sector 127) */
326+
#define FLASH_TOP (0x081FFFFF) /*!< FLASH end address (sector 127) */
309327

310328
#define FLASH_KEY1 (0x45670123U)
311329
#define FLASH_KEY2 (0xCDEF89ABU)

0 commit comments

Comments
 (0)