Added OTP support for STM32H5

pull/449/head
Daniele Lacamera 2024-05-14 18:02:37 +02:00
parent 5f2a3d5ac7
commit 02bfe8a6a1
8 changed files with 118 additions and 14 deletions

View File

@ -37,7 +37,7 @@ static void RAMFUNCTION flash_set_waitstates(unsigned int waitstates)
while ((FLASH_ACR & FLASH_ACR_LATENCY_MASK) != waitstates); while ((FLASH_ACR & FLASH_ACR_LATENCY_MASK) != waitstates);
} }
void RAMFUNCTION hal_flash_wait_complete(uint8_t bank) static void RAMFUNCTION hal_flash_wait_complete(void)
{ {
while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY) while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY)
; ;
@ -48,6 +48,17 @@ void RAMFUNCTION hal_flash_wait_complete(uint8_t bank)
} }
static void RAMFUNCTION hal_flash_wait_buffer_empty(void)
{
while ((FLASH_SR & FLASH_SR_DBNE) == FLASH_SR_DBNE)
;
#if (TZ_SECURE())
while ((FLASH_NS_SR & FLASH_SR_DBNE) == FLASH_SR_DBNE)
;
#endif
}
void RAMFUNCTION hal_flash_clear_errors(uint8_t bank) void RAMFUNCTION hal_flash_clear_errors(uint8_t bank)
{ {
FLASH_CCR |= ( FLASH_CCR_CLR_WBNE | FLASH_CCR_CLR_DBNE | FLASH_CCR_CLR_INCE| FLASH_CCR |= ( FLASH_CCR_CLR_WBNE | FLASH_CCR_CLR_DBNE | FLASH_CCR_CLR_INCE|
@ -85,7 +96,7 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
dst[i >> 2] = dword[0]; dst[i >> 2] = dword[0];
ISB(); ISB();
dst[(i >> 2) + 1] = dword[1]; dst[(i >> 2) + 1] = dword[1];
hal_flash_wait_complete(0); hal_flash_wait_complete();
if ((*sr & FLASH_SR_EOP) != 0) if ((*sr & FLASH_SR_EOP) != 0)
*sr |= FLASH_SR_EOP; *sr |= FLASH_SR_EOP;
*cr &= ~FLASH_CR_PG; *cr &= ~FLASH_CR_PG;
@ -99,7 +110,7 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
void RAMFUNCTION hal_flash_unlock(void) void RAMFUNCTION hal_flash_unlock(void)
{ {
hal_flash_wait_complete(0); hal_flash_wait_complete();
if ((FLASH_CR & FLASH_CR_LOCK) != 0) { if ((FLASH_CR & FLASH_CR_LOCK) != 0) {
FLASH_KEYR = FLASH_KEY1; FLASH_KEYR = FLASH_KEY1;
DMB(); DMB();
@ -112,14 +123,14 @@ void RAMFUNCTION hal_flash_unlock(void)
void RAMFUNCTION hal_flash_lock(void) void RAMFUNCTION hal_flash_lock(void)
{ {
hal_flash_wait_complete(0); hal_flash_wait_complete();
if ((FLASH_CR & FLASH_CR_LOCK) == 0) if ((FLASH_CR & FLASH_CR_LOCK) == 0)
FLASH_CR |= FLASH_CR_LOCK; FLASH_CR |= FLASH_CR_LOCK;
} }
void RAMFUNCTION hal_flash_opt_unlock(void) void RAMFUNCTION hal_flash_opt_unlock(void)
{ {
hal_flash_wait_complete(0); hal_flash_wait_complete();
if ((FLASH_OPTCR & FLASH_OPTCR_OPTLOCK) != 0) { if ((FLASH_OPTCR & FLASH_OPTCR_OPTLOCK) != 0) {
FLASH_OPTKEYR = FLASH_OPTKEY1; FLASH_OPTKEYR = FLASH_OPTKEY1;
DMB(); DMB();
@ -134,7 +145,7 @@ void RAMFUNCTION hal_flash_opt_unlock(void)
void RAMFUNCTION hal_flash_opt_lock(void) void RAMFUNCTION hal_flash_opt_lock(void)
{ {
FLASH_OPTCR |= FLASH_OPTCR_OPTSTRT; FLASH_OPTCR |= FLASH_OPTCR_OPTSTRT;
hal_flash_wait_complete(0); hal_flash_wait_complete();
if ((FLASH_OPTCR & FLASH_OPTCR_OPTLOCK) == 0) if ((FLASH_OPTCR & FLASH_OPTCR_OPTLOCK) == 0)
FLASH_OPTCR |= FLASH_OPTCR_OPTLOCK; FLASH_OPTCR |= FLASH_OPTCR_OPTLOCK;
} }
@ -149,7 +160,7 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
if (len == 0) if (len == 0)
return -1; return -1;
if (address < ARCH_FLASH_OFFSET) if (address < 0x08000000)
return -1; return -1;
end_address = address + len - 1; end_address = address + len - 1;
@ -176,7 +187,7 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
FLASH_CR = reg; FLASH_CR = reg;
DMB(); DMB();
FLASH_CR |= FLASH_CR_STRT; FLASH_CR |= FLASH_CR_STRT;
hal_flash_wait_complete(0); hal_flash_wait_complete();
} }
/* If the erase operation is completed, disable the associated bits */ /* If the erase operation is completed, disable the associated bits */
FLASH_CR &= ~FLASH_CR_SER ; FLASH_CR &= ~FLASH_CR_SER ;
@ -421,3 +432,72 @@ void hal_prepare_boot(void)
#endif #endif
} }
#ifdef FLASH_OTP_ROT
/* Public API */
int hal_flash_otp_write(uint32_t flashAddress, const void* data, uint16_t length)
{
volatile uint16_t tmp;
uint16_t *pdata = (uint16_t *)data;
uint16_t idx = 0, len_align;
uint16_t last_word;
if (!(flashAddress >= FLASH_OTP_BASE && flashAddress <= FLASH_OTP_END)) {
return -1;
}
hal_flash_wait_complete();
hal_flash_wait_buffer_empty();
hal_flash_unlock();
hal_flash_clear_errors(0);
/* Truncate to 2B alignment */
length = (length / 2 * 2);
while (idx < length && flashAddress <= FLASH_OTP_END-1) {
hal_flash_wait_complete();
/* Set PG bit */
FLASH_CR |= FLASH_CR_PG;
/* Program an OTP word (32 bits) */
*(volatile uint16_t*)flashAddress = *pdata;
ISB();
DSB();
/* Read it back */
tmp = *(volatile uint16_t*)flashAddress;
if (tmp != *pdata) {
/* Provisioning failed. OTP already programmed? */
while(1)
;
}
/* Clear PG bit */
FLASH_CR &= ~FLASH_CR_PG;
flashAddress += sizeof(uint16_t);
pdata++;
idx += sizeof(uint16_t);
}
hal_flash_lock();
return 0;
}
int hal_flash_otp_read(uint32_t flashAddress, void* data, uint32_t length)
{
uint16_t i;
uint16_t *pdata = (uint16_t *)data;
if (!(flashAddress >= FLASH_OTP_BASE && flashAddress <= FLASH_OTP_END)) {
return -1;
}
for (i = 0;
(i < length) && (flashAddress <= (FLASH_OTP_END-1));
i += sizeof(uint16_t))
{
*pdata = *(volatile uint16_t*)flashAddress;
flashAddress += sizeof(uint16_t);
pdata++;
}
return 0;
}
#endif /* FLASH_OTP_ROT */

View File

@ -355,18 +355,25 @@
#define RCC_APB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xA4)) #define RCC_APB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xA4))
#define UART1_APB2_CLOCK_ER_VAL (1 << 14) #define UART1_APB2_CLOCK_ER_VAL (1 << 14)
/* OTP FLASH AREA */
#define FLASH_OTP_BASE 0x08FFF000
#define FLASH_OTP_END 0x08FFF7FF
#define OTP_SIZE 2048
#define OTP_BLOCKS 32
/* UART1 pin configuration */
#define UART1_PIN_AF 8 #define UART1_PIN_AF 8
#define UART1_RX_PIN 8 #define UART1_RX_PIN 8
#define UART1_TX_PIN 7 #define UART1_TX_PIN 7
/* GPIO secure configuration */
#define GPIO_SECCFGR(base) (*(volatile uint32_t *)(base + 0x30)) #define GPIO_SECCFGR(base) (*(volatile uint32_t *)(base + 0x30))
#define LED_AHB2_ENABLE (GPIOG_AHB2_CLOCK_ER | GPIOB_AHB2_CLOCK_ER | \ #define LED_AHB2_ENABLE (GPIOG_AHB2_CLOCK_ER | GPIOB_AHB2_CLOCK_ER | \
GPIOF_AHB2_CLOCK_ER) GPIOF_AHB2_CLOCK_ER)
#define LED_BOOT_PIN (4) /* PG4 - Nucleo board - Orange Led */ #define LED_BOOT_PIN (4) /* PG4 - Nucleo board - Orange Led */
#define LED_USR_PIN (0) /* PB0 - Nucleo board - Green Led */ #define LED_USR_PIN (0) /* PB0 - Nucleo board - Green Led */
#define LED_EXTRA_PIN (4) /* PF4 - Nucleo board - Blue Led */ #define LED_EXTRA_PIN (4) /* PF4 - Nucleo board - Blue Led */
#endif /* STM32H5_DEF_INCLUDED */ #endif /* STM32H5_DEF_INCLUDED */

View File

@ -35,6 +35,7 @@ extern "C" {
#define KEYSTORE_PUBKEY_SIZE 576 /* Max is RSA 4096 */ #define KEYSTORE_PUBKEY_SIZE 576 /* Max is RSA 4096 */
#endif #endif
struct keystore_slot { struct keystore_slot {
uint32_t slot_id; uint32_t slot_id;
uint32_t key_type; uint32_t key_type;
@ -43,7 +44,8 @@ struct keystore_slot {
uint8_t pubkey[KEYSTORE_PUBKEY_SIZE]; uint8_t pubkey[KEYSTORE_PUBKEY_SIZE];
}; };
#define SIZEOF_KEYSTORE_SLOT (32 + KEYSTORE_PUBKEY_SIZE) #define KEYSTORE_HDR_SIZE 16
#define SIZEOF_KEYSTORE_SLOT (KEYSTORE_HDR_SIZE + KEYSTORE_PUBKEY_SIZE)
/* KeyStore API */ /* KeyStore API */
int keystore_num_pubkeys(void); int keystore_num_pubkeys(void);

View File

@ -32,6 +32,8 @@
*/ */
#ifdef TARGET_stm32h7 #ifdef TARGET_stm32h7
#include "hal/stm32h7.h" #include "hal/stm32h7.h"
#elif defined TARGET_stm32h5
#include "hal/stm32h5.h"
#else #else
#error "Unsupported target for OTP" #error "Unsupported target for OTP"
#endif #endif

View File

@ -175,6 +175,10 @@ extern "C" {
#endif #endif
#endif #endif
#endif
#if defined __WOLFBOOT || defined __FLASH_OTP_PRIMER
/* Authentication configuration */ /* Authentication configuration */
#if defined(WOLFBOOT_NO_SIGN) #if defined(WOLFBOOT_NO_SIGN)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_NONE # define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_NONE

View File

@ -45,7 +45,7 @@ int keystore_num_pubkeys(void)
return hdr->item_count; return hdr->item_count;
} }
static uint16_t otp_slot_item_cache[SIZEOF_KEYSTORE_SLOT/2]; static uint8_t otp_slot_item_cache[SIZEOF_KEYSTORE_SLOT];
uint8_t *keystore_get_buffer(int id) uint8_t *keystore_get_buffer(int id)
{ {

View File

@ -9,7 +9,7 @@ CROSS_COMPILE?=arm-none-eabi-
CFLAGS+=-O0 -ggdb CFLAGS+=-O0 -ggdb
CFLAGS+=-I. -I../../../ -I../../../include CFLAGS+=-I. -I../../../ -I../../../include
CFLAGS+=-I./wcs CFLAGS+=-I./wcs
CFLAGS+=-DFLASH_OTP_ROT CFLAGS+=-DFLASH_OTP_ROT -D__FLASH_OTP_PRIMER
OBJS+=startup.o otp-keystore-primer.o ../../../src/keystore.o OBJS+=startup.o otp-keystore-primer.o ../../../src/keystore.o
LSCRIPT=target.ld LSCRIPT=target.ld
LDFLAGS+=$(CFLAGS) -T$(LSCRIPT) -lc -Wl,-Map=otp-keystore-primer.map LDFLAGS+=$(CFLAGS) -T$(LSCRIPT) -lc -Wl,-Map=otp-keystore-primer.map
@ -19,6 +19,11 @@ ifeq ($(TARGET),stm32h7)
CFLAGS+=-mcpu=cortex-m7 -ffunction-sections -fdata-sections -fno-common -ffreestanding -nostartfiles CFLAGS+=-mcpu=cortex-m7 -ffunction-sections -fdata-sections -fno-common -ffreestanding -nostartfiles
OBJS+=../../../hal/stm32h7.o OBJS+=../../../hal/stm32h7.o
endif endif
ifeq ($(TARGET),stm32h5)
CFLAGS+=-DTARGET_stm32h5
CFLAGS+=-mcpu=cortex-m33 -ffunction-sections -fdata-sections -fno-common -ffreestanding -nostartfiles
OBJS+=../../../hal/stm32h5.o
endif
CC=$(CROSS_COMPILE)gcc CC=$(CROSS_COMPILE)gcc
OBJCOPY?=$(CROSS_COMPILE)objcopy OBJCOPY?=$(CROSS_COMPILE)objcopy
SIZE?=$(CROSS_COMPILE)size SIZE?=$(CROSS_COMPILE)size

View File

@ -23,6 +23,7 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "wolfboot/wolfboot.h"
#include "hal.h" #include "hal.h"
#include "otp_keystore.h" #include "otp_keystore.h"
@ -33,6 +34,9 @@ void main(void)
int n_keys = keystore_num_pubkeys(); int n_keys = keystore_num_pubkeys();
int i; int i;
struct wolfBoot_otp_hdr hdr; struct wolfBoot_otp_hdr hdr;
hal_init();
memcpy(hdr.keystore_hdr_magic, KEYSTORE_HDR_MAGIC, 8); memcpy(hdr.keystore_hdr_magic, KEYSTORE_HDR_MAGIC, 8);
hdr.item_count = n_keys; hdr.item_count = n_keys;
hdr.flags = 0; hdr.flags = 0;