From 77030503b6d1c6f36bf7d429c906ef64798acb3c Mon Sep 17 00:00:00 2001 From: Jason Yu Date: Sun, 16 Nov 2025 20:28:39 +0800 Subject: [PATCH] drivers: flash: soc_mcux: Fix ram function permission issue Add workaround for MCUXSDK FTFX driver when FTFx_DRIVER_IS_FLASH_RESIDENT is enabled. The SDK places the run command function in data section which is not executable when Zephyr configures memory permissions. Implement a RAM function to replace the FTFX driver's run command function Fixes: #98560 Signed-off-by: Jason Yu --- drivers/flash/soc_flash_mcux.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/flash/soc_flash_mcux.c b/drivers/flash/soc_flash_mcux.c index 052d377fc8ed4..2fe55be1ebfa4 100644 --- a/drivers/flash/soc_flash_mcux.c +++ b/drivers/flash/soc_flash_mcux.c @@ -155,6 +155,23 @@ static void clear_flash_caches(void) #define clear_flash_caches(...) #endif +#if defined(FTFx_DRIVER_IS_FLASH_RESIDENT) && FTFx_DRIVER_IS_FLASH_RESIDENT +/* + * MCUXSDK FTFX driver (fsl_ftfx_controller.c) places the run command function + * in data section (array s_ftfxRunCommand). When Zephyr configured the memory + * permission, the data section is not executable. The workaround is + * implementing a ram function in Zephyr, to replace FTFX driver's run command + * function. + */ +static __ramfunc void flash_ftfx_run_command(FTFx_REG8_ACCESS_TYPE ftfx_fstat) +{ + *ftfx_fstat = FTFx_FSTAT_CCIF_MASK; + + while (!((*ftfx_fstat) & FTFx_FSTAT_CCIF_MASK)) { + } +} +#endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */ + struct flash_priv { flash_config_t config; /* @@ -376,6 +393,15 @@ static int flash_mcux_init(const struct device *dev) rc = FLASH_Init(&priv->config); +#if defined(FTFx_DRIVER_IS_FLASH_RESIDENT) && FTFx_DRIVER_IS_FLASH_RESIDENT + /* MCUXSDK FTFX driver's commadAddr is an address to data (LSB = 0), but + * (uint32_t)flash_ftfx_run_command is an address to code (LDB = 1), so + * clear the LSB here. + */ + priv->config.ftfxConfig->runCmdFuncAddr.commadAddr = + ((uint32_t)flash_ftfx_run_command) & ~0x01U; +#endif /* FTFx_DRIVER_IS_FLASH_RESIDENT */ + FLASH_GetProperty(&priv->config, FLASH_PROP_BLOCK_BASE, &pflash_block_base); priv->pflash_block_base = (uint32_t) pflash_block_base;