From 11152d46a8d5034c688aaa1a6f66a9f85ac5cfc4 Mon Sep 17 00:00:00 2001 From: Chen Jichang Date: Tue, 2 Dec 2025 11:13:34 +0800 Subject: [PATCH 1/3] fix(dma): fix dma alignment when flash_enc enabled Closes https://github.com/espressif/esp-idf/issues/17708 --- components/esp_driver_dma/src/gdma.c | 16 +++++-- components/esp_driver_dma/src/gdma_link.c | 18 +++++-- components/esp_driver_dma/src/gdma_priv.h | 3 +- .../test_apps/dma/main/test_async_memcpy.c | 18 +++++-- .../test_apps/dma/main/test_dw_gdma.c | 4 ++ .../test_apps/dma/main/test_gdma.c | 48 +++++++++++++++---- .../test_apps/dma/main/test_gdma_crc.c | 23 ++++++--- .../test_apps/dma/pytest_dma.py | 26 ++++++++++ .../dma/sdkconfig.ci.ext_mem_encryption | 9 ++++ .../dma/sdkconfig.ci.weighted_arbitration | 2 + .../esp_hal_dma/esp32c5/include/hal/gdma_ll.h | 1 + .../esp32c61/include/hal/gdma_ll.h | 1 + .../esp32h21/include/hal/gdma_ll.h | 1 + .../esp_hal_dma/esp32h4/include/hal/gdma_ll.h | 1 + .../esp_hal_dma/esp32p4/include/hal/gdma_ll.h | 1 + .../esp_hal_dma/esp32s3/include/hal/gdma_ll.h | 1 + components/esp_mm/heap_align_hw.c | 12 ++++- .../api-reference/peripherals/lcd/dsi_lcd.rst | 4 ++ .../api-reference/peripherals/lcd/dsi_lcd.rst | 4 ++ 19 files changed, 161 insertions(+), 32 deletions(-) create mode 100644 components/esp_driver_dma/test_apps/dma/sdkconfig.ci.ext_mem_encryption create mode 100644 components/esp_driver_dma/test_apps/dma/sdkconfig.ci.weighted_arbitration diff --git a/components/esp_driver_dma/src/gdma.c b/components/esp_driver_dma/src/gdma.c index 58ff052844..488c38bf88 100644 --- a/components/esp_driver_dma/src/gdma.c +++ b/components/esp_driver_dma/src/gdma.c @@ -28,7 +28,6 @@ #include "gdma_priv.h" #include "esp_memory_utils.h" -#include "esp_flash_encrypt.h" #define GDMA_INVALID_PERIPH_TRIG (0x3F) #define SEARCH_REQUEST_RX_CHANNEL (1 << 0) @@ -435,12 +434,21 @@ 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 (esp_flash_encryption_enabled()) { + if (efuse_hal_flash_encryption_enabled()) { gdma_hal_enable_access_encrypt_mem(hal, pair->pair_id, dma_chan->direction, config->access_ext_mem); - // when DMA access the encrypted memory, extra alignment is needed for external memory +#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, GDMA_ACCESS_ENCRYPTION_MEM_ALIGNMENT); + 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); } diff --git a/components/esp_driver_dma/src/gdma_link.c b/components/esp_driver_dma/src/gdma_link.c index af699f83e7..107c430d32 100644 --- a/components/esp_driver_dma/src/gdma_link.c +++ b/components/esp_driver_dma/src/gdma_link.c @@ -16,6 +16,7 @@ #include "esp_heap_caps.h" #include "esp_private/gdma_link.h" #include "hal/cache_hal.h" +#include "hal/efuse_hal.h" #include "hal/cache_ll.h" #include "esp_cache.h" @@ -79,9 +80,16 @@ esp_err_t gdma_new_link_list(const gdma_link_list_config_t *config, gdma_link_li // guard against overflow when calculating total bytes for descriptors ESP_GOTO_ON_FALSE(num_items <= SIZE_MAX / item_size, ESP_ERR_INVALID_SIZE, err, TAG, "list too big"); + bool items_in_ext_mem = config->flags.items_in_ext_mem; uint32_t list_items_mem_caps = MALLOC_CAP_8BIT | MALLOC_CAP_DMA; - if (config->flags.items_in_ext_mem) { - list_items_mem_caps |= MALLOC_CAP_SPIRAM; + if (items_in_ext_mem) { + if (efuse_hal_flash_encryption_enabled()) { + items_in_ext_mem = false; + list_items_mem_caps |= MALLOC_CAP_INTERNAL; + ESP_LOGW(TAG, "DMA linked list items cannot be placed in PSRAM when external memory encryption is enabled, using internal memory instead"); + } else { + list_items_mem_caps |= MALLOC_CAP_SPIRAM; + } } else { list_items_mem_caps |= MALLOC_CAP_INTERNAL; } @@ -90,7 +98,7 @@ esp_err_t gdma_new_link_list(const gdma_link_list_config_t *config, gdma_link_li // do memory sync if the list items are in the cache uint32_t data_cache_line_size = 0; - if (config->flags.items_in_ext_mem) { + if (items_in_ext_mem) { data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); } else { data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); @@ -178,6 +186,10 @@ esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, int start_item_i size_t max_buffer_mount_length = ALIGN_DOWN(GDMA_MAX_BUFFER_SIZE_PER_LINK_ITEM, buffer_alignment); if (!config->flags.bypass_buffer_align_check) { ESP_RETURN_ON_FALSE_ISR(((uintptr_t)buf & (buffer_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "buf misalign idx=%"PRIu32" align=%"PRIu32, bi, buffer_alignment); + if (efuse_hal_flash_encryption_enabled()) { + // buffer size must be aligned to the encryption alignment which should be provided by the upper buffer_alignment + ESP_RETURN_ON_FALSE_ISR((len & (buffer_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "buf len misalign idx=%"PRIu32" len=%"PRIu32" align=%"PRIu32"", bi, len, buffer_alignment); + } } size_t num_items_need = (len + max_buffer_mount_length - 1) / max_buffer_mount_length; ESP_RETURN_ON_FALSE_ISR(num_items_need <= remaining, ESP_ERR_INVALID_ARG, TAG, diff --git a/components/esp_driver_dma/src/gdma_priv.h b/components/esp_driver_dma/src/gdma_priv.h index ecaf09a178..fcc8b677f8 100644 --- a/components/esp_driver_dma/src/gdma_priv.h +++ b/components/esp_driver_dma/src/gdma_priv.h @@ -30,6 +30,7 @@ #include "hal/gdma_hal_ahb.h" #include "hal/gdma_hal_axi.h" #include "hal/gdma_periph.h" +#include "hal/efuse_hal.h" #include "soc/periph_defs.h" #include "esp_private/gdma.h" #include "esp_private/periph_ctrl.h" @@ -42,8 +43,6 @@ #define GDMA_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT #endif -#define GDMA_ACCESS_ENCRYPTION_MEM_ALIGNMENT 16 /*!< The alignment of the memory and size when DMA accesses the encryption memory */ - #ifdef __cplusplus extern "C" { #endif diff --git a/components/esp_driver_dma/test_apps/dma/main/test_async_memcpy.c b/components/esp_driver_dma/test_apps/dma/main/test_async_memcpy.c index 2e4e5f570c..720cac7fd5 100644 --- a/components/esp_driver_dma/test_apps/dma/main/test_async_memcpy.c +++ b/components/esp_driver_dma/test_apps/dma/main/test_async_memcpy.c @@ -16,6 +16,8 @@ #include "freertos/semphr.h" #include "ccomp_timer.h" #include "esp_async_memcpy.h" +#include "hal/efuse_hal.h" + #if SOC_GDMA_SUPPORTED #include "hal/gdma_ll.h" #endif @@ -152,17 +154,19 @@ static bool test_async_memcpy_cb_v1(async_memcpy_handle_t mcp_hdl, async_memcpy_ static void test_memory_copy_blocking(async_memcpy_handle_t driver) { SemaphoreHandle_t sem = xSemaphoreCreateBinary(); - const uint32_t test_buffer_size[] = {256, 512, 1024, 2048, 4096, 5012}; + const uint32_t test_buffer_size[] = {256, 512, 1024, 2048, 4096, 5008}; memcpy_testbench_context_t test_context = { - .align = 4, + .align = 16, }; for (int i = 0; i < sizeof(test_buffer_size) / sizeof(test_buffer_size[0]); i++) { // Test different align edge for (int off = 0; off < 4; off++) { test_context.buffer_size = test_buffer_size[i]; test_context.seed = i; - test_context.src_offset = off; - test_context.dst_offset = off; + if (!efuse_hal_flash_encryption_enabled()) { + test_context.src_offset = off; + test_context.dst_offset = off; + } async_memcpy_setup_testbench(&test_context); TEST_ESP_OK(esp_async_memcpy(driver, test_context.to_addr, test_context.from_addr, test_context.copy_size, test_async_memcpy_cb_v1, sem)); @@ -239,6 +243,10 @@ TEST_CASE("memory copy with dest address unaligned", "[async mcp]") }; [[maybe_unused]] async_memcpy_handle_t driver = NULL; + if (efuse_hal_flash_encryption_enabled()) { + TEST_PASS_MESSAGE("Flash encryption is enabled, skip this test"); + } + #if SOC_CP_DMA_SUPPORTED printf("Testing memcpy by CP DMA\r\n"); TEST_ESP_OK(esp_async_memcpy_install_cpdma(&driver_config, &driver)); @@ -459,7 +467,7 @@ TEST_CASE("GDMA M2M Weighted Arbitration Test SRAM->SRAM", "[GDMA][M2M][async mc { async_memcpy_config_t driver_config = { .backlog = TEST_ASYNC_MEMCPY_BENCH_COUNTS, - .dma_burst_size = 64, + .dma_burst_size = 32, }; async_memcpy_handle_t driver[2] = {NULL}; diff --git a/components/esp_driver_dma/test_apps/dma/main/test_dw_gdma.c b/components/esp_driver_dma/test_apps/dma/main/test_dw_gdma.c index 45eeb11c32..37999612cb 100644 --- a/components/esp_driver_dma/test_apps/dma/main/test_dw_gdma.c +++ b/components/esp_driver_dma/test_apps/dma/main/test_dw_gdma.c @@ -11,6 +11,7 @@ #include "unity.h" #include "esp_private/dw_gdma.h" #include "hal/dw_gdma_ll.h" +#include "hal/efuse_hal.h" #include "esp_cache.h" #include "esp_private/esp_cache_private.h" @@ -540,6 +541,9 @@ TEST_CASE("DW_GDMA M2M Test: memory set with fixed address", "[DW_GDMA]") size_t int_mem_alignment = 0; TEST_ESP_OK(esp_cache_get_alignment(MALLOC_CAP_SPIRAM, &ext_mem_alignment)); TEST_ESP_OK(esp_cache_get_alignment(0, &int_mem_alignment)); + if (efuse_hal_flash_encryption_enabled()) { + TEST_PASS_MESSAGE("Flash encryption is enabled, skip this test"); + } uint8_t *src_buf = heap_caps_aligned_calloc(ext_mem_alignment, 1, 256, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); uint8_t *dst_buf = heap_caps_aligned_calloc(int_mem_alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); TEST_ASSERT_NOT_NULL(src_buf); diff --git a/components/esp_driver_dma/test_apps/dma/main/test_gdma.c b/components/esp_driver_dma/test_apps/dma/main/test_gdma.c index 28f94a6342..0e6b367f1e 100644 --- a/components/esp_driver_dma/test_apps/dma/main/test_gdma.c +++ b/components/esp_driver_dma/test_apps/dma/main/test_gdma.c @@ -20,6 +20,7 @@ #include "hal/gdma_ll.h" #include "hal/cache_ll.h" #include "hal/cache_hal.h" +#include "hal/efuse_hal.h" #include "esp_cache.h" #include "esp_memory_utils.h" #include "gdma_test_utils.h" @@ -149,7 +150,8 @@ TEST_CASE("GDMA channel allocation", "[GDMA]") } static void test_gdma_config_link_list(gdma_channel_handle_t tx_chan, gdma_channel_handle_t rx_chan, - gdma_link_list_handle_t *tx_link_list, gdma_link_list_handle_t *rx_link_list, bool dma_link_in_ext_mem) + gdma_link_list_handle_t *tx_link_list, gdma_link_list_handle_t *rx_link_list, + size_t burst_size, bool dma_link_in_ext_mem) { gdma_strategy_config_t strategy = { @@ -159,6 +161,15 @@ static void test_gdma_config_link_list(gdma_channel_handle_t tx_chan, gdma_chann TEST_ESP_OK(gdma_apply_strategy(tx_chan, &strategy)); TEST_ESP_OK(gdma_apply_strategy(rx_chan, &strategy)); + gdma_transfer_config_t transfer_cfg = { + .max_data_burst_size = burst_size, +#if SOC_DMA_CAN_ACCESS_FLASH + .access_ext_mem = true, +#endif + }; + TEST_ESP_OK(gdma_config_transfer(tx_chan, &transfer_cfg)); + TEST_ESP_OK(gdma_config_transfer(rx_chan, &transfer_cfg)); + gdma_trigger_t m2m_trigger = GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_M2M, 0); // get a free DMA trigger ID for memory copy uint32_t free_m2m_id_mask = 0; @@ -207,16 +218,24 @@ static void test_gdma_m2m_transaction(gdma_channel_handle_t tx_chan, gdma_channe TEST_ASSERT_NOT_NULL(done_sem); TEST_ESP_OK(gdma_register_rx_event_callbacks(rx_chan, &rx_cbs, done_sem)); + if (efuse_hal_flash_encryption_enabled()) { + dma_link_in_ext_mem = false; + } + gdma_link_list_handle_t tx_link_list = NULL; gdma_link_list_handle_t rx_link_list = NULL; - test_gdma_config_link_list(tx_chan, rx_chan, &tx_link_list, &rx_link_list, dma_link_in_ext_mem); + test_gdma_config_link_list(tx_chan, rx_chan, &tx_link_list, &rx_link_list, 16, dma_link_in_ext_mem); + + size_t int_mem_alignment = 0; + size_t ext_mem_alignment = 0; + TEST_ESP_OK(gdma_get_alignment_constraints(tx_chan, &int_mem_alignment, &ext_mem_alignment)); // allocate the source buffer from SRAM - uint8_t *src_data = heap_caps_calloc(1, 128, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + uint8_t *src_data = heap_caps_aligned_calloc(int_mem_alignment, 1, 128, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); TEST_ASSERT_NOT_NULL(src_data); // allocate the destination buffer from SRAM - uint8_t *dst_data = heap_caps_calloc(1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + uint8_t *dst_data = heap_caps_aligned_calloc(int_mem_alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); TEST_ASSERT_NOT_NULL(dst_data); // prepare the source data @@ -229,7 +248,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 - const char *src_string = "GDMA can read data from MSPI Flash"; + static const char src_string[] __attribute__((aligned(GDMA_LL_GET(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)); @@ -244,12 +263,12 @@ static void test_gdma_m2m_transaction(gdma_channel_handle_t tx_chan, gdma_channe gdma_buffer_mount_config_t tx_buf_mount_config[] = { [0] = { .buffer = src_data, - .buffer_alignment = 1, + .buffer_alignment = int_mem_alignment, .length = 64, }, [1] = { .buffer = src_data + 64, - .buffer_alignment = 1, + .buffer_alignment = int_mem_alignment, .length = 64, #if !SOC_DMA_CAN_ACCESS_FLASH .flags = { @@ -261,7 +280,7 @@ static void test_gdma_m2m_transaction(gdma_channel_handle_t tx_chan, gdma_channe #if SOC_DMA_CAN_ACCESS_FLASH [2] = { .buffer = (void *)src_string, - .buffer_alignment = 1, + .buffer_alignment = ext_mem_alignment, .length = src_string_len, .flags = { .mark_eof = true, @@ -369,6 +388,8 @@ static void test_gdma_m2m_unaligned_buffer_test(uint8_t *dst_data, uint8_t *src_ { TEST_ASSERT_NOT_NULL(src_data); TEST_ASSERT_NOT_NULL(dst_data); + memset(src_data, 0, data_length + offset_len); + memset(dst_data, 0, data_length + offset_len); gdma_channel_handle_t tx_chan = NULL; gdma_channel_handle_t rx_chan = NULL; gdma_channel_alloc_config_t chan_alloc_config = {}; @@ -377,7 +398,10 @@ static void test_gdma_m2m_unaligned_buffer_test(uint8_t *dst_data, uint8_t *src_ gdma_link_list_handle_t tx_link_list = NULL; gdma_link_list_handle_t rx_link_list = NULL; - test_gdma_config_link_list(tx_chan, rx_chan, &tx_link_list, &rx_link_list, false); + test_gdma_config_link_list(tx_chan, rx_chan, &tx_link_list, &rx_link_list, 0, false); + + size_t rx_mem_alignment = 0; + TEST_ESP_OK(gdma_get_alignment_constraints(rx_chan, &rx_mem_alignment, NULL)); // prepare the source data for (int i = 0; i < data_length; i++) { @@ -407,7 +431,7 @@ static void test_gdma_m2m_unaligned_buffer_test(uint8_t *dst_data, uint8_t *src_ TEST_ESP_OK(esp_dma_split_rx_buffer_to_cache_aligned(dst_data + offset_len, data_length, &align_array, &stash_buffer)); for (int i = 0; i < 3; i++) { rx_aligned_buf_mount_config[i].buffer = align_array.aligned_buffer[i].aligned_buffer; - rx_aligned_buf_mount_config[i].buffer_alignment = sram_alignment; + rx_aligned_buf_mount_config[i].buffer_alignment = MAX(sram_alignment, rx_mem_alignment); rx_aligned_buf_mount_config[i].length = align_array.aligned_buffer[i].length; } TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, rx_aligned_buf_mount_config, 3, NULL)); @@ -443,6 +467,10 @@ static void test_gdma_m2m_unaligned_buffer_test(uint8_t *dst_data, uint8_t *src_ TEST_CASE("GDMA M2M Unaligned RX Buffer Test", "[GDMA][M2M]") { + if (efuse_hal_flash_encryption_enabled()) { + TEST_PASS_MESSAGE("Flash encryption is enabled, skip this test"); + } + uint8_t *sbuf = heap_caps_aligned_calloc(64, 1, 10240, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); uint8_t *dbuf = heap_caps_aligned_calloc(64, 1, 10240, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); diff --git a/components/esp_driver_dma/test_apps/dma/main/test_gdma_crc.c b/components/esp_driver_dma/test_apps/dma/main/test_gdma_crc.c index ce56c4e725..9ab75ac552 100644 --- a/components/esp_driver_dma/test_apps/dma/main/test_gdma_crc.c +++ b/components/esp_driver_dma/test_apps/dma/main/test_gdma_crc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +17,7 @@ #include "soc/soc_caps.h" #include "hal/cache_hal.h" #include "hal/cache_ll.h" +#include "hal/gdma_ll.h" #include "esp_cache.h" typedef struct { @@ -32,37 +33,47 @@ static test_crc_case_t crc_test_cases[] = { .crc_bit_width = 8, .init_value = 0x00, .poly_hex = 0x07, - .expected_result = 0xC6, + .expected_result = 0xB8, }, [1] = { .crc_bit_width = 8, .init_value = 0x00, .poly_hex = 0x07, .reverse_data_mask = true, // refin = true - .expected_result = 0xDE, + .expected_result = 0xF0, }, // CRC16, x^16+x^12+x^5+1 [2] = { .crc_bit_width = 16, .init_value = 0xFFFF, .poly_hex = 0x1021, - .expected_result = 0x5289, + .expected_result = 0xA9B2, }, // CRC32, x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 [3] = { .crc_bit_width = 32, .init_value = 0xFFFFFFFF, .poly_hex = 0x04C11DB7, - .expected_result = 0x63B3E283, + .expected_result = 0x692F6C7E, } }; // CRC online: https://www.lddgo.net/en/encrypt/crc static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_num_crc_algorithm) { + // Note, burst size should be at least 16 when accessing encrypted external memory + gdma_transfer_config_t transfer_cfg = { + .max_data_burst_size = 16, + .access_ext_mem = true, + }; + TEST_ESP_OK(gdma_config_transfer(tx_chan, &transfer_cfg)); + uint32_t crc_result = 0; - const char *test_input_string = "Share::Connect::Innovate"; + + static const char test_input_string[] __attribute__((aligned(GDMA_LL_GET(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); // 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_driver_dma/test_apps/dma/pytest_dma.py b/components/esp_driver_dma/test_apps/dma/pytest_dma.py index a009ce6d50..a684d7fdc5 100644 --- a/components/esp_driver_dma/test_apps/dma/pytest_dma.py +++ b/components/esp_driver_dma/test_apps/dma/pytest_dma.py @@ -47,3 +47,29 @@ def test_dma_psram(dut: Dut) -> None: @idf_parametrize('target', soc_filtered_targets('SOC_GDMA_SUPPORT_WEIGHTED_ARBITRATION == 1'), indirect=['target']) def test_dma_weighted_arbitration(dut: Dut) -> None: dut.run_all_single_board_cases(reset=True) + + +@pytest.mark.flash_encryption +@pytest.mark.parametrize( + 'config', + [ + 'ext_mem_encryption', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32p4', 'esp32c5'], indirect=['target']) +def test_dma_ext_mem_encryption(dut: Dut) -> None: + dut.run_all_single_board_cases(reset=True) + + +@pytest.mark.flash_encryption_f4r8 +@pytest.mark.parametrize( + 'config', + [ + 'ext_mem_encryption', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) +def test_dma_ext_mem_encryption_s3_f4r8(dut: Dut) -> None: + dut.run_all_single_board_cases(reset=True) diff --git a/components/esp_driver_dma/test_apps/dma/sdkconfig.ci.ext_mem_encryption b/components/esp_driver_dma/test_apps/dma/sdkconfig.ci.ext_mem_encryption new file mode 100644 index 0000000000..5be9651c38 --- /dev/null +++ b/components/esp_driver_dma/test_apps/dma/sdkconfig.ci.ext_mem_encryption @@ -0,0 +1,9 @@ +CONFIG_PARTITION_TABLE_OFFSET=0x9000 +CONFIG_SECURE_FLASH_ENC_ENABLED=y +CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y +CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y +CONFIG_SECURE_BOOT_ALLOW_JTAG=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y +CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y diff --git a/components/esp_driver_dma/test_apps/dma/sdkconfig.ci.weighted_arbitration b/components/esp_driver_dma/test_apps/dma/sdkconfig.ci.weighted_arbitration new file mode 100644 index 0000000000..2bf15839c9 --- /dev/null +++ b/components/esp_driver_dma/test_apps/dma/sdkconfig.ci.weighted_arbitration @@ -0,0 +1,2 @@ +CONFIG_GDMA_ENABLE_WEIGHTED_ARBITRATION=y +CONFIG_IDF_EXPERIMENTAL_FEATURES=y diff --git a/components/esp_hal_dma/esp32c5/include/hal/gdma_ll.h b/components/esp_hal_dma/esp32c5/include/hal/gdma_ll.h index 9a759a5d57..5b098afb30 100644 --- a/components/esp_hal_dma/esp32c5/include/hal/gdma_ll.h +++ b/components/esp_hal_dma/esp32c5/include/hal/gdma_ll.h @@ -17,6 +17,7 @@ #define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size #define GDMA_LL_MAX_BURST_SIZE_PSRAM 32 // PSRAM controller doesn't support burst access with size > 32 bytes +#define GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT 16 // The alignment of the memory and size when DMA accesses encrypted memory #ifdef __cplusplus extern "C" { diff --git a/components/esp_hal_dma/esp32c61/include/hal/gdma_ll.h b/components/esp_hal_dma/esp32c61/include/hal/gdma_ll.h index 9a759a5d57..5b098afb30 100644 --- a/components/esp_hal_dma/esp32c61/include/hal/gdma_ll.h +++ b/components/esp_hal_dma/esp32c61/include/hal/gdma_ll.h @@ -17,6 +17,7 @@ #define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size #define GDMA_LL_MAX_BURST_SIZE_PSRAM 32 // PSRAM controller doesn't support burst access with size > 32 bytes +#define GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT 16 // The alignment of the memory and size when DMA accesses encrypted memory #ifdef __cplusplus extern "C" { diff --git a/components/esp_hal_dma/esp32h21/include/hal/gdma_ll.h b/components/esp_hal_dma/esp32h21/include/hal/gdma_ll.h index 23fdc99fb8..e8a391d29b 100644 --- a/components/esp_hal_dma/esp32h21/include/hal/gdma_ll.h +++ b/components/esp_hal_dma/esp32h21/include/hal/gdma_ll.h @@ -53,6 +53,7 @@ extern "C" { #define GDMA_LL_AHB_DESC_ALIGNMENT 4 #define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 +#define GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT 16 // The alignment of the memory and size when DMA accesses encrypted memory #define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x07 // pair 0,1,2 are M2M capable diff --git a/components/esp_hal_dma/esp32h4/include/hal/gdma_ll.h b/components/esp_hal_dma/esp32h4/include/hal/gdma_ll.h index f9c7127989..38e434b991 100644 --- a/components/esp_hal_dma/esp32h4/include/hal/gdma_ll.h +++ b/components/esp_hal_dma/esp32h4/include/hal/gdma_ll.h @@ -17,6 +17,7 @@ #define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size #define GDMA_LL_MAX_BURST_SIZE_PSRAM 64 // PSRAM support INCR16 +#define GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT 16 // The alignment of the memory and size when DMA accesses encrypted memory #ifdef __cplusplus extern "C" { diff --git a/components/esp_hal_dma/esp32p4/include/hal/gdma_ll.h b/components/esp_hal_dma/esp32p4/include/hal/gdma_ll.h index db94709822..a2feabafee 100644 --- a/components/esp_hal_dma/esp32p4/include/hal/gdma_ll.h +++ b/components/esp_hal_dma/esp32p4/include/hal/gdma_ll.h @@ -58,6 +58,7 @@ #define GDMA_LL_AHB_DESC_ALIGNMENT 4 #define GDMA_LL_AXI_DESC_ALIGNMENT 8 #define GDMA_LL_MAX_BURST_SIZE_PSRAM 128 // PSRAM controller doesn't support burst access with size > 128 bytes +#define GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT 16 // The alignment of the memory and size when DMA accesses encrypted memory #if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 #define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size diff --git a/components/esp_hal_dma/esp32s3/include/hal/gdma_ll.h b/components/esp_hal_dma/esp32s3/include/hal/gdma_ll.h index b3680dda2f..1c4936e273 100644 --- a/components/esp_hal_dma/esp32s3/include/hal/gdma_ll.h +++ b/components/esp_hal_dma/esp32s3/include/hal/gdma_ll.h @@ -71,6 +71,7 @@ extern "C" { #define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size #define GDMA_LL_AHB_RX_BURST_NEEDS_ALIGNMENT 1 #define GDMA_LL_MAX_BURST_SIZE_PSRAM 64 // PSRAM controller doesn't support burst access with size > 64 bytes +#define GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT 16 // The alignment of the memory and size when DMA accesses encrypted memory #define GDMA_LL_AHB_M2M_CAPABLE_PAIR_MASK 0x1F // pair 0,1,2,3,4 are M2M capable diff --git a/components/esp_mm/heap_align_hw.c b/components/esp_mm/heap_align_hw.c index 74afffbee9..294fb5a2d7 100644 --- a/components/esp_mm/heap_align_hw.c +++ b/components/esp_mm/heap_align_hw.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,9 +9,11 @@ #include "sdkconfig.h" #include "esp_heap_caps.h" #include "esp_private/esp_cache_private.h" +#include "esp_private/gdma.h" #include "soc/soc_caps.h" -#if SOC_GDMA_SUPPORTED +#if SOC_HAS(GDMA) #include "hal/gdma_ll.h" +#include "hal/efuse_hal.h" #endif #if CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH @@ -80,6 +82,12 @@ HEAP_IRAM_ATTR void esp_heap_adjust_alignment_to_hw(size_t *p_alignment, size_t } #endif +#if SOC_HAS(GDMA) && (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); + } +#endif + // Align up `size` to resulting alignment as well. size = (size + alignment - 1) & (~(alignment - 1)); diff --git a/docs/en/api-reference/peripherals/lcd/dsi_lcd.rst b/docs/en/api-reference/peripherals/lcd/dsi_lcd.rst index a92defdecc..93a7a513c3 100644 --- a/docs/en/api-reference/peripherals/lcd/dsi_lcd.rst +++ b/docs/en/api-reference/peripherals/lcd/dsi_lcd.rst @@ -92,6 +92,10 @@ MIPI DSI Interfaced LCD ESP_ERROR_CHECK(esp_lcd_dpi_panel_enable_dma2d(mipi_dpi_panel)); + .. note:: + + Due to hardware limitation, if external memory encryption is enabled, DMA2D can only access address and length that are aligned to 16 bytes. Unless you can ensure that your draw buffer's address and length are aligned to 16 bytes, it is not recommended to use DMA2D to draw bitmap. + If you need more advanced applications, you can add a custom hook for draw bitmap, such as using PPA to implement rotation, scaling, etc. .. code-block:: c diff --git a/docs/zh_CN/api-reference/peripherals/lcd/dsi_lcd.rst b/docs/zh_CN/api-reference/peripherals/lcd/dsi_lcd.rst index 41964aaf5f..32694f3bb7 100644 --- a/docs/zh_CN/api-reference/peripherals/lcd/dsi_lcd.rst +++ b/docs/zh_CN/api-reference/peripherals/lcd/dsi_lcd.rst @@ -92,6 +92,10 @@ MIPI DSI 接口的 LCD ESP_ERROR_CHECK(esp_lcd_dpi_panel_enable_dma2d(mipi_dpi_panel)); + .. note:: + + 由于硬件限制,如果启用了外部存储加密,则 DMA2D 只能访问地址和长度都对齐到 16 字节的地址空间。除非你能确保你的绘制 buffer 的地址和长度都对齐到 16 字节, 否则不建议使用 DMA2D 来绘制位图。 + 若需更高级的应用,用户可为绘制位图添加自定义钩子,例如通过 PPA 实现旋转、缩放等操作。 .. code-block:: c From ca55f935e55b1b41b87876c353e9682a82f0914a Mon Sep 17 00:00:00 2001 From: Chen Jichang Date: Thu, 8 Jan 2026 16:13:01 +0800 Subject: [PATCH 2/3] fix(gdma): fix dma burst size when flash enc enabled --- components/esp_driver_dma/src/gdma.c | 37 ++++++++----------- .../esp32p4/include/hal/axi_dma_ll.h | 8 +++- components/esp_hal_dma/gdma_hal_axi.c | 12 +----- components/esp_hal_dma/gdma_hal_top.c | 9 +---- components/esp_hal_dma/include/hal/gdma_hal.h | 3 -- 5 files changed, 25 insertions(+), 44 deletions(-) diff --git a/components/esp_driver_dma/src/gdma.c b/components/esp_driver_dma/src/gdma.c index 488c38bf88..b73d5a5125 100644 --- a/components/esp_driver_dma/src/gdma.c +++ b/components/esp_driver_dma/src/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 */ @@ -416,6 +416,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_GET(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); @@ -433,26 +448,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_hal_dma/esp32p4/include/hal/axi_dma_ll.h b/components/esp_hal_dma/esp32p4/include/hal/axi_dma_ll.h index 290047b127..9b8b32d041 100644 --- a/components/esp_hal_dma/esp32p4/include/hal/axi_dma_ll.h +++ b/components/esp_hal_dma/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 */ @@ -302,6 +302,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) { @@ -543,6 +546,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/esp_hal_dma/gdma_hal_axi.c b/components/esp_hal_dma/gdma_hal_axi.c index f92af63585..c3a6b9ad11 100644 --- a/components/esp_hal_dma/gdma_hal_axi.c +++ b/components/esp_hal_dma/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 */ @@ -170,15 +170,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) { @@ -266,7 +257,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/esp_hal_dma/gdma_hal_top.c b/components/esp_hal_dma/gdma_hal_top.c index 04e82977d2..b1ebc075b2 100644 --- a/components/esp_hal_dma/gdma_hal_top.c +++ b/components/esp_hal_dma/gdma_hal_top.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 */ @@ -95,13 +95,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/esp_hal_dma/include/hal/gdma_hal.h b/components/esp_hal_dma/include/hal/gdma_hal.h index 6d0eeecd47..9c670c87d5 100644 --- a/components/esp_hal_dma/include/hal/gdma_hal.h +++ b/components/esp_hal_dma/include/hal/gdma_hal.h @@ -91,7 +91,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 @@ -139,8 +138,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); From 4c92df4926335c0ecf1a7a175bc88cd48fdc3005 Mon Sep 17 00:00:00 2001 From: Chen Jichang Date: Tue, 27 Jan 2026 15:05:35 +0800 Subject: [PATCH 3/3] fix(gdma): skip alignment check for AHBDMA version 1 when flash enc --- components/esp_driver_dma/src/gdma.c | 4 +++- components/esp_mm/heap_align_hw.c | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/components/esp_driver_dma/src/gdma.c b/components/esp_driver_dma/src/gdma.c index b73d5a5125..75d97bc8db 100644 --- a/components/esp_driver_dma/src/gdma.c +++ b/components/esp_driver_dma/src/gdma.c @@ -417,7 +417,9 @@ esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transf bool en_desc_burst = true; bool en_data_burst = max_data_burst_size > 0; -#if SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH + // There's auto alignment for AHB GDMA version 1, so we don't need to do anything here + // While, for AHB GDMA version 2 and AXI GDMA, we need to ensure the alignment by software +#if (SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH) && SOC_AHB_GDMA_VERSION != 1 // 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_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT); diff --git a/components/esp_mm/heap_align_hw.c b/components/esp_mm/heap_align_hw.c index 294fb5a2d7..bc0088b458 100644 --- a/components/esp_mm/heap_align_hw.c +++ b/components/esp_mm/heap_align_hw.c @@ -9,7 +9,6 @@ #include "sdkconfig.h" #include "esp_heap_caps.h" #include "esp_private/esp_cache_private.h" -#include "esp_private/gdma.h" #include "soc/soc_caps.h" #if SOC_HAS(GDMA) #include "hal/gdma_ll.h"