Skip to content

Commit 02bfe8a

Browse files
committed
Added OTP support for STM32H5
1 parent 5f2a3d5 commit 02bfe8a

File tree

8 files changed

+118
-14
lines changed

8 files changed

+118
-14
lines changed

hal/stm32h5.c

Lines changed: 88 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static void RAMFUNCTION flash_set_waitstates(unsigned int waitstates)
3737
while ((FLASH_ACR & FLASH_ACR_LATENCY_MASK) != waitstates);
3838
}
3939

40-
void RAMFUNCTION hal_flash_wait_complete(uint8_t bank)
40+
static void RAMFUNCTION hal_flash_wait_complete(void)
4141
{
4242
while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY)
4343
;
@@ -48,6 +48,17 @@ void RAMFUNCTION hal_flash_wait_complete(uint8_t bank)
4848

4949
}
5050

51+
static void RAMFUNCTION hal_flash_wait_buffer_empty(void)
52+
{
53+
while ((FLASH_SR & FLASH_SR_DBNE) == FLASH_SR_DBNE)
54+
;
55+
#if (TZ_SECURE())
56+
while ((FLASH_NS_SR & FLASH_SR_DBNE) == FLASH_SR_DBNE)
57+
;
58+
#endif
59+
60+
}
61+
5162
void RAMFUNCTION hal_flash_clear_errors(uint8_t bank)
5263
{
5364
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)
8596
dst[i >> 2] = dword[0];
8697
ISB();
8798
dst[(i >> 2) + 1] = dword[1];
88-
hal_flash_wait_complete(0);
99+
hal_flash_wait_complete();
89100
if ((*sr & FLASH_SR_EOP) != 0)
90101
*sr |= FLASH_SR_EOP;
91102
*cr &= ~FLASH_CR_PG;
@@ -99,7 +110,7 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
99110

100111
void RAMFUNCTION hal_flash_unlock(void)
101112
{
102-
hal_flash_wait_complete(0);
113+
hal_flash_wait_complete();
103114
if ((FLASH_CR & FLASH_CR_LOCK) != 0) {
104115
FLASH_KEYR = FLASH_KEY1;
105116
DMB();
@@ -112,14 +123,14 @@ void RAMFUNCTION hal_flash_unlock(void)
112123

113124
void RAMFUNCTION hal_flash_lock(void)
114125
{
115-
hal_flash_wait_complete(0);
126+
hal_flash_wait_complete();
116127
if ((FLASH_CR & FLASH_CR_LOCK) == 0)
117128
FLASH_CR |= FLASH_CR_LOCK;
118129
}
119130

120131
void RAMFUNCTION hal_flash_opt_unlock(void)
121132
{
122-
hal_flash_wait_complete(0);
133+
hal_flash_wait_complete();
123134
if ((FLASH_OPTCR & FLASH_OPTCR_OPTLOCK) != 0) {
124135
FLASH_OPTKEYR = FLASH_OPTKEY1;
125136
DMB();
@@ -134,7 +145,7 @@ void RAMFUNCTION hal_flash_opt_unlock(void)
134145
void RAMFUNCTION hal_flash_opt_lock(void)
135146
{
136147
FLASH_OPTCR |= FLASH_OPTCR_OPTSTRT;
137-
hal_flash_wait_complete(0);
148+
hal_flash_wait_complete();
138149
if ((FLASH_OPTCR & FLASH_OPTCR_OPTLOCK) == 0)
139150
FLASH_OPTCR |= FLASH_OPTCR_OPTLOCK;
140151
}
@@ -149,7 +160,7 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
149160
if (len == 0)
150161
return -1;
151162

152-
if (address < ARCH_FLASH_OFFSET)
163+
if (address < 0x08000000)
153164
return -1;
154165

155166
end_address = address + len - 1;
@@ -176,7 +187,7 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
176187
FLASH_CR = reg;
177188
DMB();
178189
FLASH_CR |= FLASH_CR_STRT;
179-
hal_flash_wait_complete(0);
190+
hal_flash_wait_complete();
180191
}
181192
/* If the erase operation is completed, disable the associated bits */
182193
FLASH_CR &= ~FLASH_CR_SER ;
@@ -421,3 +432,72 @@ void hal_prepare_boot(void)
421432
#endif
422433
}
423434

435+
#ifdef FLASH_OTP_ROT
436+
437+
/* Public API */
438+
439+
int hal_flash_otp_write(uint32_t flashAddress, const void* data, uint16_t length)
440+
{
441+
volatile uint16_t tmp;
442+
uint16_t *pdata = (uint16_t *)data;
443+
uint16_t idx = 0, len_align;
444+
uint16_t last_word;
445+
if (!(flashAddress >= FLASH_OTP_BASE && flashAddress <= FLASH_OTP_END)) {
446+
return -1;
447+
}
448+
449+
hal_flash_wait_complete();
450+
hal_flash_wait_buffer_empty();
451+
hal_flash_unlock();
452+
hal_flash_clear_errors(0);
453+
454+
455+
/* Truncate to 2B alignment */
456+
length = (length / 2 * 2);
457+
458+
while (idx < length && flashAddress <= FLASH_OTP_END-1) {
459+
hal_flash_wait_complete();
460+
/* Set PG bit */
461+
FLASH_CR |= FLASH_CR_PG;
462+
/* Program an OTP word (32 bits) */
463+
*(volatile uint16_t*)flashAddress = *pdata;
464+
ISB();
465+
DSB();
466+
/* Read it back */
467+
tmp = *(volatile uint16_t*)flashAddress;
468+
if (tmp != *pdata) {
469+
/* Provisioning failed. OTP already programmed? */
470+
while(1)
471+
;
472+
}
473+
474+
/* Clear PG bit */
475+
FLASH_CR &= ~FLASH_CR_PG;
476+
flashAddress += sizeof(uint16_t);
477+
pdata++;
478+
idx += sizeof(uint16_t);
479+
}
480+
481+
hal_flash_lock();
482+
return 0;
483+
}
484+
485+
int hal_flash_otp_read(uint32_t flashAddress, void* data, uint32_t length)
486+
{
487+
uint16_t i;
488+
uint16_t *pdata = (uint16_t *)data;
489+
if (!(flashAddress >= FLASH_OTP_BASE && flashAddress <= FLASH_OTP_END)) {
490+
return -1;
491+
}
492+
for (i = 0;
493+
(i < length) && (flashAddress <= (FLASH_OTP_END-1));
494+
i += sizeof(uint16_t))
495+
{
496+
*pdata = *(volatile uint16_t*)flashAddress;
497+
flashAddress += sizeof(uint16_t);
498+
pdata++;
499+
}
500+
return 0;
501+
}
502+
503+
#endif /* FLASH_OTP_ROT */

hal/stm32h5.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,18 +355,25 @@
355355
#define RCC_APB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xA4))
356356
#define UART1_APB2_CLOCK_ER_VAL (1 << 14)
357357

358+
359+
/* OTP FLASH AREA */
360+
#define FLASH_OTP_BASE 0x08FFF000
361+
#define FLASH_OTP_END 0x08FFF7FF
362+
#define OTP_SIZE 2048
363+
#define OTP_BLOCKS 32
364+
365+
/* UART1 pin configuration */
358366
#define UART1_PIN_AF 8
359367
#define UART1_RX_PIN 8
360368
#define UART1_TX_PIN 7
361369

370+
/* GPIO secure configuration */
362371
#define GPIO_SECCFGR(base) (*(volatile uint32_t *)(base + 0x30))
363-
364-
365-
366372
#define LED_AHB2_ENABLE (GPIOG_AHB2_CLOCK_ER | GPIOB_AHB2_CLOCK_ER | \
367373
GPIOF_AHB2_CLOCK_ER)
368374
#define LED_BOOT_PIN (4) /* PG4 - Nucleo board - Orange Led */
369375
#define LED_USR_PIN (0) /* PB0 - Nucleo board - Green Led */
370376
#define LED_EXTRA_PIN (4) /* PF4 - Nucleo board - Blue Led */
371377

378+
372379
#endif /* STM32H5_DEF_INCLUDED */

include/keystore.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern "C" {
3535
#define KEYSTORE_PUBKEY_SIZE 576 /* Max is RSA 4096 */
3636
#endif
3737

38+
3839
struct keystore_slot {
3940
uint32_t slot_id;
4041
uint32_t key_type;
@@ -43,7 +44,8 @@ struct keystore_slot {
4344
uint8_t pubkey[KEYSTORE_PUBKEY_SIZE];
4445
};
4546

46-
#define SIZEOF_KEYSTORE_SLOT (32 + KEYSTORE_PUBKEY_SIZE)
47+
#define KEYSTORE_HDR_SIZE 16
48+
#define SIZEOF_KEYSTORE_SLOT (KEYSTORE_HDR_SIZE + KEYSTORE_PUBKEY_SIZE)
4749

4850
/* KeyStore API */
4951
int keystore_num_pubkeys(void);

include/otp_keystore.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
*/
3333
#ifdef TARGET_stm32h7
3434
#include "hal/stm32h7.h"
35+
#elif defined TARGET_stm32h5
36+
#include "hal/stm32h5.h"
3537
#else
3638
#error "Unsupported target for OTP"
3739
#endif

include/wolfboot/wolfboot.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ extern "C" {
175175
#endif
176176
#endif
177177

178+
#endif
179+
180+
#if defined __WOLFBOOT || defined __FLASH_OTP_PRIMER
181+
178182
/* Authentication configuration */
179183
#if defined(WOLFBOOT_NO_SIGN)
180184
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_NONE

src/flash_otp_keystore.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ int keystore_num_pubkeys(void)
4545
return hdr->item_count;
4646
}
4747

48-
static uint16_t otp_slot_item_cache[SIZEOF_KEYSTORE_SLOT/2];
48+
static uint8_t otp_slot_item_cache[SIZEOF_KEYSTORE_SLOT];
4949

5050
uint8_t *keystore_get_buffer(int id)
5151
{

tools/keytools/otp/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ CROSS_COMPILE?=arm-none-eabi-
99
CFLAGS+=-O0 -ggdb
1010
CFLAGS+=-I. -I../../../ -I../../../include
1111
CFLAGS+=-I./wcs
12-
CFLAGS+=-DFLASH_OTP_ROT
12+
CFLAGS+=-DFLASH_OTP_ROT -D__FLASH_OTP_PRIMER
1313
OBJS+=startup.o otp-keystore-primer.o ../../../src/keystore.o
1414
LSCRIPT=target.ld
1515
LDFLAGS+=$(CFLAGS) -T$(LSCRIPT) -lc -Wl,-Map=otp-keystore-primer.map
@@ -19,6 +19,11 @@ ifeq ($(TARGET),stm32h7)
1919
CFLAGS+=-mcpu=cortex-m7 -ffunction-sections -fdata-sections -fno-common -ffreestanding -nostartfiles
2020
OBJS+=../../../hal/stm32h7.o
2121
endif
22+
ifeq ($(TARGET),stm32h5)
23+
CFLAGS+=-DTARGET_stm32h5
24+
CFLAGS+=-mcpu=cortex-m33 -ffunction-sections -fdata-sections -fno-common -ffreestanding -nostartfiles
25+
OBJS+=../../../hal/stm32h5.o
26+
endif
2227
CC=$(CROSS_COMPILE)gcc
2328
OBJCOPY?=$(CROSS_COMPILE)objcopy
2429
SIZE?=$(CROSS_COMPILE)size

tools/keytools/otp/otp-keystore-primer.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424
#include <stdint.h>
2525
#include <string.h>
26+
#include "wolfboot/wolfboot.h"
2627
#include "hal.h"
2728
#include "otp_keystore.h"
2829

@@ -33,6 +34,9 @@ void main(void)
3334
int n_keys = keystore_num_pubkeys();
3435
int i;
3536
struct wolfBoot_otp_hdr hdr;
37+
38+
hal_init();
39+
3640
memcpy(hdr.keystore_hdr_magic, KEYSTORE_HDR_MAGIC, 8);
3741
hdr.item_count = n_keys;
3842
hdr.flags = 0;

0 commit comments

Comments
 (0)