/* * Copyright (c) 2023 Google Inc * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #ifdef CONFIG_USERSPACE #include #include #endif #include #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 */