diff --git a/components/esp_hw_support/dma/gdma.c b/components/esp_hw_support/dma/gdma.c index f222e9817e..54f0caa91f 100644 --- a/components/esp_hw_support/dma/gdma.c +++ b/components/esp_hw_support/dma/gdma.c @@ -28,7 +28,6 @@ #include "gdma_priv.h" #include "esp_memory_utils.h" -#include "esp_flash_encrypt.h" #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP #include "esp_private/gdma_sleep_retention.h" @@ -380,12 +379,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_hw_support/dma/gdma_link.c b/components/esp_hw_support/dma/gdma_link.c index d7b020e361..b1000fb28b 100644 --- a/components/esp_hw_support/dma/gdma_link.c +++ b/components/esp_hw_support/dma/gdma_link.c @@ -14,6 +14,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" @@ -75,9 +76,16 @@ esp_err_t gdma_new_link_list(const gdma_link_list_config_t *config, gdma_link_li // each list item should align to the specified alignment size_t item_size = ALIGN_UP(sizeof(gdma_link_list_item_t), item_alignment); + 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; } @@ -86,7 +94,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); @@ -166,7 +174,11 @@ esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, int start_item_i ESP_RETURN_ON_FALSE_ISR((buffer_alignment & (buffer_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "invalid buffer alignment: %"PRIu32"", buffer_alignment); 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, "buffer not aligned to %"PRIu32"", buffer_alignment); + 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); + } } uint32_t num_items_need = (len + max_buffer_mount_length - 1) / max_buffer_mount_length; // check if there are enough link list items diff --git a/components/esp_hw_support/dma/gdma_priv.h b/components/esp_hw_support/dma/gdma_priv.h index 4c0d921a59..977bd05db0 100644 --- a/components/esp_hw_support/dma/gdma_priv.h +++ b/components/esp_hw_support/dma/gdma_priv.h @@ -30,6 +30,7 @@ #include "hal/gdma_hal_ahb.h" #include "hal/gdma_hal_axi.h" #include "soc/gdma_periph.h" +#include "hal/efuse_hal.h" #include "soc/periph_defs.h" #include "esp_private/gdma.h" #include "esp_private/periph_ctrl.h" @@ -40,8 +41,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 */ - ///!< Logging settings #define TAG "gdma" diff --git a/components/esp_hw_support/test_apps/dma/main/test_async_memcpy.c b/components/esp_hw_support/test_apps/dma/main/test_async_memcpy.c index e2c7a370dd..3f0a61d8e5 100644 --- a/components/esp_hw_support/test_apps/dma/main/test_async_memcpy.c +++ b/components/esp_hw_support/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 @@ -148,17 +150,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)); @@ -235,6 +239,9 @@ 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"); diff --git a/components/esp_hw_support/test_apps/dma/main/test_dw_gdma.c b/components/esp_hw_support/test_apps/dma/main/test_dw_gdma.c index 45eeb11c32..37999612cb 100644 --- a/components/esp_hw_support/test_apps/dma/main/test_dw_gdma.c +++ b/components/esp_hw_support/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_hw_support/test_apps/dma/main/test_gdma.c b/components/esp_hw_support/test_apps/dma/main/test_gdma.c index 6545d361ce..06ddc609b0 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 @@ -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" @@ -153,7 +154,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 = { @@ -163,6 +165,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; @@ -211,16 +222,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 @@ -233,7 +252,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)); @@ -248,12 +267,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 = { @@ -265,7 +284,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, @@ -392,6 +411,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 tx_chan_alloc_config = {}; @@ -410,7 +431,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++) { @@ -440,7 +464,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)); @@ -476,6 +500,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_hw_support/test_apps/dma/main/test_gdma_crc.c b/components/esp_hw_support/test_apps/dma/main/test_gdma_crc.c index fd0e75a5fd..ad8a11b16f 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 @@ -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_hw_support/test_apps/dma/pytest_dma.py b/components/esp_hw_support/test_apps/dma/pytest_dma.py index 1d741f14fb..035c39dd54 100644 --- a/components/esp_hw_support/test_apps/dma/pytest_dma.py +++ b/components/esp_hw_support/test_apps/dma/pytest_dma.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut @@ -35,3 +35,29 @@ def test_dma(dut: Dut) -> None: ) def test_dma_psram(dut: Dut) -> None: dut.run_all_single_board_cases(reset=True) + + +@pytest.mark.esp32p4 +@pytest.mark.flash_encryption +@pytest.mark.parametrize( + 'config', + [ + 'ext_mem_encryption', + ], + indirect=True, +) +def test_dma_ext_mem_encryption(dut: Dut) -> None: + dut.run_all_single_board_cases(reset=True) + + +@pytest.mark.esp32s3 +@pytest.mark.flash_encryption_f4r8 +@pytest.mark.parametrize( + 'config', + [ + 'ext_mem_encryption', + ], + indirect=True, +) +def test_dma_ext_mem_encryption_s3_f4r8(dut: Dut) -> None: + dut.run_all_single_board_cases(reset=True) diff --git a/components/esp_hw_support/test_apps/dma/sdkconfig.ci.ext_mem_encryption b/components/esp_hw_support/test_apps/dma/sdkconfig.ci.ext_mem_encryption new file mode 100644 index 0000000000..5be9651c38 --- /dev/null +++ b/components/esp_hw_support/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_mm/heap_align_hw.c b/components/esp_mm/heap_align_hw.c index d31ea59bd3..af609e32c9 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 #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_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); + } +#endif + // Align up `size` to resulting alignment as well. size = (size + alignment - 1) & (~(alignment - 1)); diff --git a/components/hal/esp32c5/include/hal/gdma_ll.h b/components/hal/esp32c5/include/hal/gdma_ll.h index f167217769..cb979a0d75 100644 --- a/components/hal/esp32c5/include/hal/gdma_ll.h +++ b/components/hal/esp32c5/include/hal/gdma_ll.h @@ -8,6 +8,7 @@ #include "soc/pcr_struct.h" #include "hal/ahb_dma_ll.h" #define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size +#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/hal/esp32c61/include/hal/gdma_ll.h b/components/hal/esp32c61/include/hal/gdma_ll.h index 5dfa8e31af..9b49714568 100644 --- a/components/hal/esp32c61/include/hal/gdma_ll.h +++ b/components/hal/esp32c61/include/hal/gdma_ll.h @@ -9,6 +9,7 @@ #include "soc/pcr_struct.h" #include "hal/ahb_dma_ll.h" #define GDMA_LL_AHB_BURST_SIZE_ADJUSTABLE 1 // AHB GDMA supports adjustable burst size +#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/hal/esp32p4/include/hal/gdma_ll.h b/components/hal/esp32p4/include/hal/gdma_ll.h index 6e463aa781..a39dd65714 100644 --- a/components/hal/esp32p4/include/hal/gdma_ll.h +++ b/components/hal/esp32p4/include/hal/gdma_ll.h @@ -48,6 +48,7 @@ #define GDMA_LL_AHB_DESC_ALIGNMENT 4 #define GDMA_LL_AXI_DESC_ALIGNMENT 8 +#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/hal/esp32s3/include/hal/gdma_ll.h b/components/hal/esp32s3/include/hal/gdma_ll.h index c232966ca5..712aeed3dc 100644 --- a/components/hal/esp32s3/include/hal/gdma_ll.h +++ b/components/hal/esp32s3/include/hal/gdma_ll.h @@ -64,6 +64,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_ACCESS_ENCRYPTION_MEM_ALIGNMENT 16 // The alignment of the memory and size when DMA accesses encrypted memory ///////////////////////////////////// Common /////////////////////////////////////////