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