1 /*
2 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 //////////////////////////////////////////////////////////
8 // ESP32-S3 PMS memory protection types
9 //
10
11 #pragma once
12
13 #include <stdint.h>
14 #include <stdbool.h>
15 #include "soc/soc.h"
16 #include "freertos/FreeRTOSConfig.h"
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
22 /**
23 * @brief Memory types recognized by PMS
24 */
25 typedef enum {
26 MEMPROT_TYPE_NONE = 0x00000000,
27 MEMPROT_TYPE_IRAM0_SRAM = 0x00000001,
28 MEMPROT_TYPE_DRAM0_SRAM = 0x00000002,
29 MEMPROT_TYPE_IRAM0_RTCFAST = 0x00000004,
30 MEMPROT_TYPE_ALL = 0x7FFFFFFF,
31 MEMPROT_TYPE_INVALID = 0x80000000,
32 MEMPROT_TYPE_IRAM0_ANY = MEMPROT_TYPE_IRAM0_SRAM | MEMPROT_TYPE_IRAM0_RTCFAST
33 } esp_mprot_mem_t;
34
35 /**
36 * @brief Splitting address (line) type
37 */
38 typedef enum {
39 MEMPROT_SPLIT_ADDR_NONE = 0x00000000,
40 MEMPROT_SPLIT_ADDR_IRAM0_DRAM0 = 0x00000001,
41 MEMPROT_SPLIT_ADDR_IRAM0_LINE_0 = 0x00000002,
42 MEMPROT_SPLIT_ADDR_IRAM0_LINE_1 = 0x00000004,
43 MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_0 = 0x00000008,
44 MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_1 = 0x00000010,
45 MEMPROT_SPLIT_ADDR_ALL = 0x7FFFFFFF,
46 MEMPROT_SPLIT_ADDR_INVALID = 0x80000000,
47 MEMPROT_SPLIT_ADDR_MAIN = MEMPROT_SPLIT_ADDR_IRAM0_DRAM0
48 } esp_mprot_split_addr_t;
49
50 /**
51 * @brief PMS area type (memory space between adjacent splitting addresses or above/below the main splt.address)
52 */
53 typedef enum {
54 MEMPROT_PMS_AREA_NONE = 0x00000000,
55 MEMPROT_PMS_AREA_IRAM0_0 = 0x00000001,
56 MEMPROT_PMS_AREA_IRAM0_1 = 0x00000002,
57 MEMPROT_PMS_AREA_IRAM0_2 = 0x00000004,
58 MEMPROT_PMS_AREA_IRAM0_3 = 0x00000008,
59 MEMPROT_PMS_AREA_DRAM0_0 = 0x00000010,
60 MEMPROT_PMS_AREA_DRAM0_1 = 0x00000020,
61 MEMPROT_PMS_AREA_DRAM0_2 = 0x00000040,
62 MEMPROT_PMS_AREA_DRAM0_3 = 0x00000080,
63 MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO = 0x00000100,
64 MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI = 0x00000200,
65 MEMPROT_PMS_AREA_ICACHE_0 = 0x00000400,
66 MEMPROT_PMS_AREA_ICACHE_1 = 0x00000800,
67 MEMPROT_PMS_AREA_ALL = 0x7FFFFFFF,
68 MEMPROT_PMS_AREA_INVALID = 0x80000000
69 } esp_mprot_pms_area_t;
70
71 /**
72 * @brief Memory protection configuration
73 */
74 typedef struct {
75 bool invoke_panic_handler; /*!< Register PMS violation interrupt for panic-handling */
76 bool lock_feature; /*!< Lock all PMS settings */
77 void *split_addr; /*!< Main I/D splitting address */
78 uint32_t mem_type_mask; /*!< Memory types required to protect. See esp_mprot_mem_t enum */
79 size_t target_cpu_count; /*!< Real CPU/core count (max 2) */
80 int target_cpu[portNUM_PROCESSORS]; /*!< Array of CPU/core IDs required to receive given PMS protection */
81 } esp_memp_config_t;
82
83 //2-CPU configuration
84 #if portNUM_PROCESSORS > 1
85
86 //default IDF configuration (basic memory regions, split line detection, locked, panic mode on)
87 #define ESP_MEMPROT_DEFAULT_CONFIG() { \
88 .invoke_panic_handler = true, \
89 .lock_feature = true, \
90 .split_addr = NULL, \
91 .mem_type_mask = MEMPROT_TYPE_ALL, \
92 .target_cpu_count = 2, \
93 .target_cpu = {PRO_CPU_NUM, APP_CPU_NUM} \
94 }
95 //zero (no-go) configuration
96 #define ESP_MEMPROT_ZERO_CONFIG() { \
97 .target_cpu_count = 2, \
98 .target_cpu = {PRO_CPU_NUM, APP_CPU_NUM} \
99 }
100
101 #else //1-CPU configuration
102
103 #define ESP_MEMPROT_DEFAULT_CONFIG() { \
104 .invoke_panic_handler = true, \
105 .lock_feature = true, \
106 .split_addr = NULL, \
107 .mem_type_mask = MEMPROT_TYPE_ALL, \
108 .target_cpu_count = 1, \
109 .target_cpu = {PRO_CPU_NUM} \
110 }
111 #define ESP_MEMPROT_ZERO_CONFIG() { \
112 .target_cpu_count = 1, \
113 .target_cpu = {PRO_CPU_NUM} \
114 }
115
116 #endif //end of CPU-count based defines
117
118 /**
119 * @brief Converts Memory protection type to string
120 *
121 * @param mem_type Memory protection type
122 */
esp_mprot_mem_type_to_str(const esp_mprot_mem_t mem_type)123 static inline const char *esp_mprot_mem_type_to_str(const esp_mprot_mem_t mem_type)
124 {
125 switch (mem_type) {
126 case MEMPROT_TYPE_NONE:
127 return "NONE";
128 case MEMPROT_TYPE_IRAM0_SRAM:
129 return "IRAM0_SRAM";
130 case MEMPROT_TYPE_DRAM0_SRAM:
131 return "DRAM0_SRAM";
132 case MEMPROT_TYPE_IRAM0_RTCFAST:
133 return "IRAM0_RTCFAST";
134 case MEMPROT_TYPE_IRAM0_ANY:
135 return "IRAM0_ANY";
136 case MEMPROT_TYPE_ALL:
137 return "ALL";
138 default:
139 return "INVALID";
140 }
141 }
142
143 /**
144 * @brief Converts Splitting address type to string
145 *
146 * @param line_type Split line type
147 */
esp_mprot_split_addr_to_str(const esp_mprot_split_addr_t line_type)148 static inline const char *esp_mprot_split_addr_to_str(const esp_mprot_split_addr_t line_type)
149 {
150 switch (line_type) {
151 case MEMPROT_SPLIT_ADDR_NONE:
152 return "SPLIT_ADDR_NONE";
153 case MEMPROT_SPLIT_ADDR_IRAM0_DRAM0:
154 return "SPLIT_ADDR_IRAM0_DRAM0";
155 case MEMPROT_SPLIT_ADDR_IRAM0_LINE_0:
156 return "SPLIT_ADDR_IRAM0_LINE_0";
157 case MEMPROT_SPLIT_ADDR_IRAM0_LINE_1:
158 return "SPLIT_ADDR_IRAM0_LINE_1";
159 case MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_0:
160 return "SPLIT_ADDR_DRAM0_DMA_LINE_0";
161 case MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_1:
162 return "SPLIT_ADDR_DRAM0_DMA_LINE_1";
163 case MEMPROT_SPLIT_ADDR_ALL:
164 return "SPLIT_ADDR_ALL";
165 default:
166 return "SPLIT_ADDR_INVALID";
167 }
168 }
169
170 /**
171 * @brief Converts PMS Area type to string
172 *
173 * @param area_type PMS Area type
174 */
esp_mprot_pms_area_to_str(const esp_mprot_pms_area_t area_type)175 static inline const char *esp_mprot_pms_area_to_str(const esp_mprot_pms_area_t area_type)
176 {
177 switch (area_type) {
178 case MEMPROT_PMS_AREA_NONE:
179 return "PMS_AREA_NONE";
180 case MEMPROT_PMS_AREA_IRAM0_0:
181 return "PMS_AREA_IRAM0_0";
182 case MEMPROT_PMS_AREA_IRAM0_1:
183 return "PMS_AREA_IRAM0_1";
184 case MEMPROT_PMS_AREA_IRAM0_2:
185 return "PMS_AREA_IRAM0_2";
186 case MEMPROT_PMS_AREA_IRAM0_3:
187 return "PMS_AREA_IRAM0_3";
188 case MEMPROT_PMS_AREA_DRAM0_0:
189 return "PMS_AREA_DRAM0_0";
190 case MEMPROT_PMS_AREA_DRAM0_1:
191 return "PMS_AREA_DRAM0_1";
192 case MEMPROT_PMS_AREA_DRAM0_2:
193 return "PMS_AREA_DRAM0_2";
194 case MEMPROT_PMS_AREA_DRAM0_3:
195 return "PMS_AREA_DRAM0_3";
196 case MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO:
197 return "PMS_AREA_IRAM0_RTCFAST_LO";
198 case MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI:
199 return "PMS_AREA_IRAM0_RTCFAST_HI";
200 case MEMPROT_PMS_AREA_ICACHE_0:
201 return "PMS_AREA_ICACHE_0";
202 case MEMPROT_PMS_AREA_ICACHE_1:
203 return "PMS_AREA_ICACHE_1";
204 case MEMPROT_PMS_AREA_ALL:
205 return "PMS_AREA_ALL";
206 default:
207 return "PMS_AREA_INVALID";
208 }
209 }
210
211 #ifdef __cplusplus
212 }
213 #endif
214