fix(gdma): fix dma burst size when flash enc enabled

This commit is contained in:
Chen Jichang
2026-01-08 16:13:01 +08:00
committed by morris
parent eef2372dce
commit 4f52afeb25
8 changed files with 29 additions and 48 deletions
+16 -21
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -382,6 +382,21 @@ esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transf
// always enable descriptor burst as the descriptor is always word aligned and is in the internal SRAM
bool en_desc_burst = true;
bool en_data_burst = max_data_burst_size > 0;
#if SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH
// if MSPI encryption is enabled, and DMA wants to read/write external memory
if (efuse_hal_flash_encryption_enabled() && config->access_ext_mem) {
uint32_t enc_mem_alignment = GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT;
// when DMA access the encrypted external memory, extra alignment is needed for external memory
ext_mem_alignment = MAX(ext_mem_alignment, enc_mem_alignment);
if (max_data_burst_size < enc_mem_alignment) {
ESP_LOGW(TAG, "GDMA channel access encrypted external memory, adjust burst size to %d", enc_mem_alignment);
en_data_burst = true;
max_data_burst_size = enc_mem_alignment;
}
}
#endif // SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH
gdma_hal_enable_burst(hal, pair->pair_id, dma_chan->direction, en_data_burst, en_desc_burst);
if (en_data_burst) {
gdma_hal_set_burst_size(hal, pair->pair_id, dma_chan->direction, max_data_burst_size);
@@ -394,26 +409,6 @@ esp_err_t gdma_config_transfer(gdma_channel_handle_t dma_chan, const gdma_transf
}
#endif
// if MSPI encryption is enabled, and DMA wants to read/write external memory
if (efuse_hal_flash_encryption_enabled()) {
gdma_hal_enable_access_encrypt_mem(hal, pair->pair_id, dma_chan->direction, config->access_ext_mem);
#if SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH
uint32_t enc_mem_alignment = GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT);
// when DMA access the encrypted external memory, extra alignment is needed for external memory
if (config->access_ext_mem) {
ext_mem_alignment = MAX(ext_mem_alignment, enc_mem_alignment);
}
#if SOC_HAS(AXI_GDMA)
if (group->bus_id == SOC_GDMA_BUS_AXI) {
// once AXI-GDMA enables access to encrypted memory, internal memory also needs to align
int_mem_alignment = MAX(int_mem_alignment, enc_mem_alignment);
}
#endif // SOC_HAS(AXI_GDMA)
#endif // SOC_PSRAM_DMA_CAPABLE
} else {
gdma_hal_enable_access_encrypt_mem(hal, pair->pair_id, dma_chan->direction, false);
}
// if the channel is not allowed to access external memory, set a super big (meaningless) alignment value
// so when the upper layer checks the alignment with an external buffer, the check should fail
if (!config->access_ext_mem) {
@@ -272,7 +272,7 @@ static void test_gdma_m2m_transaction(gdma_channel_handle_t tx_chan, gdma_channe
}
// test DMA can read data from main flash
#if SOC_DMA_CAN_ACCESS_FLASH
static const char src_string[] __attribute__((aligned(GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT)))) = "GDMA can read MSPI Flash data!!!";
static const char src_string[] __attribute__((aligned(GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT))) = "GDMA can read MSPI Flash data!!!";
size_t src_string_len = strlen(src_string);
TEST_ASSERT_TRUE(esp_ptr_in_drom(src_string));
@@ -70,10 +70,10 @@ static void test_gdma_crc_calculation(gdma_channel_handle_t tx_chan, int test_nu
uint32_t crc_result = 0;
static const char test_input_string[] __attribute__((aligned(GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT)))) = "GDMACRC Share::Connect::Innovate";
static const char test_input_string[] __attribute__((aligned(GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT))) = "GDMACRC Share::Connect::Innovate";
size_t input_data_size = strlen(test_input_string);
TEST_ASSERT_EQUAL((uintptr_t)test_input_string % GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT), 0);
TEST_ASSERT_EQUAL((uintptr_t)test_input_string % GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT, 0);
// this test case also test the GDMA can fetch data from MSPI Flash
TEST_ASSERT_TRUE(esp_ptr_in_drom(test_input_string));
printf("Calculate CRC value for string: \"%s\"\r\n", test_input_string);
+1 -1
View File
@@ -84,7 +84,7 @@ HEAP_IRAM_ATTR void esp_heap_adjust_alignment_to_hw(size_t *p_alignment, size_t
#if SOC_GDMA_SUPPORTED && (SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH)
if ((caps & MALLOC_CAP_DMA) && efuse_hal_flash_encryption_enabled()) {
alignment = (alignment > GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT)) ? alignment : GDMA_LL_GET(ACCESS_ENCRYPTION_MEM_ALIGNMENT);
alignment = (alignment > GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT) ? alignment : GDMA_LL_ACCESS_ENCRYPTION_MEM_ALIGNMENT;
}
#endif
@@ -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)
{
+1 -11
View File
@@ -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 -8
View File
@@ -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)
{
-3
View File
@@ -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);