From 11fe9fdad6920bb99185e17bf7767b83775e31cf Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Mon, 15 Dec 2025 17:44:59 +0530 Subject: [PATCH] feat(hal): Add support for flash/PSRAM protection through MSPI PMS --- .../esp32c5/include/hal/mspi_pms_ll.h | 195 +++++++++++++++ .../esp32c5/include/hal/psram_ctrlr_ll.h | 103 +------- .../esp32c61/include/hal/mspi_pms_ll.h | 195 +++++++++++++++ .../esp32c61/include/hal/psram_ctrlr_ll.h | 103 +------- .../esp32h4/include/hal/mspi_pms_ll.h | 200 ++++++++++++++++ .../esp32h4/include/hal/psram_ctrlr_ll.h | 103 +------- .../esp32p4/include/hal/mspi_pms_ll.h | 223 ++++++++++++++++++ .../esp32p4/include/hal/psram_ctrlr_ll.h | 99 -------- .../esp32s31/include/hal/mspi_pms_ll.h | 221 +++++++++++++++++ .../esp32s31/include/hal/psram_ctrlr_ll.h | 99 -------- .../esp_hal_mspi/include/hal/mspi_pms_types.h | 54 +++++ .../esp_psram/device/esp_psram_impl_ap_hex.c | 11 +- .../esp_psram/device/esp_psram_impl_ap_oct.c | 11 +- .../esp_psram/device/esp_psram_impl_ap_quad.c | 16 +- components/soc/esp32p4/include/soc/apm_defs.h | 5 - 15 files changed, 1114 insertions(+), 524 deletions(-) create mode 100644 components/esp_hal_mspi/esp32c5/include/hal/mspi_pms_ll.h create mode 100644 components/esp_hal_mspi/esp32c61/include/hal/mspi_pms_ll.h create mode 100644 components/esp_hal_mspi/esp32h4/include/hal/mspi_pms_ll.h create mode 100644 components/esp_hal_mspi/esp32p4/include/hal/mspi_pms_ll.h create mode 100644 components/esp_hal_mspi/esp32s31/include/hal/mspi_pms_ll.h create mode 100644 components/esp_hal_mspi/include/hal/mspi_pms_types.h diff --git a/components/esp_hal_mspi/esp32c5/include/hal/mspi_pms_ll.h b/components/esp_hal_mspi/esp32c5/include/hal/mspi_pms_ll.h new file mode 100644 index 00000000000..b707208bd4d --- /dev/null +++ b/components/esp_hal_mspi/esp32c5/include/hal/mspi_pms_ll.h @@ -0,0 +1,195 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include "hal/assert.h" +#include "hal/config.h" +#include "hal/mspi_ll.h" +#include "hal/mspi_pms_types.h" +#include "soc/spi_mem_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MSPI_LL_PMS_REGION_NUM 4 +#define MSPI_LL_PMS_REGION_ADDR_ALIGN 0x1000 + +/** + * @brief Enable/Disable MSPI PMS permission management + * + * @param mem Memory type (shared register - value ignored on this target) + * @param enable true to enable, false to disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_enable(mspi_pms_mem_t mem, bool enable) +{ + (void)mem; + SPIMEM0.mem_pms_reject.mem_pm_en = enable; +} + +/** + * @brief Set MSPI PMS region start address + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param addr Start address of the PMS region + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_addr(mspi_pms_mem_t mem, uint32_t regn, uint32_t addr) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_addr[regn].fmem_pmsn_addr_s = addr; + } else { + SPIMEM0.smem_pmsn_addr[regn].smem_pmsn_addr_s = addr; + } +} + +/** + * @brief Set MSPI PMS region size (in bytes) + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param size Size in bytes (must be a multiple of MSPI_LL_PMS_REGION_ADDR_ALIGN) + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_size(mspi_pms_mem_t mem, uint32_t regn, uint32_t size) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + HAL_ASSERT((size % MSPI_LL_PMS_REGION_ADDR_ALIGN) == 0); + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_size[regn].fmem_pmsn_size = size / MSPI_LL_PMS_REGION_ADDR_ALIGN; + } else { + SPIMEM0.smem_pmsn_size[regn].smem_pmsn_size = size / MSPI_LL_PMS_REGION_ADDR_ALIGN; + } +} + +/** + * @brief Get MSPI PMS region start address + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @return Start address of the PMS region + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_region_addr(mspi_pms_mem_t mem, uint32_t regn) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + uint32_t addr = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + addr = SPIMEM0.fmem_pmsn_addr[regn].fmem_pmsn_addr_s; + } else { + addr = SPIMEM0.smem_pmsn_addr[regn].smem_pmsn_addr_s; + } + return addr; +} + +/** + * @brief Get MSPI PMS region size (in bytes) + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @return Size of the PMS region in bytes + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_region_size(mspi_pms_mem_t mem, uint32_t regn) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + uint32_t size = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + size = SPIMEM0.fmem_pmsn_size[regn].fmem_pmsn_size; + } else { + size = SPIMEM0.smem_pmsn_size[regn].smem_pmsn_size; + } + return size * MSPI_LL_PMS_REGION_ADDR_ALIGN; +} + +/** + * @brief Set MSPI PMS region attributes for a specific security mode + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param mode Security mode + * @param attr Region attribute flags - RD/WR/ECC (mspi_pms_attr_t) + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_attr(mspi_pms_mem_t mem, uint32_t regn, mspi_pms_mode_t mode, mspi_pms_attr_t attr) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + if (mode != MSPI_PMS_MODE_TEE) { + return; + } + + uint32_t bits = attr & (MSPI_PMS_ATTR_RD | MSPI_PMS_ATTR_WR | MSPI_PMS_ATTR_ECC); + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_attr[regn].val = bits; + } else { + SPIMEM0.smem_pmsn_attr[regn].val = bits; + } +} + +/** + * @brief Get MSPI PMS reject address + * + * @param mem Memory type (shared register - value ignored on this target) + * @return Address that caused PMS violation + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_reject_addr(mspi_pms_mem_t mem) +{ + (void)mem; + return SPIMEM0.mem_pms_reject_addr.mem_reject_addr; +} + +/** + * @brief Get MSPI PMS error mask + * + * @param mem Memory type (shared register - value ignored on this target) + * @return Bitmask of error types (mspi_pms_err_t), or MSPI_PMS_ERR_NONE if no error + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_err_mask(mspi_pms_mem_t mem) +{ + (void)mem; + uint32_t err = MSPI_PMS_ERR_NONE; + if (SPIMEM0.mem_pms_reject.mem_pms_multi_hit) { + err |= MSPI_PMS_ERR_ADDR_MULTI; + } + if (SPIMEM0.mem_pms_reject.mem_pms_ivd) { + err |= MSPI_PMS_ERR_ADDR_MISS; + } + if (SPIMEM0.mem_pms_reject.mem_pms_st) { + err |= MSPI_PMS_ERR_WRITE; + } + if (SPIMEM0.mem_pms_reject.mem_pms_ld) { + err |= MSPI_PMS_ERR_READ; + } + return err; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32c5/include/hal/psram_ctrlr_ll.h b/components/esp_hal_mspi/esp32c5/include/hal/psram_ctrlr_ll.h index 9f3bd778e7d..80cc18ec5a7 100644 --- a/components/esp_hal_mspi/esp32c5/include/hal/psram_ctrlr_ll.h +++ b/components/esp_hal_mspi/esp32c5/include/hal/psram_ctrlr_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,9 +33,6 @@ extern "C" { #define PSRAM_CTRLR_LL_MSPI_ID_PERI PSRAM_CTRLR_LL_MSPI_ID_1 #define PSRAM_LL_CS_SEL SPI_MEM_CS1_DIS_M -#define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4 -#define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0) -#define PSRAM_CTRLR_LL_PMS_ATTR_READABLE (1<<1) #define PSRAM_CTRLR_LL_PMS_INT_SUPPORTED 1 #define PSRAM_CTRLR_LL_ADDR_INT_SUPPORTED 1 @@ -429,104 +426,6 @@ static inline void psram_ctrlr_ll_enable_ecc_addr_conversion(uint32_t mspi_id, b SPIMEM0.smem_ecc_ctrl.smem_ecc_addr_en = en; } -/*--------------------------------------------------------------- - PMS ----------------------------------------------------------------*/ -/** - * @brief Enable PMS ECC - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param en enable / disable - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_enable_pms_region_ecc(uint32_t mspi_id, uint32_t region_id, bool en) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_ecc = en; -} - -/** - * @brief Set PMS attr - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param attr_mask attribute mask - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_attr(uint32_t mspi_id, uint32_t region_id, uint32_t attr_mask) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_wr_attr = 0; - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_rd_attr = 0; - if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE) { - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_wr_attr = 1; - } - if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_READABLE) { - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_rd_attr = 1; - } -} - -/** - * @brief Set PMS address - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param addr start addr - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id, uint32_t addr) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_addr[region_id].smem_pmsn_addr_s = addr; -} - -/** - * @brief Set PMS size - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param size size - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_size(uint32_t mspi_id, uint32_t region_id, uint32_t size) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_size[region_id].smem_pmsn_size = size; -} - -/** - * @brief Get PMS address - * - * @param mspi_id mspi_id - * @param region_id region_id - */ -__attribute__((always_inline)) -static inline uint32_t psram_ctrlr_ll_get_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - return SPIMEM0.smem_pmsn_addr[region_id].smem_pmsn_addr_s; -} - -/** - * @brief Get PMS size - * - * @param mspi_id mspi_id - * @param region_id region_id - */ -__attribute__((always_inline)) -static inline uint32_t psram_ctrlr_ll_get_pms_region_size(uint32_t mspi_id, uint32_t region_id) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - return SPIMEM0.smem_pmsn_size[region_id].smem_pmsn_size; -} - #ifdef __cplusplus } #endif diff --git a/components/esp_hal_mspi/esp32c61/include/hal/mspi_pms_ll.h b/components/esp_hal_mspi/esp32c61/include/hal/mspi_pms_ll.h new file mode 100644 index 00000000000..b707208bd4d --- /dev/null +++ b/components/esp_hal_mspi/esp32c61/include/hal/mspi_pms_ll.h @@ -0,0 +1,195 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include "hal/assert.h" +#include "hal/config.h" +#include "hal/mspi_ll.h" +#include "hal/mspi_pms_types.h" +#include "soc/spi_mem_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MSPI_LL_PMS_REGION_NUM 4 +#define MSPI_LL_PMS_REGION_ADDR_ALIGN 0x1000 + +/** + * @brief Enable/Disable MSPI PMS permission management + * + * @param mem Memory type (shared register - value ignored on this target) + * @param enable true to enable, false to disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_enable(mspi_pms_mem_t mem, bool enable) +{ + (void)mem; + SPIMEM0.mem_pms_reject.mem_pm_en = enable; +} + +/** + * @brief Set MSPI PMS region start address + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param addr Start address of the PMS region + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_addr(mspi_pms_mem_t mem, uint32_t regn, uint32_t addr) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_addr[regn].fmem_pmsn_addr_s = addr; + } else { + SPIMEM0.smem_pmsn_addr[regn].smem_pmsn_addr_s = addr; + } +} + +/** + * @brief Set MSPI PMS region size (in bytes) + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param size Size in bytes (must be a multiple of MSPI_LL_PMS_REGION_ADDR_ALIGN) + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_size(mspi_pms_mem_t mem, uint32_t regn, uint32_t size) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + HAL_ASSERT((size % MSPI_LL_PMS_REGION_ADDR_ALIGN) == 0); + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_size[regn].fmem_pmsn_size = size / MSPI_LL_PMS_REGION_ADDR_ALIGN; + } else { + SPIMEM0.smem_pmsn_size[regn].smem_pmsn_size = size / MSPI_LL_PMS_REGION_ADDR_ALIGN; + } +} + +/** + * @brief Get MSPI PMS region start address + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @return Start address of the PMS region + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_region_addr(mspi_pms_mem_t mem, uint32_t regn) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + uint32_t addr = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + addr = SPIMEM0.fmem_pmsn_addr[regn].fmem_pmsn_addr_s; + } else { + addr = SPIMEM0.smem_pmsn_addr[regn].smem_pmsn_addr_s; + } + return addr; +} + +/** + * @brief Get MSPI PMS region size (in bytes) + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @return Size of the PMS region in bytes + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_region_size(mspi_pms_mem_t mem, uint32_t regn) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + uint32_t size = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + size = SPIMEM0.fmem_pmsn_size[regn].fmem_pmsn_size; + } else { + size = SPIMEM0.smem_pmsn_size[regn].smem_pmsn_size; + } + return size * MSPI_LL_PMS_REGION_ADDR_ALIGN; +} + +/** + * @brief Set MSPI PMS region attributes for a specific security mode + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param mode Security mode + * @param attr Region attribute flags - RD/WR/ECC (mspi_pms_attr_t) + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_attr(mspi_pms_mem_t mem, uint32_t regn, mspi_pms_mode_t mode, mspi_pms_attr_t attr) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + if (mode != MSPI_PMS_MODE_TEE) { + return; + } + + uint32_t bits = attr & (MSPI_PMS_ATTR_RD | MSPI_PMS_ATTR_WR | MSPI_PMS_ATTR_ECC); + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_attr[regn].val = bits; + } else { + SPIMEM0.smem_pmsn_attr[regn].val = bits; + } +} + +/** + * @brief Get MSPI PMS reject address + * + * @param mem Memory type (shared register - value ignored on this target) + * @return Address that caused PMS violation + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_reject_addr(mspi_pms_mem_t mem) +{ + (void)mem; + return SPIMEM0.mem_pms_reject_addr.mem_reject_addr; +} + +/** + * @brief Get MSPI PMS error mask + * + * @param mem Memory type (shared register - value ignored on this target) + * @return Bitmask of error types (mspi_pms_err_t), or MSPI_PMS_ERR_NONE if no error + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_err_mask(mspi_pms_mem_t mem) +{ + (void)mem; + uint32_t err = MSPI_PMS_ERR_NONE; + if (SPIMEM0.mem_pms_reject.mem_pms_multi_hit) { + err |= MSPI_PMS_ERR_ADDR_MULTI; + } + if (SPIMEM0.mem_pms_reject.mem_pms_ivd) { + err |= MSPI_PMS_ERR_ADDR_MISS; + } + if (SPIMEM0.mem_pms_reject.mem_pms_st) { + err |= MSPI_PMS_ERR_WRITE; + } + if (SPIMEM0.mem_pms_reject.mem_pms_ld) { + err |= MSPI_PMS_ERR_READ; + } + return err; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32c61/include/hal/psram_ctrlr_ll.h b/components/esp_hal_mspi/esp32c61/include/hal/psram_ctrlr_ll.h index 9f3bd778e7d..80cc18ec5a7 100644 --- a/components/esp_hal_mspi/esp32c61/include/hal/psram_ctrlr_ll.h +++ b/components/esp_hal_mspi/esp32c61/include/hal/psram_ctrlr_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,9 +33,6 @@ extern "C" { #define PSRAM_CTRLR_LL_MSPI_ID_PERI PSRAM_CTRLR_LL_MSPI_ID_1 #define PSRAM_LL_CS_SEL SPI_MEM_CS1_DIS_M -#define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4 -#define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0) -#define PSRAM_CTRLR_LL_PMS_ATTR_READABLE (1<<1) #define PSRAM_CTRLR_LL_PMS_INT_SUPPORTED 1 #define PSRAM_CTRLR_LL_ADDR_INT_SUPPORTED 1 @@ -429,104 +426,6 @@ static inline void psram_ctrlr_ll_enable_ecc_addr_conversion(uint32_t mspi_id, b SPIMEM0.smem_ecc_ctrl.smem_ecc_addr_en = en; } -/*--------------------------------------------------------------- - PMS ----------------------------------------------------------------*/ -/** - * @brief Enable PMS ECC - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param en enable / disable - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_enable_pms_region_ecc(uint32_t mspi_id, uint32_t region_id, bool en) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_ecc = en; -} - -/** - * @brief Set PMS attr - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param attr_mask attribute mask - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_attr(uint32_t mspi_id, uint32_t region_id, uint32_t attr_mask) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_wr_attr = 0; - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_rd_attr = 0; - if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE) { - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_wr_attr = 1; - } - if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_READABLE) { - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_rd_attr = 1; - } -} - -/** - * @brief Set PMS address - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param addr start addr - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id, uint32_t addr) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_addr[region_id].smem_pmsn_addr_s = addr; -} - -/** - * @brief Set PMS size - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param size size - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_size(uint32_t mspi_id, uint32_t region_id, uint32_t size) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_size[region_id].smem_pmsn_size = size; -} - -/** - * @brief Get PMS address - * - * @param mspi_id mspi_id - * @param region_id region_id - */ -__attribute__((always_inline)) -static inline uint32_t psram_ctrlr_ll_get_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - return SPIMEM0.smem_pmsn_addr[region_id].smem_pmsn_addr_s; -} - -/** - * @brief Get PMS size - * - * @param mspi_id mspi_id - * @param region_id region_id - */ -__attribute__((always_inline)) -static inline uint32_t psram_ctrlr_ll_get_pms_region_size(uint32_t mspi_id, uint32_t region_id) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - return SPIMEM0.smem_pmsn_size[region_id].smem_pmsn_size; -} - #ifdef __cplusplus } #endif diff --git a/components/esp_hal_mspi/esp32h4/include/hal/mspi_pms_ll.h b/components/esp_hal_mspi/esp32h4/include/hal/mspi_pms_ll.h new file mode 100644 index 00000000000..34e3ae5f981 --- /dev/null +++ b/components/esp_hal_mspi/esp32h4/include/hal/mspi_pms_ll.h @@ -0,0 +1,200 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include "hal/assert.h" +#include "hal/config.h" +#include "hal/mspi_ll.h" +#include "hal/mspi_pms_types.h" +#include "soc/spi_mem_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MSPI_LL_PMS_REGION_NUM 4 +#define MSPI_LL_PMS_REGION_ADDR_ALIGN 0x1000 +/* Each security-mode field in the PMS attribute register is 3 bits wide: + bit 0/3: RD, bit 1/4: WR, bit 2/5: ECC. */ +#define MSPI_LL_PMS_MODE_FIELD_WIDTH 3 +#define MSPI_LL_PMS_FIELD_MASK ((1U << MSPI_LL_PMS_MODE_FIELD_WIDTH) - 1) + +/** + * @brief Enable/Disable MSPI PMS permission management + * + * @param mem Memory type (shared register - value ignored on this target) + * @param enable true to enable, false to disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_enable(mspi_pms_mem_t mem, bool enable) +{ + (void)mem; + SPIMEM0.pms_reject.pm_en = enable; +} + +/** + * @brief Set MSPI PMS region start address + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param addr Start address of the PMS region + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_addr(mspi_pms_mem_t mem, uint32_t regn, uint32_t addr) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_addr[regn].fmem_pmsn_addr_s = addr; + } else { + SPIMEM0.smem_pmsn_addr[regn].smem_pmsn_addr_s = addr; + } +} + +/** + * @brief Set MSPI PMS region size (in bytes) + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param size Size in bytes (must be a multiple of MSPI_LL_PMS_REGION_ADDR_ALIGN) + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_size(mspi_pms_mem_t mem, uint32_t regn, uint32_t size) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + HAL_ASSERT((size % MSPI_LL_PMS_REGION_ADDR_ALIGN) == 0); + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_size[regn].fmem_pmsn_size = size / MSPI_LL_PMS_REGION_ADDR_ALIGN; + } else { + SPIMEM0.smem_pmsn_size[regn].smem_pmsn_size = size / MSPI_LL_PMS_REGION_ADDR_ALIGN; + } +} + +/** + * @brief Get MSPI PMS region start address + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @return Start address of the PMS region + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_region_addr(mspi_pms_mem_t mem, uint32_t regn) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + uint32_t addr = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + addr = SPIMEM0.fmem_pmsn_addr[regn].fmem_pmsn_addr_s; + } else { + addr = SPIMEM0.smem_pmsn_addr[regn].smem_pmsn_addr_s; + } + return addr; +} + +/** + * @brief Get MSPI PMS region size (in bytes) + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @return Size of the PMS region in bytes + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_region_size(mspi_pms_mem_t mem, uint32_t regn) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + uint32_t size = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + size = SPIMEM0.fmem_pmsn_size[regn].fmem_pmsn_size; + } else { + size = SPIMEM0.smem_pmsn_size[regn].smem_pmsn_size; + } + return size * MSPI_LL_PMS_REGION_ADDR_ALIGN; +} + +/** + * @brief Set MSPI PMS region attributes for a specific security mode + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param mode Security mode (TEE or REE) + * @param attr Region attribute flags - RD/WR/ECC (mspi_pms_attr_t) + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_attr(mspi_pms_mem_t mem, uint32_t regn, mspi_pms_mode_t mode, mspi_pms_attr_t attr) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + /* Each mode field is 3 bits wide [RD, WR, ECC]: TEE at bits [2:0], + REE at bits [5:3] - replace the whole field, shifted by mode * 3. */ + uint32_t shift = (uint32_t)mode * MSPI_LL_PMS_MODE_FIELD_WIDTH; + uint32_t mask = MSPI_LL_PMS_FIELD_MASK << shift; + uint32_t bits = (uint32_t)attr << shift; + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_attr[regn].val = (SPIMEM0.fmem_pmsn_attr[regn].val & ~mask) | bits; + } else { + SPIMEM0.smem_pmsn_attr[regn].val = (SPIMEM0.smem_pmsn_attr[regn].val & ~mask) | bits; + } +} + +/** + * @brief Get MSPI PMS reject address + * + * @param mem Memory type (shared register - value ignored on this target) + * @return Address that caused PMS violation + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_reject_addr(mspi_pms_mem_t mem) +{ + (void)mem; + return SPIMEM0.pms_reject_addr.reject_addr; +} + +/** + * @brief Get MSPI PMS error mask + * + * @param mem Memory type (shared register - value ignored on this target) + * @return Bitmask of error types (mspi_pms_err_t), or MSPI_PMS_ERR_NONE if no error + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_err_mask(mspi_pms_mem_t mem) +{ + (void)mem; + uint32_t err = MSPI_PMS_ERR_NONE; + if (SPIMEM0.pms_reject.pms_multi_hit) { + err |= MSPI_PMS_ERR_ADDR_MULTI; + } + if (SPIMEM0.pms_reject.pms_ivd) { + err |= MSPI_PMS_ERR_ADDR_MISS; + } + if (SPIMEM0.pms_reject.pms_st) { + err |= MSPI_PMS_ERR_WRITE; + } + if (SPIMEM0.pms_reject.pms_ld) { + err |= MSPI_PMS_ERR_READ; + } + return err; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32h4/include/hal/psram_ctrlr_ll.h b/components/esp_hal_mspi/esp32h4/include/hal/psram_ctrlr_ll.h index bed423c9983..b69ce68645b 100644 --- a/components/esp_hal_mspi/esp32h4/include/hal/psram_ctrlr_ll.h +++ b/components/esp_hal_mspi/esp32h4/include/hal/psram_ctrlr_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,9 +33,6 @@ extern "C" { #define PSRAM_CTRLR_LL_MSPI_ID_PERI PSRAM_CTRLR_LL_MSPI_ID_1 #define PSRAM_LL_CS_SEL SPI_MEM_CS1_DIS_M -#define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4 -#define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0) -#define PSRAM_CTRLR_LL_PMS_ATTR_READABLE (1<<1) #define PSRAM_CTRLR_LL_PMS_INT_SUPPORTED 1 #define PSRAM_CTRLR_LL_ADDR_INT_SUPPORTED 1 @@ -429,104 +426,6 @@ static inline void psram_ctrlr_ll_enable_ecc_addr_conversion(uint32_t mspi_id, b SPIMEM0.smem_ecc_ctrl.smem_ecc_addr_en = en; } -/*--------------------------------------------------------------- - PMS ----------------------------------------------------------------*/ -/** - * @brief Enable PMS ECC - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param en enable / disable - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_enable_pms_region_ecc(uint32_t mspi_id, uint32_t region_id, bool en) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_ecc = en; -} - -/** - * @brief Set PMS attr - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param attr_mask attribute mask - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_attr(uint32_t mspi_id, uint32_t region_id, uint32_t attr_mask) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_wr_attr = 0; - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_rd_attr = 0; - if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE) { - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_wr_attr = 1; - } - if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_READABLE) { - SPIMEM0.smem_pmsn_attr[region_id].smem_pmsn_rd_attr = 1; - } -} - -/** - * @brief Set PMS address - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param addr start addr - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id, uint32_t addr) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_addr[region_id].smem_pmsn_addr_s = addr; -} - -/** - * @brief Set PMS size - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param size size - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_size(uint32_t mspi_id, uint32_t region_id, uint32_t size) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM0.smem_pmsn_size[region_id].smem_pmsn_size = size; -} - -/** - * @brief Get PMS address - * - * @param mspi_id mspi_id - * @param region_id region_id - */ -__attribute__((always_inline)) -static inline uint32_t psram_ctrlr_ll_get_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - return SPIMEM0.smem_pmsn_addr[region_id].smem_pmsn_addr_s; -} - -/** - * @brief Get PMS size - * - * @param mspi_id mspi_id - * @param region_id region_id - */ -__attribute__((always_inline)) -static inline uint32_t psram_ctrlr_ll_get_pms_region_size(uint32_t mspi_id, uint32_t region_id) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - return SPIMEM0.smem_pmsn_size[region_id].smem_pmsn_size; -} - #ifdef __cplusplus } #endif diff --git a/components/esp_hal_mspi/esp32p4/include/hal/mspi_pms_ll.h b/components/esp_hal_mspi/esp32p4/include/hal/mspi_pms_ll.h new file mode 100644 index 00000000000..438cc383fb3 --- /dev/null +++ b/components/esp_hal_mspi/esp32p4/include/hal/mspi_pms_ll.h @@ -0,0 +1,223 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include "hal/assert.h" +#include "hal/config.h" +#include "hal/mspi_ll.h" +#include "hal/mspi_pms_types.h" +#include "soc/spi_mem_struct.h" +#include "soc/spi_mem_s_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MSPI_LL_PMS_REGION_NUM 4 +#define MSPI_LL_PMS_REGION_ADDR_ALIGN 0x1000 +/* Each security-mode field in the PMS attribute register is 3 bits wide: + bit 0/3: RD, bit 1/4: WR, bit 2/5: ECC. */ +#define MSPI_LL_PMS_MODE_FIELD_WIDTH 3 +#define MSPI_LL_PMS_FIELD_MASK ((1U << MSPI_LL_PMS_MODE_FIELD_WIDTH) - 1) + +/** + * @brief Enable/Disable MSPI PMS permission management + * + * @param mem Memory type (flash or PSRAM) + * @param enable true to enable, false to disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_enable(mspi_pms_mem_t mem, bool enable) +{ + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.pms_reject.pm_en = enable; + } else { + SPIMEM2.mem_pms_reject.mem_pm_en = enable; + } +} + +/** + * @brief Set MSPI PMS region start address + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param addr Start address of the PMS region + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_addr(mspi_pms_mem_t mem, uint32_t regn, uint32_t addr) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_addr[regn].fmem_pmsn_addr_s = addr; + } else { + SPIMEM2.smem_pmsn_addr[regn].smem_pms_addr_s = addr; + } +} + +/** + * @brief Set MSPI PMS region size (in bytes) + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param size Size in bytes (must be a multiple of MSPI_LL_PMS_REGION_ADDR_ALIGN) + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_size(mspi_pms_mem_t mem, uint32_t regn, uint32_t size) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + HAL_ASSERT((size % MSPI_LL_PMS_REGION_ADDR_ALIGN) == 0); + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_size[regn].fmem_pmsn_size = size / MSPI_LL_PMS_REGION_ADDR_ALIGN; + } else { + SPIMEM2.smem_pmsn_size[regn].smem_pms_size = size / MSPI_LL_PMS_REGION_ADDR_ALIGN; + } +} + +/** + * @brief Get MSPI PMS region start address + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @return Start address of the PMS region + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_region_addr(mspi_pms_mem_t mem, uint32_t regn) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + uint32_t addr = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + addr = SPIMEM0.fmem_pmsn_addr[regn].fmem_pmsn_addr_s; + } else { + addr = SPIMEM2.smem_pmsn_addr[regn].smem_pms_addr_s; + } + return addr; +} + +/** + * @brief Get MSPI PMS region size (in bytes) + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @return Size of the PMS region in bytes + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_region_size(mspi_pms_mem_t mem, uint32_t regn) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + uint32_t size = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + size = SPIMEM0.fmem_pmsn_size[regn].fmem_pmsn_size; + } else { + size = SPIMEM2.smem_pmsn_size[regn].smem_pms_size; + } + return size * MSPI_LL_PMS_REGION_ADDR_ALIGN; +} + +/** + * @brief Set MSPI PMS region attributes for a specific security mode + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param mode Security mode (TEE or REE) + * @param attr Region attribute flags - RD/WR/ECC (mspi_pms_attr_t) + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_attr(mspi_pms_mem_t mem, uint32_t regn, mspi_pms_mode_t mode, mspi_pms_attr_t attr) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + /* Each mode field is 3 bits wide [RD, WR, ECC]: TEE at bits [2:0], + REE at bits [5:3] - replace the whole field, shifted by mode * 3. */ + uint32_t shift = (uint32_t)mode * MSPI_LL_PMS_MODE_FIELD_WIDTH; + uint32_t mask = MSPI_LL_PMS_FIELD_MASK << shift; + uint32_t bits = (uint32_t)attr << shift; + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_attr[regn].val = (SPIMEM0.fmem_pmsn_attr[regn].val & ~mask) | bits; + } else { + SPIMEM2.smem_pmsn_attr[regn].val = (SPIMEM2.smem_pmsn_attr[regn].val & ~mask) | bits; + } +} + +/** + * @brief Get MSPI PMS reject address + * + * @param mem Memory type (flash or PSRAM) + * @return Address that caused PMS violation + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_reject_addr(mspi_pms_mem_t mem) +{ + uint32_t addr = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + addr = SPIMEM0.pms_reject.reject_addr; + } else { + addr = SPIMEM2.mem_pms_reject.mem_reject_addr; + } + return addr; +} + +/** + * @brief Get MSPI PMS error mask + * + * @param mem Memory type (flash or PSRAM) + * @return Bitmask of error types (mspi_pms_err_t), or MSPI_PMS_ERR_NONE if no error + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_err_mask(mspi_pms_mem_t mem) +{ + bool multi_hit, ivd, st, ld; + if (mem == MSPI_PMS_MEM_FLASH) { + spi_mem_c_pms_reject_reg_t r = { .val = SPIMEM0.pms_reject.val }; + multi_hit = r.pms_multi_hit; + ivd = r.pms_ivd; + st = r.pms_st; + ld = r.pms_ld; + } else { + spi_mem_s_pms_reject_reg_t r = { .val = SPIMEM2.mem_pms_reject.val }; + multi_hit = r.mem_pms_multi_hit; + ivd = r.mem_pms_ivd; + st = r.mem_pms_st; + ld = r.mem_pms_ld; + } + + uint32_t err = MSPI_PMS_ERR_NONE; + if (multi_hit) { + err |= MSPI_PMS_ERR_ADDR_MULTI; + } + if (ivd) { + err |= MSPI_PMS_ERR_ADDR_MISS; + } + if (st) { + err |= MSPI_PMS_ERR_WRITE; + } + if (ld) { + err |= MSPI_PMS_ERR_READ; + } + return err; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32p4/include/hal/psram_ctrlr_ll.h b/components/esp_hal_mspi/esp32p4/include/hal/psram_ctrlr_ll.h index d59c3faffef..fd9cfe26731 100644 --- a/components/esp_hal_mspi/esp32p4/include/hal/psram_ctrlr_ll.h +++ b/components/esp_hal_mspi/esp32p4/include/hal/psram_ctrlr_ll.h @@ -37,10 +37,6 @@ extern "C" { #define PSRAM_CTRLR_LL_MSPI_ID_SYSTEM PSRAM_CTRLR_LL_MSPI_ID_2 #define PSRAM_CTRLR_LL_MSPI_ID_PERI PSRAM_CTRLR_LL_MSPI_ID_3 -#define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4 -#define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0) -#define PSRAM_CTRLR_LL_PMS_ATTR_READABLE (1<<1) - #define PSRAM_CTRLR_LL_FIFO_MAX_BYTES 64 #define PSRAM_CTRLR_LL_THRESH_INT_SUPPORTED 1 @@ -708,101 +704,6 @@ static inline uint32_t psram_ctrlr_ll_get_page_size(uint32_t mspi_id) return page_size; } -/** - * @brief Enable PMS ECC - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param en enable / disable - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_enable_pms_region_ecc(uint32_t mspi_id, uint32_t region_id, bool en) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM2.smem_pmsn_attr[region_id].smem_pms_ecc = en; -} - -/** - * @brief Set PMS attr - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param attr_mask attribute mask - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_attr(uint32_t mspi_id, uint32_t region_id, uint32_t attr_mask) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM2.smem_pmsn_attr[region_id].smem_pms_wr_attr = 0; - SPIMEM2.smem_pmsn_attr[region_id].smem_pms_rd_attr = 0; - if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE) { - SPIMEM2.smem_pmsn_attr[region_id].smem_pms_wr_attr = 1; - } - if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_READABLE) { - SPIMEM2.smem_pmsn_attr[region_id].smem_pms_rd_attr = 1; - } -} - -/** - * @brief Set PMS address - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param addr start addr - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id, uint32_t addr) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM2.smem_pmsn_addr[region_id].smem_pms_addr_s = addr; -} - -/** - * @brief Set PMS size - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param size size - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_size(uint32_t mspi_id, uint32_t region_id, uint32_t size) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM2.smem_pmsn_size[region_id].smem_pms_size = size; -} - -/** - * @brief Get PMS address - * - * @param mspi_id mspi_id - * @param region_id region_id - */ -__attribute__((always_inline)) -static inline uint32_t psram_ctrlr_ll_get_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - return SPIMEM2.smem_pmsn_addr[region_id].smem_pms_addr_s; -} - -/** - * @brief Get PMS size - * - * @param mspi_id mspi_id - * @param region_id region_id - */ -__attribute__((always_inline)) -static inline uint32_t psram_ctrlr_ll_get_pms_region_size(uint32_t mspi_id, uint32_t region_id) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - return SPIMEM2.smem_pmsn_size[region_id].smem_pms_size; -} - /** * @brief PSRAM common transaction * diff --git a/components/esp_hal_mspi/esp32s31/include/hal/mspi_pms_ll.h b/components/esp_hal_mspi/esp32s31/include/hal/mspi_pms_ll.h new file mode 100644 index 00000000000..bce16331f09 --- /dev/null +++ b/components/esp_hal_mspi/esp32s31/include/hal/mspi_pms_ll.h @@ -0,0 +1,221 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The ll is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include "hal/assert.h" +#include "hal/config.h" +#include "hal/mspi_ll.h" +#include "hal/mspi_pms_types.h" +#include "soc/spi_mem_struct.h" +#include "soc/spi_mem_s_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MSPI_LL_PMS_REGION_NUM 4 +#define MSPI_LL_PMS_REGION_ADDR_ALIGN 0x1000 +/* Each security-mode field in the PMS attribute register is 3 bits wide: + bit 0/3: RD, bit 1/4: WR, bit 2/5: ECC. */ +#define MSPI_LL_PMS_MODE_FIELD_WIDTH 3 +#define MSPI_LL_PMS_FIELD_MASK ((1U << MSPI_LL_PMS_MODE_FIELD_WIDTH) - 1) + +/** + * @brief Enable/Disable MSPI PMS permission management + * + * @param mem Memory type (flash or PSRAM) + * @param enable true to enable, false to disable + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_enable(mspi_pms_mem_t mem, bool enable) +{ + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.mem_pms_reject.mem_pm_en = enable; + } else { + SPIMEM2.mem_pms_reject.mem_pm_en = enable; + } +} + +/** + * @brief Set MSPI PMS region start address + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param addr Start address of the PMS region + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_addr(mspi_pms_mem_t mem, uint32_t regn, uint32_t addr) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_addr[regn].fmem_pmsn_addr_s = addr; + } else { + SPIMEM2.smem_pmsn_addr[regn].smem_pmsn_addr_s = addr; + } +} + +/** + * @brief Set MSPI PMS region size (in bytes) + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param size Size in bytes (must be a multiple of MSPI_LL_PMS_REGION_ADDR_ALIGN) + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_size(mspi_pms_mem_t mem, uint32_t regn, uint32_t size) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + HAL_ASSERT((size % MSPI_LL_PMS_REGION_ADDR_ALIGN) == 0); + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_size[regn].fmem_pmsn_size = size / MSPI_LL_PMS_REGION_ADDR_ALIGN; + } else { + SPIMEM2.smem_pmsn_size[regn].smem_pmsn_size = size / MSPI_LL_PMS_REGION_ADDR_ALIGN; + } +} + +/** + * @brief Get MSPI PMS region start address + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @return Start address of the PMS region + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_region_addr(mspi_pms_mem_t mem, uint32_t regn) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + uint32_t addr = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + addr = SPIMEM0.fmem_pmsn_addr[regn].fmem_pmsn_addr_s; + } else { + addr = SPIMEM2.smem_pmsn_addr[regn].smem_pmsn_addr_s; + } + return addr; +} + +/** + * @brief Get MSPI PMS region size (in bytes) + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @return Size of the PMS region in bytes + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_region_size(mspi_pms_mem_t mem, uint32_t regn) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + uint32_t size = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + size = SPIMEM0.fmem_pmsn_size[regn].fmem_pmsn_size; + } else { + size = SPIMEM2.smem_pmsn_size[regn].smem_pmsn_size; + } + return size * MSPI_LL_PMS_REGION_ADDR_ALIGN; +} + +/** + * @brief Set MSPI PMS region attributes for a specific security mode + * + * @param mem Memory type (flash or PSRAM) + * @param regn Region number (0-3) + * @param mode Security mode (TEE or REE) + * @param attr Region attribute flags - RD/WR/ECC (mspi_pms_attr_t) + */ +__attribute__((always_inline)) +static inline void mspi_ll_pms_set_region_attr(mspi_pms_mem_t mem, uint32_t regn, mspi_pms_mode_t mode, mspi_pms_attr_t attr) +{ + HAL_ASSERT(mem == MSPI_PMS_MEM_FLASH || mem == MSPI_PMS_MEM_PSRAM); + HAL_ASSERT(regn < MSPI_LL_PMS_REGION_NUM); + + /* Each mode field is 3 bits wide [RD, WR, ECC]: TEE at bits [2:0], + REE at bits [5:3] - replace the whole field, shifted by mode * 3. */ + uint32_t shift = (uint32_t)mode * MSPI_LL_PMS_MODE_FIELD_WIDTH; + uint32_t mask = MSPI_LL_PMS_FIELD_MASK << shift; + uint32_t bits = (uint32_t)attr << shift; + + if (mem == MSPI_PMS_MEM_FLASH) { + SPIMEM0.fmem_pmsn_attr[regn].val = (SPIMEM0.fmem_pmsn_attr[regn].val & ~mask) | bits; + } else { + SPIMEM2.smem_pmsn_attr[regn].val = (SPIMEM2.smem_pmsn_attr[regn].val & ~mask) | bits; + } +} + +/** + * @brief Get MSPI PMS reject address + * + * @param mem Memory type (flash or PSRAM) + * @return Address that caused PMS violation + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_reject_addr(mspi_pms_mem_t mem) +{ + uint32_t addr = 0; + if (mem == MSPI_PMS_MEM_FLASH) { + addr = SPIMEM0.mem_pms_reject_addr.mem_reject_addr; + } else { + addr = SPIMEM2.mem_pms_reject_addr.mem_reject_addr; + } + return addr; +} + +/** + * @brief Get MSPI PMS error mask + * + * @param mem Memory type (flash or PSRAM) + * @return Bitmask of error types (mspi_pms_err_t), or MSPI_PMS_ERR_NONE if no error + */ +__attribute__((always_inline)) +static inline uint32_t mspi_ll_pms_get_err_mask(mspi_pms_mem_t mem) +{ + bool multi_hit, ivd, st, ld; + if (mem == MSPI_PMS_MEM_FLASH) { + multi_hit = SPIMEM0.mem_pms_reject.mem_pms_multi_hit; + ivd = SPIMEM0.mem_pms_reject.mem_pms_ivd; + st = SPIMEM0.mem_pms_reject.mem_pms_st; + ld = SPIMEM0.mem_pms_reject.mem_pms_ld; + } else { + multi_hit = SPIMEM2.mem_pms_reject.mem_pms_multi_hit; + ivd = SPIMEM2.mem_pms_reject.mem_pms_ivd; + st = SPIMEM2.mem_pms_reject.mem_pms_st; + ld = SPIMEM2.mem_pms_reject.mem_pms_ld; + } + + uint32_t err = MSPI_PMS_ERR_NONE; + if (multi_hit) { + err |= MSPI_PMS_ERR_ADDR_MULTI; + } + if (ivd) { + err |= MSPI_PMS_ERR_ADDR_MISS; + } + if (st) { + err |= MSPI_PMS_ERR_WRITE; + } + if (ld) { + err |= MSPI_PMS_ERR_READ; + } + return err; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hal_mspi/esp32s31/include/hal/psram_ctrlr_ll.h b/components/esp_hal_mspi/esp32s31/include/hal/psram_ctrlr_ll.h index d2474305cfe..0602272852a 100644 --- a/components/esp_hal_mspi/esp32s31/include/hal/psram_ctrlr_ll.h +++ b/components/esp_hal_mspi/esp32s31/include/hal/psram_ctrlr_ll.h @@ -38,10 +38,6 @@ extern "C" { #define PSRAM_CTRLR_LL_MSPI_ID_SYSTEM PSRAM_CTRLR_LL_MSPI_ID_2 #define PSRAM_CTRLR_LL_MSPI_ID_PERI PSRAM_CTRLR_LL_MSPI_ID_3 -#define PSRAM_CTRLR_LL_PMS_REGION_NUMS 4 -#define PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE (1<<0) -#define PSRAM_CTRLR_LL_PMS_ATTR_READABLE (1<<1) - #define PSRAM_CTRLR_LL_FIFO_MAX_BYTES 64 #define PSRAM_CTRLR_LL_THRESH_INT_SUPPORTED 1 @@ -697,101 +693,6 @@ static inline uint32_t psram_ctrlr_ll_get_page_size(uint32_t mspi_id) return page_size; } -/** - * @brief Enable PMS ECC - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param en enable / disable - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_enable_pms_region_ecc(uint32_t mspi_id, uint32_t region_id, bool en) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM2.smem_pmsn_attr[region_id].smem_pmsn_ecc = en; -} - -/** - * @brief Set PMS attr - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param attr_mask attribute mask - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_attr(uint32_t mspi_id, uint32_t region_id, uint32_t attr_mask) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM2.smem_pmsn_attr[region_id].smem_pmsn_wr_attr = 0; - SPIMEM2.smem_pmsn_attr[region_id].smem_pmsn_rd_attr = 0; - if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE) { - SPIMEM2.smem_pmsn_attr[region_id].smem_pmsn_wr_attr = 1; - } - if (attr_mask & PSRAM_CTRLR_LL_PMS_ATTR_READABLE) { - SPIMEM2.smem_pmsn_attr[region_id].smem_pmsn_rd_attr = 1; - } -} - -/** - * @brief Set PMS address - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param addr start addr - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id, uint32_t addr) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM2.smem_pmsn_addr[region_id].smem_pmsn_addr_s = addr; -} - -/** - * @brief Set PMS size - * - * @param mspi_id mspi_id - * @param region_id region_id - * @param size size - */ -__attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_pms_region_size(uint32_t mspi_id, uint32_t region_id, uint32_t size) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - SPIMEM2.smem_pmsn_size[region_id].smem_pmsn_size = size; -} - -/** - * @brief Get PMS address - * - * @param mspi_id mspi_id - * @param region_id region_id - */ -__attribute__((always_inline)) -static inline uint32_t psram_ctrlr_ll_get_pms_region_start_addr(uint32_t mspi_id, uint32_t region_id) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - return SPIMEM2.smem_pmsn_addr[region_id].smem_pmsn_addr_s; -} - -/** - * @brief Get PMS size - * - * @param mspi_id mspi_id - * @param region_id region_id - */ -__attribute__((always_inline)) -static inline uint32_t psram_ctrlr_ll_get_pms_region_size(uint32_t mspi_id, uint32_t region_id) -{ - (void)mspi_id; - HAL_ASSERT(region_id < PSRAM_CTRLR_LL_PMS_REGION_NUMS); - return SPIMEM2.smem_pmsn_size[region_id].smem_pmsn_size; -} - /** * @brief PSRAM common transaction * diff --git a/components/esp_hal_mspi/include/hal/mspi_pms_types.h b/components/esp_hal_mspi/include/hal/mspi_pms_types.h new file mode 100644 index 00000000000..c36228e08bb --- /dev/null +++ b/components/esp_hal_mspi/include/hal/mspi_pms_types.h @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief MSPI memory type protected by PMS + */ +typedef enum { + MSPI_PMS_MEM_FLASH = 0, /*!< Flash memory */ + MSPI_PMS_MEM_PSRAM = 1, /*!< PSRAM memory */ +} mspi_pms_mem_t; + +/** + * @brief PMS security mode + */ +typedef enum { + MSPI_PMS_MODE_TEE = 0, /*!< Secure mode */ + MSPI_PMS_MODE_REE = 1, /*!< Non-secure mode */ +} mspi_pms_mode_t; + +/** + * @brief PMS region attribute bits (can be ORed together) + */ +typedef enum { + MSPI_PMS_ATTR_NONE = 0, /*!< No permissions */ + MSPI_PMS_ATTR_RD = BIT(0), /*!< Read permission */ + MSPI_PMS_ATTR_WR = BIT(1), /*!< Write permission */ + MSPI_PMS_ATTR_ECC = BIT(2), /*!< ECC enabled for the region */ +} mspi_pms_attr_t; + +/** + * @brief PMS error types + */ +typedef enum { + MSPI_PMS_ERR_NONE = 0, /*!< No error */ + MSPI_PMS_ERR_WRITE = BIT(0), /*!< Write access error */ + MSPI_PMS_ERR_READ = BIT(1), /*!< Read access error */ + MSPI_PMS_ERR_ADDR_MISS = BIT(2), /*!< Address miss error */ + MSPI_PMS_ERR_ADDR_MULTI = BIT(3), /*!< Address multi-hit error */ +} mspi_pms_err_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_psram/device/esp_psram_impl_ap_hex.c b/components/esp_psram/device/esp_psram_impl_ap_hex.c index 5f4e5566cfb..ddbbd5e86e9 100644 --- a/components/esp_psram/device/esp_psram_impl_ap_hex.c +++ b/components/esp_psram/device/esp_psram_impl_ap_hex.c @@ -13,6 +13,9 @@ #include "esp_private/esp_psram_impl.h" #include "hal/psram_ctrlr_ll.h" #include "hal/mspi_ll.h" +#if CONFIG_SPIRAM_ECC_ENABLE +#include "hal/mspi_pms_ll.h" +#endif #include "soc/rtc.h" #include "esp_check.h" #include "esp_private/esp_clk_tree_common.h" @@ -383,9 +386,9 @@ static void s_set_psram_cs_timing(void) #if CONFIG_SPIRAM_ECC_ENABLE static void s_mspi_ecc_show_info(void) { - for (int i = 0; i < PSRAM_CTRLR_LL_PMS_REGION_NUMS; i++) { - ESP_EARLY_LOGV(TAG, "region[%d] addr: 0x%08x", i, psram_ctrlr_ll_get_pms_region_start_addr(PSRAM_CTRLR_LL_MSPI_ID_2, i)); - ESP_EARLY_LOGV(TAG, "region[%d] size: 0x%08x", i, psram_ctrlr_ll_get_pms_region_size(PSRAM_CTRLR_LL_MSPI_ID_2, i)); + for (int i = 0; i < MSPI_LL_PMS_REGION_NUM; i++) { + ESP_EARLY_LOGV(TAG, "region[%d] addr: 0x%08x", i, mspi_ll_pms_get_region_addr(MSPI_PMS_MEM_PSRAM, i)); + ESP_EARLY_LOGV(TAG, "region[%d] size: 0x%08x", i, mspi_ll_pms_get_region_size(MSPI_PMS_MEM_PSRAM, i)); } uint32_t page_size = psram_ctrlr_ll_get_page_size(PSRAM_CTRLR_LL_MSPI_ID_2); @@ -408,7 +411,7 @@ static void s_configure_psram_ecc(void) * Default: ACE0 range: 0 ~ 256MB * Current Hex PSRAM is 8MB, ACE0 is enough */ - psram_ctrlr_ll_enable_pms_region_ecc(PSRAM_CTRLR_LL_MSPI_ID_2, 0, true); + mspi_ll_pms_set_region_attr(MSPI_PMS_MEM_PSRAM, 0, MSPI_PMS_MODE_TEE, MSPI_PMS_ATTR_ECC); ESP_EARLY_LOGI(TAG, "ECC is enabled"); s_mspi_ecc_show_info(); diff --git a/components/esp_psram/device/esp_psram_impl_ap_oct.c b/components/esp_psram/device/esp_psram_impl_ap_oct.c index 6dfbc39924c..f507b634cd2 100644 --- a/components/esp_psram/device/esp_psram_impl_ap_oct.c +++ b/components/esp_psram/device/esp_psram_impl_ap_oct.c @@ -15,6 +15,9 @@ #include "esp_private/esp_psram_impl.h" #include "hal/psram_ctrlr_ll.h" #include "hal/mspi_ll.h" +#if CONFIG_SPIRAM_ECC_ENABLE +#include "hal/mspi_pms_ll.h" +#endif #include "soc/rtc.h" #define AP_OCT_PSRAM_SYNC_READ 0x0000 @@ -378,9 +381,9 @@ static void s_set_psram_cs_timing(void) #if CONFIG_SPIRAM_ECC_ENABLE static void s_mspi_ecc_show_info(void) { - for (int i = 0; i < PSRAM_CTRLR_LL_PMS_REGION_NUMS; i++) { - ESP_EARLY_LOGV(TAG, "region[%d] addr: 0x%08x", i, psram_ctrlr_ll_get_pms_region_start_addr(PSRAM_CTRLR_LL_MSPI_ID_2, i)); - ESP_EARLY_LOGV(TAG, "region[%d] size: 0x%08x", i, psram_ctrlr_ll_get_pms_region_size(PSRAM_CTRLR_LL_MSPI_ID_2, i)); + for (int i = 0; i < MSPI_LL_PMS_REGION_NUM; i++) { + ESP_EARLY_LOGV(TAG, "region[%d] addr: 0x%08x", i, mspi_ll_pms_get_region_addr(MSPI_PMS_MEM_PSRAM, i)); + ESP_EARLY_LOGV(TAG, "region[%d] size: 0x%08x", i, mspi_ll_pms_get_region_size(MSPI_PMS_MEM_PSRAM, i)); } uint32_t page_size = psram_ctrlr_ll_get_page_size(PSRAM_CTRLR_LL_MSPI_ID_2); @@ -403,7 +406,7 @@ static void s_configure_psram_ecc(void) * Default: ACE0 range: 0 ~ 256MB * Current PSRAM is 8MB, ACE0 is enough */ - psram_ctrlr_ll_enable_pms_region_ecc(PSRAM_CTRLR_LL_MSPI_ID_2, 0, true); + mspi_ll_pms_set_region_attr(MSPI_PMS_MEM_PSRAM, 0, MSPI_PMS_MODE_TEE, MSPI_PMS_ATTR_ECC); ESP_EARLY_LOGI(TAG, "ECC is enabled"); s_mspi_ecc_show_info(); diff --git a/components/esp_psram/device/esp_psram_impl_ap_quad.c b/components/esp_psram/device/esp_psram_impl_ap_quad.c index c12d2481d55..02df86c7f02 100644 --- a/components/esp_psram/device/esp_psram_impl_ap_quad.c +++ b/components/esp_psram/device/esp_psram_impl_ap_quad.c @@ -15,6 +15,9 @@ #include "esp_private/mspi_timing_tuning.h" #include "esp_private/esp_gpio_reserve.h" #include "hal/psram_ctrlr_ll.h" +#if CONFIG_SPIRAM_ECC_ENABLE +#include "hal/mspi_pms_ll.h" +#endif #include "esp_quad_psram_defs_ap.h" #include "soc/soc_caps.h" @@ -215,9 +218,9 @@ static esp_err_t s_check_psram_connected(int spi_num) #if CONFIG_SPIRAM_ECC_ENABLE static void s_mspi_ecc_show_info(void) { - for (int i = 0; i < PSRAM_CTRLR_LL_PMS_REGION_NUMS; i++) { - ESP_EARLY_LOGV(TAG, "region[%d] addr: 0x%08x", i, psram_ctrlr_ll_get_pms_region_start_addr(PSRAM_CTRLR_LL_MSPI_ID_0, i)); - ESP_EARLY_LOGV(TAG, "region[%d] size: 0x%08x", i, psram_ctrlr_ll_get_pms_region_size(PSRAM_CTRLR_LL_MSPI_ID_0, i)); + for (int i = 0; i < MSPI_LL_PMS_REGION_NUM; i++) { + ESP_EARLY_LOGV(TAG, "region[%d] addr: 0x%08x", i, mspi_ll_pms_get_region_addr(MSPI_PMS_MEM_PSRAM, i)); + ESP_EARLY_LOGV(TAG, "region[%d] size: 0x%08x", i, mspi_ll_pms_get_region_size(MSPI_PMS_MEM_PSRAM, i)); } uint32_t page_size = psram_ctrlr_ll_get_page_size(PSRAM_CTRLR_LL_MSPI_ID_0); @@ -240,10 +243,9 @@ static void s_configure_psram_ecc(void) * Default: ACE0 range: 0 ~ 256MB * For current Quad PSRAM, ACE0 is enough */ - psram_ctrlr_ll_set_pms_region_start_addr(PSRAM_CTRLR_LL_MSPI_ID_0, 0, 0); - psram_ctrlr_ll_set_pms_region_size(PSRAM_CTRLR_LL_MSPI_ID_0, 0, 4096); - psram_ctrlr_ll_set_pms_region_attr(PSRAM_CTRLR_LL_MSPI_ID_0, 0, PSRAM_CTRLR_LL_PMS_ATTR_WRITABLE | PSRAM_CTRLR_LL_PMS_ATTR_READABLE); - psram_ctrlr_ll_enable_pms_region_ecc(PSRAM_CTRLR_LL_MSPI_ID_0, 0, true); + mspi_ll_pms_set_region_addr(MSPI_PMS_MEM_PSRAM, 0, 0); + mspi_ll_pms_set_region_size(MSPI_PMS_MEM_PSRAM, 0, 16 * 1024 * 1024); + mspi_ll_pms_set_region_attr(MSPI_PMS_MEM_PSRAM, 0, MSPI_PMS_MODE_TEE, MSPI_PMS_ATTR_ECC); ESP_EARLY_LOGI(TAG, "ECC is enabled"); s_mspi_ecc_show_info(); } diff --git a/components/soc/esp32p4/include/soc/apm_defs.h b/components/soc/esp32p4/include/soc/apm_defs.h index 2461baacb6f..b864705dee9 100644 --- a/components/soc/esp32p4/include/soc/apm_defs.h +++ b/components/soc/esp32p4/include/soc/apm_defs.h @@ -30,11 +30,6 @@ extern "C" { /* Alignment required for start/end addresses for LP_PERI_PMS regions */ #define APM_LP_PERI_PMS_REGION_ADDR_ALIGN (4) -/* Number of configurable MSPI PMS regions (flash/PSRAM) */ -#define APM_MSPI_PMS_REGION_NUM (4) -/* Alignment required for start/end addresses for MSPI_PMS regions */ -#define APM_MSPI_PMS_REGION_ADDR_ALIGN (0x1000) - /* CPU_PERIPH slave mask */ #define APM_SLAVE_CPU_PERI_ALL_MASK (0x0FCFU) /* HP_PERIPH0 slave mask */