mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
feat(dma2d,ppa): Support flash encryption for DMA2D and PPA
This commit is contained in:
@@ -6,5 +6,5 @@ set(srcs "test_app_main.c"
|
||||
# the component can be registered as WHOLE_ARCHIVE
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES unity esp_mm esp_psram esp_driver_dma
|
||||
PRIV_REQUIRES unity esp_mm esp_psram esp_driver_dma efuse
|
||||
WHOLE_ARCHIVE)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -17,6 +17,9 @@
|
||||
#include "hal/color_types.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_cache.h"
|
||||
#include "esp_efuse.h"
|
||||
|
||||
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
|
||||
// All test will perform `M2M_TRANS_TIMES` times memcpy transactions, utilizing all available 2D-DMA channels.
|
||||
// This tests the hardware capability of multiple 2D-DMA transactions running together, and the driver capbility of
|
||||
@@ -25,6 +28,7 @@
|
||||
#define M2M_TRANS_TIMES (12)
|
||||
|
||||
// Descriptor and buffer address and size should aligned to 64 bytes (the cacheline size alignment restriction) to be used by CPU
|
||||
// Additionally, if flash encryption is enabled, no matter descriptor or buffer, if in internal RAM, the address should be 16-byte aligned; if in external RAM, the address and size both should be 16-byte aligned.
|
||||
|
||||
static dma2d_descriptor_t *tx_dsc[M2M_TRANS_TIMES];
|
||||
static dma2d_descriptor_t *rx_dsc[M2M_TRANS_TIMES];
|
||||
@@ -71,8 +75,13 @@ TEST_CASE("DMA2D_M2M_1D_basic", "[DMA2D]")
|
||||
memset(m2m_trans_config, 0, M2M_TRANS_TIMES * sizeof(dma2d_m2m_trans_config_t));
|
||||
TEST_ESP_OK(dma2d_m2m_init());
|
||||
|
||||
dma2d_descriptor_t *tx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, MALLOC_CAP_DEFAULT);
|
||||
dma2d_descriptor_t *rx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, MALLOC_CAP_DEFAULT);
|
||||
uint32_t desc_malloc_cap = MALLOC_CAP_DEFAULT; // can be in internal RAM or external RAM
|
||||
if (esp_efuse_is_flash_encryption_enabled()) {
|
||||
// descriptor size is not 16-byte aligned, so can not be in external RAM
|
||||
desc_malloc_cap = MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT;
|
||||
}
|
||||
dma2d_descriptor_t *tx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, desc_malloc_cap);
|
||||
dma2d_descriptor_t *rx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, desc_malloc_cap);
|
||||
TEST_ASSERT_NOT_NULL(tx_link_buffer);
|
||||
TEST_ASSERT_NOT_NULL(rx_link_buffer);
|
||||
for (int i = 0; i < M2M_TRANS_TIMES; i++) {
|
||||
@@ -88,7 +97,8 @@ TEST_CASE("DMA2D_M2M_1D_basic", "[DMA2D]")
|
||||
TEST_ASSERT_NOT_NULL(rx_buf);
|
||||
|
||||
dma2d_transfer_ability_t transfer_ability_config = {
|
||||
.data_burst_length = DMA2D_DATA_BURST_LENGTH_64,
|
||||
.access_ext_mem = true,
|
||||
.data_burst_length = 64,
|
||||
.desc_burst_en = true,
|
||||
.mb_size = DMA2D_MACRO_BLOCK_SIZE_NONE,
|
||||
};
|
||||
@@ -210,8 +220,13 @@ TEST_CASE("DMA2D_M2M_1D_RGB565_to_RGB888", "[DMA2D]")
|
||||
memset(m2m_trans_config, 0, M2M_TRANS_TIMES * sizeof(dma2d_m2m_trans_config_t));
|
||||
TEST_ESP_OK(dma2d_m2m_init());
|
||||
|
||||
dma2d_descriptor_t *tx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, MALLOC_CAP_DEFAULT);
|
||||
dma2d_descriptor_t *rx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, MALLOC_CAP_DEFAULT);
|
||||
uint32_t desc_malloc_cap = MALLOC_CAP_DEFAULT; // can be in internal RAM or external RAM
|
||||
if (esp_efuse_is_flash_encryption_enabled()) {
|
||||
// descriptor size is not 16-byte aligned, so can not be in external RAM
|
||||
desc_malloc_cap = MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT;
|
||||
}
|
||||
dma2d_descriptor_t *tx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, desc_malloc_cap);
|
||||
dma2d_descriptor_t *rx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, desc_malloc_cap);
|
||||
TEST_ASSERT_NOT_NULL(tx_link_buffer);
|
||||
TEST_ASSERT_NOT_NULL(rx_link_buffer);
|
||||
for (int i = 0; i < M2M_TRANS_TIMES; i++) {
|
||||
@@ -229,7 +244,8 @@ TEST_CASE("DMA2D_M2M_1D_RGB565_to_RGB888", "[DMA2D]")
|
||||
SemaphoreHandle_t counting_sem = xSemaphoreCreateCounting(M2M_TRANS_TIMES, 0);
|
||||
|
||||
dma2d_transfer_ability_t transfer_ability_config = {
|
||||
.data_burst_length = DMA2D_DATA_BURST_LENGTH_128,
|
||||
.access_ext_mem = true,
|
||||
.data_burst_length = 128,
|
||||
.desc_burst_en = true,
|
||||
.mb_size = DMA2D_MACRO_BLOCK_SIZE_NONE,
|
||||
};
|
||||
@@ -323,8 +339,13 @@ TEST_CASE("DMA2D_M2M_2D_basic", "[DMA2D]")
|
||||
memset(m2m_trans_config, 0, M2M_TRANS_TIMES * sizeof(dma2d_m2m_trans_config_t));
|
||||
TEST_ESP_OK(dma2d_m2m_init());
|
||||
|
||||
dma2d_descriptor_t *tx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, MALLOC_CAP_DEFAULT);
|
||||
dma2d_descriptor_t *rx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, MALLOC_CAP_DEFAULT);
|
||||
uint32_t desc_malloc_cap = MALLOC_CAP_DEFAULT; // can be in internal RAM or external RAM
|
||||
if (esp_efuse_is_flash_encryption_enabled()) {
|
||||
// descriptor size is not 16-byte aligned, so can not be in external RAM
|
||||
desc_malloc_cap = MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT;
|
||||
}
|
||||
dma2d_descriptor_t *tx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, desc_malloc_cap);
|
||||
dma2d_descriptor_t *rx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, desc_malloc_cap);
|
||||
TEST_ASSERT_NOT_NULL(tx_link_buffer);
|
||||
TEST_ASSERT_NOT_NULL(rx_link_buffer);
|
||||
for (int i = 0; i < M2M_TRANS_TIMES; i++) {
|
||||
@@ -342,7 +363,8 @@ TEST_CASE("DMA2D_M2M_2D_basic", "[DMA2D]")
|
||||
SemaphoreHandle_t counting_sem = xSemaphoreCreateCounting(M2M_TRANS_TIMES, 0);
|
||||
|
||||
dma2d_transfer_ability_t transfer_ability_config = {
|
||||
.data_burst_length = DMA2D_DATA_BURST_LENGTH_128,
|
||||
.access_ext_mem = true,
|
||||
.data_burst_length = 128,
|
||||
.desc_burst_en = true,
|
||||
.mb_size = DMA2D_MACRO_BLOCK_SIZE_NONE,
|
||||
};
|
||||
@@ -456,8 +478,13 @@ TEST_CASE("DMA2D_M2M_2D_RGB888_to_RGB565", "[DMA2D]")
|
||||
memset(m2m_trans_config, 0, M2M_TRANS_TIMES * sizeof(dma2d_m2m_trans_config_t));
|
||||
TEST_ESP_OK(dma2d_m2m_init());
|
||||
|
||||
dma2d_descriptor_t *tx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, MALLOC_CAP_DEFAULT);
|
||||
dma2d_descriptor_t *rx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, MALLOC_CAP_DEFAULT);
|
||||
uint32_t desc_malloc_cap = MALLOC_CAP_DEFAULT; // can be in internal RAM or external RAM
|
||||
if (esp_efuse_is_flash_encryption_enabled()) {
|
||||
// descriptor size is not 16-byte aligned, so can not be in external RAM
|
||||
desc_malloc_cap = MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT;
|
||||
}
|
||||
dma2d_descriptor_t *tx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, desc_malloc_cap);
|
||||
dma2d_descriptor_t *rx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, desc_malloc_cap);
|
||||
TEST_ASSERT_NOT_NULL(tx_link_buffer);
|
||||
TEST_ASSERT_NOT_NULL(rx_link_buffer);
|
||||
for (int i = 0; i < M2M_TRANS_TIMES; i++) {
|
||||
@@ -475,7 +502,8 @@ TEST_CASE("DMA2D_M2M_2D_RGB888_to_RGB565", "[DMA2D]")
|
||||
SemaphoreHandle_t counting_sem = xSemaphoreCreateCounting(M2M_TRANS_TIMES, 0);
|
||||
|
||||
dma2d_transfer_ability_t transfer_ability_config = {
|
||||
.data_burst_length = DMA2D_DATA_BURST_LENGTH_16,
|
||||
.access_ext_mem = true,
|
||||
.data_burst_length = 16,
|
||||
.desc_burst_en = true,
|
||||
.mb_size = DMA2D_MACRO_BLOCK_SIZE_NONE,
|
||||
};
|
||||
@@ -562,17 +590,30 @@ TEST_CASE("DMA2D_M2M_2D_RGB888_to_RGB565", "[DMA2D]")
|
||||
|
||||
TEST_CASE("DMA2D_M2M_2D_window", "[DMA2D]")
|
||||
{
|
||||
// Test 2D memcpy to a 2 x 2 block at (2, 4) in a 8 x 8 picture (pixel in RGB565 format)
|
||||
// Test 2D memcpy to a 8 x 2 block at (8,0) in a 24 x 8 picture (pixel in RGB565 format)
|
||||
|
||||
// When flash encryption is enabled, and tx/rx buffer are in PSRAM (if located in internal RAM, there is no alignment restriction due to encryption):
|
||||
// - The address and size of the tx/rx buffer should be 16-byte aligned
|
||||
// - The width of the window multiply byte number of one pixel should be 16-byte aligned
|
||||
// - The address of every row of the window should be 16-byte aligned
|
||||
|
||||
const esp_color_fourcc_t pixel_format = ESP_COLOR_FOURCC_RGB16;
|
||||
const uint32_t va = 8, ha = 8; // Define picture height and width (unit: pixel)
|
||||
const uint32_t vb = 2, hb = 2; // Define block height and width (unit: pixel)
|
||||
const uint32_t x_offset = 2, y_offset = 4; // Define block location in the picture (unit: pixel)
|
||||
const uint32_t va = 8, ha = 24; // Define picture height and width (unit: pixel)
|
||||
const uint32_t vb = 2, hb = 8; // Define block height and width (unit: pixel)
|
||||
const uint32_t x_offset = 8, y_offset = 0; // Define block location in the picture (unit: pixel)
|
||||
|
||||
memset(m2m_trans_config, 0, M2M_TRANS_TIMES * sizeof(dma2d_m2m_trans_config_t));
|
||||
TEST_ESP_OK(dma2d_m2m_init());
|
||||
|
||||
dma2d_descriptor_t *tx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, MALLOC_CAP_DEFAULT);
|
||||
dma2d_descriptor_t *rx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, MALLOC_CAP_DEFAULT);
|
||||
uint32_t desc_malloc_cap = MALLOC_CAP_DEFAULT; // can be in internal RAM or external RAM
|
||||
uint32_t buf_malloc_cap = MALLOC_CAP_INTERNAL;
|
||||
if (esp_efuse_is_flash_encryption_enabled()) {
|
||||
// descriptor size is not 16-byte aligned, so can not be in external RAM
|
||||
desc_malloc_cap = MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT;
|
||||
buf_malloc_cap = MALLOC_CAP_SPIRAM; // to test its strict alignment requirement
|
||||
}
|
||||
dma2d_descriptor_t *tx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, desc_malloc_cap);
|
||||
dma2d_descriptor_t *rx_link_buffer = (dma2d_descriptor_t *)heap_caps_aligned_calloc(64, M2M_TRANS_TIMES, 64, desc_malloc_cap);
|
||||
TEST_ASSERT_NOT_NULL(tx_link_buffer);
|
||||
TEST_ASSERT_NOT_NULL(rx_link_buffer);
|
||||
for (int i = 0; i < M2M_TRANS_TIMES; i++) {
|
||||
@@ -582,15 +623,18 @@ TEST_CASE("DMA2D_M2M_2D_window", "[DMA2D]")
|
||||
|
||||
uint8_t *prtx;
|
||||
uint8_t *prrx;
|
||||
uint8_t *tx_buf = heap_caps_aligned_calloc(64, 64 * M2M_TRANS_TIMES, sizeof(uint8_t), MALLOC_CAP_INTERNAL);
|
||||
uint8_t *rx_buf = heap_caps_aligned_calloc(64, va * ha * 2 * M2M_TRANS_TIMES, sizeof(uint8_t), MALLOC_CAP_INTERNAL);
|
||||
size_t tx_buf_size = ALIGN_UP(vb * hb * 2, 64); // buffer msync alignment restriction
|
||||
uint8_t *tx_buf = heap_caps_aligned_calloc(64, tx_buf_size * M2M_TRANS_TIMES, sizeof(uint8_t), buf_malloc_cap);
|
||||
size_t rx_buf_size = ALIGN_UP(va * ha * 2, 64); // buffer msync alignment restriction
|
||||
uint8_t *rx_buf = heap_caps_aligned_calloc(64, rx_buf_size * M2M_TRANS_TIMES, sizeof(uint8_t), buf_malloc_cap);
|
||||
TEST_ASSERT_NOT_NULL(tx_buf);
|
||||
TEST_ASSERT_NOT_NULL(rx_buf);
|
||||
|
||||
SemaphoreHandle_t counting_sem = xSemaphoreCreateCounting(M2M_TRANS_TIMES, 0);
|
||||
|
||||
dma2d_transfer_ability_t transfer_ability_config = {
|
||||
.data_burst_length = DMA2D_DATA_BURST_LENGTH_128,
|
||||
.access_ext_mem = (buf_malloc_cap & MALLOC_CAP_SPIRAM) ? true : false,
|
||||
.data_burst_length = 128,
|
||||
.desc_burst_en = true,
|
||||
.mb_size = DMA2D_MACRO_BLOCK_SIZE_NONE,
|
||||
};
|
||||
@@ -598,8 +642,8 @@ TEST_CASE("DMA2D_M2M_2D_window", "[DMA2D]")
|
||||
// Preparation
|
||||
for (int i = 0; i < M2M_TRANS_TIMES; i++) {
|
||||
// Buffer data preparation
|
||||
prtx = tx_buf + i * 64;
|
||||
prrx = rx_buf + i * va * ha * 2;
|
||||
prtx = tx_buf + i * tx_buf_size;
|
||||
prrx = rx_buf + i * rx_buf_size;
|
||||
for (int idx = 0; idx < vb * hb; idx++) {
|
||||
prtx[idx * 2] = 0x55 + idx + i;
|
||||
prtx[idx * 2 + 1] = 0xAA + idx + i;
|
||||
@@ -610,8 +654,8 @@ TEST_CASE("DMA2D_M2M_2D_window", "[DMA2D]")
|
||||
}
|
||||
|
||||
// Writeback TX and RX buffers
|
||||
esp_cache_msync((void *)prtx, 64, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||
esp_cache_msync((void *)prrx, va * ha * 2, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||
esp_cache_msync((void *)prtx, tx_buf_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||
esp_cache_msync((void *)prrx, rx_buf_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||
|
||||
// DMA description preparation
|
||||
dma2d_link_dscr_init((uint32_t *)tx_dsc[i], NULL, (void *)prtx,
|
||||
@@ -649,12 +693,12 @@ TEST_CASE("DMA2D_M2M_2D_window", "[DMA2D]")
|
||||
|
||||
// Print the picture and check result
|
||||
for (int i = 0; i < M2M_TRANS_TIMES; i++) {
|
||||
prtx = tx_buf + i * 64;
|
||||
prrx = rx_buf + i * va * ha * 2;
|
||||
prtx = tx_buf + i * tx_buf_size;
|
||||
prrx = rx_buf + i * rx_buf_size;
|
||||
|
||||
// Invalidate TX and RX buffers
|
||||
esp_cache_msync((void *)prtx, 64, ESP_CACHE_MSYNC_FLAG_DIR_M2C);
|
||||
esp_cache_msync((void *)prrx, va * ha * 2, ESP_CACHE_MSYNC_FLAG_DIR_M2C);
|
||||
esp_cache_msync((void *)prtx, tx_buf_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C);
|
||||
esp_cache_msync((void *)prrx, rx_buf_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C);
|
||||
|
||||
printf("pic:\n");
|
||||
for (int idx = 0; idx < va * ha; idx++) {
|
||||
|
||||
@@ -15,6 +15,18 @@ from pytest_embedded_idf.utils import soc_filtered_targets
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', soc_filtered_targets('SOC_DMA2D_SUPPORTED == 1'), indirect=['target'])
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='p4 rev3 migration')
|
||||
def test_dma2d(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
|
||||
@pytest.mark.flash_encryption
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'flash_enc',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', soc_filtered_targets('SOC_DMA2D_SUPPORTED == 1'), indirect=['target'])
|
||||
def test_dma2d_flash_encryption(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user