PR cleanups based on peer review. Fixes to support < 10KB wolfBoot for either RSA2048 or ED25519. Partition scheme allows 10KB application partition or (6KB actual due to NVM write once). Made space using NO_MPU=1, RAM_CODE=0, USE_SLOW_SHA256 and !FLASH_SECURABLE_MEMORY_SUPPORT.

pull/381/head
David Garske 2023-10-09 13:05:46 -07:00 committed by Daniele Lacamera
parent a1d584b838
commit c4dfa3f986
9 changed files with 69 additions and 154 deletions

View File

@ -87,11 +87,6 @@ ifeq ($(ARCH),ARM)
ifeq ($(TARGET),stm32c0) ifeq ($(TARGET),stm32c0)
CORTEX_M0=1 CORTEX_M0=1
ARCH_FLASH_OFFSET=0x08000000 ARCH_FLASH_OFFSET=0x08000000
# Enable this feature for secure memory support
# Makes the flash sectors for the bootloader unacessible from the application
# Requires using the STM32CubeProgrammer to set FLASH_SECR -> SEC_SIZE pages
CFLAGS+=-DFLASH_SECURABLE_MEMORY_SUPPORT
endif endif
ifeq ($(TARGET),stm32g0) ifeq ($(TARGET),stm32g0)
@ -99,7 +94,7 @@ ifeq ($(ARCH),ARM)
ARCH_FLASH_OFFSET=0x08000000 ARCH_FLASH_OFFSET=0x08000000
# Enable this feature for secure memory support # Enable this feature for secure memory support
# Makes the flash sectors for the bootloader unacessible from the application # Makes the flash sectors for the bootloader unaccessible from the application
# Requires using the STM32CubeProgrammer to set FLASH_SECR -> SEC_SIZE pages # Requires using the STM32CubeProgrammer to set FLASH_SECR -> SEC_SIZE pages
CFLAGS+=-DFLASH_SECURABLE_MEMORY_SUPPORT CFLAGS+=-DFLASH_SECURABLE_MEMORY_SUPPORT
endif endif

View File

@ -1,12 +1,13 @@
ARCH?=ARM ARCH?=ARM
TARGET?=stm32c0 TARGET?=stm32c0
SIGN?=ED25519 #Supports ED25519/SHA384 or RSA2048/SHA256
#Using SHA384 with ED25519 saves about 2kB without SHA256 code SIGN?=RSA2048
HASH?=SHA384 HASH?=SHA256
DEBUG?=0 DEBUG?=0
VTOR?=1 VTOR?=1
CORTEX_M0?=1 CORTEX_M0?=1
NO_ASM?=0 NO_ASM?=0
NO_MPU?=1
EXT_FLASH?=0 EXT_FLASH?=0
SPI_FLASH?=0 SPI_FLASH?=0
ALLOW_DOWNGRADE?=0 ALLOW_DOWNGRADE?=0
@ -14,21 +15,33 @@ NVM_FLASH_WRITEONCE?=1
WOLFBOOT_VERSION?=0 WOLFBOOT_VERSION?=0
V?=0 V?=0
SPMATH?=1 SPMATH?=1
RAM_CODE?=1
DUALBANK_SWAP?=0 DUALBANK_SWAP?=0
#Max APP size is 4kB
# Enable this to support wolfBoot self-update
RAM_CODE?=0
# Use slightly smaller SHA2-256
CFLAGS_EXTRA+=-DUSE_SLOW_SHA256
# Enable this feature for secure memory support
# Makes the flash sectors for the bootloader unaccessible from the application
# Requires using the STM32CubeProgrammer to set FLASH_SECR -> SEC_SIZE pages
#CFLAGS_EXTRA+=-DFLASH_SECURABLE_MEMORY_SUPPORT
#Partition: Boot: 10KB, App, 10KB
WOLFBOOT_PARTITION_SIZE?=0x2000 WOLFBOOT_PARTITION_SIZE?=0x2000
WOLFBOOT_SECTOR_SIZE?=0x800 WOLFBOOT_SECTOR_SIZE?=0x800
#Max WOLFBOOT size is 14kB. Currently only 10kB #Max WOLFBOOT size is 10KB
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08003800 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08002800
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08005800 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08005000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x08007800 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x08007800
#For a debug/not size optimized layout: #Example debugging partition for larger wolfBoot
#Partition: Boot: 22KB, App, 4K
#DEBUG?=1 #DEBUG?=1
#WOLFBOOT_PARTITION_SIZE?=0x1000 #WOLFBOOT_PARTITION_SIZE?=0x1000
#WOLFBOOT_SECTOR_SIZE?=0x800 #WOLFBOOT_SECTOR_SIZE?=0x800
#WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08005800 #WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08005800
#WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08006800 #WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08006800
#WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x08007800 #WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x08007800

View File

@ -19,7 +19,7 @@ and RAM boundaries.
## Supported platforms ## Supported platforms
The following platforms are supported in the current version: The following platforms are supported in the current version:
- STM32F4, STM32L5, STM32L0, STM32F7, STM32H7, STM32G0, STM32C0 - STM32C0, STM32F4, STM32F7, STM32G0, STM32H7, STM32L5, STM32L0, STM32U5, STM32WB55
- nRF52 - nRF52
- Atmel samR21 - Atmel samR21
- TI cc26x2 - TI cc26x2

View File

@ -427,50 +427,46 @@ mon reset init
## STM32C0 ## STM32C0
Supports STM32C0x0/STM32C0x1. Supports STM32C0x0/STM32C0x1. Instructions are for the STM Nucleo-C031C6 dev board.
Example and instructions are for the STM Nucleo-C031C6 dev board using the Tested build configurations:
STM32Cube * With RSA2048 and SHA2-256 the code size is 9724 and it boots in under 1 second.
* With ED25519 and SHA2-384 the code size is 10024 and takes about 10 seconds for the LED to turn on.
Example 32KB partitioning on STM32-G070: Example 32KB partitioning on STM32-G070:
- Sector size: 2KB - Sector size: 2KB
- Wolfboot partition size: 14KB - Wolfboot partition size: 10KB
- Application partition size: 8 KB - Application partition size: 10 KB
- Swap size 2KB - Swap size 2KB
```C ```C
#define WOLFBOOT_SECTOR_SIZE 0x800 /* 2 KB */ #define WOLFBOOT_SECTOR_SIZE 0x800 /* 2 KB */
#define WOLFBOOT_PARTITION_BOOT_ADDRESS 0x08004000 /* offset 16kB to 24kB */ #define WOLFBOOT_PARTITION_BOOT_ADDRESS 0x08002800 /* at 10KB */
#define WOLFBOOT_PARTITION_SIZE 0x2000 /* 8 KB */ #define WOLFBOOT_PARTITION_SIZE 0x2800 /* 10 KB */
#define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0x08006000 /* offset 24kB to 32kB */ #define WOLFBOOT_PARTITION_UPDATE_ADDRESS 0x08005000 /* at 20KB */
#define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x08003800 /* offset 14kB to 16kB */ #define WOLFBOOT_PARTITION_SWAP_ADDRESS 0x08007800 /* at 30KB */
``` ```
### Building STM32C0 ### Building STM32C0
xxx
Reference configuration (see [/config/examples/stm32g0.config](/config/examples/stm32g0.config)). Reference configuration (see [/config/examples/stm32c0.config](/config/examples/stm32c0.config)).
You can copy this to wolfBoot root as `.config`: `cp ./config/examples/stm32g0.config .config`.
You can copy this to wolfBoot root as `.config`: `cp ./config/examples/stm32c0.config .config`.
To build you can use `make`. To build you can use `make`.
The TARGET for this is `stm32g0`: `make TARGET=stm32g0`. The TARGET for this is `stm32c0`: `make TARGET=stm32c0`.
The option `CORTEX_M0` is automatically selected for this target. The option `CORTEX_M0` is automatically selected for this target.
The option `NVM_FLASH_WRITEONCE=1` is mandatory on this target, since the IAP driver does not support The option `NVM_FLASH_WRITEONCE=1` is mandatory on this target, since the IAP driver does not support
multiple writes after each erase operation. multiple writes after each erase operation.
This target also supports secure memory protection on the bootloader region
using the `FLASH_CR:SEC_PROT` and `FLASH_SECT:SEC_SIZE` registers. This is the
number of 2KB pages to block access to from the 0x8000000 base address.
``` ```
STM32_Programmer_CLI -c port=swd mode=hotplug -ob SEC_SIZE=0x10 STM32_Programmer_CLI -c port=swd mode=hotplug -ob SEC_SIZE=0x10
``` ```
For RAMFUNCTION support (required for SEC_PROT) make sure `RAM_CODE=1`.
### STM32C0 Programming ### STM32C0 Programming
xxx
Compile requirements: `make TARGET=stm32g0 NVM_FLASH_WRITEONCE=1` Compile requirements: `make TARGET=stm32c0 NVM_FLASH_WRITEONCE=1`
The output is a single `factory.bin` that includes `wolfboot.bin` and `test-app/image_v1_signed.bin` combined together. The output is a single `factory.bin` that includes `wolfboot.bin` and `test-app/image_v1_signed.bin` combined together.
This should be programmed to the flash start address `0x08000000`. This should be programmed to the flash start address `0x08000000`.
@ -482,7 +478,7 @@ STM32_Programmer_CLI -c port=swd -d factory.bin 0x08000000
``` ```
### STM32C0 Debugging ### STM32C0 Debugging
xxx
Use `make DEBUG=1` and program firmware again. Use `make DEBUG=1` and program firmware again.
Start GDB server on port 3333: Start GDB server on port 3333:

View File

@ -26,9 +26,6 @@
# error "wolfBoot STM32C0 HAL: no WRITEONCE support detected. Please define NVM_FLASH_WRITEONCE" # error "wolfBoot STM32C0 HAL: no WRITEONCE support detected. Please define NVM_FLASH_WRITEONCE"
#endif #endif
/* XXX Debug only! */
#define NO_FLASH_SEC_SIZE_CHECK 1
/* STM32 C0 register configuration */ /* STM32 C0 register configuration */
/* Assembly helpers */ /* Assembly helpers */
@ -138,8 +135,6 @@ static void RAMFUNCTION flash_clear_errors(void)
{ {
/* Consider only writing here as there is no reason to read first (rc_w1), /* Consider only writing here as there is no reason to read first (rc_w1),
* unless other error bits are set*/ * unless other error bits are set*/
/* FLASH_SR = (FLASH_SR_SIZERR | FLASH_SR_PGAERR | FLASH_SR_WRPERR |
FLASH_SR_PROGERR); */
FLASH_SR |= (FLASH_SR_SIZERR | FLASH_SR_PGAERR | FLASH_SR_WRPERR | FLASH_SR |= (FLASH_SR_SIZERR | FLASH_SR_PGAERR | FLASH_SR_WRPERR |
FLASH_SR_PROGERR); FLASH_SR_PROGERR);
} }
@ -233,17 +228,11 @@ static void clock_pll_off(void)
reg32 &= ~((1 << 1) | (1 << 0)); reg32 &= ~((1 << 1) | (1 << 0));
RCC_CFGR = (reg32 | RCC_CFGR_SW_HSISYS); RCC_CFGR = (reg32 | RCC_CFGR_SW_HSISYS);
DMB(); DMB();
#if 0
/* Turn off PLL */
RCC_CR &= ~RCC_CR_PLLON;
DMB();
#endif
} }
/* This implementation will setup HSI RC 48 MHz as System Clock Source, set /* This implementation will setup HSI RC 48 MHz as System Clock Source, set
* flash wait state to 2, and set all peripherals to 16MHz (div4) * flash wait state to 1, and set all peripherals to 16MHz (div4)
* */
* */
static void clock_pll_on(int powersave) static void clock_pll_on(int powersave)
{ {
uint32_t reg32; uint32_t reg32;
@ -276,45 +265,6 @@ static void clock_pll_on(int powersave)
RCC_CFGR = (reg32 | RCC_CFGR_SW_HSISYS); RCC_CFGR = (reg32 | RCC_CFGR_SW_HSISYS);
DMB(); DMB();
#if 0
/* Disable PLL */
RCC_CR &= ~RCC_CR_PLLON;
/* Set prescalers for AHB, ADC, ABP1, ABP2. */
reg32 = RCC_CFGR;
reg32 &= ~(0xF0); /* don't change bits [0-3] that were previously set */
RCC_CFGR = (reg32 | (hpre << 8)); /* RM0444 - 5.4.3 - RCC_CFGR */
DMB();
reg32 = RCC_CFGR;
reg32 &= ~(0x1C00); /* don't change bits [0-14] */
RCC_CFGR = (reg32 | (ppre << 12)); /* RM0444 - 5.4.3 - RCC_CFGR */
DMB();
/* Set PLL config */
reg32 = RCC_PLLCFGR;
reg32 |= RCC_PLLCFGR_PLLSRC_HSI16;
reg32 |= ((pllm - 1) << 4);
reg32 |= plln << 8;
reg32 |= ((pllp - 1) << 17);
reg32 |= ((pllr - 1) << 29);
RCC_PLLCFGR = reg32;
DMB();
/* Enable PLL oscillator and wait for it to stabilize. */
RCC_PLLCFGR |= RCC_PLLCFGR_PLLR_EN;
RCC_CR |= RCC_CR_PLLON;
DMB();
while ((RCC_CR & RCC_CR_PLLRDY) == 0) {};
/* Select PLL as SYSCLK source. */
reg32 = RCC_CFGR;
reg32 &= ~((1 << 1) | (1 << 0));
RCC_CFGR = (reg32 | RCC_CFGR_SW_PLL);
DMB();
/* Wait for PLL clock to be selected. */
while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SW_PLL) {};
#endif
/* SYSCFG, COMP and VREFBUF clock enable */ /* SYSCFG, COMP and VREFBUF clock enable */
APB2_CLOCK_ER |= SYSCFG_APB2_CLOCK_ER_VAL; APB2_CLOCK_ER |= SYSCFG_APB2_CLOCK_ER_VAL;
} }

View File

@ -1,7 +1,7 @@
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00002FFF RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 12K-1
} }
SECTIONS SECTIONS

View File

@ -267,6 +267,9 @@ endif
ifeq ($(TARGET),stm32g0) ifeq ($(TARGET),stm32g0)
CFLAGS+=-DNVM_FLASH_WRITEONCE=1 CFLAGS+=-DNVM_FLASH_WRITEONCE=1
endif endif
ifeq ($(TARGET),stm32c0)
CFLAGS+=-DNVM_FLASH_WRITEONCE=1
endif
ifeq ($(TARGET),hifive1.freedom) ifeq ($(TARGET),hifive1.freedom)
CFLAGS+=-I$(FREEDOM_E_SDK)/freedom-metal/ -D__METAL_MACHINE_HEADER=\"$(FREEDOM_E_SDK)/bsp/sifive-hifive1/metal.h\" CFLAGS+=-I$(FREEDOM_E_SDK)/freedom-metal/ -D__METAL_MACHINE_HEADER=\"$(FREEDOM_E_SDK)/bsp/sifive-hifive1/metal.h\"

View File

@ -1,4 +1,4 @@
/* main.c /* app_stm32c0.c
* *
* Test bare-metal boot-led-on application * Test bare-metal boot-led-on application
* *
@ -36,4 +36,3 @@ void main(void) {
; ;
} }
#endif /* PLATFORM_stm32c0 */ #endif /* PLATFORM_stm32c0 */

View File

@ -110,13 +110,9 @@ void boot_led_off(void)
#endif /* PLATFORM_stm32l0 */ #endif /* PLATFORM_stm32l0 */
#ifdef PLATFORM_stm32g0 #if defined(PLATFORM_stm32g0) || defined(PLATFORM_stm32c0)
#include <stdint.h> /* GPIOA5 */
#include "wolfboot/wolfboot.h" #define RCC_IOPENR (*(volatile uint32_t *)(0x40021034))
/*GPIOA5*/
#define RCC_IOPENR (*(volatile uint32_t *)(0x40021034)) // 40021034
#define RCC_IOPENR_GPIOAEN (1 << 0) #define RCC_IOPENR_GPIOAEN (1 << 0)
#define GPIOA_BASE 0x50000000 #define GPIOA_BASE 0x50000000
@ -138,50 +134,13 @@ void boot_led_on(void)
uint32_t pin = LED_BOOT_PIN; uint32_t pin = LED_BOOT_PIN;
RCC_IOPENR |= RCC_IOPENR_GPIOAEN; RCC_IOPENR |= RCC_IOPENR_GPIOAEN;
reg = GPIOA_MODE & ~(0x03 << (pin * 2)); reg = GPIOA_MODE & ~(0x03 << (pin * 2));
GPIOA_MODE = reg | (1 << (pin * 2)); // general purpose output mode GPIOA_MODE = reg | (1 << (pin * 2)); /* general purpose output mode */
reg = GPIOA_PUPD & ~(0x03 << (pin * 2)); reg = GPIOA_PUPD & ~(0x03 << (pin * 2));
GPIOA_PUPD = reg | (1 << (pin * 2)); // pull-up GPIOA_PUPD = reg | (1 << (pin * 2)); /* pull-up */
GPIOA_BSRR |= (1 << pin); // set pin GPIOA_BSRR |= (1 << pin); /* set pin */
} }
#endif /** PLATFORM_stm32g0 **/ #endif /* PLATFORM_stm32g0 || PLATFORM_stm32c0 */
#ifdef PLATFORM_stm32c0
#include <stdint.h>
#include "wolfboot/wolfboot.h"
/*GPIOA5 on Nucleo C031C6*/
#define RCC_IOPENR (*(volatile uint32_t *)(0x40021034)) // 40021034
#define RCC_IOPENR_GPIOAEN (1 << 0)
#define GPIOA_BASE 0x50000000
#define GPIOA_MODE (*(volatile uint32_t *)(GPIOA_BASE + 0x00))
#define GPIOA_OTYPE (*(volatile uint32_t *)(GPIOA_BASE + 0x04))
#define GPIOA_OSPD (*(volatile uint32_t *)(GPIOA_BASE + 0x08))
#define GPIOA_PUPD (*(volatile uint32_t *)(GPIOA_BASE + 0x0c))
#define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14))
#define GPIOA_BSRR (*(volatile uint32_t *)(GPIOA_BASE + 0x18))
#define GPIOA_AFL (*(volatile uint32_t *)(GPIOA_BASE + 0x20))
#define GPIOA_AFH (*(volatile uint32_t *)(GPIOA_BASE + 0x24))
#define LED_PIN (5)
#define LED_BOOT_PIN (5)
#define GPIO_OSPEED_100MHZ (0x03)
void boot_led_on(void)
{
uint32_t reg;
uint32_t pin = LED_BOOT_PIN;
RCC_IOPENR |= RCC_IOPENR_GPIOAEN;
reg = GPIOA_MODE & ~(0x03 << (pin * 2));
GPIOA_MODE = reg | (1 << (pin * 2)); // general purpose output mode
reg = GPIOA_PUPD & ~(0x03 << (pin * 2));
GPIOA_PUPD = reg | (1 << (pin * 2)); // pull-up
GPIOA_BSRR |= (1 << pin); // set pin
}
#endif /** PLATFORM_stm32c0 **/
#ifdef PLATFORM_stm32wb #ifdef PLATFORM_stm32wb
#define LED_BOOT_PIN (0) #define LED_BOOT_PIN (0)