From 4f52afeb25783997c6abc0a522cabc9210aa129a Mon Sep 17 00:00:00 2001 From: Chen Jichang Date: Thu, 8 Jan 2026 16:13:01 +0800 Subject: [PATCH] fix(gdma): fix dma burst size when flash enc enabled --- components/esp_hw_support/dma/gdma.c | 37 ++++++++----------- .../test_apps/dma/main/test_gdma.c | 2 +- .../test_apps/dma/main/test_gdma_crc.c | 4 +- components/esp_mm/heap_align_hw.c | 2 +- .../hal/esp32p4/include/hal/axi_dma_ll.h | 8 +++- components/hal/gdma_hal_axi.c | 12 +----- components/hal/gdma_hal_top.c | 9 +---- components/hal/include/hal/gdma_hal.h | 3 -- 8 files changed, 29 insertions(+), 48 deletions(-) diff --git a/components/esp_hw_support/dma/gdma.c b/components/esp_hw_support/dma/gdma.c index 4ee4f2843d..23c6f12b47 100644 --- a/components/esp_hw_support/dma/gdma.c +++ b/components/esp_hw_support/dma/gdma.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -382,6 +382,21 @@ esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transf // always enable descriptor burst as the descriptor is always word aligned and is in the internal SRAM bool en_desc_burst = true; bool en_data_burst = max_data_burst_size > 0; + +#if SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH + // if MSPI encryption is enabled, and DMA wants to read/write external memory + if (efuse_hal_flash_encryption_enabled() && config->access_ext_mem) { + uint32_t enc_mem_alignment = GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT; + // when DMA access the encrypted external memory, extra alignment is needed for external memory + ext_mem_alignment = MAX(ext_mem_alignment, enc_mem_alignment); + if (max_data_burst_size < enc_mem_alignment) { + ESP_LOGW(TAG, "GDMA channel access encrypted external memory, adjust burst size to %d", enc_mem_alignment); + en_data_burst = true; + max_data_burst_size = enc_mem_alignment; + } + } +#endif // SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH + gdma_hal_enable_burst(hal, pair->pair_id, dma_chan->direction, en_data_burst, en_desc_burst); if (en_data_burst) { gdma_hal_set_burst_size(hal, pair->pair_id, dma_chan->direction, max_data_burst_size); @@ -394,26 +409,6 @@ esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transf } #endif - // if MSPI encryption is enabled, and DMA wants to read/write external memory - if (efuse_hal_flash_encryption_enabled()) { - gdma_hal_enable_access_encrypt_mem(hal, pair->pair_id, dma_chan->direction, config->access_ext_mem); -#if SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH - uint32_t enc_mem_alignment = GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT); - // when DMA access the encrypted external memory, extra alignment is needed for external memory - if (config->access_ext_mem) { - ext_mem_alignment = MAX(ext_mem_alignment, enc_mem_alignment); - } -#if SOC_HAS(AXI_GDMA) - if (group->bus_id == SOC_GDMA_BUS_AXI) { - // once AXI-GDMA enables access to encrypted memory, internal memory also needs to align - int_mem_alignment = MAX(int_mem_alignment, enc_mem_alignment); - } -#endif // SOC_HAS(AXI_GDMA) -#endif // SOC_PSRAM_DMA_CAPABLE - } else { - gdma_hal_enable_access_encrypt_mem(hal, pair->pair_id, dma_chan->direction, false); - } - // if the channel is not allowed to access external memory, set a super big (meaningless) alignment value // so when the upper layer checks the alignment with an external buffer, the check should fail if (!config->access_ext_mem) { diff --git a/components/esp_hw_support/test_apps/dma/main/test_gdma.c b/components/esp_hw_support/test_apps/dma/main/test_gdma.c index 4092c67abd..d9e0bc5065 100644 --- a/components/esp_hw_support/test_apps/dma/main/test_gdma.c +++ b/components/esp_hw_support/test_apps/dma/main/test_gdma.c @@ -272,7 +272,7 @@ static void test_gdma_m2m_transaction(gdma_channel_handle_t tx_chan, gdma_channe } // test DMA can read data from main flash #if SOC_DMA_CAN_ACCESS_FLASH - static const char src_string[] __attribute__((aligned(GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT)))) = "GDMA can read MSPI Flash data!!!"; + static const char src_string[] __attribute__((aligned(GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT))) = "GDMA can read MSPI Flash data!!!"; size_t src_string_len = strlen(src_string); TEST_ASSERT_TRUE(esp_ptr_in_drom(src_string)); diff --git a/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c b/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c index ad8a11b16f..b54d81a20d 100644 --- a/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c +++ b/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c @@ -70,10 +70,10 @@ static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_nu uint32_t crc_result = 0; - static const char test_input_string[] __attribute__((aligned(GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT)))) = "GDMACRC Share::Connect::Innovate"; + static const char test_input_string[] __attribute__((aligned(GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT))) = "GDMACRC Share::Connect::Innovate"; size_t input_data_size = strlen(test_input_string); - TEST_ASSERT_EQUAL((uintptr_t)test_input_string % GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT), 0); + TEST_ASSERT_EQUAL((uintptr_t)test_input_string % GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT, 0); // this test case also test the GDMA can fetch data from MSPI Flash TEST_ASSERT_TRUE(esp_ptr_in_drom(test_input_string)); printf("Calculate CRC value for string: \"%s\"\r\n", test_input_string); diff --git a/components/esp_mm/heap_align_hw.c b/components/esp_mm/heap_align_hw.c index af609e32c9..344b27b882 100644 --- a/components/esp_mm/heap_align_hw.c +++ b/components/esp_mm/heap_align_hw.c @@ -84,7 +84,7 @@ HEAP_IRAM_ATTR void esp_heap_adjust_alignment_to_hw(size_t *p_alignment, size_t #if SOC_GDMA_SUPPORTED && (SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH) if ((caps & MALLOC_CAP_DMA) && efuse_hal_flash_encryption_enabled()) { - alignment = (alignment > GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT)) ? alignment : GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT); + alignment = (alignment > GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT) ? alignment : GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT; } #endif diff --git a/components/hal/esp32p4/include/hal/axi_dma_ll.h b/components/hal/esp32p4/include/hal/axi_dma_ll.h index a6c5a2dae1..5bd6eb601a 100644 --- a/components/hal/esp32p4/include/hal/axi_dma_ll.h +++ b/components/hal/esp32p4/include/hal/axi_dma_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -294,6 +294,9 @@ static inline void axi_dma_ll_rx_enable_etm_task(axi_dma_dev_t *dev, uint32_t ch /** * @brief Whether to enable access to ecc or aes memory + * + * @note This function is not used for AXI-GDMA because it will affect the alignment requirement for internal memory. + * We have ensured that the AXI-GDMA can access the encrypted memory by 16-bytes alignment in software. */ static inline void axi_dma_ll_rx_enable_ext_mem_ecc_aes_access(axi_dma_dev_t *dev, uint32_t channel, bool enable) { @@ -528,6 +531,9 @@ static inline void axi_dma_ll_tx_enable_etm_task(axi_dma_dev_t *dev, uint32_t ch /** * @brief Whether to enable access to ecc or aes memory + * + * @note This function is not used for AXI-GDMA because it will affect the alignment requirement for internal memory. + * We have ensured that the AXI-GDMA can access the encrypted memory by 16-bytes alignment in software. */ static inline void axi_dma_ll_tx_enable_ext_mem_ecc_aes_access(axi_dma_dev_t *dev, uint32_t channel, bool enable) { diff --git a/components/hal/gdma_hal_axi.c b/components/hal/gdma_hal_axi.c index e01e87d647..9e2da3ac9f 100644 --- a/components/hal/gdma_hal_axi.c +++ b/components/hal/gdma_hal_axi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -163,15 +163,6 @@ uint32_t gdma_axi_hal_get_eof_desc_addr(gdma_hal_context_t *hal, int chan_id, gd } } -void gdma_axi_hal_enable_access_encrypt_mem(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis) -{ - if (dir == GDMA_CHANNEL_DIRECTION_RX) { - axi_dma_ll_rx_enable_ext_mem_ecc_aes_access(hal->axi_dma_dev, chan_id, en_or_dis); - } else { - axi_dma_ll_tx_enable_ext_mem_ecc_aes_access(hal->axi_dma_dev, chan_id, en_or_dis); - } -} - #if SOC_GDMA_SUPPORT_CRC void gdma_axi_hal_clear_crc(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir) { @@ -258,7 +249,6 @@ void gdma_axi_hal_init(gdma_hal_context_t *hal, const gdma_hal_config_t *config) hal->get_intr_status_reg = gdma_axi_hal_get_intr_status_reg; hal->get_eof_desc_addr = gdma_axi_hal_get_eof_desc_addr; hal->set_burst_size = gdma_axi_hal_set_burst_size; - hal->enable_access_encrypt_mem = gdma_axi_hal_enable_access_encrypt_mem; #if SOC_GDMA_SUPPORT_CRC hal->clear_crc = gdma_axi_hal_clear_crc; hal->set_crc_poly = gdma_axi_hal_set_crc_poly; diff --git a/components/hal/gdma_hal_top.c b/components/hal/gdma_hal_top.c index d41eb342cb..fce58d443c 100644 --- a/components/hal/gdma_hal_top.c +++ b/components/hal/gdma_hal_top.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -90,13 +90,6 @@ uint32_t gdma_hal_get_eof_desc_addr(gdma_hal_context_t *hal, int chan_id, gdma_c return hal->get_eof_desc_addr(hal, chan_id, dir, is_success); } -void gdma_hal_enable_access_encrypt_mem(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis) -{ - if (hal->enable_access_encrypt_mem) { - hal->enable_access_encrypt_mem(hal, chan_id, dir, en_or_dis); - } -} - #if SOC_GDMA_SUPPORT_CRC void gdma_hal_clear_crc(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir) { diff --git a/components/hal/include/hal/gdma_hal.h b/components/hal/include/hal/gdma_hal.h index 3231cc583e..a9af957a12 100644 --- a/components/hal/include/hal/gdma_hal.h +++ b/components/hal/include/hal/gdma_hal.h @@ -87,7 +87,6 @@ struct gdma_hal_context_t { void (*clear_intr)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, uint32_t intr_event_mask); /// Clear the channel interrupt uint32_t (*read_intr_status)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool raw); /// Read the channel interrupt status uint32_t (*get_eof_desc_addr)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool is_success); /// Get the address of the descriptor with success/error EOF flag set - void (*enable_access_encrypt_mem)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis); /// Enable the access to the encrypted memory #if SOC_GDMA_SUPPORT_CRC void (*clear_crc)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir); /// Clear the CRC interim results void (*set_crc_poly)(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, const gdma_hal_crc_config_t *config); /// Set the CRC polynomial @@ -130,8 +129,6 @@ uint32_t gdma_hal_read_intr_status(gdma_hal_context_t *hal, int chan_id, gdma_ch uint32_t gdma_hal_get_eof_desc_addr(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool is_success); -void gdma_hal_enable_access_encrypt_mem(gdma_hal_context_t *hal, int chan_id, gdma_channel_direction_t dir, bool en_or_dis); - #if SOC_GDMA_SUPPORT_CRC void gdma_hal_build_parallel_crc_matrix(int crc_width, uint32_t crc_poly_hex, int data_width, uint32_t *lfsr_transform_matrix, uint32_t *data_transform_matrix);