|
17 | 17 | #include <zephyr/pm/policy.h> |
18 | 18 | #include <zephyr/logging/log.h> |
19 | 19 | #include <zephyr/irq.h> |
| 20 | +#include <zephyr/cache.h> |
20 | 21 | #include <soc.h> |
21 | 22 | #include <stm32_ll_rcc.h> |
22 | 23 |
|
@@ -561,13 +562,32 @@ static int stm32_sdmmc_access_read(struct disk_info *disk, uint8_t *data_buf, |
561 | 562 | } |
562 | 563 | #endif |
563 | 564 |
|
| 565 | +#if STM32_SDMMC_USE_DMA || IS_ENABLED(DT_PROP(DT_DRV_INST(0), idma)) |
| 566 | + /* A flush is performed before the DMA operation, to prevent accidental data |
| 567 | + * loss when the buffer is not properly aligned to the cache-line (e.g: |
| 568 | + * 32-bytes for STM32H7). |
| 569 | + */ |
| 570 | + sys_cache_data_flush_and_invd_range(data_buf, BLOCKSIZE * num_sector); |
| 571 | +#endif |
| 572 | + |
564 | 573 | err = stm32_sdmmc_read_blocks(&priv->hsd, data_buf, start_sector, num_sector); |
565 | 574 | if (err != 0) { |
566 | 575 | goto end; |
567 | 576 | } |
568 | 577 |
|
569 | 578 | k_sem_take(&priv->sync, K_FOREVER); |
570 | 579 |
|
| 580 | +#if STM32_SDMMC_USE_DMA || IS_ENABLED(DT_PROP(DT_DRV_INST(0), idma)) |
| 581 | + /* Invalidate again after the operation is complete, to protect against |
| 582 | + * speculative / spurious reads. Note that this is slightly unsafe when |
| 583 | + * `data_buf` is not aligned to the cache line, and shares the cache line |
| 584 | + * with other data... Hopefully the previous (otherwise unnecessary) flush & |
| 585 | + * invalidate reduces this risk enough. |
| 586 | + * This is a balance between forcing callers to have aligned buffers. |
| 587 | + */ |
| 588 | + sys_cache_data_invd_range(data_buf, BLOCKSIZE * num_sector); |
| 589 | +#endif |
| 590 | + |
571 | 591 | #if STM32_SDMMC_USE_DMA_SHARED |
572 | 592 | if (HAL_DMA_DeInit(&priv->dma_txrx_handle) != HAL_OK) { |
573 | 593 | err = -EIO; |
@@ -598,6 +618,8 @@ static int stm32_sdmmc_write_blocks(HandleTypeDef *hsd, |
598 | 618 |
|
599 | 619 | #if STM32_SDMMC_USE_DMA || IS_ENABLED(DT_PROP(DT_DRV_INST(0), idma)) |
600 | 620 |
|
| 621 | + sys_cache_data_flush_range(data_buf, BLOCKSIZE * num_sector); |
| 622 | + |
601 | 623 | #ifdef CONFIG_SDMMC_STM32_EMMC |
602 | 624 | hal_ret = HAL_MMC_WriteBlocks_DMA(hsd, data_buf, start_sector, num_sector); |
603 | 625 | #else |
|
0 commit comments