|
1 | 1 | /*
|
2 | 2 | * Copyright (c) 2016 Open-RnD Sp. z o.o.
|
3 | 3 | * Copyright (c) 2016 Linaro Limited.
|
| 4 | + * Copyright (c) 2024 STMicroelectronics |
4 | 5 | *
|
5 | 6 | * SPDX-License-Identifier: Apache-2.0
|
6 | 7 | */
|
|
39 | 40 | #include <stm32_ll_exti.h>
|
40 | 41 | #endif /* CONFIG_PM */
|
41 | 42 |
|
| 43 | +#ifdef CONFIG_DCACHE |
| 44 | +#include <zephyr/linker/linker-defs.h> |
| 45 | +#include <zephyr/mem_mgmt/mem_attr.h> |
| 46 | +#include <zephyr/dt-bindings/memory-attr/memory-attr-arm.h> |
| 47 | +#endif /* CONFIG_DCACHE */ |
| 48 | + |
42 | 49 | #include <zephyr/logging/log.h>
|
43 | 50 | #include <zephyr/irq.h>
|
44 | 51 | LOG_MODULE_REGISTER(uart_stm32, CONFIG_UART_LOG_LEVEL);
|
@@ -1301,6 +1308,32 @@ static void uart_stm32_isr(const struct device *dev)
|
1301 | 1308 |
|
1302 | 1309 | #ifdef CONFIG_UART_ASYNC_API
|
1303 | 1310 |
|
| 1311 | +#ifdef CONFIG_DCACHE |
| 1312 | +static bool buf_in_nocache(uintptr_t buf, size_t len_bytes) |
| 1313 | +{ |
| 1314 | + bool buf_within_nocache = false; |
| 1315 | + |
| 1316 | +#ifdef CONFIG_NOCACHE_MEMORY |
| 1317 | + buf_within_nocache = (buf >= ((uintptr_t)_nocache_ram_start)) && |
| 1318 | + ((buf + len_bytes - 1) <= ((uintptr_t)_nocache_ram_end)); |
| 1319 | + if (buf_within_nocache) { |
| 1320 | + return true; |
| 1321 | + } |
| 1322 | +#endif /* CONFIG_NOCACHE_MEMORY */ |
| 1323 | + |
| 1324 | + buf_within_nocache = mem_attr_check_buf( |
| 1325 | + (void *)buf, len_bytes, DT_MEM_ARM_MPU_RAM_NOCACHE) == 0; |
| 1326 | + if (buf_within_nocache) { |
| 1327 | + return true; |
| 1328 | + } |
| 1329 | + |
| 1330 | + buf_within_nocache = (buf >= ((uintptr_t)__rodata_region_start)) && |
| 1331 | + ((buf + len_bytes - 1) <= ((uintptr_t)__rodata_region_end)); |
| 1332 | + |
| 1333 | + return buf_within_nocache; |
| 1334 | +} |
| 1335 | +#endif /* CONFIG_DCACHE */ |
| 1336 | + |
1304 | 1337 | static int uart_stm32_async_callback_set(const struct device *dev,
|
1305 | 1338 | uart_callback_t callback,
|
1306 | 1339 | void *user_data)
|
@@ -1512,6 +1545,13 @@ static int uart_stm32_async_tx(const struct device *dev,
|
1512 | 1545 | return -EBUSY;
|
1513 | 1546 | }
|
1514 | 1547 |
|
| 1548 | +#ifdef CONFIG_DCACHE |
| 1549 | + if (!buf_in_nocache((uintptr_t)tx_data, buf_size)) { |
| 1550 | + LOG_ERR("Tx buffer should be placed in a nocache memory region"); |
| 1551 | + return -EFAULT; |
| 1552 | + } |
| 1553 | +#endif /* CONFIG_DCACHE */ |
| 1554 | + |
1515 | 1555 | data->dma_tx.buffer = (uint8_t *)tx_data;
|
1516 | 1556 | data->dma_tx.buffer_length = buf_size;
|
1517 | 1557 | data->dma_tx.timeout = timeout;
|
@@ -1572,6 +1612,13 @@ static int uart_stm32_async_rx_enable(const struct device *dev,
|
1572 | 1612 | return -EBUSY;
|
1573 | 1613 | }
|
1574 | 1614 |
|
| 1615 | +#ifdef CONFIG_DCACHE |
| 1616 | + if (!buf_in_nocache((uintptr_t)rx_buf, buf_size)) { |
| 1617 | + LOG_ERR("Rx buffer should be placed in a nocache memory region"); |
| 1618 | + return -EFAULT; |
| 1619 | + } |
| 1620 | +#endif /* CONFIG_DCACHE */ |
| 1621 | + |
1575 | 1622 | data->dma_rx.offset = 0;
|
1576 | 1623 | data->dma_rx.buffer = rx_buf;
|
1577 | 1624 | 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,
|
1696 | 1743 | } else if (!data->dma_rx.enabled) {
|
1697 | 1744 | err = -EACCES;
|
1698 | 1745 | } else {
|
| 1746 | +#ifdef CONFIG_DCACHE |
| 1747 | + if (!buf_in_nocache((uintptr_t)buf, len)) { |
| 1748 | + LOG_ERR("Rx buffer should be placed in a nocache memory region"); |
| 1749 | + return -EFAULT; |
| 1750 | + } |
| 1751 | +#endif /* CONFIG_DCACHE */ |
1699 | 1752 | data->rx_next_buffer = buf;
|
1700 | 1753 | data->rx_next_buffer_len = len;
|
1701 | 1754 | }
|
|
0 commit comments