diff --git a/components/esp_hw_support/dma/gdma.c b/components/esp_hw_support/dma/gdma.c index a1348db51c..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 */ @@ -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" @@ -383,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); @@ -395,17 +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 (esp_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 (config->access_ext_mem) { - ext_mem_alignment = MAX(ext_mem_alignment, GDMA_ACCESS_ENCRYPTION_MEM_ALIGNMENT); - } - } 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/dma/gdma_link.c b/components/esp_hw_support/dma/gdma_link.c index 8994399d0e..dc8b057c29 100644 --- a/components/esp_hw_support/dma/gdma_link.c +++ b/components/esp_hw_support/dma/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_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 7374d0589c..b5c9456a21 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 bb487b2a2b..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 @@ -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" @@ -173,7 +174,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 = { @@ -183,6 +185,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; @@ -231,16 +242,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 @@ -253,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 - const char *src_string = "GDMA can read data from MSPI Flash"; + 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)); @@ -268,12 +287,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 = { @@ -285,7 +304,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, @@ -412,6 +431,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 = {}; @@ -430,7 +451,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++) { @@ -460,7 +484,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)); @@ -496,6 +520,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..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 @@ -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_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_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 e70adf3476..d9b663c51c 100644 --- a/components/esp_hw_support/test_apps/dma/pytest_dma.py +++ b/components/esp_hw_support/test_apps/dma/pytest_dma.py @@ -33,3 +33,29 @@ def test_dma(dut: Dut) -> None: @idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_dma_psram(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_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..344b27b882 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_ACCESS_ENCRYPTION_MEM_ALIGNMENT) ? alignment : GDMA_LL_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 f4a17e88f4..8176ed1c40 100644 --- a/components/hal/esp32c5/include/hal/gdma_ll.h +++ b/components/hal/esp32c5/include/hal/gdma_ll.h @@ -9,6 +9,7 @@ #include "hal/ahb_dma_ll.h" #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/hal/esp32c61/include/hal/gdma_ll.h b/components/hal/esp32c61/include/hal/gdma_ll.h index f4a17e88f4..8176ed1c40 100644 --- a/components/hal/esp32c61/include/hal/gdma_ll.h +++ b/components/hal/esp32c61/include/hal/gdma_ll.h @@ -9,6 +9,7 @@ #include "hal/ahb_dma_ll.h" #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/hal/esp32h21/include/hal/gdma_ll.h b/components/hal/esp32h21/include/hal/gdma_ll.h index 4d0f42c613..3e56d0d621 100644 --- a/components/hal/esp32h21/include/hal/gdma_ll.h +++ b/components/hal/esp32h21/include/hal/gdma_ll.h @@ -49,6 +49,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/hal/esp32h4/include/hal/gdma_ll.h b/components/hal/esp32h4/include/hal/gdma_ll.h index 0e04e3b495..83db6730c6 100644 --- a/components/hal/esp32h4/include/hal/gdma_ll.h +++ b/components/hal/esp32h4/include/hal/gdma_ll.h @@ -9,6 +9,7 @@ #include "hal/ahb_dma_ll.h" #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/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/esp32p4/include/hal/gdma_ll.h b/components/hal/esp32p4/include/hal/gdma_ll.h index 6316a33f94..f987c56503 100644 --- a/components/hal/esp32p4/include/hal/gdma_ll.h +++ b/components/hal/esp32p4/include/hal/gdma_ll.h @@ -49,6 +49,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/hal/esp32s3/include/hal/gdma_ll.h b/components/hal/esp32s3/include/hal/gdma_ll.h index 58cc22253c..8cfba49a12 100644 --- a/components/hal/esp32s3/include/hal/gdma_ll.h +++ b/components/hal/esp32s3/include/hal/gdma_ll.h @@ -65,6 +65,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/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);