diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c index e79ba3bf0f3..f5a831f0d2b 100644 --- a/drivers/serial/uart_stm32.c +++ b/drivers/serial/uart_stm32.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2016 Open-RnD Sp. z o.o. * Copyright (c) 2016 Linaro Limited. + * Copyright (c) 2024 STMicroelectronics * * SPDX-License-Identifier: Apache-2.0 */ @@ -39,6 +40,12 @@ #include #endif /* CONFIG_PM */ +#ifdef CONFIG_DCACHE +#include +#include +#include +#endif /* CONFIG_DCACHE */ + #include #include LOG_MODULE_REGISTER(uart_stm32, CONFIG_UART_LOG_LEVEL); @@ -1301,6 +1308,32 @@ static void uart_stm32_isr(const struct device *dev) #ifdef CONFIG_UART_ASYNC_API +#ifdef CONFIG_DCACHE +static bool buf_in_nocache(uintptr_t buf, size_t len_bytes) +{ + bool buf_within_nocache = false; + +#ifdef CONFIG_NOCACHE_MEMORY + buf_within_nocache = (buf >= ((uintptr_t)_nocache_ram_start)) && + ((buf + len_bytes - 1) <= ((uintptr_t)_nocache_ram_end)); + if (buf_within_nocache) { + return true; + } +#endif /* CONFIG_NOCACHE_MEMORY */ + + buf_within_nocache = mem_attr_check_buf( + (void *)buf, len_bytes, DT_MEM_ARM_MPU_RAM_NOCACHE) == 0; + if (buf_within_nocache) { + return true; + } + + buf_within_nocache = (buf >= ((uintptr_t)__rodata_region_start)) && + ((buf + len_bytes - 1) <= ((uintptr_t)__rodata_region_end)); + + return buf_within_nocache; +} +#endif /* CONFIG_DCACHE */ + static int uart_stm32_async_callback_set(const struct device *dev, uart_callback_t callback, void *user_data) @@ -1512,6 +1545,13 @@ static int uart_stm32_async_tx(const struct device *dev, return -EBUSY; } +#ifdef CONFIG_DCACHE + if (!buf_in_nocache((uintptr_t)tx_data, buf_size)) { + LOG_ERR("Tx buffer should be placed in a nocache memory region"); + return -EFAULT; + } +#endif /* CONFIG_DCACHE */ + data->dma_tx.buffer = (uint8_t *)tx_data; data->dma_tx.buffer_length = buf_size; data->dma_tx.timeout = timeout; @@ -1572,6 +1612,13 @@ static int uart_stm32_async_rx_enable(const struct device *dev, return -EBUSY; } +#ifdef CONFIG_DCACHE + if (!buf_in_nocache((uintptr_t)rx_buf, buf_size)) { + LOG_ERR("Rx buffer should be placed in a nocache memory region"); + return -EFAULT; + } +#endif /* CONFIG_DCACHE */ + data->dma_rx.offset = 0; data->dma_rx.buffer = rx_buf; data->dma_rx.buffer_length = buf_size; @@ -1696,6 +1743,12 @@ static int uart_stm32_async_rx_buf_rsp(const struct device *dev, uint8_t *buf, } else if (!data->dma_rx.enabled) { err = -EACCES; } else { +#ifdef CONFIG_DCACHE + if (!buf_in_nocache((uintptr_t)buf, len)) { + LOG_ERR("Rx buffer should be placed in a nocache memory region"); + return -EFAULT; + } +#endif /* CONFIG_DCACHE */ data->rx_next_buffer = buf; data->rx_next_buffer_len = len; }