mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-18 06:35:35 +03:00
feat(hal): Add support for flash/PSRAM protection through MSPI PMS
This commit is contained in:
195
components/esp_hal_mspi/esp32c5/include/hal/mspi_pms_ll.h
Normal file
195
components/esp_hal_mspi/esp32c5/include/hal/mspi_pms_ll.h
Normal file
@@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#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
|
||||
@@ -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
|
||||
|
||||
195
components/esp_hal_mspi/esp32c61/include/hal/mspi_pms_ll.h
Normal file
195
components/esp_hal_mspi/esp32c61/include/hal/mspi_pms_ll.h
Normal file
@@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#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
|
||||
@@ -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
|
||||
|
||||
200
components/esp_hal_mspi/esp32h4/include/hal/mspi_pms_ll.h
Normal file
200
components/esp_hal_mspi/esp32h4/include/hal/mspi_pms_ll.h
Normal file
@@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#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
|
||||
@@ -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
|
||||
|
||||
223
components/esp_hal_mspi/esp32p4/include/hal/mspi_pms_ll.h
Normal file
223
components/esp_hal_mspi/esp32p4/include/hal/mspi_pms_ll.h
Normal file
@@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#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
|
||||
@@ -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
|
||||
*
|
||||
|
||||
221
components/esp_hal_mspi/esp32s31/include/hal/mspi_pms_ll.h
Normal file
221
components/esp_hal_mspi/esp32s31/include/hal/mspi_pms_ll.h
Normal file
@@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#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
|
||||
@@ -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
|
||||
*
|
||||
|
||||
54
components/esp_hal_mspi/include/hal/mspi_pms_types.h
Normal file
54
components/esp_hal_mspi/include/hal/mspi_pms_types.h
Normal file
@@ -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
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user