Merge branch 'fix/fix_dma_fail_when_flash_enc_enabled_v5.5' into 'release/v5.5'
fix(dma): fix dma alignment when flash_enc enabled (v5.5) See merge request espressif/esp-idf!45080
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user