d652da5acb
This patch adds flash readout protection support for STM32F4 devices family. These devices can enable protection on entire flash content. Readout protection functionality was exposed as vendor extended operation. To change readout protection state, caller should provide a structure which describes desired RDP state. Enabling readout protection permanently or disabling readout protection (changing from level 1 to level 0) is guarded by CONFIG_FLASH_STM32_READOUT_PROTECTION_PERMANENT_ALLOW and CONFIG_FLASH_STM32_READOUT_PROTECTION_DISABLE_ALLOW respectively. Signed-off-by: Patryk Duda <pdk@semihalf.com>
143 lines
3 KiB
C
143 lines
3 KiB
C
/*
|
|
* Copyright (c) 2023 Google Inc
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <zephyr/device.h>
|
|
#include <zephyr/drivers/flash/stm32_flash_api_extensions.h>
|
|
#include <zephyr/kernel.h>
|
|
|
|
#ifdef CONFIG_USERSPACE
|
|
#include <zephyr/syscall.h>
|
|
#include <zephyr/syscall_handler.h>
|
|
#endif
|
|
|
|
#include <soc.h>
|
|
#include "flash_stm32.h"
|
|
|
|
#if defined(CONFIG_FLASH_STM32_WRITE_PROTECT)
|
|
int flash_stm32_ex_op_sector_wp(const struct device *dev, const uintptr_t in,
|
|
void *out)
|
|
{
|
|
const struct flash_stm32_ex_op_sector_wp_in *request =
|
|
(const struct flash_stm32_ex_op_sector_wp_in *)in;
|
|
struct flash_stm32_ex_op_sector_wp_out *result =
|
|
(struct flash_stm32_ex_op_sector_wp_out *)out;
|
|
uint32_t change_mask;
|
|
int rc = 0, rc2 = 0;
|
|
#ifdef CONFIG_USERSPACE
|
|
bool syscall_trap = z_syscall_trap();
|
|
#endif
|
|
|
|
if (request != NULL) {
|
|
#ifdef CONFIG_USERSPACE
|
|
struct flash_stm32_ex_op_sector_wp_in in_copy;
|
|
|
|
if (syscall_trap) {
|
|
Z_OOPS(z_user_from_copy(&in_copy, request,
|
|
sizeof(in_copy)));
|
|
request = &in_copy;
|
|
}
|
|
#endif
|
|
change_mask = request->enable_mask;
|
|
|
|
if (!IS_ENABLED(
|
|
CONFIG_FLASH_STM32_WRITE_PROTECT_DISABLE_PREVENTION)) {
|
|
change_mask |= request->disable_mask;
|
|
}
|
|
|
|
rc = flash_stm32_option_bytes_lock(dev, false);
|
|
if (rc == 0) {
|
|
rc = flash_stm32_update_wp_sectors(
|
|
dev, change_mask, request->enable_mask);
|
|
}
|
|
|
|
rc2 = flash_stm32_option_bytes_lock(dev, true);
|
|
if (!rc) {
|
|
rc = rc2;
|
|
}
|
|
}
|
|
|
|
if (result != NULL) {
|
|
#ifdef CONFIG_USERSPACE
|
|
struct flash_stm32_ex_op_sector_wp_out out_copy;
|
|
|
|
if (syscall_trap) {
|
|
result = &out_copy;
|
|
}
|
|
#endif
|
|
rc2 = flash_stm32_get_wp_sectors(dev, &result->protected_mask);
|
|
if (!rc) {
|
|
rc = rc2;
|
|
}
|
|
|
|
#ifdef CONFIG_USERSPACE
|
|
if (syscall_trap) {
|
|
Z_OOPS(z_user_to_copy(out, result, sizeof(out_copy)));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
#endif /* CONFIG_FLASH_STM32_WRITE_PROTECT */
|
|
|
|
#if defined(CONFIG_FLASH_STM32_READOUT_PROTECTION)
|
|
int flash_stm32_ex_op_rdp(const struct device *dev, const uintptr_t in,
|
|
void *out)
|
|
{
|
|
const struct flash_stm32_ex_op_rdp *request =
|
|
(const struct flash_stm32_ex_op_rdp *)in;
|
|
struct flash_stm32_ex_op_rdp *result =
|
|
(struct flash_stm32_ex_op_rdp *)out;
|
|
|
|
#ifdef CONFIG_USERSPACE
|
|
struct flash_stm32_ex_op_rdp copy;
|
|
bool syscall_trap = z_syscall_trap();
|
|
#endif
|
|
int rc = 0, rc2 = 0;
|
|
|
|
if (request != NULL) {
|
|
#ifdef CONFIG_USERSPACE
|
|
if (syscall_trap) {
|
|
Z_OOPS(z_user_from_copy(©, request, sizeof(copy)));
|
|
request = ©
|
|
}
|
|
#endif
|
|
rc = flash_stm32_option_bytes_lock(dev, false);
|
|
if (rc == 0) {
|
|
rc = flash_stm32_update_rdp(dev, request->enable,
|
|
request->permanent);
|
|
}
|
|
|
|
rc2 = flash_stm32_option_bytes_lock(dev, true);
|
|
if (!rc) {
|
|
rc = rc2;
|
|
}
|
|
}
|
|
|
|
if (result != NULL) {
|
|
#ifdef CONFIG_USERSPACE
|
|
if (syscall_trap) {
|
|
result = ©
|
|
}
|
|
#endif
|
|
rc2 = flash_stm32_get_rdp(dev, &result->enable,
|
|
&result->permanent);
|
|
if (!rc) {
|
|
rc = rc2;
|
|
}
|
|
|
|
#ifdef CONFIG_USERSPACE
|
|
if (syscall_trap) {
|
|
Z_OOPS(z_user_to_copy(out, result, sizeof(copy)));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
#endif /* CONFIG_FLASH_STM32_READOUT_PROTECTION */
|