1 /* 2 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 ///////////////////////////////////////////////////////////////////////////////////////// 8 // ESP Memory Protection API (PMS) 9 // - allows configuration and violation-interrupt handling of the PMS module operations 10 // - not intended for public use. 11 12 #pragma once 13 14 #include "sdkconfig.h" 15 #if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_MEMPROT_TEST 16 17 #include <stdbool.h> 18 #include <stdint.h> 19 #include "esp_err.h" 20 #include "esp_memprot_err.h" 21 #include "soc_memprot_types.h" 22 #include "esp_memprot_types.h" 23 24 #ifdef __cplusplus 25 extern "C" { 26 #endif 27 28 #define DEFAULT_CPU_NUM -1 29 #define ESP_MEMPROT_ERR_CHECK(retval, fnc) if ((retval=fnc) != ESP_OK) { return retval; } 30 31 /** 32 * @brief Basic PMS interrupt source info 33 */ 34 typedef struct { 35 esp_mprot_mem_t mem_type; /*!< Memory type containing the faulting address */ 36 int core; /*!< CPU/Core ID running the faulting instruction */ 37 } esp_memp_intr_source_t; 38 39 /** 40 * @brief Clears current interrupt ON flag for given Memory type and CPU/Core ID 41 * 42 * This operation is non-atomic for some chips by PMS module design 43 * In such a case the interrupt clearing happens in two steps: 44 * 1. Interrupt CLR flag is set (clears interrupt-ON status and inhibits linked interrupt processing) 45 * 2. Interrupt CLR flag is reset (resumes the interrupt monitoring) 46 * 47 * @param mem_type Memory type (see esp_mprot_mem_t enum) 48 * @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems 49 * 50 * @return ESP_OK on success 51 * ESP_ERR_INVALID_ARG on passing invalid pointer 52 * ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type 53 */ 54 esp_err_t esp_mprot_monitor_clear_intr(const esp_mprot_mem_t mem_type, const int core); 55 56 /** 57 * @brief Checks whether any of the PMS settings is locked 58 * 59 * @param[out] locked Any lock on? (true/false) 60 * 61 * @return ESP_OK on success 62 * ESP_ERR_INVALID_ARG on invalid locked ptr 63 * Other failures: error code of any failing esp_mprot_get_*_lock() routine (called internally) 64 */ 65 esp_err_t esp_mprot_is_conf_locked_any(bool *locked); 66 67 /** 68 * @brief Checks whether any PMS violation-interrupt monitoring is enabled 69 * 70 * @param[out] locked Any PMS violation interrupt monitor is enabled (true/false) 71 * 72 * @return ESP_OK on success 73 * ESP_ERR_INVALID_ARG on invalid enabled ptr 74 * Other failures: error code of esp_mprot_get_monitor_en() routine (called internally for all Memory types) 75 */ 76 esp_err_t esp_mprot_is_intr_ena_any(bool *enabled); 77 78 /** 79 * @brief Returns active PMS violation-interrupt Memory type if any (MEMPROT_TYPE_NONE when none detected) 80 * and the CPU/CoreID which was running the faulty code (-1 when no interrupt available) 81 * 82 * 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) 83 * 84 * @param[out] mem_type Out-pointer for Memory type given by the faulting address (see esp_mprot_mem_t enum) 85 * @param[out] core Out-pointer for CPU/Core ID (see *_CPU_NUM defs in soc.h) 86 * 87 * @return ESP_OK on success 88 * ESP_ERR_INVALID_ARG on passing invalid pointer(s) 89 */ 90 esp_err_t esp_mprot_get_active_intr(esp_memp_intr_source_t *active_memp_intr); 91 92 /** 93 * @brief Returns the address which caused the violation interrupt for given Memory type and CPU/Core ID. 94 * This function is to be called after a basic resolving of (current) interrupt's parameters (ie corresponding 95 * Memory type and CPU ID see esp_mprot_get_active_intr()). This is to minimize processing time of actual exception 96 * as this API is typicaly used in a panic-handling code. 97 * If there is no active interrupt available for the Memory type/CPU ID required, fault_addr is set to NULL. 98 * 99 * @param mem_type memory type 100 * @param[out] fault_addr Address of the operation which caused the PMS violation interrupt 101 * @param core Faulting instruction CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems 102 * 103 * @return ESP_OK on success 104 * ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type 105 * ESP_ERR_INVALID_ARG on invalid fault_addr pointer 106 */ 107 esp_err_t esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, void **fault_addr, const int core); 108 109 /** 110 * @brief Returns PMS World identifier of the code causing the violation interrupt 111 * 112 * The value is read from appropriate PMS violation status register and thus might be 0 if the interrupt is not currently active. 113 * 114 * @param mem_type Memory type 115 * @param[out] world PMS World type (see esp_mprot_pms_world_t) 116 * @param core Faulting instruction CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems 117 * 118 * @return ESP_OK on success 119 * ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type 120 * ESP_ERR_INVALID_ARG on passing invalid pointer(s) 121 * ESP_ERR_MEMPROT_WORLD_INVALID on invalid World identifier fetched from the register 122 */ 123 esp_err_t esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type, esp_mprot_pms_world_t *world, const int core); 124 125 /** 126 * @brief Returns an operation type which caused the violation interrupt 127 * 128 * The operation resolving is processed over various PMS status register flags, according to given Memory type argument. 129 * If the interrupt is not active the result returned is irrelevant (likely evaluated to MEMPROT_OP_READ). 130 * 131 * @param mem_type Memory type 132 * @param[out] oper Operation type (see MEMPROT_OP_* defines) 133 * @param core Faulting instruction CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems 134 * 135 * @return ESP_OK on success 136 * ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type 137 * ESP_ERR_INVALID_ARG on invalid oper pointer 138 */ 139 esp_err_t esp_mprot_get_violate_operation(const esp_mprot_mem_t mem_type, uint32_t *oper, const int core); 140 141 /** 142 * @brief Checks whether given memory type supports byte-enables info 143 * 144 * Byte-enables status is available only for DMA/DRAM operations 145 * 146 * @param mem_type memory type 147 * 148 * @return byte-enables info available true/false 149 */ 150 bool esp_mprot_has_byte_enables(const esp_mprot_mem_t mem_type); 151 152 /** 153 * @brief Returns byte-enables for the address which caused the violation interrupt 154 * 155 * The value is taken from appropriate PMS violation status register, based on given Memory type 156 * 157 * @param mem_type Memory type (MEMPROT_TYPE_DRAM0_SRAM) 158 * @param[out] byte_en Byte-enables bits 159 * @param core Faulting instruction CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems 160 * 161 * @return ESP_OK on success 162 * ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type 163 * ESP_ERR_INVALID_ARGUMENT on invalid byte_en pointer 164 */ 165 esp_err_t esp_mprot_get_violate_byte_enables(const esp_mprot_mem_t mem_type, uint32_t *byte_en, const int core); 166 167 /** 168 * @brief Convenient routine for setting the PMS defaults 169 * 170 * Called on system startup, depending on ESP_SYSTEM_MEMPROT_FEATURE Kconfig value 171 * 172 * @param memp_config pointer to Memprot configuration structure (esp_memp_config_t). The structure si chip-specific, 173 * for details and defaults see appropriate [target-chip]/soc_memprot_types.h 174 * 175 * @return ESP_OK on success 176 * Other failures: error code of the failing routine called internally. No specific error processing provided in such a case 177 * due to large number of embedded calls (ie no global unique error table is provided and thus one error code can have different meanings, 178 * depending on the routine issuing the error) 179 */ 180 esp_err_t esp_mprot_set_prot(const esp_memp_config_t *memp_config); 181 182 /** 183 * @brief Generates PMS configuration string of actual device (diagnostics) 184 * 185 * The functions generates a string from current configuration, control and status registers of the PMS (or similar) module of actual device. 186 * The values are fetched using HAL LL calls to help finding possible errors in the Memprot API implementation 187 * 188 * @param[out] dump_info_string configuration string buffer pointer. The string is allocated by the callee and must be freed by the caller. 189 * 190 * @return ESP_OK on success 191 * ESP_ERR_NO_MEM on buffer allocation failure 192 * ESP_ERR_INVALID_ARGUMENT on invalid dump_info_string pointer 193 */ 194 esp_err_t esp_mprot_dump_configuration(char **dump_info_string); 195 196 #ifdef __cplusplus 197 } 198 #endif 199 200 #endif //CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_MEMPROT_TEST 201