Skip to content

Commit 5b92e7a

Browse files
committed
drivers: flash: stm32: add STM32 option bytes extended ops
Add two new flash extended operations for reading and writing STM32 option bytes from the application code. Signed-off-by: Fabio Baltieri <[email protected]>
1 parent 21e3893 commit 5b92e7a

File tree

8 files changed

+108
-17
lines changed

8 files changed

+108
-17
lines changed

drivers/flash/Kconfig.stm32

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ config FLASH_STM32_BLOCK_REGISTERS
8585
registers improves system security, because flash content (or
8686
protection settings) can't be changed even when exploit was found.
8787

88+
config FLASH_STM32_OPTION_BYTES
89+
bool "Extended operation for option bytes access"
90+
select FLASH_HAS_EX_OP
91+
default n
92+
help
93+
Enables flash extended operations that can be used to read and write
94+
STM32 option bytes.
95+
8896
config USE_MICROCHIP_QSPI_FLASH_WITH_STM32
8997
bool "Include patch for Microchip qspi flash when running with stm32"
9098
depends on DT_HAS_ST_STM32_QSPI_NOR_ENABLED

drivers/flash/flash_stm32.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,11 @@ int flash_stm32_wait_flash_idle(const struct device *dev);
326326

327327
int flash_stm32_option_bytes_lock(const struct device *dev, bool enable);
328328

329+
uint32_t flash_stm32_option_bytes_read(const struct device *dev);
330+
331+
int flash_stm32_option_bytes_write(const struct device *dev, uint32_t mask,
332+
uint32_t value);
333+
329334
#ifdef CONFIG_SOC_SERIES_STM32WBX
330335
int flash_stm32_check_status(const struct device *dev);
331336
#endif /* CONFIG_SOC_SERIES_STM32WBX */

drivers/flash/flash_stm32_ex_op.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,41 @@ int flash_stm32_ex_op(const struct device *dev, uint16_t code,
252252
rv = flash_stm32_control_register_disable(dev);
253253
break;
254254
#endif /* CONFIG_FLASH_STM32_BLOCK_REGISTERS */
255+
#if defined(CONFIG_FLASH_STM32_OPTION_BYTES) && ( \
256+
defined(CONFIG_DT_HAS_ST_STM32F4_FLASH_CONTROLLER_ENABLED) || \
257+
defined(CONFIG_DT_HAS_ST_STM32F7_FLASH_CONTROLLER_ENABLED) || \
258+
defined(CONFIG_DT_HAS_ST_STM32G4_FLASH_CONTROLLER_ENABLED) || \
259+
defined(CONFIG_DT_HAS_ST_STM32L4_FLASH_CONTROLLER_ENABLED))
260+
case FLASH_STM32_EX_OP_OPTB_READ:
261+
if (out == NULL) {
262+
rv = -EINVAL;
263+
break;
264+
}
265+
266+
*(uint32_t *)out = flash_stm32_option_bytes_read(dev);
267+
rv = 0;
268+
269+
break;
270+
case FLASH_STM32_EX_OP_OPTB_WRITE:
271+
int rv2;
272+
273+
rv = flash_stm32_option_bytes_lock(dev, false);
274+
if (rv > 0) {
275+
break;
276+
}
277+
278+
rv2 = flash_stm32_option_bytes_write(dev, UINT32_MAX, (uint32_t)in);
279+
/* returned later, we always re-lock */
280+
281+
rv = flash_stm32_option_bytes_lock(dev, true);
282+
if (rv > 0) {
283+
break;
284+
}
285+
286+
rv = rv2;
287+
288+
break;
289+
#endif
255290
}
256291

257292
flash_stm32_sem_give(dev);

drivers/flash/flash_stm32f4x.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,8 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset,
231231
return rc;
232232
}
233233

234-
static __unused int write_optb(const struct device *dev, uint32_t mask,
235-
uint32_t value)
234+
int flash_stm32_option_bytes_write(const struct device *dev, uint32_t mask,
235+
uint32_t value)
236236
{
237237
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
238238
int rc;
@@ -264,6 +264,13 @@ static __unused int write_optb(const struct device *dev, uint32_t mask,
264264
return 0;
265265
}
266266

267+
uint32_t flash_stm32_option_bytes_read(const struct device *dev)
268+
{
269+
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
270+
271+
return regs->OPTCR;
272+
}
273+
267274
#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT)
268275
int flash_stm32_update_wp_sectors(const struct device *dev,
269276
uint32_t changed_sectors,
@@ -279,7 +286,8 @@ int flash_stm32_update_wp_sectors(const struct device *dev,
279286
/* Sector is protected when bit == 0. Flip protected_sectors bits */
280287
protected_sectors = ~protected_sectors & changed_sectors;
281288

282-
return write_optb(dev, changed_sectors, protected_sectors);
289+
return flash_stm32_option_bytes_write(dev, changed_sectors,
290+
protected_sectors);
283291
}
284292

285293
int flash_stm32_get_wp_sectors(const struct device *dev,
@@ -304,8 +312,8 @@ uint8_t flash_stm32_get_rdp_level(const struct device *dev)
304312

305313
void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level)
306314
{
307-
write_optb(dev, FLASH_OPTCR_RDP_Msk,
308-
(uint32_t)level << FLASH_OPTCR_RDP_Pos);
315+
flash_stm32_option_bytes_write(dev, FLASH_OPTCR_RDP_Msk,
316+
(uint32_t)level << FLASH_OPTCR_RDP_Pos);
309317
}
310318
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */
311319

drivers/flash/flash_stm32f7x.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset,
159159
return rc;
160160
}
161161

162-
static __unused int write_optb(const struct device *dev, uint32_t mask,
163-
uint32_t value)
162+
int flash_stm32_option_bytes_write(const struct device *dev, uint32_t mask,
163+
uint32_t value)
164164
{
165165
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
166166
int rc;
@@ -187,6 +187,13 @@ static __unused int write_optb(const struct device *dev, uint32_t mask,
187187
return flash_stm32_wait_flash_idle(dev);
188188
}
189189

190+
uint32_t flash_stm32_option_bytes_read(const struct device *dev)
191+
{
192+
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
193+
194+
return regs->OPTCR;
195+
}
196+
190197
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION)
191198
uint8_t flash_stm32_get_rdp_level(const struct device *dev)
192199
{
@@ -197,8 +204,8 @@ uint8_t flash_stm32_get_rdp_level(const struct device *dev)
197204

198205
void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level)
199206
{
200-
write_optb(dev, FLASH_OPTCR_RDP_Msk,
201-
(uint32_t)level << FLASH_OPTCR_RDP_Pos);
207+
flash_stm32_option_bytes_write(dev, FLASH_OPTCR_RDP_Msk,
208+
(uint32_t)level << FLASH_OPTCR_RDP_Pos);
202209
}
203210
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */
204211

drivers/flash/flash_stm32g4x.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset,
255255
return rc;
256256
}
257257

258-
static __unused int write_optb(const struct device *dev, uint32_t mask,
259-
uint32_t value)
258+
int flash_stm32_option_bytes_write(const struct device *dev, uint32_t mask,
259+
uint32_t value)
260260
{
261261
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
262262
int rc;
@@ -288,6 +288,13 @@ static __unused int write_optb(const struct device *dev, uint32_t mask,
288288
return 0;
289289
}
290290

291+
uint32_t flash_stm32_option_bytes_read(const struct device *dev)
292+
{
293+
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
294+
295+
return regs->OPTR;
296+
}
297+
291298
#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT)
292299

293300
/*
@@ -314,8 +321,8 @@ uint8_t flash_stm32_get_rdp_level(const struct device *dev)
314321

315322
void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level)
316323
{
317-
write_optb(dev, FLASH_OPTR_RDP_Msk,
318-
(uint32_t)level << FLASH_OPTR_RDP_Pos);
324+
flash_stm32_option_bytes_write(dev, FLASH_OPTR_RDP_Msk,
325+
(uint32_t)level << FLASH_OPTR_RDP_Pos);
319326
}
320327
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */
321328

drivers/flash/flash_stm32l4x.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset,
246246
return rc;
247247
}
248248

249-
static __unused int write_optb(const struct device *dev, uint32_t mask,
250-
uint32_t value)
249+
int flash_stm32_option_bytes_write(const struct device *dev, uint32_t mask,
250+
uint32_t value)
251251
{
252252
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
253253
int rc;
@@ -279,6 +279,13 @@ static __unused int write_optb(const struct device *dev, uint32_t mask,
279279
return 0;
280280
}
281281

282+
uint32_t flash_stm32_option_bytes_read(const struct device *dev)
283+
{
284+
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
285+
286+
return regs->OPTR;
287+
}
288+
282289
#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT)
283290

284291
/*
@@ -305,8 +312,8 @@ uint8_t flash_stm32_get_rdp_level(const struct device *dev)
305312

306313
void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level)
307314
{
308-
write_optb(dev, FLASH_OPTR_RDP_Msk,
309-
(uint32_t)level << FLASH_OPTR_RDP_Pos);
315+
flash_stm32_option_bytes_write(dev, FLASH_OPTR_RDP_Msk,
316+
(uint32_t)level << FLASH_OPTR_RDP_Pos);
310317
}
311318
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */
312319

include/zephyr/drivers/flash/stm32_flash_api_extensions.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ enum stm32_ex_ops {
4848
* erasing or writing.
4949
*/
5050
FLASH_STM32_EX_OP_BLOCK_CONTROL_REG,
51+
/*
52+
* STM32 option bytes read.
53+
*
54+
* Read the option bytes content, out takes a *uint32_t, in is unused.
55+
*/
56+
FLASH_STM32_EX_OP_OPTB_READ,
57+
/*
58+
* STM32 option bytes write.
59+
*
60+
* Write the option bytes content, in takes the new value, out is
61+
* unused. Note that the new value only takes effect after the device
62+
* is restarted.
63+
*/
64+
FLASH_STM32_EX_OP_OPTB_WRITE,
5165
};
5266

5367
#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT)

0 commit comments

Comments
 (0)