feat(mspi): split dma and mspi alignment

This commit is contained in:
Chen Jichang
2026-09-03 19:09:30 +08:00
committed by Chen Ji Chang
parent ef4387144e
commit 305d434bda
54 changed files with 668 additions and 420 deletions
+3 -1
View File
@@ -24,7 +24,8 @@ set(priv_requires efuse # only esp_hw_support/adc_share_hw_ctrl.
esp_hal_ana_conv # sleep process requires backup/restore some ADC, TSENS registers
)
set(srcs "cpu.c" "port/${IDF_TARGET}/esp_cpu_intr.c" "esp_memory_utils.c" "port/${IDF_TARGET}/cpu_region_protect.c")
set(srcs "cpu.c" "port/${IDF_TARGET}/esp_cpu_intr.c" "esp_memory_utils.c" "port/${IDF_TARGET}/cpu_region_protect.c"
"mspi/esp_mspi_align/esp_mspi_align.c")
if(NOT non_os_build)
list(APPEND srcs "esp_clk.c"
"clk_ctrl_os.c"
@@ -181,6 +182,7 @@ set(public_include_dirs "include" "include/soc"
"ldo/include" "debug_probe/include" "etm/include"
"mspi/mspi_timing_tuning/include" "mspi/mspi_timing_tuning/tuning_scheme_impl/include"
"mspi/mspi_intr/include"
"mspi/esp_mspi_align/include"
"power_supply/include" "modem/include")
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/include/soc/${target}")
+6 -3
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -14,6 +14,7 @@
#include "hal/gdma_ll.h"
#include "hal/efuse_hal.h"
#include "esp_efuse.h"
#include "esp_private/esp_mspi_align.h"
#endif
#if CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH
@@ -83,8 +84,10 @@ HEAP_IRAM_ATTR void esp_heap_adjust_alignment_to_hw(size_t *p_alignment, size_t
#endif
#if SOC_HAS(GDMA) && (SOC_PSRAM_DMA_CAPABLE || SOC_DMA_CAN_ACCESS_FLASH)
if ((caps & MALLOC_CAP_DMA) && esp_efuse_is_flash_encryption_enabled()) {
alignment = (alignment > SOC_MEMSPI_ENCRYPTION_ALIGNMENT) ? alignment : SOC_MEMSPI_ENCRYPTION_ALIGNMENT;
// CPU access to PSRAM always via cache, so alignment to MSPI alignment is needed when DMA is enabled and PSRAM is enabled.
if ((caps & MALLOC_CAP_DMA) && (caps & MALLOC_CAP_SPIRAM)) {
size_t mspi_align = esp_mspi_get_alignment(NULL);
alignment = (alignment > mspi_align) ? alignment : mspi_align;
}
#endif
@@ -0,0 +1,59 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <sys/param.h>
#include "sdkconfig.h"
#include "esp_efuse.h"
#include "esp_memory_utils.h"
#include "esp_private/esp_mspi_align.h"
#if CONFIG_SPIRAM
#include "esp_psram.h"
#endif /* CONFIG_SPIRAM */
#include "soc/soc_caps.h"
#define MSPI_FLASH_ENC_ALIGNMENT SOC_MEMSPI_ENCRYPTION_ALIGNMENT
#define MSPI_PSRAM_ECC_ALIGNMENT SOC_MEMSPI_ENCRYPTION_ALIGNMENT
size_t esp_mspi_get_alignment(const void *ptr)
{
size_t alignment = 1;
bool generic_query = ptr == NULL;
bool __attribute__((unused)) is_psram = esp_ptr_external_ram(ptr);
bool is_drom = esp_ptr_in_drom(ptr);
bool is_psram_enc = false;
#if CONFIG_SPIRAM
is_psram_enc = is_psram && !esp_psram_ptr_is_no_enc(ptr);
#endif /* CONFIG_SPIRAM */
if (esp_efuse_is_flash_encryption_enabled() && (generic_query || is_drom || is_psram_enc)) {
alignment = MAX(alignment, MSPI_FLASH_ENC_ALIGNMENT);
}
#if CONFIG_SPIRAM_ECC_ENABLE
if (generic_query || is_psram) {
alignment = MAX(alignment, MSPI_PSRAM_ECC_ALIGNMENT);
}
#endif
return alignment;
}
bool esp_mspi_buffer_alignment_satisfied(const void *ptr, size_t size)
{
// Zero-length is not a valid MSPI transfer, so it never satisfies the check.
if (ptr == NULL || size == 0) {
return false;
}
size_t alignment = esp_mspi_get_alignment(ptr);
if (alignment <= 1) {
return true;
}
uintptr_t addr = (uintptr_t)ptr;
return ((addr & (alignment - 1)) == 0) && ((size & (alignment - 1)) == 0);
}
@@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get MSPI alignment requirement for an address
*
* The address is used so future targets can apply different alignment rules to
* different MSPI-backed regions. Pass NULL when only the generic external-memory
* requirement is needed and no concrete address is available yet.
*
* @param ptr Buffer pointer in the region to be accessed, or NULL for generic query
* @return Required alignment in bytes, or 1 when no extra MSPI alignment is needed
*/
size_t esp_mspi_get_alignment(const void *ptr);
/**
* @brief Check whether a buffer satisfies MSPI strict alignment requirements
*
* Returns false when @p ptr is NULL or @p size is 0 (not a valid transfer).
* When strict alignment is not required, returns true for any non-empty buffer.
* When required, both @p ptr and @p size must be aligned to the rule returned by
* @ref esp_mspi_get_alignment for that address.
*
* @param ptr Buffer pointer
* @param size Transfer size in bytes
* @return true if alignment requirements are satisfied
*/
bool esp_mspi_buffer_alignment_satisfied(const void *ptr, size_t size);
#ifdef __cplusplus
}
#endif
+7
View File
@@ -1,3 +1,10 @@
[mapping:esp_mspi_align]
archive: libesp_hw_support.a
entries:
if APP_BUILD_TYPE_PURE_RAM_APP = n:
esp_mspi_align:esp_mspi_get_alignment (noflash)
esp_mspi_align:esp_mspi_buffer_alignment_satisfied (noflash)
[mapping:mspi_timing_tuning_driver]
archive: libesp_hw_support.a
entries: