forked from espressif/arduino-esp32
Esp32 s3 support (#6341)
Co-authored-by: Jason2866 <24528715+Jason2866@users.noreply.github.com> Co-authored-by: Unexpected Maker <seon@unexpectedmaker.com> Co-authored-by: Rodrigo Garcia <rodrigo.garcia@espressif.com> Co-authored-by: Tomáš Pilný <34927466+PilnyTomas@users.noreply.github.com> Co-authored-by: Pedro Minatel <pedro.minatel@espressif.com> Co-authored-by: Ivan Grokhotkov <ivan@espressif.com> Co-authored-by: Jan Procházka <90197375+P-R-O-C-H-Y@users.noreply.github.com> Co-authored-by: Limor "Ladyada" Fried <limor@ladyada.net>
This commit is contained in:
@ -33,6 +33,7 @@ typedef enum {
|
||||
#define CHIP_FEATURE_BLE BIT(4) //!< Chip has Bluetooth LE
|
||||
#define CHIP_FEATURE_BT BIT(5) //!< Chip has Bluetooth Classic
|
||||
#define CHIP_FEATURE_IEEE802154 BIT(6) //!< Chip has IEEE 802.15.4
|
||||
#define CHIP_FEATURE_EMB_PSRAM BIT(7) //!< Chip has embedded psram
|
||||
|
||||
/**
|
||||
* @brief The structure represents information about the chip
|
||||
|
199
tools/sdk/esp32s2/include/esp_hw_support/include/esp_memprot.h
Normal file
199
tools/sdk/esp32s2/include/esp_hw_support/include/esp_memprot.h
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ESP Memory Protection API (PMS)
|
||||
// - allows configuration and violation-interrupt handling of the PMS module operations
|
||||
// - not intended for public use.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_MEMPROT_TEST
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_memprot_err.h"
|
||||
#include "soc_memprot_types.h"
|
||||
#include "esp_memprot_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_MEMPROT_ERR_CHECK(retval, fnc) if ((retval=fnc) != ESP_OK) { return retval; }
|
||||
|
||||
/**
|
||||
* @brief Basic PMS interrupt source info
|
||||
*/
|
||||
typedef struct {
|
||||
esp_mprot_mem_t mem_type; /*!< Memory type containing the faulting address */
|
||||
int core; /*!< CPU/Core ID running the faulting instruction */
|
||||
} esp_memp_intr_source_t;
|
||||
|
||||
/**
|
||||
* @brief Clears current interrupt ON flag for given Memory type and CPU/Core ID
|
||||
*
|
||||
* This operation is non-atomic for some chips by PMS module design
|
||||
* In such a case the interrupt clearing happens in two steps:
|
||||
* 1. Interrupt CLR flag is set (clears interrupt-ON status and inhibits linked interrupt processing)
|
||||
* 2. Interrupt CLR flag is reset (resumes the interrupt monitoring)
|
||||
*
|
||||
* @param mem_type Memory type (see esp_mprot_mem_t enum)
|
||||
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_INVALID_ARG on passing invalid pointer
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
*/
|
||||
esp_err_t esp_mprot_monitor_clear_intr(const esp_mprot_mem_t mem_type, int const *const core);
|
||||
|
||||
/**
|
||||
* @brief Checks whether any of the PMS settings is locked
|
||||
*
|
||||
* @param[out] locked Any lock on? (true/false)
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_INVALID_ARG on invalid locked ptr
|
||||
* Other failures: error code of any failing esp_mprot_get_*_lock() routine (called internally)
|
||||
*/
|
||||
esp_err_t esp_mprot_is_conf_locked_any(bool *locked);
|
||||
|
||||
/**
|
||||
* @brief Checks whether any PMS violation-interrupt monitoring is enabled
|
||||
*
|
||||
* @param[out] locked Any PMS violation interrupt monitor is enabled (true/false)
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_INVALID_ARG on invalid enabled ptr
|
||||
* Other failures: error code of esp_mprot_get_monitor_en() routine (called internally for all Memory types)
|
||||
*/
|
||||
esp_err_t esp_mprot_is_intr_ena_any(bool *enabled);
|
||||
|
||||
/**
|
||||
* @brief Returns active PMS violation-interrupt Memory type if any (MEMPROT_TYPE_NONE when none detected)
|
||||
* and the CPU/CoreID which was running the faulty code (-1 when no interrupt available)
|
||||
*
|
||||
* If there are more interrupts indicated on (shouldn't happen), the order of precedence is given by 'esp_mprot_mem_t' enum definition (low->high)
|
||||
*
|
||||
* @param[out] mem_type Out-pointer for Memory type given by the faulting address (see esp_mprot_mem_t enum)
|
||||
* @param[out] core Out-pointer for CPU/Core ID (see *_CPU_NUM defs in soc.h)
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_INVALID_ARG on passing invalid pointer(s)
|
||||
*/
|
||||
esp_err_t esp_mprot_get_active_intr(esp_memp_intr_source_t *active_memp_intr);
|
||||
|
||||
/**
|
||||
* @brief Returns the address which caused the violation interrupt for given Memory type and CPU/Core ID.
|
||||
* This function is to be called after a basic resolving of (current) interrupt's parameters (ie corresponding
|
||||
* Memory type and CPU ID see esp_mprot_get_active_intr()). This is to minimize processing time of actual exception
|
||||
* as this API is typicaly used in a panic-handling code.
|
||||
* If there is no active interrupt available for the Memory type/CPU ID required, fault_addr is set to NULL.
|
||||
*
|
||||
* @param mem_type memory type
|
||||
* @param[out] fault_addr Address of the operation which caused the PMS violation interrupt
|
||||
* @param core Faulting instruction CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
* ESP_ERR_INVALID_ARG on invalid fault_addr pointer
|
||||
*/
|
||||
esp_err_t esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, void **fault_addr, int const *const core);
|
||||
|
||||
/**
|
||||
* @brief Returns PMS World identifier of the code causing the violation interrupt
|
||||
*
|
||||
* The value is read from appropriate PMS violation status register and thus might be 0 if the interrupt is not currently active.
|
||||
*
|
||||
* @param mem_type Memory type
|
||||
* @param[out] world PMS World type (see esp_mprot_pms_world_t)
|
||||
* @param core Faulting instruction CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
* ESP_ERR_INVALID_ARG on passing invalid pointer(s)
|
||||
* ESP_ERR_MEMPROT_WORLD_INVALID on invalid World identifier fetched from the register
|
||||
*/
|
||||
esp_err_t esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type, esp_mprot_pms_world_t *world, int const *const core);
|
||||
|
||||
/**
|
||||
* @brief Returns an operation type which caused the violation interrupt
|
||||
*
|
||||
* The operation resolving is processed over various PMS status register flags, according to given Memory type argument.
|
||||
* If the interrupt is not active the result returned is irrelevant (likely evaluated to MEMPROT_OP_READ).
|
||||
*
|
||||
* @param mem_type Memory type
|
||||
* @param[out] oper Operation type (see MEMPROT_OP_* defines)
|
||||
* @param core Faulting instruction CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
* ESP_ERR_INVALID_ARG on invalid oper pointer
|
||||
*/
|
||||
esp_err_t esp_mprot_get_violate_operation(const esp_mprot_mem_t mem_type, uint32_t *oper, int const *const core);
|
||||
|
||||
/**
|
||||
* @brief Checks whether given memory type supports byte-enables info
|
||||
*
|
||||
* Byte-enables status is available only for DMA/DRAM operations
|
||||
*
|
||||
* @param mem_type memory type
|
||||
*
|
||||
* @return byte-enables info available true/false
|
||||
*/
|
||||
bool esp_mprot_has_byte_enables(const esp_mprot_mem_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns byte-enables for the address which caused the violation interrupt
|
||||
*
|
||||
* The value is taken from appropriate PMS violation status register, based on given Memory type
|
||||
*
|
||||
* @param mem_type Memory type (MEMPROT_TYPE_DRAM0_SRAM)
|
||||
* @param[out] byte_en Byte-enables bits
|
||||
* @param core Faulting instruction CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
* ESP_ERR_INVALID_ARGUMENT on invalid byte_en pointer
|
||||
*/
|
||||
esp_err_t esp_mprot_get_violate_byte_enables(const esp_mprot_mem_t mem_type, uint32_t *byte_en, int const *const core);
|
||||
|
||||
/**
|
||||
* @brief Convenient routine for setting the PMS defaults
|
||||
*
|
||||
* Called on system startup, depending on ESP_SYSTEM_MEMPROT_FEATURE Kconfig value
|
||||
*
|
||||
* @param memp_config pointer to Memprot configuration structure (esp_memp_config_t). The structure si chip-specific,
|
||||
* for details and defaults see appropriate [target-chip]/soc_memprot_types.h
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* Other failures: error code of the failing routine called internally. No specific error processing provided in such a case
|
||||
* due to large number of embedded calls (ie no global unique error table is provided and thus one error code can have different meanings,
|
||||
* depending on the routine issuing the error)
|
||||
*/
|
||||
esp_err_t esp_mprot_set_prot(const esp_memp_config_t *memp_config);
|
||||
|
||||
/**
|
||||
* @brief Generates PMS configuration string of actual device (diagnostics)
|
||||
*
|
||||
* The functions generates a string from current configuration, control and status registers of the PMS (or similar) module of actual device.
|
||||
* The values are fetched using HAL LL calls to help finding possible errors in the Memprot API implementation
|
||||
*
|
||||
* @param[out] dump_info_string configuration string buffer pointer. The string is allocated by the callee and must be freed by the caller.
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_NO_MEM on buffer allocation failure
|
||||
* ESP_ERR_INVALID_ARGUMENT on invalid dump_info_string pointer
|
||||
*/
|
||||
esp_err_t esp_mprot_dump_configuration(char **dump_info_string);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_MEMPROT_TEST
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ESP Memprot API error code definition
|
||||
*/
|
||||
#define ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID (ESP_ERR_MEMPROT_BASE + 1) /**< Memory type invalid in given context */
|
||||
#define ESP_ERR_MEMPROT_SPLIT_ADDR_INVALID (ESP_ERR_MEMPROT_BASE + 2) /**< Splitting address invalid in given context */
|
||||
#define ESP_ERR_MEMPROT_SPLIT_ADDR_OUT_OF_RANGE (ESP_ERR_MEMPROT_BASE + 3) /**< Splitting address out of range */
|
||||
#define ESP_ERR_MEMPROT_SPLIT_ADDR_UNALIGNED (ESP_ERR_MEMPROT_BASE + 4) /**< Splitting address not aligned to required boundaries */
|
||||
#define ESP_ERR_MEMPROT_UNIMGMT_BLOCK_INVALID (ESP_ERR_MEMPROT_BASE + 5) /**< Required unified-management block is not valid */
|
||||
#define ESP_ERR_MEMPROT_WORLD_INVALID (ESP_ERR_MEMPROT_BASE + 6) /**< Required World identifier is not valid */
|
||||
#define ESP_ERR_MEMPROT_AREA_INVALID (ESP_ERR_MEMPROT_BASE + 7) /**< Required Area identifier is not valid */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PMS World type (attribute per PMS area, similar to x86 Ring scheme)
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_PMS_WORLD_NONE = 0x00000000,
|
||||
MEMPROT_PMS_WORLD_0 = 0x00000001,
|
||||
MEMPROT_PMS_WORLD_1 = 0x00000002,
|
||||
MEMPROT_PMS_WORLD_2 = 0x00000004,
|
||||
MEMPROT_PMS_WORLD_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_PMS_WORLD_INVALID = 0x80000000
|
||||
} esp_mprot_pms_world_t;
|
||||
|
||||
/**
|
||||
* @brief Memory operation/permission type recognized by PMS
|
||||
*/
|
||||
#define MEMPROT_OP_NONE 0x00000000
|
||||
#define MEMPROT_OP_READ 0x00000001
|
||||
#define MEMPROT_OP_WRITE 0x00000002
|
||||
#define MEMPROT_OP_EXEC 0x00000004
|
||||
#define MEMPROT_OP_INVALID 0x80000000
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_MEMPROT_TEST
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_memprot_err.h"
|
||||
#include "hal/memprot_types.h"
|
||||
#include "soc_memprot_types.h"
|
||||
#include "esp_memprot_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Convert Memprot low level errors to esp_err_t
|
||||
*/
|
||||
esp_err_t esp_mprot_ll_err_to_esp_err(const memprot_ll_err_t err);
|
||||
|
||||
/**
|
||||
* @brief Convert Memprot low level PMS World IDs to esp_mprot_pms_world_t
|
||||
*/
|
||||
esp_mprot_pms_world_t esp_mprot_ll_world_to_hl_world(const memprot_ll_world_t world);
|
||||
|
||||
/**
|
||||
* @brief Converts operation type to string, no combination of operations allowed
|
||||
*
|
||||
* @param oper_type PMS operation type
|
||||
*/
|
||||
const char *esp_mprot_oper_type_to_str(const uint32_t oper_type);
|
||||
|
||||
/**
|
||||
* @brief Converts PMS World type to string
|
||||
*
|
||||
* @param area_type PMS World type
|
||||
*/
|
||||
const char *esp_mprot_pms_world_to_str(const esp_mprot_pms_world_t world_type);
|
||||
|
||||
/**
|
||||
* @brief Sets splitting address for given line type in the target Memory type
|
||||
*
|
||||
* @param mem_type memory type
|
||||
* @param line_type split address type
|
||||
* @param line_addr target address from a memory range relevant to given line_addr
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
* ESP_ERR_MEMPROT_SPLIT_ADDR_INVALID on invalid line_type
|
||||
* ESP_ERR_MEMPROT_SPLIT_ADDR_OUT_OF_RANGE on splitting line out of given memory-type range
|
||||
* ESP_ERR_MEMPROT_SPLIT_ADDR_UNALIGNED on splitting line not aligned to PMS-required boundaries
|
||||
*/
|
||||
esp_err_t esp_mprot_set_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, const void *line_addr);
|
||||
|
||||
/**
|
||||
* @brief Gets PMS splitting address for given split_addr type
|
||||
*
|
||||
* The value is read from the PMS configuration registers
|
||||
*
|
||||
* @param mem_type memory type
|
||||
* @param line_type Split line type (see esp_mprot_split_addr_t enum)
|
||||
* @param[out] line_addr Split line address from the configuration register
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_INVALID_ARG on line_addr is pointer
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
* ESP_ERR_MEMPROT_SPLIT_ADDR_INVALID on invalid line_type
|
||||
*/
|
||||
esp_err_t esp_mprot_get_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, void **line_addr);
|
||||
|
||||
/**
|
||||
* @brief Returns default main I/D splitting address for given Memory type
|
||||
*
|
||||
* @param mem_type memory type
|
||||
* @param[out] def_split_addr Main I/D splitting address of required mem_type
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_INVALID_ARG on invalid def_split_addr pointer
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
*/
|
||||
esp_err_t esp_mprot_get_default_main_split_addr(const esp_mprot_mem_t mem_type, void **def_split_addr);
|
||||
|
||||
/**
|
||||
* @brief Sets a lock for the main IRAM/DRAM splitting addresses
|
||||
* Locks can be unlocked only by digital system reset
|
||||
*
|
||||
* @param mem_type memory type
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
*/
|
||||
esp_err_t esp_mprot_set_split_addr_lock(const esp_mprot_mem_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets a lock status for the splitting address configuration of given Memory type
|
||||
*
|
||||
* @param mem_type memory type
|
||||
* @param[out] locked mem_type related lock status
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_INVALID_ARGUMENT on invalid locked pointer
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
*/
|
||||
esp_err_t esp_mprot_get_split_addr_lock(const esp_mprot_mem_t mem_type, bool *locked);
|
||||
|
||||
/**
|
||||
* @brief Sets a lock for PMS Area settings of required Memory type
|
||||
* Locks can be unlocked only by digital system reset
|
||||
*
|
||||
* @param mem_type memory type
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
*/
|
||||
esp_err_t esp_mprot_set_pms_lock(const esp_mprot_mem_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets a lock status for PMS Area settings of required Memory type
|
||||
*
|
||||
* @param mem_type memory type
|
||||
* @param[out] locked mem_type related lock status
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
* ESP_ERR_INVALID_ARGUMENT on invalid locked pointer
|
||||
*/
|
||||
esp_err_t esp_mprot_get_pms_lock(const esp_mprot_mem_t mem_type, bool *locked);
|
||||
|
||||
/**
|
||||
* @brief Sets permissions for given PMS Area
|
||||
*
|
||||
* @param area_type PMS area type
|
||||
* @param flags combination of MEMPROT_OP_* defines
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
*/
|
||||
esp_err_t esp_mprot_set_pms_area(const esp_mprot_pms_area_t area_type, const uint32_t flags);
|
||||
|
||||
/**
|
||||
* @brief Gets current permissions for given PMS Area
|
||||
*
|
||||
* @param area_type PMS area type
|
||||
* @param[out] flags combination of MEMPROT_OP_* defines
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
* ESP_ERR_INVALID_ARG on invalid flags pointer
|
||||
*/
|
||||
esp_err_t esp_mprot_get_pms_area(const esp_mprot_pms_area_t area_type, uint32_t *flags);
|
||||
|
||||
/**
|
||||
* @brief Sets a lock for PMS interrupt monitor settings of required Memory type
|
||||
*
|
||||
* Locks can be unlocked only by digital system reset
|
||||
*
|
||||
* @param mem_type memory type (see esp_mprot_mem_t enum)
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
*/
|
||||
esp_err_t esp_mprot_set_monitor_lock(const esp_mprot_mem_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets a lock status for PMS interrupt monitor settings of required Memory type
|
||||
*
|
||||
* @param mem_type memory type
|
||||
* @param[out] locked mem_type related lock status
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
* ESP_ERR_INVALID_ARG on invalid locked pointer
|
||||
*/
|
||||
esp_err_t esp_mprot_get_monitor_lock(const esp_mprot_mem_t mem_type, bool *locked);
|
||||
|
||||
/**
|
||||
* @brief Enable PMS violation interrupt monitoring of required Memory type
|
||||
*
|
||||
* @param mem_type memory type
|
||||
* @param enable enable/disable violation interrupt monitoring
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
|
||||
*/
|
||||
esp_err_t esp_mprot_set_monitor_en(const esp_mprot_mem_t mem_type, const bool enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_MEMPROT_TEST
|
@ -1,449 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
/* INTERNAL API
|
||||
* generic interface to PMS memory protection features
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef IRAM_SRAM_START
|
||||
#define IRAM_SRAM_START 0x4037C000
|
||||
#endif
|
||||
|
||||
#ifndef DRAM_SRAM_START
|
||||
#define DRAM_SRAM_START 0x3FC7C000
|
||||
#endif
|
||||
|
||||
#ifndef MAP_DRAM_TO_IRAM
|
||||
#define MAP_DRAM_TO_IRAM(addr) (addr - DRAM_SRAM_START + IRAM_SRAM_START)
|
||||
#endif
|
||||
|
||||
#ifndef MAP_IRAM_TO_DRAM
|
||||
#define MAP_IRAM_TO_DRAM(addr) (addr - IRAM_SRAM_START + DRAM_SRAM_START)
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
MEMPROT_NONE = 0x00000000,
|
||||
MEMPROT_IRAM0_SRAM = 0x00000001,
|
||||
MEMPROT_DRAM0_SRAM = 0x00000002,
|
||||
MEMPROT_ALL = 0xFFFFFFFF
|
||||
} mem_type_prot_t;
|
||||
|
||||
typedef enum {
|
||||
MEMPROT_SPLITLINE_NONE = 0,
|
||||
MEMPROT_IRAM0_DRAM0_SPLITLINE,
|
||||
MEMPROT_IRAM0_LINE_0_SPLITLINE,
|
||||
MEMPROT_IRAM0_LINE_1_SPLITLINE,
|
||||
MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE,
|
||||
MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE
|
||||
} split_line_t;
|
||||
|
||||
typedef enum {
|
||||
MEMPROT_PMS_AREA_NONE = 0,
|
||||
MEMPROT_IRAM0_PMS_AREA_0,
|
||||
MEMPROT_IRAM0_PMS_AREA_1,
|
||||
MEMPROT_IRAM0_PMS_AREA_2,
|
||||
MEMPROT_IRAM0_PMS_AREA_3,
|
||||
MEMPROT_DRAM0_PMS_AREA_0,
|
||||
MEMPROT_DRAM0_PMS_AREA_1,
|
||||
MEMPROT_DRAM0_PMS_AREA_2,
|
||||
MEMPROT_DRAM0_PMS_AREA_3
|
||||
} pms_area_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MEMPROT_PMS_WORLD_0 = 0,
|
||||
MEMPROT_PMS_WORLD_1,
|
||||
MEMPROT_PMS_WORLD_2,
|
||||
MEMPROT_PMS_WORLD_INVALID = 0xFFFFFFFF
|
||||
} pms_world_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MEMPROT_PMS_OP_READ = 0,
|
||||
MEMPROT_PMS_OP_WRITE,
|
||||
MEMPROT_PMS_OP_FETCH,
|
||||
MEMPROT_PMS_OP_INVALID = 0xFFFFFFFF
|
||||
} pms_operation_type_t;
|
||||
|
||||
/**
|
||||
* @brief Converts Memory protection type to string
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*/
|
||||
const char *esp_memprot_mem_type_to_str(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Converts Split line type to string
|
||||
*
|
||||
* @param line_type Split line type (see split_line_t enum)
|
||||
*/
|
||||
const char *esp_memprot_split_line_to_str(split_line_t line_type);
|
||||
|
||||
/**
|
||||
* @brief Converts PMS Area type to string
|
||||
*
|
||||
* @param area_type PMS Area type (see pms_area_t enum)
|
||||
*/
|
||||
const char *esp_memprot_pms_to_str(pms_area_t area_type);
|
||||
|
||||
/**
|
||||
* @brief Returns PMS splitting address for given Split line type
|
||||
*
|
||||
* The value is taken from PMS configuration registers (IRam0 range)
|
||||
* For details on split lines see 'esp_memprot_set_prot_int' function description
|
||||
*
|
||||
* @param line_type Split line type (see split_line_t enum)
|
||||
*
|
||||
* @return appropriate split line address
|
||||
*/
|
||||
uint32_t *esp_memprot_get_split_addr(split_line_t line_type);
|
||||
|
||||
/**
|
||||
* @brief Returns default main IRAM/DRAM splitting address
|
||||
*
|
||||
* The address value is given by _iram_text_end global (IRam0 range)
|
||||
|
||||
* @return Main I/D split line (IRam0_DRam0_Split_Addr)
|
||||
*/
|
||||
void *esp_memprot_get_default_main_split_addr(void);
|
||||
|
||||
/**
|
||||
* @brief Sets a lock for the main IRAM/DRAM splitting address
|
||||
*
|
||||
* Locks can be unlocked only by digital system reset
|
||||
*/
|
||||
void esp_memprot_set_split_line_lock(void);
|
||||
|
||||
/**
|
||||
* @brief Gets a lock status for the main IRAM/DRAM splitting address
|
||||
*
|
||||
* @return true/false (locked/unlocked)
|
||||
*/
|
||||
bool esp_memprot_get_split_line_lock(void);
|
||||
|
||||
/**
|
||||
* @brief Sets required split line address
|
||||
*
|
||||
* @param line_type Split line type (see split_line_t enum)
|
||||
* @param line_addr target address from a memory range relevant to given line_type (IRAM/DRAM)
|
||||
*/
|
||||
void esp_memprot_set_split_line(split_line_t line_type, const void *line_addr);
|
||||
|
||||
/**
|
||||
* @brief Sets a lock for PMS Area settings of required Memory type
|
||||
*
|
||||
* Locks can be unlocked only by digital system reset
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*/
|
||||
void esp_memprot_set_pms_lock(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets a lock status for PMS Area settings of required Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return true/false (locked/unlocked)
|
||||
*/
|
||||
bool esp_memprot_get_pms_lock(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Sets permissions for given PMS Area in IRam0 memory range (MEMPROT_IRAM0_SRAM)
|
||||
*
|
||||
* @param area_type IRam0 PMS Area type (see pms_area_t enum)
|
||||
* @param r Read permission flag
|
||||
* @param w Write permission flag
|
||||
* @param x Execute permission flag
|
||||
*/
|
||||
void esp_memprot_iram_set_pms_area(pms_area_t area_type, bool r, bool w, bool x);
|
||||
|
||||
/**
|
||||
* @brief Gets current permissions for given PMS Area in IRam0 memory range (MEMPROT_IRAM0_SRAM)
|
||||
*
|
||||
* @param area_type IRam0 PMS Area type (see pms_area_t enum)
|
||||
* @param r Read permission flag holder
|
||||
* @param w Write permission flag holder
|
||||
* @param x Execute permission flag holder
|
||||
*/
|
||||
void esp_memprot_iram_get_pms_area(pms_area_t area_type, bool *r, bool *w, bool *x);
|
||||
|
||||
/**
|
||||
* @brief Sets permissions for given PMS Area in DRam0 memory range (MEMPROT_DRAM0_SRAM)
|
||||
*
|
||||
* @param area_type DRam0 PMS Area type (see pms_area_t enum)
|
||||
* @param r Read permission flag
|
||||
* @param w Write permission flag
|
||||
*/
|
||||
void esp_memprot_dram_set_pms_area(pms_area_t area_type, bool r, bool w);
|
||||
|
||||
/**
|
||||
* @brief Gets current permissions for given PMS Area in DRam0 memory range (MEMPROT_DRAM0_SRAM)
|
||||
*
|
||||
* @param area_type DRam0 PMS Area type (see pms_area_t enum)
|
||||
* @param r Read permission flag holder
|
||||
* @param w Write permission flag holder
|
||||
*/
|
||||
void esp_memprot_dram_get_pms_area(pms_area_t area_type, bool *r, bool *w);
|
||||
|
||||
/**
|
||||
* @brief Sets a lock for PMS interrupt monitor settings of required Memory type
|
||||
*
|
||||
* Locks can be unlocked only by digital system reset
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*/
|
||||
void esp_memprot_set_monitor_lock(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets a lock status for PMS interrupt monitor settings of required Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return true/false (locked/unlocked)
|
||||
*/
|
||||
bool esp_memprot_get_monitor_lock(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Enable PMS violation interrupt monitoring of required Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
* @param enable/disable
|
||||
*/
|
||||
void esp_memprot_set_monitor_en(mem_type_prot_t mem_type, bool enable);
|
||||
|
||||
/**
|
||||
* @brief Gets enable/disable status for PMS interrupt monitor settings of required Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return true/false (enabled/disabled)
|
||||
*/
|
||||
bool esp_memprot_get_monitor_en(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets CPU ID for currently active PMS violation interrupt
|
||||
*
|
||||
* @return CPU ID (CPU_PRO for ESP32C3)
|
||||
*/
|
||||
int IRAM_ATTR esp_memprot_intr_get_cpuid(void);
|
||||
|
||||
/**
|
||||
* @brief Clears current interrupt ON flag for given Memory type
|
||||
*
|
||||
* Interrupt clearing happens in two steps:
|
||||
* 1. Interrupt CLR flag is set (to clear the interrupt ON status)
|
||||
* 2. Interrupt CLR flag is reset (to allow further monitoring)
|
||||
* This operation is non-atomic by PMS module design
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*/
|
||||
void IRAM_ATTR esp_memprot_monitor_clear_intr(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns active PMS violation interrupt (if any)
|
||||
*
|
||||
* This function iterates through supported Memory type status registers
|
||||
* and returns the first interrupt-on flag. If none is found active,
|
||||
* MEMPROT_NONE is returned.
|
||||
* Order of checking (in current version):
|
||||
* 1. MEMPROT_IRAM0_SRAM
|
||||
* 2. MEMPROT_DRAM0_SRAM
|
||||
*
|
||||
* @return mem_type Memory protection type related to active interrupt found (see mem_type_prot_t enum)
|
||||
*/
|
||||
mem_type_prot_t IRAM_ATTR esp_memprot_get_active_intr_memtype(void);
|
||||
|
||||
/**
|
||||
* @brief Checks whether any violation interrupt is active
|
||||
*
|
||||
* @return true/false (yes/no)
|
||||
*/
|
||||
bool IRAM_ATTR esp_memprot_is_locked_any(void);
|
||||
|
||||
/**
|
||||
* @brief Checks whether any violation interrupt is enabled
|
||||
*
|
||||
* @return true/false (yes/no)
|
||||
*/
|
||||
bool IRAM_ATTR esp_memprot_is_intr_ena_any(void);
|
||||
|
||||
/**
|
||||
* @brief Checks whether any violation interrupt is enabled
|
||||
*
|
||||
* @return true/false (yes/no)
|
||||
*/
|
||||
bool IRAM_ATTR esp_memprot_get_violate_intr_on(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns the address which caused the violation interrupt (if any)
|
||||
*
|
||||
* The address is taken from appropriate PMS violation status register, based given Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return faulting address
|
||||
*/
|
||||
uint32_t IRAM_ATTR esp_memprot_get_violate_addr(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns the World identifier of the code causing the violation interrupt (if any)
|
||||
*
|
||||
* The value is taken from appropriate PMS violation status register, based given Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return World identifier (see pms_world_t enum)
|
||||
*/
|
||||
pms_world_t IRAM_ATTR esp_memprot_get_violate_world(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns Read or Write operation type which caused the violation interrupt (if any)
|
||||
*
|
||||
* The value (bit) is taken from appropriate PMS violation status register, based given Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return PMS operation type relevant to mem_type parameter (se pms_operation_type_t)
|
||||
*/
|
||||
pms_operation_type_t IRAM_ATTR esp_memprot_get_violate_wr(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns LoadStore flag of the operation type which caused the violation interrupt (if any)
|
||||
*
|
||||
* The value (bit) is taken from appropriate PMS violation status register, based given Memory type
|
||||
* Effective only on IRam0 access
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return true/false (LoadStore bit on/off)
|
||||
*/
|
||||
bool IRAM_ATTR esp_memprot_get_violate_loadstore(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns byte-enables for the address which caused the violation interrupt (if any)
|
||||
*
|
||||
* The value is taken from appropriate PMS violation status register, based given Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return byte-enables
|
||||
*/
|
||||
uint32_t IRAM_ATTR esp_memprot_get_violate_byte_en(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns raw contents of DRam0 status register 1
|
||||
*
|
||||
* @return 32-bit register value
|
||||
*/
|
||||
uint32_t IRAM_ATTR esp_memprot_get_dram_status_reg_1(void);
|
||||
|
||||
/**
|
||||
* @brief Returns raw contents of DRam0 status register 2
|
||||
*
|
||||
* @return 32-bit register value
|
||||
*/
|
||||
uint32_t IRAM_ATTR esp_memprot_get_dram_status_reg_2(void);
|
||||
|
||||
/**
|
||||
* @brief Returns raw contents of IRam0 status register
|
||||
*
|
||||
* @return 32-bit register value
|
||||
*/
|
||||
uint32_t IRAM_ATTR esp_memprot_get_iram_status_reg(void);
|
||||
|
||||
/**
|
||||
* @brief Register PMS violation interrupt in global interrupt matrix for given Memory type
|
||||
*
|
||||
* Memory protection components uses specific interrupt number, see ETS_MEMPROT_ERR_INUM
|
||||
* The registration makes the panic-handler routine being called when the interrupt appears
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*/
|
||||
void esp_memprot_set_intr_matrix(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Convenient routine for setting the PMS defaults
|
||||
*
|
||||
* Called on application startup, depending on CONFIG_ESP_SYSTEM_MEMPROT_FEATURE Kconfig settings
|
||||
* For implementation details see 'esp_memprot_set_prot_int' description
|
||||
*
|
||||
* @param invoke_panic_handler register all interrupts for panic handling (true/false)
|
||||
* @param lock_feature lock the defaults to prevent further PMS settings changes (true/false)
|
||||
* @param mem_type_mask 32-bit field of specific PMS parts to configure (see 'esp_memprot_set_prot_int')
|
||||
*/
|
||||
void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask);
|
||||
|
||||
/**
|
||||
* @brief Internal routine for setting the PMS defaults
|
||||
*
|
||||
* Called on application startup from within 'esp_memprot_set_prot'. Allows setting a specific splitting address
|
||||
* (main I/D split line) - see the parameter 'split_addr'. If the 'split_addr' equals to NULL, default I/D split line
|
||||
* is used (&_iram_text_end) and all the remaining lines share the same address.
|
||||
* The function sets all the split lines and PMS areas to the same space,
|
||||
* ie there is a single instruction space and single data space at the end.
|
||||
* The PMS split lines and permission areas scheme described below:
|
||||
*
|
||||
* DRam0/DMA IRam0
|
||||
* -----------------------------------------------
|
||||
* ... | IRam0_PMS_0 |
|
||||
* DRam0_PMS_0 ----------------------------------------------- IRam0_line1_Split_addr
|
||||
* ... | IRam0_PMS_1 |
|
||||
* ... ----------------------------------------------- IRam0_line0_Split_addr
|
||||
* | IRam0_PMS_2 |
|
||||
* =============================================== IRam0_DRam0_Split_addr (main I/D)
|
||||
* | DRam0_PMS_1 |
|
||||
* DRam0_DMA_line0_Split_addr ----------------------------------------------- ...
|
||||
* | DRam0_PMS_2 | ...
|
||||
* DRam0_DMA_line1_Split_addr ----------------------------------------------- IRam0_PMS_3
|
||||
* | DRam0_PMS_3 | ...
|
||||
* -----------------------------------------------
|
||||
*
|
||||
* Default settings provided by 'esp_memprot_set_prot_int' are as follows:
|
||||
*
|
||||
* DRam0/DMA IRam0
|
||||
* -----------------------------------------------
|
||||
* | IRam0_PMS_0 = IRam0_PMS_1 = IRam0_PMS_2 |
|
||||
* | DRam0_PMS_0 | IRam0_line1_Split_addr
|
||||
* DRam0_DMA_line0_Split_addr | | =
|
||||
* = =============================================== IRam0_line0_Split_addr
|
||||
* DRam0_DMA_line1_Split_addr | | =
|
||||
* | DRam0_PMS_1 = DRam0_PMS_2 = DRam0_PMS_3 | IRam0_DRam0_Split_addr (main I/D)
|
||||
* | IRam0_PMS_3 |
|
||||
* -----------------------------------------------
|
||||
*
|
||||
* Once the memprot feature is locked, it can be unlocked only by digital system reset
|
||||
*
|
||||
* @param invoke_panic_handler register all the violation interrupts for panic handling (true/false)
|
||||
* @param lock_feature lock the defaults to prevent further PMS settings changes (true/false)
|
||||
* @param split_addr specific main I/D adrees or NULL to use default ($_iram_text_end)
|
||||
* @param mem_type_mask 32-bit field of specific PMS parts to configure (members of mem_type_prot_t)
|
||||
*/
|
||||
void esp_memprot_set_prot_int(bool invoke_panic_handler, bool lock_feature, void *split_addr, uint32_t *mem_type_mask);
|
||||
|
||||
/**
|
||||
* @brief Returns raw contents of PMS interrupt monitor register for given Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return 32-bit register value
|
||||
*/
|
||||
uint32_t esp_memprot_get_monitor_enable_reg(mem_type_prot_t mem_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// ESP32-C3 PMS memory protection types
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Memory types recognized by PMS
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_TYPE_NONE = 0x00000000,
|
||||
MEMPROT_TYPE_IRAM0_SRAM = 0x00000001,
|
||||
MEMPROT_TYPE_DRAM0_SRAM = 0x00000002,
|
||||
MEMPROT_TYPE_IRAM0_RTCFAST = 0x00000004,
|
||||
MEMPROT_TYPE_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_TYPE_INVALID = 0x80000000,
|
||||
MEMPROT_TYPE_IRAM0_ANY = MEMPROT_TYPE_IRAM0_SRAM | MEMPROT_TYPE_IRAM0_RTCFAST
|
||||
} esp_mprot_mem_t;
|
||||
|
||||
/**
|
||||
* @brief Splitting address (line) type
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_SPLIT_ADDR_NONE = 0x00000000,
|
||||
MEMPROT_SPLIT_ADDR_IRAM0_DRAM0 = 0x00000001,
|
||||
MEMPROT_SPLIT_ADDR_IRAM0_LINE_0 = 0x00000002,
|
||||
MEMPROT_SPLIT_ADDR_IRAM0_LINE_1 = 0x00000004,
|
||||
MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_0 = 0x00000008,
|
||||
MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_1 = 0x00000010,
|
||||
MEMPROT_SPLIT_ADDR_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_SPLIT_ADDR_INVALID = 0x80000000,
|
||||
MEMPROT_SPLIT_ADDR_MAIN = MEMPROT_SPLIT_ADDR_IRAM0_DRAM0
|
||||
} esp_mprot_split_addr_t;
|
||||
|
||||
/**
|
||||
* @brief PMS area type (memory space between adjacent splitting addresses or above/below the main splt.address)
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_PMS_AREA_NONE = 0x00000000,
|
||||
MEMPROT_PMS_AREA_IRAM0_0 = 0x00000001,
|
||||
MEMPROT_PMS_AREA_IRAM0_1 = 0x00000002,
|
||||
MEMPROT_PMS_AREA_IRAM0_2 = 0x00000004,
|
||||
MEMPROT_PMS_AREA_IRAM0_3 = 0x00000008,
|
||||
MEMPROT_PMS_AREA_DRAM0_0 = 0x00000010,
|
||||
MEMPROT_PMS_AREA_DRAM0_1 = 0x00000020,
|
||||
MEMPROT_PMS_AREA_DRAM0_2 = 0x00000040,
|
||||
MEMPROT_PMS_AREA_DRAM0_3 = 0x00000080,
|
||||
MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO = 0x00000100,
|
||||
MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI = 0x00000200,
|
||||
MEMPROT_PMS_AREA_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_PMS_AREA_INVALID = 0x80000000
|
||||
} esp_mprot_pms_area_t;
|
||||
|
||||
/**
|
||||
* @brief Memory protection configuration
|
||||
*/
|
||||
typedef struct {
|
||||
bool invoke_panic_handler; /*!< Register PMS violation interrupt for panic-handling */
|
||||
bool lock_feature; /*!< Lock all PMS settings */
|
||||
void *split_addr; /*!< Main I/D splitting address */
|
||||
uint32_t mem_type_mask; /*!< Memory types required to protect. See esp_mprot_mem_t enum */
|
||||
} esp_memp_config_t;
|
||||
|
||||
#define ESP_MEMPROT_DEFAULT_CONFIG() { \
|
||||
.invoke_panic_handler = true, \
|
||||
.lock_feature = true, \
|
||||
.split_addr = NULL, \
|
||||
.mem_type_mask = MEMPROT_TYPE_ALL \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts Memory protection type to string
|
||||
*
|
||||
* @param mem_type Memory protection type
|
||||
*/
|
||||
static inline const char *esp_mprot_mem_type_to_str(const esp_mprot_mem_t mem_type)
|
||||
{
|
||||
switch (mem_type) {
|
||||
case MEMPROT_TYPE_NONE:
|
||||
return "NONE";
|
||||
case MEMPROT_TYPE_IRAM0_SRAM:
|
||||
return "IRAM0_SRAM";
|
||||
case MEMPROT_TYPE_DRAM0_SRAM:
|
||||
return "DRAM0_SRAM";
|
||||
case MEMPROT_TYPE_IRAM0_RTCFAST:
|
||||
return "IRAM0_RTCFAST";
|
||||
case MEMPROT_TYPE_IRAM0_ANY:
|
||||
return "IRAM0_ANY";
|
||||
case MEMPROT_TYPE_ALL:
|
||||
return "ALL";
|
||||
default:
|
||||
return "INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts Splitting address type to string
|
||||
*
|
||||
* @param line_type Split line type
|
||||
*/
|
||||
static inline const char *esp_mprot_split_addr_to_str(const esp_mprot_split_addr_t line_type)
|
||||
{
|
||||
switch (line_type) {
|
||||
case MEMPROT_SPLIT_ADDR_NONE:
|
||||
return "SPLIT_ADDR_NONE";
|
||||
case MEMPROT_SPLIT_ADDR_IRAM0_DRAM0:
|
||||
return "SPLIT_ADDR_IRAM0_DRAM0";
|
||||
case MEMPROT_SPLIT_ADDR_IRAM0_LINE_0:
|
||||
return "SPLIT_ADDR_IRAM0_LINE_0";
|
||||
case MEMPROT_SPLIT_ADDR_IRAM0_LINE_1:
|
||||
return "SPLIT_ADDR_IRAM0_LINE_1";
|
||||
case MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_0:
|
||||
return "SPLIT_ADDR_DRAM0_DMA_LINE_0";
|
||||
case MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_1:
|
||||
return "SPLIT_ADDR_DRAM0_DMA_LINE_1";
|
||||
case MEMPROT_SPLIT_ADDR_ALL:
|
||||
return "SPLIT_ADDR_ALL";
|
||||
default:
|
||||
return "SPLIT_ADDR_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts PMS Area type to string
|
||||
*
|
||||
* @param area_type PMS Area type
|
||||
*/
|
||||
static inline const char *esp_mprot_pms_area_to_str(const esp_mprot_pms_area_t area_type)
|
||||
{
|
||||
switch (area_type) {
|
||||
case MEMPROT_PMS_AREA_NONE:
|
||||
return "PMS_AREA_NONE";
|
||||
case MEMPROT_PMS_AREA_IRAM0_0:
|
||||
return "PMS_AREA_IRAM0_0";
|
||||
case MEMPROT_PMS_AREA_IRAM0_1:
|
||||
return "PMS_AREA_IRAM0_1";
|
||||
case MEMPROT_PMS_AREA_IRAM0_2:
|
||||
return "PMS_AREA_IRAM0_2";
|
||||
case MEMPROT_PMS_AREA_IRAM0_3:
|
||||
return "PMS_AREA_IRAM0_3";
|
||||
case MEMPROT_PMS_AREA_DRAM0_0:
|
||||
return "PMS_AREA_DRAM0_0";
|
||||
case MEMPROT_PMS_AREA_DRAM0_1:
|
||||
return "PMS_AREA_DRAM0_1";
|
||||
case MEMPROT_PMS_AREA_DRAM0_2:
|
||||
return "PMS_AREA_DRAM0_2";
|
||||
case MEMPROT_PMS_AREA_DRAM0_3:
|
||||
return "PMS_AREA_DRAM0_3";
|
||||
case MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO:
|
||||
return "PMS_AREA_IRAM0_RTCFAST_LO";
|
||||
case MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI:
|
||||
return "PMS_AREA_IRAM0_RTCFAST_HI";
|
||||
case MEMPROT_PMS_AREA_ALL:
|
||||
return "PMS_AREA_ALL";
|
||||
default:
|
||||
return "PMS_AREA_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,448 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
/* INTERNAL API
|
||||
* generic interface to PMS memory protection features
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef IRAM_SRAM_START
|
||||
#define IRAM_SRAM_START 0x4037C000
|
||||
#endif
|
||||
|
||||
#ifndef DRAM_SRAM_START
|
||||
#define DRAM_SRAM_START 0x3FC7C000
|
||||
#endif
|
||||
|
||||
#ifndef MAP_DRAM_TO_IRAM
|
||||
#define MAP_DRAM_TO_IRAM(addr) (addr - DRAM_SRAM_START + IRAM_SRAM_START)
|
||||
#endif
|
||||
|
||||
#ifndef MAP_IRAM_TO_DRAM
|
||||
#define MAP_IRAM_TO_DRAM(addr) (addr - IRAM_SRAM_START + DRAM_SRAM_START)
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
MEMPROT_NONE = 0x00000000,
|
||||
MEMPROT_IRAM0_SRAM = 0x00000001,
|
||||
MEMPROT_DRAM0_SRAM = 0x00000002,
|
||||
MEMPROT_ALL = 0xFFFFFFFF
|
||||
} mem_type_prot_t;
|
||||
|
||||
typedef enum {
|
||||
MEMPROT_SPLITLINE_NONE = 0,
|
||||
MEMPROT_IRAM0_DRAM0_SPLITLINE,
|
||||
MEMPROT_IRAM0_LINE_0_SPLITLINE,
|
||||
MEMPROT_IRAM0_LINE_1_SPLITLINE,
|
||||
MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE,
|
||||
MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE
|
||||
} split_line_t;
|
||||
|
||||
typedef enum {
|
||||
MEMPROT_PMS_AREA_NONE = 0,
|
||||
MEMPROT_IRAM0_PMS_AREA_0,
|
||||
MEMPROT_IRAM0_PMS_AREA_1,
|
||||
MEMPROT_IRAM0_PMS_AREA_2,
|
||||
MEMPROT_IRAM0_PMS_AREA_3,
|
||||
MEMPROT_DRAM0_PMS_AREA_0,
|
||||
MEMPROT_DRAM0_PMS_AREA_1,
|
||||
MEMPROT_DRAM0_PMS_AREA_2,
|
||||
MEMPROT_DRAM0_PMS_AREA_3
|
||||
} pms_area_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MEMPROT_PMS_WORLD_0 = 0,
|
||||
MEMPROT_PMS_WORLD_1,
|
||||
MEMPROT_PMS_WORLD_2,
|
||||
MEMPROT_PMS_WORLD_INVALID = 0xFFFFFFFF
|
||||
} pms_world_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MEMPROT_PMS_OP_READ = 0,
|
||||
MEMPROT_PMS_OP_WRITE,
|
||||
MEMPROT_PMS_OP_FETCH,
|
||||
MEMPROT_PMS_OP_INVALID = 0xFFFFFFFF
|
||||
} pms_operation_type_t;
|
||||
|
||||
/**
|
||||
* @brief Converts Memory protection type to string
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*/
|
||||
const char *esp_memprot_mem_type_to_str(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Converts Split line type to string
|
||||
*
|
||||
* @param line_type Split line type (see split_line_t enum)
|
||||
*/
|
||||
const char *esp_memprot_split_line_to_str(split_line_t line_type);
|
||||
|
||||
/**
|
||||
* @brief Converts PMS Area type to string
|
||||
*
|
||||
* @param area_type PMS Area type (see pms_area_t enum)
|
||||
*/
|
||||
const char *esp_memprot_pms_to_str(pms_area_t area_type);
|
||||
|
||||
/**
|
||||
* @brief Returns PMS splitting address for given Split line type
|
||||
*
|
||||
* The value is taken from PMS configuration registers (IRam0 range)
|
||||
* For details on split lines see 'esp_memprot_set_prot_int' function description
|
||||
*
|
||||
* @param line_type Split line type (see split_line_t enum)
|
||||
*
|
||||
* @return appropriate split line address
|
||||
*/
|
||||
uint32_t *esp_memprot_get_split_addr(split_line_t line_type);
|
||||
|
||||
/**
|
||||
* @brief Returns default main IRAM/DRAM splitting address
|
||||
*
|
||||
* The address value is given by _iram_text_end global (IRam0 range)
|
||||
|
||||
* @return Main I/D split line (IRam0_DRam0_Split_Addr)
|
||||
*/
|
||||
void *esp_memprot_get_default_main_split_addr(void);
|
||||
|
||||
/**
|
||||
* @brief Sets a lock for the main IRAM/DRAM splitting address
|
||||
*
|
||||
* Locks can be unlocked only by digital system reset
|
||||
*/
|
||||
void esp_memprot_set_split_line_lock(void);
|
||||
|
||||
/**
|
||||
* @brief Gets a lock status for the main IRAM/DRAM splitting address
|
||||
*
|
||||
* @return true/false (locked/unlocked)
|
||||
*/
|
||||
bool esp_memprot_get_split_line_lock(void);
|
||||
|
||||
/**
|
||||
* @brief Sets required split line address
|
||||
*
|
||||
* @param line_type Split line type (see split_line_t enum)
|
||||
* @param line_addr target address from a memory range relevant to given line_type (IRAM/DRAM)
|
||||
*/
|
||||
void esp_memprot_set_split_line(split_line_t line_type, const void *line_addr);
|
||||
|
||||
/**
|
||||
* @brief Sets a lock for PMS Area settings of required Memory type
|
||||
*
|
||||
* Locks can be unlocked only by digital system reset
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*/
|
||||
void esp_memprot_set_pms_lock(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets a lock status for PMS Area settings of required Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return true/false (locked/unlocked)
|
||||
*/
|
||||
bool esp_memprot_get_pms_lock(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Sets permissions for given PMS Area in IRam0 memory range (MEMPROT_IRAM0_SRAM)
|
||||
*
|
||||
* @param area_type IRam0 PMS Area type (see pms_area_t enum)
|
||||
* @param r Read permission flag
|
||||
* @param w Write permission flag
|
||||
* @param x Execute permission flag
|
||||
*/
|
||||
void esp_memprot_iram_set_pms_area(pms_area_t area_type, bool r, bool w, bool x);
|
||||
|
||||
/**
|
||||
* @brief Gets current permissions for given PMS Area in IRam0 memory range (MEMPROT_IRAM0_SRAM)
|
||||
*
|
||||
* @param area_type IRam0 PMS Area type (see pms_area_t enum)
|
||||
* @param r Read permission flag holder
|
||||
* @param w Write permission flag holder
|
||||
* @param x Execute permission flag holder
|
||||
*/
|
||||
void esp_memprot_iram_get_pms_area(pms_area_t area_type, bool *r, bool *w, bool *x);
|
||||
|
||||
/**
|
||||
* @brief Sets permissions for given PMS Area in DRam0 memory range (MEMPROT_DRAM0_SRAM)
|
||||
*
|
||||
* @param area_type DRam0 PMS Area type (see pms_area_t enum)
|
||||
* @param r Read permission flag
|
||||
* @param w Write permission flag
|
||||
*/
|
||||
void esp_memprot_dram_set_pms_area(pms_area_t area_type, bool r, bool w);
|
||||
|
||||
/**
|
||||
* @brief Gets current permissions for given PMS Area in DRam0 memory range (MEMPROT_DRAM0_SRAM)
|
||||
*
|
||||
* @param area_type DRam0 PMS Area type (see pms_area_t enum)
|
||||
* @param r Read permission flag holder
|
||||
* @param w Write permission flag holder
|
||||
*/
|
||||
void esp_memprot_dram_get_pms_area(pms_area_t area_type, bool *r, bool *w);
|
||||
|
||||
/**
|
||||
* @brief Sets a lock for PMS interrupt monitor settings of required Memory type
|
||||
*
|
||||
* Locks can be unlocked only by digital system reset
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*/
|
||||
void esp_memprot_set_monitor_lock(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets a lock status for PMS interrupt monitor settings of required Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return true/false (locked/unlocked)
|
||||
*/
|
||||
bool esp_memprot_get_monitor_lock(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Enable PMS violation interrupt monitoring of required Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
* @param enable/disable
|
||||
*/
|
||||
void esp_memprot_set_monitor_en(mem_type_prot_t mem_type, bool enable);
|
||||
|
||||
/**
|
||||
* @brief Gets enable/disable status for PMS interrupt monitor settings of required Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return true/false (enabled/disabled)
|
||||
*/
|
||||
bool esp_memprot_get_monitor_en(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets CPU ID for currently active PMS violation interrupt
|
||||
*
|
||||
* @return CPU ID (CPU_PRO for ESP32H2)
|
||||
*/
|
||||
int IRAM_ATTR esp_memprot_intr_get_cpuid(void);
|
||||
|
||||
/**
|
||||
* @brief Clears current interrupt ON flag for given Memory type
|
||||
*
|
||||
* Interrupt clearing happens in two steps:
|
||||
* 1. Interrupt CLR flag is set (to clear the interrupt ON status)
|
||||
* 2. Interrupt CLR flag is reset (to allow further monitoring)
|
||||
* This operation is non-atomic by PMS module design
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*/
|
||||
void IRAM_ATTR esp_memprot_monitor_clear_intr(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns active PMS violation interrupt (if any)
|
||||
*
|
||||
* This function iterates through supported Memory type status registers
|
||||
* and returns the first interrupt-on flag. If none is found active,
|
||||
* MEMPROT_NONE is returned.
|
||||
* Order of checking (in current version):
|
||||
* 1. MEMPROT_IRAM0_SRAM
|
||||
* 2. MEMPROT_DRAM0_SRAM
|
||||
*
|
||||
* @return mem_type Memory protection type related to active interrupt found (see mem_type_prot_t enum)
|
||||
*/
|
||||
mem_type_prot_t IRAM_ATTR esp_memprot_get_active_intr_memtype(void);
|
||||
|
||||
/**
|
||||
* @brief Checks whether any violation interrupt is active
|
||||
*
|
||||
* @return true/false (yes/no)
|
||||
*/
|
||||
bool IRAM_ATTR esp_memprot_is_locked_any(void);
|
||||
|
||||
/**
|
||||
* @brief Checks whether any violation interrupt is enabled
|
||||
*
|
||||
* @return true/false (yes/no)
|
||||
*/
|
||||
bool IRAM_ATTR esp_memprot_is_intr_ena_any(void);
|
||||
|
||||
/**
|
||||
* @brief Checks whether any violation interrupt is enabled
|
||||
*
|
||||
* @return true/false (yes/no)
|
||||
*/
|
||||
bool IRAM_ATTR esp_memprot_get_violate_intr_on(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns the address which caused the violation interrupt (if any)
|
||||
*
|
||||
* The address is taken from appropriate PMS violation status register, based given Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return faulting address
|
||||
*/
|
||||
uint32_t IRAM_ATTR esp_memprot_get_violate_addr(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns the World identifier of the code causing the violation interrupt (if any)
|
||||
*
|
||||
* The value is taken from appropriate PMS violation status register, based given Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return World identifier (see pms_world_t enum)
|
||||
*/
|
||||
pms_world_t IRAM_ATTR esp_memprot_get_violate_world(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns Read or Write operation type which caused the violation interrupt (if any)
|
||||
*
|
||||
* The value (bit) is taken from appropriate PMS violation status register, based given Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return PMS operation type relevant to mem_type parameter (se pms_operation_type_t)
|
||||
*/
|
||||
pms_operation_type_t IRAM_ATTR esp_memprot_get_violate_wr(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns LoadStore flag of the operation type which caused the violation interrupt (if any)
|
||||
*
|
||||
* The value (bit) is taken from appropriate PMS violation status register, based given Memory type
|
||||
* Effective only on IRam0 access
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return true/false (LoadStore bit on/off)
|
||||
*/
|
||||
bool IRAM_ATTR esp_memprot_get_violate_loadstore(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns byte-enables for the address which caused the violation interrupt (if any)
|
||||
*
|
||||
* The value is taken from appropriate PMS violation status register, based given Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return byte-enables
|
||||
*/
|
||||
uint32_t IRAM_ATTR esp_memprot_get_violate_byte_en(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns raw contents of DRam0 status register 1
|
||||
*
|
||||
* @return 32-bit register value
|
||||
*/
|
||||
uint32_t IRAM_ATTR esp_memprot_get_dram_status_reg_1(void);
|
||||
|
||||
/**
|
||||
* @brief Returns raw contents of DRam0 status register 2
|
||||
*
|
||||
* @return 32-bit register value
|
||||
*/
|
||||
uint32_t IRAM_ATTR esp_memprot_get_dram_status_reg_2(void);
|
||||
|
||||
/**
|
||||
* @brief Returns raw contents of IRam0 status register
|
||||
*
|
||||
* @return 32-bit register value
|
||||
*/
|
||||
uint32_t IRAM_ATTR esp_memprot_get_iram_status_reg(void);
|
||||
|
||||
/**
|
||||
* @brief Register PMS violation interrupt in global interrupt matrix for given Memory type
|
||||
*
|
||||
* Memory protection components uses specific interrupt number, see ETS_MEMPROT_ERR_INUM
|
||||
* The registration makes the panic-handler routine being called when the interrupt appears
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*/
|
||||
void esp_memprot_set_intr_matrix(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Convenient routine for setting the PMS defaults
|
||||
*
|
||||
* Called on application startup, depending on CONFIG_ESP_SYSTEM_MEMPROT_FEATURE Kconfig settings
|
||||
* For implementation details see 'esp_memprot_set_prot_int' description
|
||||
*
|
||||
* @param invoke_panic_handler register all interrupts for panic handling (true/false)
|
||||
* @param lock_feature lock the defaults to prevent further PMS settings changes (true/false)
|
||||
* @param mem_type_mask 32-bit field of specific PMS parts to configure (see 'esp_memprot_set_prot_int')
|
||||
*/
|
||||
void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask);
|
||||
|
||||
/**
|
||||
* @brief Internal routine for setting the PMS defaults
|
||||
*
|
||||
* Called on application startup from within 'esp_memprot_set_prot'. Allows setting a specific splitting address
|
||||
* (main I/D split line) - see the parameter 'split_addr'. If the 'split_addr' equals to NULL, default I/D split line
|
||||
* is used (&_iram_text_end) and all the remaining lines share the same address.
|
||||
* The function sets all the split lines and PMS areas to the same space,
|
||||
* ie there is a single instruction space and single data space at the end.
|
||||
* The PMS split lines and permission areas scheme described below:
|
||||
*
|
||||
* DRam0/DMA IRam0
|
||||
* -----------------------------------------------
|
||||
* ... | IRam0_PMS_0 |
|
||||
* DRam0_PMS_0 ----------------------------------------------- IRam0_line1_Split_addr
|
||||
* ... | IRam0_PMS_1 |
|
||||
* ... ----------------------------------------------- IRam0_line0_Split_addr
|
||||
* | IRam0_PMS_2 |
|
||||
* =============================================== IRam0_DRam0_Split_addr (main I/D)
|
||||
* | DRam0_PMS_1 |
|
||||
* DRam0_DMA_line0_Split_addr ----------------------------------------------- ...
|
||||
* | DRam0_PMS_2 | ...
|
||||
* DRam0_DMA_line1_Split_addr ----------------------------------------------- IRam0_PMS_3
|
||||
* | DRam0_PMS_3 | ...
|
||||
* -----------------------------------------------
|
||||
*
|
||||
* Default settings provided by 'esp_memprot_set_prot_int' are as follows:
|
||||
*
|
||||
* DRam0/DMA IRam0
|
||||
* -----------------------------------------------
|
||||
* | IRam0_PMS_0 = IRam0_PMS_1 = IRam0_PMS_2 |
|
||||
* | DRam0_PMS_0 | IRam0_line1_Split_addr
|
||||
* DRam0_DMA_line0_Split_addr | | =
|
||||
* = =============================================== IRam0_line0_Split_addr
|
||||
* DRam0_DMA_line1_Split_addr | | =
|
||||
* | DRam0_PMS_1 = DRam0_PMS_2 = DRam0_PMS_3 | IRam0_DRam0_Split_addr (main I/D)
|
||||
* | IRam0_PMS_3 |
|
||||
* -----------------------------------------------
|
||||
*
|
||||
* Once the memprot feature is locked, it can be unlocked only by digital system reset
|
||||
*
|
||||
* @param invoke_panic_handler register all the violation interrupts for panic handling (true/false)
|
||||
* @param lock_feature lock the defaults to prevent further PMS settings changes (true/false)
|
||||
* @param split_addr specific main I/D adrees or NULL to use default ($_iram_text_end)
|
||||
* @param mem_type_mask 32-bit field of specific PMS parts to configure (members of mem_type_prot_t)
|
||||
*/
|
||||
void esp_memprot_set_prot_int(bool invoke_panic_handler, bool lock_feature, void *split_addr, uint32_t *mem_type_mask);
|
||||
|
||||
/**
|
||||
* @brief Returns raw contents of PMS interrupt monitor register for given Memory type
|
||||
*
|
||||
* @param mem_type Memory protection type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return 32-bit register value
|
||||
*/
|
||||
uint32_t esp_memprot_get_monitor_enable_reg(mem_type_prot_t mem_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// ESP32-H2 PMS memory protection types
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Memory types recognized by PMS
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_TYPE_NONE = 0x00000000,
|
||||
MEMPROT_TYPE_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_TYPE_INVALID = 0x80000000
|
||||
} esp_mprot_mem_t;
|
||||
|
||||
/**
|
||||
* @brief Splitting address (line) type
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_SPLIT_ADDR_NONE = 0x00000000,
|
||||
MEMPROT_SPLIT_ADDR_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_SPLIT_ADDR_INVALID = 0x80000000
|
||||
} esp_mprot_split_addr_t;
|
||||
|
||||
/**
|
||||
* @brief PMS area type (memory space between adjacent splitting addresses or above/below the main splt.address)
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_PMS_AREA_NONE = 0x00000000,
|
||||
MEMPROT_PMS_AREA_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_PMS_AREA_INVALID = 0x80000000
|
||||
} esp_mprot_pms_area_t;
|
||||
|
||||
/**
|
||||
* @brief Memory protection configuration
|
||||
*/
|
||||
typedef struct {
|
||||
bool invoke_panic_handler; /*!< Register PMS violation interrupt for panic-handling */
|
||||
bool lock_feature; /*!< Lock all PMS settings */
|
||||
void *split_addr; /*!< Main I/D splitting address */
|
||||
uint32_t mem_type_mask; /*!< Memory types required to protect. See esp_mprot_mem_t enum */
|
||||
} esp_memp_config_t;
|
||||
|
||||
#define ESP_MEMPROT_DEFAULT_CONFIG() {\
|
||||
.invoke_panic_handler = true, \
|
||||
.lock_feature = true, \
|
||||
.split_addr = NULL, \
|
||||
.mem_type_mask = MEMPROT_TYPE_ALL \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts Memory protection type to string
|
||||
*
|
||||
* @param mem_type Memory protection type
|
||||
*/
|
||||
static inline const char *esp_mprot_mem_type_to_str(const esp_mprot_mem_t mem_type)
|
||||
{
|
||||
switch (mem_type) {
|
||||
case MEMPROT_TYPE_NONE:
|
||||
return "MEMPROT_TYPE_NONE";
|
||||
case MEMPROT_TYPE_ALL:
|
||||
return "MEMPROT_TYPE_ALL";
|
||||
default:
|
||||
return "MEMPROT_TYPE_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts Splitting address type to string
|
||||
*
|
||||
* @param line_type Split line type
|
||||
*/
|
||||
static inline const char *esp_mprot_split_addr_to_str(const esp_mprot_split_addr_t line_type)
|
||||
{
|
||||
switch (line_type) {
|
||||
case MEMPROT_SPLIT_ADDR_NONE:
|
||||
return "MEMPROT_SPLIT_ADDR_NONE";
|
||||
case MEMPROT_SPLIT_ADDR_ALL:
|
||||
return "MEMPROT_SPLIT_ADDR_ALL";
|
||||
default:
|
||||
return "MEMPROT_SPLIT_ADDR_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts PMS Area type to string
|
||||
*
|
||||
* @param area_type PMS Area type
|
||||
*/
|
||||
static inline const char *esp_mprot_pms_area_to_str(const esp_mprot_pms_area_t area_type)
|
||||
{
|
||||
switch (area_type) {
|
||||
case MEMPROT_PMS_AREA_NONE:
|
||||
return "MEMPROT_PMS_AREA_NONE";
|
||||
case MEMPROT_PMS_AREA_ALL:
|
||||
return "MEMPROT_PMS_AREA_ALL";
|
||||
default:
|
||||
return "MEMPROT_PMS_AREA_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// ESP32-S2 PMS memory protection types
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Memory types recognized by PMS
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_TYPE_NONE = 0x00000000,
|
||||
MEMPROT_TYPE_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_TYPE_INVALID = 0x80000000
|
||||
} esp_mprot_mem_t;
|
||||
|
||||
/**
|
||||
* @brief Splitting address (line) type
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_SPLIT_ADDR_NONE = 0x00000000,
|
||||
MEMPROT_SPLIT_ADDR_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_SPLIT_ADDR_INVALID = 0x80000000
|
||||
} esp_mprot_split_addr_t;
|
||||
|
||||
/**
|
||||
* @brief PMS area type (memory space between adjacent splitting addresses or above/below the main splt.address)
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_PMS_AREA_NONE = 0x00000000,
|
||||
MEMPROT_PMS_AREA_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_PMS_AREA_INVALID = 0x80000000
|
||||
} esp_mprot_pms_area_t;
|
||||
|
||||
/**
|
||||
* @brief Memory protection configuration
|
||||
*/
|
||||
typedef struct {
|
||||
bool invoke_panic_handler; /*!< Register PMS violation interrupt for panic-handling */
|
||||
bool lock_feature; /*!< Lock all PMS settings */
|
||||
void *split_addr; /*!< Main I/D splitting address */
|
||||
uint32_t mem_type_mask; /*!< Memory types required to protect. See esp_mprot_mem_t enum */
|
||||
} esp_memp_config_t;
|
||||
|
||||
#define ESP_MEMPROT_DEFAULT_CONFIG() { \
|
||||
.invoke_panic_handler = true, \
|
||||
.lock_feature = true, \
|
||||
.split_addr = NULL, \
|
||||
.mem_type_mask = MEMPROT_TYPE_ALL \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts Memory protection type to string
|
||||
*
|
||||
* @param mem_type Memory protection type
|
||||
*/
|
||||
static inline const char *esp_mprot_mem_type_to_str(const esp_mprot_mem_t mem_type)
|
||||
{
|
||||
switch (mem_type) {
|
||||
case MEMPROT_TYPE_NONE:
|
||||
return "MEMPROT_TYPE_NONE";
|
||||
case MEMPROT_TYPE_ALL:
|
||||
return "MEMPROT_TYPE_ALL";
|
||||
default:
|
||||
return "MEMPROT_TYPE_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts Splitting address type to string
|
||||
*
|
||||
* @param line_type Split line type
|
||||
*/
|
||||
static inline const char *esp_mprot_split_addr_to_str(const esp_mprot_split_addr_t line_type)
|
||||
{
|
||||
switch (line_type) {
|
||||
case MEMPROT_SPLIT_ADDR_NONE:
|
||||
return "MEMPROT_SPLIT_ADDR_NONE";
|
||||
case MEMPROT_SPLIT_ADDR_ALL:
|
||||
return "MEMPROT_SPLIT_ADDR_ALL";
|
||||
default:
|
||||
return "MEMPROT_SPLIT_ADDR_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts PMS Area type to string
|
||||
*
|
||||
* @param area_type PMS Area type
|
||||
*/
|
||||
static inline const char *esp_mprot_pms_area_to_str(const esp_mprot_pms_area_t area_type)
|
||||
{
|
||||
switch (area_type) {
|
||||
case MEMPROT_PMS_AREA_NONE:
|
||||
return "MEMPROT_PMS_AREA_NONE";
|
||||
case MEMPROT_PMS_AREA_ALL:
|
||||
return "MEMPROT_PMS_AREA_ALL";
|
||||
default:
|
||||
return "MEMPROT_PMS_AREA_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,484 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
/* INTERNAL API
|
||||
* generic interface to MMU memory protection features
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
MEMPROT_NONE = 0x00000000,
|
||||
MEMPROT_IRAM0_SRAM = 0x00000001,
|
||||
MEMPROT_DRAM0_SRAM = 0x00000002,
|
||||
MEMPROT_IRAM0_RTCFAST = 0x00000004,
|
||||
MEMPROT_DRAM0_RTCFAST = 0x00000008,
|
||||
MEMPROT_PERI1_RTCSLOW = 0x00000010,
|
||||
MEMPROT_PERI2_RTCSLOW_0 = 0x00000020,
|
||||
MEMPROT_PERI2_RTCSLOW_1 = 0x00000040,
|
||||
MEMPROT_ALL = 0xFFFFFFFF
|
||||
} mem_type_prot_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns splitting address for required memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return Splitting address for the memory region required.
|
||||
* The address is given by region-specific global symbol exported from linker script,
|
||||
* it is not read out from related configuration register.
|
||||
*/
|
||||
uint32_t *IRAM_ATTR esp_memprot_get_split_addr(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Initializes illegal memory access control (MMU) for required memory section.
|
||||
*
|
||||
* All memory access interrupts share ETS_MEMACCESS_ERR_INUM input channel, it is caller's
|
||||
* responsibility to properly detect actual intr. source as well as possible prioritization in case
|
||||
* of multiple source reported during one intr.handling routine run
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*/
|
||||
void esp_memprot_intr_init(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Enable/disable the memory protection interrupt
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param enable enable/disable
|
||||
*/
|
||||
void esp_memprot_intr_ena(mem_type_prot_t mem_type, bool enable);
|
||||
|
||||
/**
|
||||
* @brief Sets a request for clearing interrupt-on flag for specified memory region (register write)
|
||||
*
|
||||
* @note When called without actual interrupt-on flag set, subsequent occurrence of related interrupt is ignored.
|
||||
* Should be used only after the real interrupt appears, typically as the last step in interrupt handler's routine.
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*/
|
||||
void esp_memprot_clear_intr(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Detects which memory protection interrupt is active
|
||||
*
|
||||
* @note Check order
|
||||
* MEMPROT_IRAM0_SRAM
|
||||
* MEMPROT_IRAM0_RTCFAST
|
||||
* MEMPROT_DRAM0_SRAM
|
||||
* MEMPROT_DRAM0_RTCFAST
|
||||
*
|
||||
* @return Memory protection area type (see mem_type_prot_t enum)
|
||||
*/
|
||||
mem_type_prot_t IRAM_ATTR esp_memprot_get_active_intr_memtype(void);
|
||||
|
||||
/**
|
||||
* @brief Gets interrupt status register contents for specified memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return Contents of status register
|
||||
*/
|
||||
uint32_t esp_memprot_get_fault_reg(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Get details of given interrupt status
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param faulting_address Faulting address causing the interrupt [out]
|
||||
* @param op_type Operation being processed at the faulting address [out]
|
||||
* IRAM0: 0 - read, 1 - write
|
||||
* DRAM0: 0 - read, 1 - write
|
||||
* @param op_subtype Additional info for op_type [out]
|
||||
* IRAM0: 0 - instruction segment access, 1 - data segment access
|
||||
* DRAM0: 0 - non-atomic operation, 1 - atomic operation
|
||||
*/
|
||||
void IRAM_ATTR esp_memprot_get_fault_status(mem_type_prot_t mem_type, uint32_t **faulting_address, uint32_t *op_type, uint32_t *op_subtype);
|
||||
|
||||
/**
|
||||
* @brief Gets string representation of required memory region identifier
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return mem_type as string
|
||||
*/
|
||||
const char *IRAM_ATTR esp_memprot_type_to_str(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Detects whether any of the interrupt locks is active (requires digital system reset to unlock)
|
||||
*
|
||||
* @return true/false
|
||||
*/
|
||||
bool esp_memprot_is_locked_any(void);
|
||||
|
||||
/**
|
||||
* @brief Sets lock for specified memory region.
|
||||
*
|
||||
* Locks can be unlocked only by digital system reset
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*/
|
||||
void esp_memprot_set_lock(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets lock status for required memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return true/false (locked/unlocked)
|
||||
*/
|
||||
bool esp_memprot_get_lock(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets permission control configuration register contents for required memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return Permission control register contents
|
||||
*/
|
||||
uint32_t esp_memprot_get_conf_reg(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets interrupt permission settings for unified management block
|
||||
*
|
||||
* Gets interrupt permission settings register contents for required memory region, returns settings for unified management blocks
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return Permission settings register contents
|
||||
*/
|
||||
uint32_t esp_memprot_get_perm_uni_reg(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets interrupt permission settings for split management block
|
||||
*
|
||||
* Gets interrupt permission settings register contents for required memory region, returns settings for split management blocks
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return Permission settings register contents
|
||||
*/
|
||||
uint32_t esp_memprot_get_perm_split_reg(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Detects whether any of the memory protection interrupts is enabled
|
||||
*
|
||||
* @return true/false
|
||||
*/
|
||||
bool esp_memprot_is_intr_ena_any(void);
|
||||
|
||||
/**
|
||||
* @brief Gets interrupt-enabled flag for given memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return Interrupt-enabled value
|
||||
*/
|
||||
uint32_t esp_memprot_get_intr_ena_bit(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets interrupt-active flag for given memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return Interrupt-active value
|
||||
*/
|
||||
uint32_t esp_memprot_get_intr_on_bit(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets interrupt-clear request flag for given memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*
|
||||
* @return Interrupt-clear request value
|
||||
*/
|
||||
uint32_t esp_memprot_get_intr_clr_bit(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Gets read permission value for specified block and memory region
|
||||
*
|
||||
* Returns read permission bit value for required unified-management block (0-3) in given memory region.
|
||||
* Applicable to all memory types.
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param block Memory block identifier (0-3)
|
||||
*
|
||||
* @return Read permission value for required block
|
||||
*/
|
||||
uint32_t esp_memprot_get_uni_block_read_bit(mem_type_prot_t mem_type, uint32_t block);
|
||||
|
||||
/**
|
||||
* @brief Gets write permission value for specified block and memory region
|
||||
*
|
||||
* Returns write permission bit value for required unified-management block (0-3) in given memory region.
|
||||
* Applicable to all memory types.
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param block Memory block identifier (0-3)
|
||||
*
|
||||
* @return Write permission value for required block
|
||||
*/
|
||||
uint32_t esp_memprot_get_uni_block_write_bit(mem_type_prot_t mem_type, uint32_t block);
|
||||
|
||||
/**
|
||||
* @brief Gets execute permission value for specified block and memory region
|
||||
*
|
||||
* Returns execute permission bit value for required unified-management block (0-3) in given memory region.
|
||||
* Applicable only to IRAM memory types
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param block Memory block identifier (0-3)
|
||||
*
|
||||
* @return Execute permission value for required block
|
||||
*/
|
||||
uint32_t esp_memprot_get_uni_block_exec_bit(mem_type_prot_t mem_type, uint32_t block);
|
||||
|
||||
/**
|
||||
* @brief Sets permissions for specified block in DRAM region
|
||||
*
|
||||
* Sets Read and Write permission for specified unified-management block (0-3) in given memory region.
|
||||
* Applicable only to DRAM memory types
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param block Memory block identifier (0-3)
|
||||
* @param write_perm Write permission flag
|
||||
* @param read_perm Read permission flag
|
||||
*/
|
||||
void esp_memprot_set_uni_block_perm_dram(mem_type_prot_t mem_type, uint32_t block, bool write_perm, bool read_perm);
|
||||
|
||||
/**
|
||||
* @brief Sets permissions for high and low memory segment in DRAM region
|
||||
*
|
||||
* Sets Read and Write permission for both low and high memory segments given by splitting address.
|
||||
* The splitting address must be equal to or higher then beginning of block 5
|
||||
* Applicable only to DRAM memory types
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param split_addr Address to split the memory region to lower and higher segment
|
||||
* @param lw Low segment Write permission flag
|
||||
* @param lr Low segment Read permission flag
|
||||
* @param hw High segment Write permission flag
|
||||
* @param hr High segment Read permission flag
|
||||
*/
|
||||
void esp_memprot_set_prot_dram(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr);
|
||||
|
||||
/**
|
||||
* @brief Sets permissions for specified block in IRAM region
|
||||
*
|
||||
* Sets Read, Write and Execute permission for specified unified-management block (0-3) in given memory region.
|
||||
* Applicable only to IRAM memory types
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param block Memory block identifier (0-3)
|
||||
* @param write_perm Write permission flag
|
||||
* @param exec_perm Execute permission flag
|
||||
*/
|
||||
void esp_memprot_set_uni_block_perm_iram(mem_type_prot_t mem_type, uint32_t block, bool write_perm, bool read_perm, bool exec_perm);
|
||||
|
||||
/**
|
||||
* @brief Sets permissions for high and low memory segment in IRAM region
|
||||
*
|
||||
* Sets Read, Write and Execute permission for both low and high memory segments given by splitting address.
|
||||
* The splitting address must be equal to or higher then beginning of block 5
|
||||
* Applicable only to IRAM memory types
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param split_addr Address to split the memory region to lower and higher segment
|
||||
* @param lw Low segment Write permission flag
|
||||
* @param lr Low segment Read permission flag
|
||||
* @param lx Low segment Execute permission flag
|
||||
* @param hw High segment Write permission flag
|
||||
* @param hr High segment Read permission flag
|
||||
* @param hx High segment Execute permission flag
|
||||
*/
|
||||
void esp_memprot_set_prot_iram(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx);
|
||||
|
||||
/**
|
||||
* @brief Activates memory protection for all supported memory region types
|
||||
*
|
||||
* @note The feature is disabled when JTAG interface is connected
|
||||
*
|
||||
* @param invoke_panic_handler map mem.prot interrupt to ETS_MEMACCESS_ERR_INUM and thus invokes panic handler when fired ('true' not suitable for testing)
|
||||
* @param lock_feature sets LOCK bit, see esp_memprot_set_lock() ('true' not suitable for testing)
|
||||
* @param mem_type_mask holds a set of required memory protection types (bitmask built of mem_type_prot_t). NULL means default (MEMPROT_ALL in this version)
|
||||
*/
|
||||
void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask);
|
||||
|
||||
/**
|
||||
* @brief Get permission settings bits for IRAM0 split mgmt. Only IRAM0 memory types allowed
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param lw Low segment Write permission flag
|
||||
* @param lr Low segment Read permission flag
|
||||
* @param lx Low segment Execute permission flag
|
||||
* @param hw High segment Write permission flag
|
||||
* @param hr High segment Read permission flag
|
||||
* @param hx High segment Execute permission flag
|
||||
*/
|
||||
void esp_memprot_get_perm_split_bits_iram(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
|
||||
|
||||
/**
|
||||
* @brief Get permission settings bits for DRAM0 split mgmt. Only DRAM0 memory types allowed
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param lw Low segment Write permission flag
|
||||
* @param lr Low segment Read permission flag
|
||||
* @param hw High segment Write permission flag
|
||||
* @param hr High segment Read permission flag
|
||||
*/
|
||||
void esp_memprot_get_perm_split_bits_dram(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr);
|
||||
|
||||
/**
|
||||
* @brief Sets permissions for high and low memory segment in PERIBUS1 region
|
||||
*
|
||||
* Sets Read and Write permission for both low and high memory segments given by splitting address.
|
||||
* Applicable only to PERIBUS1 memory types
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param split_addr Address to split the memory region to lower and higher segment
|
||||
* @param lw Low segment Write permission flag
|
||||
* @param lr Low segment Read permission flag
|
||||
* @param hw High segment Write permission flag
|
||||
* @param hr High segment Read permission flag
|
||||
*/
|
||||
void esp_memprot_set_prot_peri1(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr);
|
||||
|
||||
/**
|
||||
* @brief Get permission settings bits for PERIBUS1 split mgmt. Only PERIBUS1 memory types allowed
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param lw Low segment Write permission flag
|
||||
* @param lr Low segment Read permission flag
|
||||
* @param hw High segment Write permission flag
|
||||
* @param hr High segment Read permission flag
|
||||
*/
|
||||
void esp_memprot_get_perm_split_bits_peri1(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr);
|
||||
|
||||
/**
|
||||
* @brief Get permission settings bits for PERIBUS2 split mgmt. Only PERIBUS2 memory types allowed
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param lw Low segment Write permission flag
|
||||
* @param lr Low segment Read permission flag
|
||||
* @param lx Low segment Execute permission flag
|
||||
* @param hw High segment Write permission flag
|
||||
* @param hr High segment Read permission flag
|
||||
* @param hx High segment Execute permission flag
|
||||
*/
|
||||
void esp_memprot_get_perm_split_bits_peri2(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
|
||||
|
||||
/**
|
||||
* @brief Sets permissions for high and low memory segment in PERIBUS2 region
|
||||
*
|
||||
* Sets Read Write permission for both low and high memory segments given by splitting address.
|
||||
* Applicable only to PERIBUS2 memory types
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param split_addr Address to split the memory region to lower and higher segment
|
||||
* @param lw Low segment Write permission flag
|
||||
* @param lr Low segment Read permission flag
|
||||
* @param lx Low segment Execute permission flag
|
||||
* @param hw High segment Write permission flag
|
||||
* @param hr High segment Read permission flag
|
||||
* @param hx High segment Execute permission flag
|
||||
*/
|
||||
void esp_memprot_set_prot_peri2(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx);
|
||||
|
||||
/**
|
||||
* @brief Get permissions for specified memory type. Irrelevant bits are ignored
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param lw Low segment Write permission flag
|
||||
* @param lr Low segment Read permission flag
|
||||
* @param lx Low segment Execute permission flag
|
||||
* @param hw High segment Write permission flag
|
||||
* @param hr High segment Read permission flag
|
||||
* @param hx High segment Execute permission flag
|
||||
*/
|
||||
void esp_memprot_get_permissions(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
|
||||
|
||||
/**
|
||||
* @brief Get Read permission settings for low and high regions of given memory type
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param lr Low segment Read permission flag
|
||||
* @param hr High segment Read permission flag
|
||||
*/
|
||||
void esp_memprot_get_perm_read(mem_type_prot_t mem_type, bool *lr, bool *hr);
|
||||
|
||||
/**
|
||||
* @brief Get Write permission settings for low and high regions of given memory type
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param lr Low segment Write permission flag
|
||||
* @param hr High segment Write permission flag
|
||||
*/
|
||||
void esp_memprot_get_perm_write(mem_type_prot_t mem_type, bool *lw, bool *hw);
|
||||
|
||||
/**
|
||||
* @brief Get Execute permission settings for low and high regions of given memory type
|
||||
* Applicable only to IBUS-compatible memory types
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param lr Low segment Exec permission flag
|
||||
* @param hr High segment Exec permission flag
|
||||
*/
|
||||
void esp_memprot_get_perm_exec(mem_type_prot_t mem_type, bool *lx, bool *hx);
|
||||
|
||||
/**
|
||||
* @brief Returns the lowest address in required memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*/
|
||||
uint32_t esp_memprot_get_low_limit(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Returns the highest address in required memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
*/
|
||||
uint32_t esp_memprot_get_high_limit(mem_type_prot_t mem_type);
|
||||
|
||||
/**
|
||||
* @brief Sets READ permission bit for required memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param lr Low segment Read permission flag
|
||||
* @param hr High segment Read permission flag
|
||||
*/
|
||||
void esp_memprot_set_read_perm(mem_type_prot_t mem_type, bool lr, bool hr);
|
||||
|
||||
/**
|
||||
* @brief Sets WRITE permission bit for required memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param lr Low segment Write permission flag
|
||||
* @param hr High segment Write permission flag
|
||||
*/
|
||||
void esp_memprot_set_write_perm(mem_type_prot_t mem_type, bool lw, bool hw);
|
||||
|
||||
/**
|
||||
* @brief Sets EXECUTE permission bit for required memory region
|
||||
*
|
||||
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
|
||||
* @param lr Low segment Exec permission flag
|
||||
* @param hr High segment Exec permission flag
|
||||
*/
|
||||
void esp_memprot_set_exec_perm(mem_type_prot_t mem_type, bool lx, bool hx);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// ESP32-S3 PMS memory protection types
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Memory types recognized by PMS
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_TYPE_NONE = 0x00000000,
|
||||
MEMPROT_TYPE_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_TYPE_INVALID = 0x80000000
|
||||
} esp_mprot_mem_t;
|
||||
|
||||
/**
|
||||
* @brief Splitting address (line) type
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_SPLIT_ADDR_NONE = 0x00000000,
|
||||
MEMPROT_SPLIT_ADDR_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_SPLIT_ADDR_INVALID = 0x80000000
|
||||
} esp_mprot_split_addr_t;
|
||||
|
||||
/**
|
||||
* @brief PMS area type (memory space between adjacent splitting addresses or above/below the main splt.address)
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPROT_PMS_AREA_NONE = 0x00000000,
|
||||
MEMPROT_PMS_AREA_ALL = 0x7FFFFFFF,
|
||||
MEMPROT_PMS_AREA_INVALID = 0x80000000
|
||||
} esp_mprot_pms_area_t;
|
||||
|
||||
/**
|
||||
* @brief Memory protection configuration
|
||||
*/
|
||||
typedef struct {
|
||||
bool invoke_panic_handler; /*!< Register PMS violation interrupt for panic-handling */
|
||||
bool lock_feature; /*!< Lock all PMS settings */
|
||||
void *split_addr; /*!< Main I/D splitting address */
|
||||
uint32_t mem_type_mask; /*!< Memory types required to protect. See esp_mprot_mem_t enum */
|
||||
int target_cpu[]; /*!< Array of CPU/core IDs required to receive given PMS protection */
|
||||
} esp_memp_config_t;
|
||||
|
||||
#define ESP_MEMPROT_DEFAULT_CONFIG() { \
|
||||
.invoke_panic_handler = true, \
|
||||
.lock_feature = true, \
|
||||
.split_addr = NULL, \
|
||||
.mem_type_mask = MEMPROT_TYPE_ALL,\
|
||||
.target_cpu[] = {PRO_CPU_NUM, APP_CPU_NUM} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts Memory protection type to string
|
||||
*
|
||||
* @param mem_type Memory protection type
|
||||
*/
|
||||
static inline const char *esp_mprot_mem_type_to_str(const esp_mprot_mem_t mem_type)
|
||||
{
|
||||
switch (mem_type) {
|
||||
case MEMPROT_TYPE_NONE:
|
||||
return "MEMPROT_TYPE_NONE";
|
||||
case MEMPROT_TYPE_ALL:
|
||||
return "MEMPROT_TYPE_ALL";
|
||||
default:
|
||||
return "MEMPROT_TYPE_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts Splitting address type to string
|
||||
*
|
||||
* @param line_type Split line type
|
||||
*/
|
||||
static inline const char *esp_mprot_split_addr_to_str(const esp_mprot_split_addr_t line_type)
|
||||
{
|
||||
switch (line_type) {
|
||||
case MEMPROT_SPLIT_ADDR_NONE:
|
||||
return "MEMPROT_SPLIT_ADDR_NONE";
|
||||
case MEMPROT_SPLIT_ADDR_ALL:
|
||||
return "MEMPROT_SPLIT_ADDR_ALL";
|
||||
default:
|
||||
return "MEMPROT_SPLIT_ADDR_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts PMS Area type to string
|
||||
*
|
||||
* @param area_type PMS Area type
|
||||
*/
|
||||
static inline const char *esp_mprot_pms_area_to_str(const esp_mprot_pms_area_t area_type)
|
||||
{
|
||||
switch (area_type) {
|
||||
case MEMPROT_PMS_AREA_NONE:
|
||||
return "MEMPROT_PMS_AREA_NONE";
|
||||
case MEMPROT_PMS_AREA_ALL:
|
||||
return "MEMPROT_PMS_AREA_ALL";
|
||||
default:
|
||||
return "MEMPROT_PMS_AREA_INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -73,3 +73,10 @@
|
||||
#define I2C_SARADC_TSENS_DAC 0x6
|
||||
#define I2C_SARADC_TSENS_DAC_MSB 3
|
||||
#define I2C_SARADC_TSENS_DAC_LSB 0
|
||||
|
||||
/**
|
||||
* Restore regi2c analog calibration related configuration registers.
|
||||
* This is a workaround, and is fixed on later chips
|
||||
*/
|
||||
#define REGI2C_ANA_CALI_PD_WORKAROUND 1
|
||||
#define REGI2C_ANA_CALI_BYTE_NUM 8
|
||||
|
@ -77,6 +77,16 @@ void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add,
|
||||
#define REGI2C_READ(block, reg_add) \
|
||||
regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add)
|
||||
|
||||
|
||||
/**
|
||||
* Restore regi2c analog calibration related configuration registers.
|
||||
* This is a workaround, and is fixed on later chips
|
||||
*/
|
||||
#if REGI2C_ANA_CALI_PD_WORKAROUND
|
||||
void regi2c_analog_cali_reg_read(void);
|
||||
void regi2c_analog_cali_reg_write(void);
|
||||
#endif //#if ADC_CALI_PD_WORKAROUND
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user