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 <benedikt.schmidt@embedded-solutions.at>
This commit is contained in:
parent
2f088fabc2
commit
db2261b6f5
5 changed files with 107 additions and 282 deletions
|
|
@ -311,12 +311,9 @@ int flash_stm32_get_wp_sectors(const struct device *dev,
|
|||
uint32_t *protected_sectors);
|
||||
#endif
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION)
|
||||
uint8_t flash_stm32_get_rdp_level(const struct device *dev);
|
||||
|
||||
int flash_stm32_update_rdp(const struct device *dev, bool enable,
|
||||
bool permanent);
|
||||
|
||||
int flash_stm32_get_rdp(const struct device *dev, bool *enabled,
|
||||
bool *permanent);
|
||||
void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level);
|
||||
#endif
|
||||
|
||||
/* Flash extended operations */
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/flash/stm32_flash_api_extensions.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
#include <zephyr/syscall.h>
|
||||
|
|
@ -17,6 +18,8 @@
|
|||
#include <soc.h>
|
||||
#include "flash_stm32.h"
|
||||
|
||||
LOG_MODULE_REGISTER(flash_stm32_ex_op, CONFIG_FLASH_LOG_LEVEL);
|
||||
|
||||
#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT)
|
||||
int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in,
|
||||
void *out)
|
||||
|
|
@ -85,6 +88,71 @@ int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in,
|
|||
#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */
|
||||
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION)
|
||||
int flash_stm32_ex_op_update_rdp(const struct device *dev, bool enable,
|
||||
bool permanent)
|
||||
{
|
||||
uint8_t current_level, target_level;
|
||||
|
||||
current_level = flash_stm32_get_rdp_level(dev);
|
||||
target_level = current_level;
|
||||
|
||||
/*
|
||||
* 0xAA = RDP level 0 (no protection)
|
||||
* 0xCC = RDP level 2 (permanent protection)
|
||||
* others = RDP level 1 (protection active)
|
||||
*/
|
||||
switch (current_level) {
|
||||
case FLASH_STM32_RDP2:
|
||||
if (!enable || !permanent) {
|
||||
LOG_DBG("RDP level 2 is permanent and can't be changed!");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
break;
|
||||
case FLASH_STM32_RDP0:
|
||||
if (enable) {
|
||||
target_level = FLASH_STM32_RDP1;
|
||||
if (permanent) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
|
||||
target_level = FLASH_STM32_RDP2;
|
||||
#else
|
||||
LOG_DBG("Permanent readout protection (RDP "
|
||||
"level 0 -> 2) not allowed");
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: /* FLASH_STM32_RDP1 */
|
||||
if (enable && permanent) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
|
||||
target_level = FLASH_STM32_RDP2;
|
||||
#else
|
||||
LOG_DBG("Permanent readout protection (RDP "
|
||||
"level 1 -> 2) not allowed");
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
if (!enable) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_DISABLE_ALLOW)
|
||||
target_level = FLASH_STM32_RDP0;
|
||||
#else
|
||||
LOG_DBG("Disabling readout protection (RDP "
|
||||
"level 1 -> 0) not allowed");
|
||||
return -EACCES;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Update RDP level if needed */
|
||||
if (current_level != target_level) {
|
||||
LOG_INF("RDP changed from 0x%02x to 0x%02x", current_level,
|
||||
target_level);
|
||||
|
||||
flash_stm32_set_rdp_level(dev, target_level);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in,
|
||||
void *out)
|
||||
{
|
||||
|
|
@ -92,6 +160,7 @@ int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in,
|
|||
(const struct flash_stm32_ex_op_rdp *)in;
|
||||
struct flash_stm32_ex_op_rdp *result =
|
||||
(struct flash_stm32_ex_op_rdp *)out;
|
||||
uint8_t current_level;
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
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,
|
|||
#endif
|
||||
rc = flash_stm32_option_bytes_lock(dev, false);
|
||||
if (rc == 0) {
|
||||
rc = flash_stm32_update_rdp(dev, request->enable,
|
||||
rc = flash_stm32_ex_op_update_rdp(dev, request->enable,
|
||||
request->permanent);
|
||||
}
|
||||
|
||||
|
|
@ -124,10 +193,26 @@ int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in,
|
|||
result = ©
|
||||
}
|
||||
#endif
|
||||
rc2 = flash_stm32_get_rdp(dev, &result->enable,
|
||||
&result->permanent);
|
||||
if (!rc) {
|
||||
rc = rc2;
|
||||
|
||||
current_level = flash_stm32_get_rdp_level(dev);
|
||||
|
||||
/*
|
||||
* 0xAA = RDP level 0 (no protection)
|
||||
* 0xCC = RDP level 2 (permanent protection)
|
||||
* others = RDP level 1 (protection active)
|
||||
*/
|
||||
switch (current_level) {
|
||||
case FLASH_STM32_RDP2:
|
||||
result->enable = true;
|
||||
result->permanent = true;
|
||||
break;
|
||||
case FLASH_STM32_RDP0:
|
||||
result->enable = false;
|
||||
result->permanent = false;
|
||||
break;
|
||||
default: /* FLASH_STM32_RDP1 */
|
||||
result->enable = true;
|
||||
result->permanent = false;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
|
|
|
|||
|
|
@ -295,102 +295,17 @@ int flash_stm32_get_wp_sectors(const struct device *dev,
|
|||
#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */
|
||||
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION)
|
||||
int flash_stm32_update_rdp(const struct device *dev, bool enable,
|
||||
bool permanent)
|
||||
uint8_t flash_stm32_get_rdp_level(const struct device *dev)
|
||||
{
|
||||
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
|
||||
uint8_t current_level, target_level;
|
||||
|
||||
current_level =
|
||||
(regs->OPTCR & FLASH_OPTCR_RDP_Msk) >> FLASH_OPTCR_RDP_Pos;
|
||||
target_level = current_level;
|
||||
|
||||
/*
|
||||
* 0xAA = RDP level 0 (no protection)
|
||||
* 0xCC = RDP level 2 (permanent protection)
|
||||
* others = RDP level 1 (protection active)
|
||||
*/
|
||||
switch (current_level) {
|
||||
case FLASH_STM32_RDP2:
|
||||
if (!enable || !permanent) {
|
||||
LOG_ERR("RDP level 2 is permanent and can't be changed!");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
break;
|
||||
case FLASH_STM32_RDP0:
|
||||
if (enable) {
|
||||
target_level = FLASH_STM32_RDP1;
|
||||
if (permanent) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
|
||||
target_level = FLASH_STM32_RDP2;
|
||||
#else
|
||||
LOG_ERR("Permanent readout protection (RDP "
|
||||
"level 0 -> 2) not allowed");
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: /* FLASH_STM32_RDP1 */
|
||||
if (enable && permanent) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
|
||||
target_level = FLASH_STM32_RDP2;
|
||||
#else
|
||||
LOG_ERR("Permanent readout protection (RDP "
|
||||
"level 1 -> 2) not allowed");
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
if (!enable) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_DISABLE_ALLOW)
|
||||
target_level = FLASH_STM32_RDP0;
|
||||
#else
|
||||
LOG_ERR("Disabling readout protection (RDP "
|
||||
"level 1 -> 0) not allowed");
|
||||
return -EACCES;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Update RDP level if needed */
|
||||
if (current_level != target_level) {
|
||||
LOG_INF("RDP changed from 0x%02x to 0x%02x", current_level,
|
||||
target_level);
|
||||
|
||||
write_optb(dev, FLASH_OPTCR_RDP_Msk,
|
||||
(uint32_t)target_level << FLASH_OPTCR_RDP_Pos);
|
||||
}
|
||||
return 0;
|
||||
return (regs->OPTCR & FLASH_OPTCR_RDP_Msk) >> FLASH_OPTCR_RDP_Pos;
|
||||
}
|
||||
|
||||
int flash_stm32_get_rdp(const struct device *dev, bool *enabled,
|
||||
bool *permanent)
|
||||
void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level)
|
||||
{
|
||||
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
|
||||
uint8_t current_level;
|
||||
|
||||
current_level =
|
||||
(regs->OPTCR & FLASH_OPTCR_RDP_Msk) >> FLASH_OPTCR_RDP_Pos;
|
||||
|
||||
/*
|
||||
* 0xAA = RDP level 0 (no protection)
|
||||
* 0xCC = RDP level 2 (permanent protection)
|
||||
* others = RDP level 1 (protection active)
|
||||
*/
|
||||
switch (current_level) {
|
||||
case FLASH_STM32_RDP2:
|
||||
*enabled = true;
|
||||
*permanent = true;
|
||||
break;
|
||||
case FLASH_STM32_RDP0:
|
||||
*enabled = false;
|
||||
*permanent = false;
|
||||
break;
|
||||
default: /* FLASH_STM32_RDP1 */
|
||||
*enabled = true;
|
||||
*permanent = false;
|
||||
}
|
||||
return 0;
|
||||
write_optb(dev, FLASH_OPTCR_RDP_Msk,
|
||||
(uint32_t)level << FLASH_OPTCR_RDP_Pos);
|
||||
}
|
||||
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */
|
||||
|
||||
|
|
|
|||
|
|
@ -305,102 +305,17 @@ static __unused int write_optb(const struct device *dev, uint32_t mask,
|
|||
#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */
|
||||
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION)
|
||||
int flash_stm32_update_rdp(const struct device *dev, bool enable,
|
||||
bool permanent)
|
||||
uint8_t flash_stm32_get_rdp_level(const struct device *dev)
|
||||
{
|
||||
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
|
||||
uint8_t current_level, target_level;
|
||||
|
||||
current_level =
|
||||
(regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos;
|
||||
target_level = current_level;
|
||||
|
||||
/*
|
||||
* 0xAA = RDP level 0 (no protection)
|
||||
* 0xCC = RDP level 2 (permanent protection)
|
||||
* others = RDP level 1 (protection active)
|
||||
*/
|
||||
switch (current_level) {
|
||||
case FLASH_STM32_RDP2:
|
||||
if (!enable || !permanent) {
|
||||
LOG_ERR("RDP level 2 is permanent and can't be changed!");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
break;
|
||||
case FLASH_STM32_RDP0:
|
||||
if (enable) {
|
||||
target_level = FLASH_STM32_RDP1;
|
||||
if (permanent) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
|
||||
target_level = FLASH_STM32_RDP2;
|
||||
#else
|
||||
LOG_ERR("Permanent readout protection (RDP "
|
||||
"level 0 -> 2) not allowed");
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: /* FLASH_STM32_RDP1 */
|
||||
if (enable && permanent) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
|
||||
target_level = FLASH_STM32_RDP2;
|
||||
#else
|
||||
LOG_ERR("Permanent readout protection (RDP "
|
||||
"level 1 -> 2) not allowed");
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
if (!enable) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_DISABLE_ALLOW)
|
||||
target_level = FLASH_STM32_RDP0;
|
||||
#else
|
||||
LOG_ERR("Disabling readout protection (RDP "
|
||||
"level 1 -> 0) not allowed");
|
||||
return -EACCES;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Update RDP level if needed */
|
||||
if (current_level != target_level) {
|
||||
LOG_INF("RDP changed from 0x%02x to 0x%02x", current_level,
|
||||
target_level);
|
||||
|
||||
write_optb(dev, FLASH_OPTR_RDP_Msk,
|
||||
(uint32_t)target_level << FLASH_OPTR_RDP_Pos);
|
||||
}
|
||||
return 0;
|
||||
return (regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos;
|
||||
}
|
||||
|
||||
int flash_stm32_get_rdp(const struct device *dev, bool *enabled,
|
||||
bool *permanent)
|
||||
void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level)
|
||||
{
|
||||
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
|
||||
uint8_t current_level;
|
||||
|
||||
current_level =
|
||||
(regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos;
|
||||
|
||||
/*
|
||||
* 0xAA = RDP level 0 (no protection)
|
||||
* 0xCC = RDP level 2 (permanent protection)
|
||||
* others = RDP level 1 (protection active)
|
||||
*/
|
||||
switch (current_level) {
|
||||
case FLASH_STM32_RDP2:
|
||||
*enabled = true;
|
||||
*permanent = true;
|
||||
break;
|
||||
case FLASH_STM32_RDP0:
|
||||
*enabled = false;
|
||||
*permanent = false;
|
||||
break;
|
||||
default: /* FLASH_STM32_RDP1 */
|
||||
*enabled = true;
|
||||
*permanent = false;
|
||||
}
|
||||
return 0;
|
||||
write_optb(dev, FLASH_OPTR_RDP_Msk,
|
||||
(uint32_t)level << FLASH_OPTR_RDP_Pos);
|
||||
}
|
||||
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */
|
||||
|
||||
|
|
|
|||
|
|
@ -295,107 +295,20 @@ static __unused int write_optb(const struct device *dev, uint32_t mask,
|
|||
#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */
|
||||
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION)
|
||||
int flash_stm32_update_rdp(const struct device *dev, bool enable,
|
||||
bool permanent)
|
||||
uint8_t flash_stm32_get_rdp_level(const struct device *dev)
|
||||
{
|
||||
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
|
||||
uint8_t current_level, target_level;
|
||||
|
||||
current_level =
|
||||
(regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos;
|
||||
target_level = current_level;
|
||||
|
||||
/*
|
||||
* 0xAA = RDP level 0 (no protection)
|
||||
* 0xCC = RDP level 2 (permanent protection)
|
||||
* others = RDP level 1 (protection active)
|
||||
*/
|
||||
switch (current_level) {
|
||||
case FLASH_STM32_RDP2:
|
||||
if (!enable || !permanent) {
|
||||
LOG_ERR("RDP level 2 is permanent and can't be changed!");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
break;
|
||||
case FLASH_STM32_RDP0:
|
||||
if (enable) {
|
||||
target_level = FLASH_STM32_RDP1;
|
||||
if (permanent) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
|
||||
target_level = FLASH_STM32_RDP2;
|
||||
#else
|
||||
LOG_ERR("Permanent readout protection (RDP "
|
||||
"level 0 -> 2) not allowed");
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: /* FLASH_STM32_RDP1 */
|
||||
if (enable && permanent) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW)
|
||||
target_level = FLASH_STM32_RDP2;
|
||||
#else
|
||||
LOG_ERR("Permanent readout protection (RDP "
|
||||
"level 1 -> 2) not allowed");
|
||||
return -ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
if (!enable) {
|
||||
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION_DISABLE_ALLOW)
|
||||
target_level = FLASH_STM32_RDP0;
|
||||
#else
|
||||
LOG_ERR("Disabling readout protection (RDP "
|
||||
"level 1 -> 0) not allowed");
|
||||
return -EACCES;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Update RDP level if needed */
|
||||
if (current_level != target_level) {
|
||||
LOG_INF("RDP changed from 0x%02x to 0x%02x", current_level,
|
||||
target_level);
|
||||
|
||||
write_optb(dev, FLASH_OPTR_RDP_Msk,
|
||||
(uint32_t)target_level << FLASH_OPTR_RDP_Pos);
|
||||
}
|
||||
return 0;
|
||||
return (regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos;
|
||||
}
|
||||
|
||||
int flash_stm32_get_rdp(const struct device *dev, bool *enabled,
|
||||
bool *permanent)
|
||||
void flash_stm32_set_rdp_level(const struct device *dev, uint8_t level)
|
||||
{
|
||||
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
|
||||
uint8_t current_level;
|
||||
|
||||
current_level =
|
||||
(regs->OPTR & FLASH_OPTR_RDP_Msk) >> FLASH_OPTR_RDP_Pos;
|
||||
|
||||
/*
|
||||
* 0xAA = RDP level 0 (no protection)
|
||||
* 0xCC = RDP level 2 (permanent protection)
|
||||
* others = RDP level 1 (protection active)
|
||||
*/
|
||||
switch (current_level) {
|
||||
case FLASH_STM32_RDP2:
|
||||
*enabled = true;
|
||||
*permanent = true;
|
||||
break;
|
||||
case FLASH_STM32_RDP0:
|
||||
*enabled = false;
|
||||
*permanent = false;
|
||||
break;
|
||||
default: /* FLASH_STM32_RDP1 */
|
||||
*enabled = true;
|
||||
*permanent = false;
|
||||
}
|
||||
return 0;
|
||||
write_optb(dev, FLASH_OPTR_RDP_Msk,
|
||||
(uint32_t)level << FLASH_OPTR_RDP_Pos);
|
||||
}
|
||||
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */
|
||||
|
||||
|
||||
|
||||
void flash_stm32_page_layout(const struct device *dev,
|
||||
const struct flash_pages_layout **layout,
|
||||
size_t *layout_size)
|
||||
|
|
|
|||
Loading…
Reference in a new issue