Skip to content

Commit 112a3af

Browse files
committed
drivers: flash: reduce redundancy in RDP implementation on STM32
Reduce the redundancy in the readout protection implementation on STM32 MCUs. Signed-off-by: Benedikt Schmidt <[email protected]>
1 parent ac52bd6 commit 112a3af

File tree

5 files changed

+107
-282
lines changed

5 files changed

+107
-282
lines changed

drivers/flash/flash_stm32.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -311,12 +311,9 @@ int flash_stm32_get_wp_sectors(const struct device *dev,
311311
uint32_t *protected_sectors);
312312
#endif
313313
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION)
314+
uint8_t flash_stm32_get_rdp_level(const struct device *dev);
314315

315-
int flash_stm32_update_rdp(const struct device *dev, bool enable,
316-
bool permanent);
317-
318-
int flash_stm32_get_rdp(const struct device *dev, bool *enabled,
319-
bool *permanent);
316+
void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level);
320317
#endif
321318

322319
/* Flash extended operations */

drivers/flash/flash_stm32_ex_op.c

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <zephyr/device.h>
99
#include <zephyr/drivers/flash/stm32_flash_api_extensions.h>
1010
#include <zephyr/kernel.h>
11+
#include <zephyr/logging/log.h>
1112

1213
#ifdef CONFIG_USERSPACE
1314
#include <zephyr/syscall.h>
@@ -17,6 +18,8 @@
1718
#include <soc.h>
1819
#include "flash_stm32.h"
1920

21+
LOG_MODULE_REGISTER(flash_stm32_ex_op, CONFIG_FLASH_LOG_LEVEL);
22+
2023
#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT)
2124
int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in,
2225
void *out)
@@ -85,13 +88,79 @@ int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in,
8588
#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */
8689

8790
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION)
91+
int flash_stm32_ex_op_update_rdp(const struct device *dev, bool enable,
92+
bool permanent)
93+
{
94+
uint8_t current_level, target_level;
95+
96+
current_level = flash_stm32_get_rdp_level(dev);
97+
target_level = current_level;
98+
99+
/*
100+
* 0xAA = RDP level 0 (no protection)
101+
* 0xCC = RDP level 2 (permanent protection)
102+
* others = RDP level 1 (protection active)
103+
*/
104+
switch (current_level) {
105+
case FLASH_STM32_RDP2:
106+
if (!enable || !permanent) {
107+
LOG_DBG("RDP level 2 is permanent and can't be changed!");
108+
return -ENOTSUP;
109+
}
110+
break;
111+
case FLASH_STM32_RDP0:
112+
if (enable) {
113+
target_level = FLASH_STM32_RDP1;
114+
if (permanent) {
115+
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
116+
target_level = FLASH_STM32_RDP2;
117+
#else
118+
LOG_DBG("Permanent readout protection (RDP "
119+
"level 0 -> 2) not allowed");
120+
return -ENOTSUP;
121+
#endif
122+
}
123+
}
124+
break;
125+
default: /* FLASH_STM32_RDP1 */
126+
if (enable && permanent) {
127+
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
128+
target_level = FLASH_STM32_RDP2;
129+
#else
130+
LOG_DBG("Permanent readout protection (RDP "
131+
"level 1 -> 2) not allowed");
132+
return -ENOTSUP;
133+
#endif
134+
}
135+
if (!enable) {
136+
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_DISABLE_ALLOW)
137+
target_level = FLASH_STM32_RDP0;
138+
#else
139+
LOG_DBG("Disabling readout protection (RDP "
140+
"level 1 -> 0) not allowed");
141+
return -EACCES;
142+
#endif
143+
}
144+
}
145+
146+
/* Update RDP level if needed */
147+
if (current_level != target_level) {
148+
LOG_INF("RDP changed from 0x%02x to 0x%02x", current_level,
149+
target_level);
150+
151+
flash_stm32_set_rdp_level(dev, target_level);
152+
}
153+
return 0;
154+
}
155+
88156
int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in,
89157
void *out)
90158
{
91159
const struct flash_stm32_ex_op_rdp *request =
92160
(const struct flash_stm32_ex_op_rdp *)in;
93161
struct flash_stm32_ex_op_rdp *result =
94162
(struct flash_stm32_ex_op_rdp *)out;
163+
uint8_t current_level;
95164

96165
#ifdef CONFIG_USERSPACE
97166
struct flash_stm32_ex_op_rdp copy;
@@ -108,7 +177,7 @@ int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in,
108177
#endif
109178
rc = flash_stm32_option_bytes_lock(dev, false);
110179
if (rc == 0) {
111-
rc = flash_stm32_update_rdp(dev, request->enable,
180+
rc = flash_stm32_ex_op_update_rdp(dev, request->enable,
112181
request->permanent);
113182
}
114183

@@ -124,10 +193,26 @@ int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in,
124193
result = &copy;
125194
}
126195
#endif
127-
rc2 = flash_stm32_get_rdp(dev, &result->enable,
128-
&result->permanent);
129-
if (!rc) {
130-
rc = rc2;
196+
197+
current_level = flash_stm32_get_rdp_level(dev);
198+
199+
/*
200+
* 0xAA = RDP level 0 (no protection)
201+
* 0xCC = RDP level 2 (permanent protection)
202+
* others = RDP level 1 (protection active)
203+
*/
204+
switch (current_level) {
205+
case FLASH_STM32_RDP2:
206+
result->enable = true;
207+
result->permanent = true;
208+
break;
209+
case FLASH_STM32_RDP0:
210+
result->enable = false;
211+
result->permanent = false;
212+
break;
213+
default: /* FLASH_STM32_RDP1 */
214+
result->enable = true;
215+
result->permanent = false;
131216
}
132217

133218
#ifdef CONFIG_USERSPACE

drivers/flash/flash_stm32f4x.c

Lines changed: 5 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -295,102 +295,17 @@ int flash_stm32_get_wp_sectors(const struct device *dev,
295295
#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */
296296

297297
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION)
298-
int flash_stm32_update_rdp(const struct device *dev, bool enable,
299-
bool permanent)
298+
uint8_t flash_stm32_get_rdp_level(const struct device *dev)
300299
{
301300
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
302-
uint8_t current_level, target_level;
303301

304-
current_level =
305-
(regs->OPTCR & FLASH_OPTCR_RDP_Msk) >> FLASH_OPTCR_RDP_Pos;
306-
target_level = current_level;
307-
308-
/*
309-
* 0xAA = RDP level 0 (no protection)
310-
* 0xCC = RDP level 2 (permanent protection)
311-
* others = RDP level 1 (protection active)
312-
*/
313-
switch (current_level) {
314-
case FLASH_STM32_RDP2:
315-
if (!enable || !permanent) {
316-
LOG_ERR("RDP level 2 is permanent and can't be changed!");
317-
return -ENOTSUP;
318-
}
319-
break;
320-
case FLASH_STM32_RDP0:
321-
if (enable) {
322-
target_level = FLASH_STM32_RDP1;
323-
if (permanent) {
324-
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
325-
target_level = FLASH_STM32_RDP2;
326-
#else
327-
LOG_ERR("Permanent readout protection (RDP "
328-
"level 0 -> 2) not allowed");
329-
return -ENOTSUP;
330-
#endif
331-
}
332-
}
333-
break;
334-
default: /* FLASH_STM32_RDP1 */
335-
if (enable && permanent) {
336-
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
337-
target_level = FLASH_STM32_RDP2;
338-
#else
339-
LOG_ERR("Permanent readout protection (RDP "
340-
"level 1 -> 2) not allowed");
341-
return -ENOTSUP;
342-
#endif
343-
}
344-
if (!enable) {
345-
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_DISABLE_ALLOW)
346-
target_level = FLASH_STM32_RDP0;
347-
#else
348-
LOG_ERR("Disabling readout protection (RDP "
349-
"level 1 -> 0) not allowed");
350-
return -EACCES;
351-
#endif
352-
}
353-
}
354-
355-
/* Update RDP level if needed */
356-
if (current_level != target_level) {
357-
LOG_INF("RDP changed from 0x%02x to 0x%02x", current_level,
358-
target_level);
359-
360-
write_optb(dev, FLASH_OPTCR_RDP_Msk,
361-
(uint32_t)target_level << FLASH_OPTCR_RDP_Pos);
362-
}
363-
return 0;
302+
return (regs->OPTCR & FLASH_OPTCR_RDP_Msk) >> FLASH_OPTCR_RDP_Pos;
364303
}
365304

366-
int flash_stm32_get_rdp(const struct device *dev, bool *enabled,
367-
bool *permanent)
305+
void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level)
368306
{
369-
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
370-
uint8_t current_level;
371-
372-
current_level =
373-
(regs->OPTCR & FLASH_OPTCR_RDP_Msk) >> FLASH_OPTCR_RDP_Pos;
374-
375-
/*
376-
* 0xAA = RDP level 0 (no protection)
377-
* 0xCC = RDP level 2 (permanent protection)
378-
* others = RDP level 1 (protection active)
379-
*/
380-
switch (current_level) {
381-
case FLASH_STM32_RDP2:
382-
*enabled = true;
383-
*permanent = true;
384-
break;
385-
case FLASH_STM32_RDP0:
386-
*enabled = false;
387-
*permanent = false;
388-
break;
389-
default: /* FLASH_STM32_RDP1 */
390-
*enabled = true;
391-
*permanent = false;
392-
}
393-
return 0;
307+
write_optb(dev, FLASH_OPTCR_RDP_Msk,
308+
(uint32_t)level << FLASH_OPTCR_RDP_Pos);
394309
}
395310
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */
396311

drivers/flash/flash_stm32g4x.c

Lines changed: 5 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -305,102 +305,17 @@ static __unused int write_optb(const struct device *dev, uint32_t mask,
305305
#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */
306306

307307
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION)
308-
int flash_stm32_update_rdp(const struct device *dev, bool enable,
309-
bool permanent)
308+
uint8_t flash_stm32_get_rdp_level(const struct device *dev)
310309
{
311310
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
312-
uint8_t current_level, target_level;
313311

314-
current_level =
315-
(regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos;
316-
target_level = current_level;
317-
318-
/*
319-
* 0xAA = RDP level 0 (no protection)
320-
* 0xCC = RDP level 2 (permanent protection)
321-
* others = RDP level 1 (protection active)
322-
*/
323-
switch (current_level) {
324-
case FLASH_STM32_RDP2:
325-
if (!enable || !permanent) {
326-
LOG_ERR("RDP level 2 is permanent and can't be changed!");
327-
return -ENOTSUP;
328-
}
329-
break;
330-
case FLASH_STM32_RDP0:
331-
if (enable) {
332-
target_level = FLASH_STM32_RDP1;
333-
if (permanent) {
334-
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
335-
target_level = FLASH_STM32_RDP2;
336-
#else
337-
LOG_ERR("Permanent readout protection (RDP "
338-
"level 0 -> 2) not allowed");
339-
return -ENOTSUP;
340-
#endif
341-
}
342-
}
343-
break;
344-
default: /* FLASH_STM32_RDP1 */
345-
if (enable && permanent) {
346-
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
347-
target_level = FLASH_STM32_RDP2;
348-
#else
349-
LOG_ERR("Permanent readout protection (RDP "
350-
"level 1 -> 2) not allowed");
351-
return -ENOTSUP;
352-
#endif
353-
}
354-
if (!enable) {
355-
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_DISABLE_ALLOW)
356-
target_level = FLASH_STM32_RDP0;
357-
#else
358-
LOG_ERR("Disabling readout protection (RDP "
359-
"level 1 -> 0) not allowed");
360-
return -EACCES;
361-
#endif
362-
}
363-
}
364-
365-
/* Update RDP level if needed */
366-
if (current_level != target_level) {
367-
LOG_INF("RDP changed from 0x%02x to 0x%02x", current_level,
368-
target_level);
369-
370-
write_optb(dev, FLASH_OPTR_RDP_Msk,
371-
(uint32_t)target_level << FLASH_OPTR_RDP_Pos);
372-
}
373-
return 0;
312+
return (regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos;
374313
}
375314

376-
int flash_stm32_get_rdp(const struct device *dev, bool *enabled,
377-
bool *permanent)
315+
void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level)
378316
{
379-
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
380-
uint8_t current_level;
381-
382-
current_level =
383-
(regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos;
384-
385-
/*
386-
* 0xAA = RDP level 0 (no protection)
387-
* 0xCC = RDP level 2 (permanent protection)
388-
* others = RDP level 1 (protection active)
389-
*/
390-
switch (current_level) {
391-
case FLASH_STM32_RDP2:
392-
*enabled = true;
393-
*permanent = true;
394-
break;
395-
case FLASH_STM32_RDP0:
396-
*enabled = false;
397-
*permanent = false;
398-
break;
399-
default: /* FLASH_STM32_RDP1 */
400-
*enabled = true;
401-
*permanent = false;
402-
}
403-
return 0;
317+
write_optb(dev, FLASH_OPTR_RDP_Msk,
318+
(uint32_t)level << FLASH_OPTR_RDP_Pos);
404319
}
405320
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */
406321

0 commit comments

Comments
 (0)