Skip to content

Commit

Permalink
Added OTP support for STM32H5
Browse files Browse the repository at this point in the history
  • Loading branch information
danielinux committed May 14, 2024
1 parent 46c3299 commit c46d82c
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 14 deletions.
96 changes: 88 additions & 8 deletions hal/stm32h5.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static void RAMFUNCTION flash_set_waitstates(unsigned int 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)
;
Expand All @@ -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)
{
FLASH_CCR |= ( FLASH_CCR_CLR_WBNE | FLASH_CCR_CLR_DBNE | FLASH_CCR_CLR_INCE|
Expand Down Expand Up @@ -85,7 +96,7 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
dst[i >> 2] = dword[0];
ISB();
dst[(i >> 2) + 1] = dword[1];
hal_flash_wait_complete(0);
hal_flash_wait_complete();
if ((*sr & FLASH_SR_EOP) != 0)
*sr |= FLASH_SR_EOP;
*cr &= ~FLASH_CR_PG;
Expand All @@ -99,7 +110,7 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)

void RAMFUNCTION hal_flash_unlock(void)
{
hal_flash_wait_complete(0);
hal_flash_wait_complete();
if ((FLASH_CR & FLASH_CR_LOCK) != 0) {
FLASH_KEYR = FLASH_KEY1;
DMB();
Expand All @@ -112,14 +123,14 @@ void RAMFUNCTION hal_flash_unlock(void)

void RAMFUNCTION hal_flash_lock(void)
{
hal_flash_wait_complete(0);
hal_flash_wait_complete();
if ((FLASH_CR & FLASH_CR_LOCK) == 0)
FLASH_CR |= FLASH_CR_LOCK;
}

void RAMFUNCTION hal_flash_opt_unlock(void)
{
hal_flash_wait_complete(0);
hal_flash_wait_complete();
if ((FLASH_OPTCR & FLASH_OPTCR_OPTLOCK) != 0) {
FLASH_OPTKEYR = FLASH_OPTKEY1;
DMB();
Expand All @@ -134,7 +145,7 @@ void RAMFUNCTION hal_flash_opt_unlock(void)
void RAMFUNCTION hal_flash_opt_lock(void)
{
FLASH_OPTCR |= FLASH_OPTCR_OPTSTRT;
hal_flash_wait_complete(0);
hal_flash_wait_complete();
if ((FLASH_OPTCR & FLASH_OPTCR_OPTLOCK) == 0)
FLASH_OPTCR |= FLASH_OPTCR_OPTLOCK;
}
Expand All @@ -149,7 +160,7 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
if (len == 0)
return -1;

if (address < ARCH_FLASH_OFFSET)
if (address < 0x08000000)
return -1;

end_address = address + len - 1;
Expand All @@ -176,7 +187,7 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
FLASH_CR = reg;
DMB();
FLASH_CR |= FLASH_CR_STRT;
hal_flash_wait_complete(0);
hal_flash_wait_complete();
}
/* If the erase operation is completed, disable the associated bits */
FLASH_CR &= ~FLASH_CR_SER ;
Expand Down Expand Up @@ -421,3 +432,72 @@ void hal_prepare_boot(void)
#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 */
13 changes: 10 additions & 3 deletions hal/stm32h5.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,18 +355,25 @@
#define RCC_APB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xA4))
#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_RX_PIN 8
#define UART1_TX_PIN 7

/* GPIO secure configuration */
#define GPIO_SECCFGR(base) (*(volatile uint32_t *)(base + 0x30))



#define LED_AHB2_ENABLE (GPIOG_AHB2_CLOCK_ER | GPIOB_AHB2_CLOCK_ER | \
GPIOF_AHB2_CLOCK_ER)
#define LED_BOOT_PIN (4) /* PG4 - Nucleo board - Orange Led */
#define LED_USR_PIN (0) /* PB0 - Nucleo board - Green Led */
#define LED_EXTRA_PIN (4) /* PF4 - Nucleo board - Blue Led */


#endif /* STM32H5_DEF_INCLUDED */
4 changes: 3 additions & 1 deletion include/keystore.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extern "C" {
#define KEYSTORE_PUBKEY_SIZE 576 /* Max is RSA 4096 */
#endif


struct keystore_slot {
uint32_t slot_id;
uint32_t key_type;
Expand All @@ -43,7 +44,8 @@ struct keystore_slot {
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 */
int keystore_num_pubkeys(void);
Expand Down
2 changes: 2 additions & 0 deletions include/otp_keystore.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
*/
#ifdef TARGET_stm32h7
#include "hal/stm32h7.h"
#elif defined TARGET_stm32h5
#include "hal/stm32h5.h"
#else
#error "Unsupported target for OTP"
#endif
Expand Down
4 changes: 4 additions & 0 deletions include/wolfboot/wolfboot.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ extern "C" {
#endif
#endif

#endif

#if defined __WOLFBOOT || defined __FLASH_OTP_PRIMER

/* Authentication configuration */
#if defined(WOLFBOOT_NO_SIGN)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_NONE
Expand Down
2 changes: 1 addition & 1 deletion src/flash_otp_keystore.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ int keystore_num_pubkeys(void)
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)
{
Expand Down
7 changes: 6 additions & 1 deletion tools/keytools/otp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ CROSS_COMPILE?=arm-none-eabi-
CFLAGS+=-O0 -ggdb
CFLAGS+=-I. -I../../../ -I../../../include
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
LSCRIPT=target.ld
LDFLAGS+=$(CFLAGS) -T$(LSCRIPT) -lc -Wl,-Map=otp-keystore-primer.map
Expand All @@ -19,6 +19,11 @@ ifeq ($(TARGET),stm32h7)
CFLAGS+=-mcpu=cortex-m7 -ffunction-sections -fdata-sections -fno-common -ffreestanding -nostartfiles
OBJS+=../../../hal/stm32h7.o
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
OBJCOPY?=$(CROSS_COMPILE)objcopy
SIZE?=$(CROSS_COMPILE)size
Expand Down
4 changes: 4 additions & 0 deletions tools/keytools/otp/otp-keystore-primer.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/
#include <stdint.h>
#include <string.h>
#include "wolfboot/wolfboot.h"
#include "hal.h"
#include "otp_keystore.h"

Expand All @@ -33,6 +34,9 @@ void main(void)
int n_keys = keystore_num_pubkeys();
int i;
struct wolfBoot_otp_hdr hdr;

hal_init();

memcpy(hdr.keystore_hdr_magic, KEYSTORE_HDR_MAGIC, 8);
hdr.item_count = n_keys;
hdr.flags = 0;
Expand Down

0 comments on commit c46d82c

Please sign in to comment.