/ components / esp32s2 / memprot.c
memprot.c
  1  // Copyright 2020 Espressif Systems (Shanghai) PTE LTD
  2  //
  3  // Licensed under the Apache License, Version 2.0 (the "License");
  4  // you may not use this file except in compliance with the License.
  5  // You may obtain a copy of the License at
  6  //
  7  //     http://www.apache.org/licenses/LICENSE-2.0
  8  //
  9  // Unless required by applicable law or agreed to in writing, software
 10  // distributed under the License is distributed on an "AS IS" BASIS,
 11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  // See the License for the specific language governing permissions and
 13  // limitations under the License.
 14  
 15  /* INTERNAL API
 16   * implementation of generic interface to MMU memory protection features
 17   */
 18  
 19  #include <stdio.h>
 20  #include "sdkconfig.h"
 21  #include "soc/sensitive_reg.h"
 22  #include "soc/dport_access.h"
 23  #include "soc/periph_defs.h"
 24  #include "esp_intr_alloc.h"
 25  
 26  #include "esp_log.h"
 27  static const char *TAG = "memprot";
 28  
 29  #include "esp32s2/memprot.h"
 30  #include "hal/memprot_ll.h"
 31  #include "hal/memprot_peri_ll.h"
 32  #include "esp_fault.h"
 33  
 34  #include "soc/cpu.h"
 35  
 36  extern int _iram_text_end;
 37  extern int _data_start;
 38  extern int _rtc_text_end;
 39  extern int _rtc_dummy_end;
 40  
 41  
 42  uint32_t *esp_memprot_iram0_sram_get_min_split_addr(void)
 43  {
 44      return (uint32_t *)&_iram_text_end;
 45  }
 46  
 47  uint32_t *esp_memprot_iram0_rtcfast_get_min_split_addr(void)
 48  {
 49      return (uint32_t *)&_rtc_text_end;
 50  }
 51  
 52  uint32_t *esp_memprot_dram0_sram_get_min_split_addr(void)
 53  {
 54      return (uint32_t *)&_data_start;
 55  }
 56  
 57  uint32_t *esp_memprot_dram0_rtcfast_get_min_split_addr(void)
 58  {
 59      return (uint32_t *)&_rtc_dummy_end;
 60  }
 61  
 62  uint32_t *esp_memprot_peri1_rtcslow_get_min_split_addr(void)
 63  {
 64      return (uint32_t *)(PERI1_RTCSLOW_ADDRESS_BASE);
 65  }
 66  
 67  uint32_t *esp_memprot_peri2_rtcslow_0_get_min_split_addr(void)
 68  {
 69      return (uint32_t *)(PERI2_RTCSLOW_0_ADDRESS_BASE);
 70  }
 71  
 72  uint32_t *esp_memprot_peri2_rtcslow_1_get_min_split_addr(void)
 73  {
 74      return (uint32_t *)(PERI2_RTCSLOW_1_ADDRESS_BASE);
 75  }
 76  
 77  uint32_t *esp_memprot_get_split_addr(mem_type_prot_t mem_type)
 78  {
 79      switch (mem_type) {
 80      case MEMPROT_IRAM0_SRAM:
 81          return esp_memprot_iram0_sram_get_min_split_addr();
 82      case MEMPROT_DRAM0_SRAM:
 83          return esp_memprot_dram0_sram_get_min_split_addr();
 84      case MEMPROT_IRAM0_RTCFAST:
 85          return esp_memprot_iram0_rtcfast_get_min_split_addr();
 86      case MEMPROT_DRAM0_RTCFAST:
 87          return esp_memprot_dram0_rtcfast_get_min_split_addr();
 88      case MEMPROT_PERI1_RTCSLOW:
 89          return esp_memprot_peri1_rtcslow_get_min_split_addr();
 90      case MEMPROT_PERI2_RTCSLOW_0:
 91          return esp_memprot_peri2_rtcslow_0_get_min_split_addr();
 92      case MEMPROT_PERI2_RTCSLOW_1:
 93          return esp_memprot_peri2_rtcslow_1_get_min_split_addr();
 94      default:
 95          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
 96          abort();
 97      }
 98  }
 99  
100  const char *esp_memprot_type_to_str(mem_type_prot_t mem_type)
101  {
102      switch (mem_type) {
103      case MEMPROT_IRAM0_SRAM:
104          return "IRAM0_SRAM";
105      case MEMPROT_DRAM0_SRAM:
106          return "DRAM0_SRAM";
107      case MEMPROT_IRAM0_RTCFAST:
108          return "IRAM0_RTCFAST";
109      case MEMPROT_DRAM0_RTCFAST:
110          return "DRAM0_RTCFAST";
111      case MEMPROT_PERI1_RTCSLOW:
112          return "PERI1_RTCSLOW";
113      case MEMPROT_PERI2_RTCSLOW_0:
114          return "PERI2_RTCSLOW_0";
115      case MEMPROT_PERI2_RTCSLOW_1:
116          return "PERI2_RTCSLOW_1";
117      default:
118          return "UNKOWN";
119      }
120  }
121  
122  void esp_memprot_intr_init(mem_type_prot_t mem_type)
123  {
124      ESP_INTR_DISABLE(ETS_MEMACCESS_ERR_INUM);
125  
126      switch (mem_type) {
127      case MEMPROT_IRAM0_SRAM:
128      case MEMPROT_IRAM0_RTCFAST:
129          intr_matrix_set(PRO_CPU_NUM, esp_memprot_iram0_get_intr_source_num(), ETS_MEMACCESS_ERR_INUM);
130          break;
131      case MEMPROT_DRAM0_SRAM:
132      case MEMPROT_DRAM0_RTCFAST:
133          intr_matrix_set(PRO_CPU_NUM, esp_memprot_dram0_get_intr_source_num(), ETS_MEMACCESS_ERR_INUM);
134          break;
135      case MEMPROT_PERI1_RTCSLOW:
136          intr_matrix_set(PRO_CPU_NUM, esp_memprot_peri1_get_intr_source_num(), ETS_MEMACCESS_ERR_INUM);
137          break;
138      case MEMPROT_PERI2_RTCSLOW_0:
139      case MEMPROT_PERI2_RTCSLOW_1:
140          intr_matrix_set(PRO_CPU_NUM, esp_memprot_peri2_get_intr_source_num(), ETS_MEMACCESS_ERR_INUM);
141          break;
142      default:
143          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
144          abort();
145      }
146  
147      ESP_INTR_ENABLE(ETS_MEMACCESS_ERR_INUM);
148  }
149  
150  void esp_memprot_intr_ena(mem_type_prot_t mem_type, bool enable)
151  {
152      switch (mem_type) {
153      case MEMPROT_IRAM0_SRAM:
154      case MEMPROT_IRAM0_RTCFAST:
155          esp_memprot_iram0_intr_ena(enable);
156          break;
157      case MEMPROT_DRAM0_SRAM:
158      case MEMPROT_DRAM0_RTCFAST:
159          esp_memprot_dram0_intr_ena(enable);
160          break;
161      case MEMPROT_PERI1_RTCSLOW:
162          esp_memprot_peri1_intr_ena(enable);
163          break;
164      case MEMPROT_PERI2_RTCSLOW_0:
165      case MEMPROT_PERI2_RTCSLOW_1:
166          esp_memprot_peri2_intr_ena(enable);
167          break;
168      default:
169          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
170          abort();
171      }
172  }
173  
174  mem_type_prot_t esp_memprot_get_active_intr_memtype()
175  {
176      if (esp_memprot_iram0_sram_is_intr_mine()) {
177          return MEMPROT_IRAM0_SRAM;
178      } else if (esp_memprot_iram0_rtcfast_is_intr_mine()) {
179          return MEMPROT_IRAM0_RTCFAST;
180      } else if (esp_memprot_dram0_sram_is_intr_mine()) {
181          return MEMPROT_DRAM0_SRAM;
182      } else if (esp_memprot_dram0_rtcfast_is_intr_mine()) {
183          return MEMPROT_DRAM0_RTCFAST;
184      } else if (esp_memprot_peri1_rtcslow_is_intr_mine()) {
185          return MEMPROT_PERI1_RTCSLOW;
186      } else if (esp_memprot_peri2_rtcslow_0_is_intr_mine()) {
187          return MEMPROT_PERI2_RTCSLOW_0;
188      } else if (esp_memprot_peri2_rtcslow_1_is_intr_mine()) {
189          return MEMPROT_PERI2_RTCSLOW_1;
190      }
191  
192      return MEMPROT_NONE;
193  }
194  
195  void esp_memprot_clear_intr(mem_type_prot_t mem_type)
196  {
197      switch (mem_type) {
198      case MEMPROT_IRAM0_SRAM:
199      case MEMPROT_IRAM0_RTCFAST:
200          esp_memprot_iram0_clear_intr();
201          break;
202      case MEMPROT_DRAM0_SRAM:
203      case MEMPROT_DRAM0_RTCFAST:
204          esp_memprot_dram0_clear_intr();
205          break;
206      case MEMPROT_PERI1_RTCSLOW:
207          esp_memprot_peri1_clear_intr();
208          break;
209      case MEMPROT_PERI2_RTCSLOW_0:
210      case MEMPROT_PERI2_RTCSLOW_1:
211          esp_memprot_peri2_clear_intr();
212          break;
213      default:
214          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
215          abort();
216      }
217  }
218  
219  void esp_memprot_set_lock(mem_type_prot_t mem_type)
220  {
221      switch (mem_type) {
222      case MEMPROT_IRAM0_SRAM:
223      case MEMPROT_IRAM0_RTCFAST:
224          esp_memprot_iram0_set_lock();
225          break;
226      case MEMPROT_DRAM0_SRAM:
227      case MEMPROT_DRAM0_RTCFAST:
228          esp_memprot_dram0_set_lock();
229          break;
230      case MEMPROT_PERI1_RTCSLOW:
231          esp_memprot_peri1_set_lock();
232          break;
233      case MEMPROT_PERI2_RTCSLOW_0:
234      case MEMPROT_PERI2_RTCSLOW_1:
235          esp_memprot_peri2_set_lock();
236          break;
237      default:
238          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
239          abort();
240      }
241  }
242  
243  bool esp_memprot_get_lock(mem_type_prot_t mem_type)
244  {
245      switch (mem_type) {
246      case MEMPROT_IRAM0_SRAM:
247      case MEMPROT_IRAM0_RTCFAST:
248          return esp_memprot_iram0_get_lock_bit() > 0;
249      case MEMPROT_DRAM0_SRAM:
250      case MEMPROT_DRAM0_RTCFAST:
251          return esp_memprot_dram0_get_lock_bit() > 0;
252      case MEMPROT_PERI1_RTCSLOW:
253          return esp_memprot_peri1_get_lock_bit() > 0;
254      case MEMPROT_PERI2_RTCSLOW_0:
255      case MEMPROT_PERI2_RTCSLOW_1:
256          return esp_memprot_peri2_get_lock_bit() > 0;
257      default:
258          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
259          abort();
260      }
261  }
262  
263  bool esp_memprot_is_locked_any()
264  {
265      return
266          esp_memprot_iram0_get_lock_bit() > 0 ||
267          esp_memprot_dram0_get_lock_bit() > 0 ||
268          esp_memprot_peri1_get_lock_bit() > 0 ||
269          esp_memprot_peri2_get_lock_bit() > 0;
270  }
271  
272  uint32_t esp_memprot_get_lock_bit(mem_type_prot_t mem_type)
273  {
274      switch (mem_type) {
275      case MEMPROT_IRAM0_SRAM:
276      case MEMPROT_IRAM0_RTCFAST:
277          return esp_memprot_iram0_get_lock_bit();
278      case MEMPROT_DRAM0_SRAM:
279      case MEMPROT_DRAM0_RTCFAST:
280          return esp_memprot_dram0_get_lock_bit();
281      case MEMPROT_PERI1_RTCSLOW:
282          return esp_memprot_peri1_get_lock_bit();
283      case MEMPROT_PERI2_RTCSLOW_0:
284      case MEMPROT_PERI2_RTCSLOW_1:
285          return esp_memprot_peri2_get_lock_bit();
286      default:
287          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
288          abort();
289      }
290  }
291  
292  uint32_t esp_memprot_get_conf_reg(mem_type_prot_t mem_type)
293  {
294      switch (mem_type) {
295      case MEMPROT_IRAM0_SRAM:
296      case MEMPROT_IRAM0_RTCFAST:
297          return esp_memprot_iram0_get_conf_reg();
298      case MEMPROT_DRAM0_SRAM:
299      case MEMPROT_DRAM0_RTCFAST:
300          return esp_memprot_dram0_get_conf_reg();
301      case MEMPROT_PERI1_RTCSLOW:
302          return esp_memprot_peri1_rtcslow_get_conf_reg();
303      case MEMPROT_PERI2_RTCSLOW_0:
304          return esp_memprot_peri2_rtcslow_0_get_conf_reg();
305      case MEMPROT_PERI2_RTCSLOW_1:
306          return esp_memprot_peri2_rtcslow_1_get_conf_reg();
307      default:
308          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
309          abort();
310      }
311  }
312  
313  uint32_t esp_memprot_get_fault_reg(mem_type_prot_t mem_type)
314  {
315      switch (mem_type) {
316      case MEMPROT_IRAM0_SRAM:
317      case MEMPROT_IRAM0_RTCFAST:
318          return esp_memprot_iram0_get_fault_reg();
319      case MEMPROT_DRAM0_SRAM:
320      case MEMPROT_DRAM0_RTCFAST:
321          return esp_memprot_dram0_get_fault_reg();
322      case MEMPROT_PERI1_RTCSLOW:
323          return esp_memprot_peri1_get_fault_reg();
324      case MEMPROT_PERI2_RTCSLOW_0:
325      case MEMPROT_PERI2_RTCSLOW_1:
326          return esp_memprot_peri2_get_fault_reg();
327      default:
328          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
329          abort();
330      }
331  }
332  
333  void esp_memprot_get_fault_status(mem_type_prot_t mem_type, uint32_t **faulting_address, uint32_t *op_type, uint32_t *op_subtype)
334  {
335      switch (mem_type) {
336      case MEMPROT_IRAM0_SRAM:
337          *faulting_address = esp_memprot_iram0_sram_get_fault_address();
338          break;
339      case MEMPROT_IRAM0_RTCFAST:
340          *faulting_address = esp_memprot_iram0_rtcfast_get_fault_address();
341          break;
342      case MEMPROT_DRAM0_SRAM:
343          *faulting_address = esp_memprot_dram0_sram_get_fault_address();
344          break;
345      case MEMPROT_DRAM0_RTCFAST:
346          *faulting_address = esp_memprot_dram0_rtcfast_get_fault_address();
347          break;
348      case MEMPROT_PERI1_RTCSLOW:
349          *faulting_address = esp_memprot_peri1_rtcslow_get_fault_address();
350          break;
351      case MEMPROT_PERI2_RTCSLOW_0:
352      case MEMPROT_PERI2_RTCSLOW_1:
353          *faulting_address = esp_memprot_peri2_rtcslow_get_fault_address();
354          break;
355      default:
356          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
357          abort();
358      }
359  
360      if (mem_type == MEMPROT_IRAM0_SRAM || mem_type == MEMPROT_IRAM0_RTCFAST) {
361          esp_memprot_iram0_get_fault_op_type(op_type, op_subtype);
362      } else if (mem_type == MEMPROT_DRAM0_SRAM || mem_type == MEMPROT_DRAM0_RTCFAST) {
363          esp_memprot_dram0_get_fault_op_type(op_type, op_subtype);
364      } else if (mem_type == MEMPROT_PERI1_RTCSLOW) {
365          esp_memprot_peri1_get_fault_op_type(op_type, op_subtype);
366      } else if (mem_type == MEMPROT_PERI2_RTCSLOW_0 || mem_type == MEMPROT_PERI2_RTCSLOW_1) {
367          esp_memprot_peri2_get_fault_op_type(op_type, op_subtype);
368      }
369  }
370  
371  bool esp_memprot_is_intr_ena_any()
372  {
373      return
374          esp_memprot_iram0_get_intr_ena_bit() > 0 ||
375          esp_memprot_dram0_get_intr_ena_bit() > 0 ||
376          esp_memprot_peri1_get_intr_ena_bit() > 0 ||
377          esp_memprot_peri2_get_intr_ena_bit() > 0;
378  }
379  
380  uint32_t esp_memprot_get_intr_ena_bit(mem_type_prot_t mem_type)
381  {
382      switch (mem_type) {
383      case MEMPROT_IRAM0_SRAM:
384      case MEMPROT_IRAM0_RTCFAST:
385          return esp_memprot_iram0_get_intr_ena_bit();
386      case MEMPROT_DRAM0_SRAM:
387      case MEMPROT_DRAM0_RTCFAST:
388          return esp_memprot_dram0_get_intr_ena_bit();
389      case MEMPROT_PERI1_RTCSLOW:
390          return esp_memprot_peri1_get_intr_ena_bit();
391      case MEMPROT_PERI2_RTCSLOW_0:
392      case MEMPROT_PERI2_RTCSLOW_1:
393          return esp_memprot_peri2_get_intr_ena_bit();
394      default:
395          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
396          abort();
397      }
398  }
399  
400  uint32_t esp_memprot_get_intr_on_bit(mem_type_prot_t mem_type)
401  {
402      switch (mem_type) {
403      case MEMPROT_IRAM0_SRAM:
404      case MEMPROT_IRAM0_RTCFAST:
405          return esp_memprot_iram0_get_intr_on_bit();
406      case MEMPROT_DRAM0_SRAM:
407      case MEMPROT_DRAM0_RTCFAST:
408          return esp_memprot_dram0_get_intr_on_bit();
409      case MEMPROT_PERI1_RTCSLOW:
410          return esp_memprot_peri1_get_intr_on_bit();
411      case MEMPROT_PERI2_RTCSLOW_0:
412      case MEMPROT_PERI2_RTCSLOW_1:
413          return esp_memprot_peri2_get_intr_on_bit();
414      default:
415          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
416          abort();
417      }
418  }
419  
420  uint32_t esp_memprot_get_intr_clr_bit(mem_type_prot_t mem_type)
421  {
422      switch (mem_type) {
423      case MEMPROT_IRAM0_SRAM:
424      case MEMPROT_IRAM0_RTCFAST:
425          return esp_memprot_iram0_get_intr_clr_bit();
426      case MEMPROT_DRAM0_SRAM:
427      case MEMPROT_DRAM0_RTCFAST:
428          return esp_memprot_dram0_get_intr_clr_bit();
429      case MEMPROT_PERI1_RTCSLOW:
430          return esp_memprot_peri1_get_intr_clr_bit();
431      case MEMPROT_PERI2_RTCSLOW_0:
432      case MEMPROT_PERI2_RTCSLOW_1:
433          return esp_memprot_peri2_get_intr_clr_bit();
434      default:
435          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
436          abort();
437      }
438  }
439  
440  uint32_t esp_memprot_get_uni_block_read_bit(mem_type_prot_t mem_type, uint32_t block)
441  {
442      switch (mem_type) {
443      case MEMPROT_IRAM0_SRAM:
444          return esp_memprot_iram0_sram_get_uni_block_read_bit(block);
445      case MEMPROT_DRAM0_SRAM:
446          return esp_memprot_dram0_sram_get_uni_block_read_bit(block);
447      default:
448          ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type);
449          abort();
450      }
451  }
452  
453  uint32_t esp_memprot_get_uni_block_write_bit(mem_type_prot_t mem_type, uint32_t block)
454  {
455      switch (mem_type) {
456      case MEMPROT_IRAM0_SRAM:
457          return esp_memprot_iram0_sram_get_uni_block_write_bit(block);
458      case MEMPROT_DRAM0_SRAM:
459          return esp_memprot_dram0_sram_get_uni_block_write_bit(block);
460      default:
461          ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type);
462          abort();
463      }
464  }
465  
466  uint32_t esp_memprot_get_uni_block_exec_bit(mem_type_prot_t mem_type, uint32_t block)
467  {
468      switch (mem_type) {
469      case MEMPROT_IRAM0_SRAM:
470          return esp_memprot_iram0_sram_get_uni_block_exec_bit(block);
471      default:
472          ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type);
473          abort();
474      }
475  }
476  
477  void esp_memprot_set_uni_block_perm_dram(mem_type_prot_t mem_type, uint32_t block, bool write_perm, bool read_perm)
478  {
479      switch (mem_type) {
480      case MEMPROT_DRAM0_SRAM:
481          esp_memprot_dram0_sram_set_uni_block_perm(block, write_perm, read_perm);
482          break;
483      default:
484          ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type);
485          abort();
486      }
487  }
488  
489  uint32_t esp_memprot_get_perm_uni_reg(mem_type_prot_t mem_type)
490  {
491      switch (mem_type) {
492      case MEMPROT_IRAM0_SRAM:
493          return esp_memprot_iram0_sram_get_perm_uni_reg();
494      case MEMPROT_DRAM0_SRAM:
495          return esp_memprot_dram0_sram_get_perm_reg();
496      default:
497          ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type);
498          abort();
499      }
500  }
501  
502  uint32_t esp_memprot_get_perm_split_reg(mem_type_prot_t mem_type)
503  {
504      switch (mem_type) {
505      case MEMPROT_IRAM0_SRAM:
506          return esp_memprot_iram0_sram_get_perm_split_reg();
507      case MEMPROT_IRAM0_RTCFAST:
508          return esp_memprot_iram0_rtcfast_get_perm_split_reg();
509      case MEMPROT_DRAM0_SRAM:
510          return esp_memprot_dram0_sram_get_perm_reg();
511      case MEMPROT_DRAM0_RTCFAST:
512          return esp_memprot_dram0_rtcfast_get_perm_split_reg();
513      case MEMPROT_PERI1_RTCSLOW:
514          return esp_memprot_peri1_rtcslow_get_conf_reg();
515      case MEMPROT_PERI2_RTCSLOW_0:
516          return esp_memprot_peri2_rtcslow_0_get_conf_reg();
517      case MEMPROT_PERI2_RTCSLOW_1:
518          return esp_memprot_peri2_rtcslow_1_get_conf_reg();
519      default:
520          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
521          abort();
522      }
523  }
524  
525  void esp_memprot_set_prot_dram(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr)
526  {
527      switch (mem_type) {
528      case MEMPROT_DRAM0_SRAM:
529          esp_memprot_dram0_sram_set_prot(split_addr != NULL ? split_addr : esp_memprot_dram0_sram_get_min_split_addr(), lw, lr, hw, hr);
530          break;
531      case MEMPROT_DRAM0_RTCFAST:
532          esp_memprot_dram0_rtcfast_set_prot(split_addr != NULL ? split_addr : esp_memprot_dram0_rtcfast_get_min_split_addr(), lw, lr, hw, hr);
533          break;
534      default:
535          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
536          abort();
537      }
538  }
539  
540  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)
541  {
542      switch (mem_type) {
543      case MEMPROT_IRAM0_SRAM:
544          esp_memprot_iram0_sram_set_uni_block_perm(block, write_perm, read_perm, exec_perm);
545          break;
546      default:
547          ESP_LOGE(TAG, "Invalid mem_type %d (unified block management not supported)", mem_type);
548          abort();
549      }
550  }
551  
552  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)
553  {
554      switch (mem_type) {
555      case MEMPROT_IRAM0_SRAM:
556          esp_memprot_iram0_sram_set_prot(split_addr != NULL ? split_addr : esp_memprot_iram0_sram_get_min_split_addr(), lw, lr, lx, hw, hr, hx);
557          break;
558      case MEMPROT_IRAM0_RTCFAST:
559          esp_memprot_iram0_rtcfast_set_prot(split_addr != NULL ? split_addr : esp_memprot_iram0_rtcfast_get_min_split_addr(), lw, lr, lx, hw, hr, hx);
560          break;
561      default:
562          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
563          abort();
564      }
565  }
566  
567  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)
568  {
569      switch (mem_type) {
570      case MEMPROT_IRAM0_SRAM:
571          esp_memprot_iram0_sram_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx);
572          break;
573      case MEMPROT_IRAM0_RTCFAST:
574          esp_memprot_iram0_rtcfast_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx);
575          break;
576      default:
577          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
578          abort();
579      }
580  }
581  
582  void esp_memprot_get_perm_split_bits_dram(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr)
583  {
584      switch (mem_type) {
585      case MEMPROT_DRAM0_SRAM:
586          esp_memprot_dram0_sram_get_split_sgnf_bits(lw, lr, hw, hr);
587          break;
588      case MEMPROT_DRAM0_RTCFAST:
589          esp_memprot_dram0_rtcfast_get_split_sgnf_bits(lw, lr, hw, hr);
590          break;
591      default:
592          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
593          abort();
594      }
595  }
596  
597  void esp_memprot_get_perm_split_bits_peri1(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr)
598  {
599      switch (mem_type) {
600      case MEMPROT_PERI1_RTCSLOW:
601          esp_memprot_peri1_rtcslow_get_split_sgnf_bits(lw, lr, hw, hr);
602          break;
603      default:
604          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
605          abort();
606      }
607  }
608  
609  void esp_memprot_set_prot_peri1(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr)
610  {
611      switch (mem_type) {
612      case MEMPROT_PERI1_RTCSLOW:
613          esp_memprot_peri1_rtcslow_set_prot(split_addr != NULL ? split_addr : esp_memprot_peri1_rtcslow_get_min_split_addr(), lw, lr, hw, hr);
614          break;
615      default:
616          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
617          abort();
618      }
619  }
620  
621  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)
622  {
623      switch (mem_type) {
624      case MEMPROT_PERI2_RTCSLOW_0:
625          esp_memprot_peri2_rtcslow_0_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx);
626          break;
627      case MEMPROT_PERI2_RTCSLOW_1:
628          esp_memprot_peri2_rtcslow_1_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx);
629          break;
630      default:
631          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
632          abort();
633      }
634  }
635  
636  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)
637  {
638      switch (mem_type) {
639      case MEMPROT_PERI2_RTCSLOW_0:
640          esp_memprot_peri2_rtcslow_0_set_prot(split_addr != NULL ? split_addr : esp_memprot_peri2_rtcslow_0_get_min_split_addr(), lw, lr, lx, hw, hr, hx);
641          break;
642      case MEMPROT_PERI2_RTCSLOW_1:
643          esp_memprot_peri2_rtcslow_1_set_prot(split_addr != NULL ? split_addr : esp_memprot_peri2_rtcslow_1_get_min_split_addr(), lw, lr, lx, hw, hr, hx);
644          break;
645      default:
646          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
647          abort();
648      }
649  }
650  
651  void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask)
652  {
653      //any IRAM0/DRAM0 enable/disable call applies to all memory modules connected
654      uint32_t required_mem_prot = mem_type_mask == NULL ? (uint32_t)MEMPROT_ALL : *mem_type_mask;
655      bool use_iram0 = required_mem_prot & MEMPROT_IRAM0_SRAM || required_mem_prot & MEMPROT_IRAM0_RTCFAST;
656      bool use_dram0 = required_mem_prot & MEMPROT_DRAM0_SRAM || required_mem_prot & MEMPROT_DRAM0_RTCFAST;
657      bool use_peri1 = required_mem_prot & MEMPROT_PERI1_RTCSLOW;
658      bool use_peri2 = required_mem_prot & MEMPROT_PERI2_RTCSLOW_0 || required_mem_prot & MEMPROT_PERI2_RTCSLOW_1;
659  
660      //disable protection
661      if (use_iram0) {
662          esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, false);
663      }
664      if (use_dram0) {
665          esp_memprot_intr_ena(MEMPROT_DRAM0_SRAM, false);
666      }
667      if (use_peri1) {
668          esp_memprot_intr_ena(MEMPROT_PERI1_RTCSLOW, false);
669      }
670      if (use_peri2) {
671          esp_memprot_intr_ena(MEMPROT_PERI2_RTCSLOW_0, false);
672      }
673  
674      //connect to intr. matrix if not being debugged
675      if (!esp_cpu_in_ocd_debug_mode()) {
676  
677          ESP_FAULT_ASSERT(!esp_cpu_in_ocd_debug_mode());
678  
679          //initialize for specific buses (any memory type does the job)
680          if (invoke_panic_handler) {
681              if (use_iram0) {
682                  esp_memprot_intr_init(MEMPROT_IRAM0_SRAM);
683              }
684              if (use_dram0) {
685                  esp_memprot_intr_init(MEMPROT_DRAM0_SRAM);
686              }
687              if (use_peri1) {
688                  esp_memprot_intr_init(MEMPROT_PERI1_RTCSLOW);
689              }
690              if (use_peri2) {
691                  esp_memprot_intr_init(MEMPROT_PERI2_RTCSLOW_0);
692              }
693          }
694  
695          //set permissions
696          if (required_mem_prot & MEMPROT_IRAM0_SRAM) {
697              esp_memprot_set_prot_iram(MEMPROT_IRAM0_SRAM, NULL, false, true, true, true, true, true);
698          }
699          if (required_mem_prot & MEMPROT_IRAM0_RTCFAST) {
700              esp_memprot_set_prot_iram(MEMPROT_IRAM0_RTCFAST, NULL, false, true, true, true, true, true);
701          }
702          if (required_mem_prot & MEMPROT_DRAM0_SRAM) {
703              esp_memprot_set_prot_dram(MEMPROT_DRAM0_SRAM, NULL, false, true, true, true);
704          }
705          if (required_mem_prot & MEMPROT_DRAM0_RTCFAST) {
706              esp_memprot_set_prot_dram(MEMPROT_DRAM0_RTCFAST, NULL, false, true, true, true);
707          }
708          if (required_mem_prot & MEMPROT_PERI1_RTCSLOW) {
709              esp_memprot_set_prot_peri1(MEMPROT_PERI1_RTCSLOW, NULL, true, true, true, true);
710          }
711          if (required_mem_prot & MEMPROT_PERI2_RTCSLOW_0) {
712              esp_memprot_set_prot_peri2(MEMPROT_PERI2_RTCSLOW_0, NULL, true, true, false, true, true, false);
713          }
714          if (required_mem_prot & MEMPROT_PERI2_RTCSLOW_1) {
715              esp_memprot_set_prot_peri2(MEMPROT_PERI2_RTCSLOW_1, NULL, true, true, false, true, true, false);
716          }
717  
718          //reenable protection (bus based)
719          if (use_iram0) {
720              esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, true);
721          }
722          if (use_dram0) {
723              esp_memprot_intr_ena(MEMPROT_DRAM0_SRAM, true);
724          }
725          if (use_peri1) {
726              esp_memprot_intr_ena(MEMPROT_PERI1_RTCSLOW, true);
727          }
728          if (use_peri2) {
729              esp_memprot_intr_ena(MEMPROT_PERI2_RTCSLOW_0, true);
730          }
731  
732          //lock if required (bus based)
733          if (lock_feature) {
734              if (use_iram0) {
735                  esp_memprot_set_lock(MEMPROT_IRAM0_SRAM);
736              }
737              if (use_dram0) {
738                  esp_memprot_set_lock(MEMPROT_DRAM0_SRAM);
739              }
740              if (use_peri1) {
741                  esp_memprot_set_lock(MEMPROT_PERI1_RTCSLOW);
742              }
743              if (use_peri2) {
744                  esp_memprot_set_lock(MEMPROT_PERI2_RTCSLOW_0);
745              }
746          }
747      }
748  }
749  
750  void esp_memprot_get_permissions(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx)
751  {
752      switch (mem_type) {
753      case MEMPROT_IRAM0_SRAM:
754          esp_memprot_iram0_sram_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx);
755          break;
756      case MEMPROT_DRAM0_SRAM:
757          esp_memprot_dram0_sram_get_split_sgnf_bits(lw, lr, hw, hr);
758          break;
759      case MEMPROT_IRAM0_RTCFAST:
760          esp_memprot_iram0_rtcfast_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx);
761          break;
762      case MEMPROT_DRAM0_RTCFAST:
763          esp_memprot_dram0_rtcfast_get_split_sgnf_bits(lw, lr, hw, hr);
764          break;
765      case MEMPROT_PERI1_RTCSLOW:
766          esp_memprot_peri1_rtcslow_get_split_sgnf_bits(lw, lr, hw, hr);
767          break;
768      case MEMPROT_PERI2_RTCSLOW_0:
769          esp_memprot_peri2_rtcslow_0_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx);
770          break;
771      case MEMPROT_PERI2_RTCSLOW_1:
772          esp_memprot_peri2_rtcslow_1_get_split_sgnf_bits(lw, lr, lx, hw, hr, hx);
773          break;
774      default:
775          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
776          abort();
777      }
778  }
779  
780  void esp_memprot_get_perm_read(mem_type_prot_t mem_type, bool *lr, bool *hr)
781  {
782      bool _lw, _lr, _lx, _hw, _hr, _hx;
783      esp_memprot_get_permissions(mem_type, &_lw, &_lr, &_lx, &_hw, &_hr, &_hx);
784      *lr = _lr;
785      *hr = _hr;
786  }
787  
788  void esp_memprot_get_perm_write(mem_type_prot_t mem_type, bool *lw, bool *hw)
789  {
790      bool _lw, _lr, _lx, _hw, _hr, _hx;
791      esp_memprot_get_permissions(mem_type, &_lw, &_lr, &_lx, &_hw, &_hr, &_hx);
792      *lw = _lw;
793      *hw = _hw;
794  }
795  
796  void esp_memprot_get_perm_exec(mem_type_prot_t mem_type, bool *lx, bool *hx)
797  {
798      if ( mem_type == MEMPROT_DRAM0_SRAM ||
799              mem_type == MEMPROT_DRAM0_RTCFAST ||
800              mem_type == MEMPROT_PERI1_RTCSLOW ) {
801          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
802          abort();
803      }
804  
805      bool _lw, _lr, _lx, _hw, _hr, _hx;
806      esp_memprot_get_permissions(mem_type, &_lw, &_lr, &_lx, &_hw, &_hr, &_hx);
807      *lx = _lx;
808      *hx = _hx;
809  }
810  
811  uint32_t esp_memprot_get_low_limit(mem_type_prot_t mem_type)
812  {
813      switch (mem_type) {
814      case MEMPROT_IRAM0_SRAM:
815          return IRAM0_SRAM_ADDRESS_LOW;
816      case MEMPROT_DRAM0_SRAM:
817          return DRAM0_SRAM_ADDRESS_LOW;
818      case MEMPROT_IRAM0_RTCFAST:
819          return IRAM0_RTCFAST_ADDRESS_LOW;
820      case MEMPROT_DRAM0_RTCFAST:
821          return DRAM0_RTCFAST_ADDRESS_LOW;
822      case MEMPROT_PERI1_RTCSLOW:
823          return PERI1_RTCSLOW_ADDRESS_LOW;
824      case MEMPROT_PERI2_RTCSLOW_0:
825          return PERI2_RTCSLOW_0_ADDRESS_LOW;
826      case MEMPROT_PERI2_RTCSLOW_1:
827          return PERI2_RTCSLOW_1_ADDRESS_LOW;
828      default:
829          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
830          abort();
831      }
832  }
833  
834  uint32_t esp_memprot_get_high_limit(mem_type_prot_t mem_type)
835  {
836      switch (mem_type) {
837      case MEMPROT_IRAM0_SRAM:
838          return IRAM0_SRAM_ADDRESS_HIGH;
839      case MEMPROT_DRAM0_SRAM:
840          return DRAM0_SRAM_ADDRESS_HIGH;
841      case MEMPROT_IRAM0_RTCFAST:
842          return IRAM0_RTCFAST_ADDRESS_HIGH;
843      case MEMPROT_DRAM0_RTCFAST:
844          return DRAM0_RTCFAST_ADDRESS_HIGH;
845      case MEMPROT_PERI1_RTCSLOW:
846          return PERI1_RTCSLOW_ADDRESS_HIGH;
847      case MEMPROT_PERI2_RTCSLOW_0:
848          return PERI2_RTCSLOW_0_ADDRESS_HIGH;
849      case MEMPROT_PERI2_RTCSLOW_1:
850          return PERI2_RTCSLOW_1_ADDRESS_HIGH;
851      default:
852          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
853          abort();
854      }
855  }
856  
857  void esp_memprot_set_read_perm(mem_type_prot_t mem_type, bool lr, bool hr)
858  {
859      switch (mem_type) {
860      case MEMPROT_IRAM0_SRAM:
861          esp_memprot_iram0_sram_set_read_perm(lr, hr);
862          break;
863      case MEMPROT_DRAM0_SRAM:
864          esp_memprot_dram0_sram_set_read_perm(lr, hr);
865          break;
866      case MEMPROT_IRAM0_RTCFAST:
867          esp_memprot_iram0_rtcfast_set_read_perm(lr, hr);
868          break;
869      case MEMPROT_DRAM0_RTCFAST:
870          esp_memprot_dram0_rtcfast_set_read_perm(lr, hr);
871          break;
872      case MEMPROT_PERI1_RTCSLOW:
873          esp_memprot_peri1_rtcslow_set_read_perm(lr, hr);
874          break;
875      case MEMPROT_PERI2_RTCSLOW_0:
876          esp_memprot_peri2_rtcslow_0_set_read_perm(lr, hr);
877          break;
878      case MEMPROT_PERI2_RTCSLOW_1:
879          esp_memprot_peri2_rtcslow_1_set_read_perm(lr, hr);
880          break;
881      default:
882          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
883          abort();
884      }
885  }
886  
887  void esp_memprot_set_write_perm(mem_type_prot_t mem_type, bool lw, bool hw)
888  {
889      switch (mem_type) {
890      case MEMPROT_IRAM0_SRAM:
891          esp_memprot_iram0_sram_set_write_perm(lw, hw);
892          break;
893      case MEMPROT_DRAM0_SRAM:
894          esp_memprot_dram0_sram_set_write_perm(lw, hw);
895          break;
896      case MEMPROT_IRAM0_RTCFAST:
897          esp_memprot_iram0_rtcfast_set_write_perm(lw, hw);
898          break;
899      case MEMPROT_DRAM0_RTCFAST:
900          esp_memprot_dram0_rtcfast_set_write_perm(lw, hw);
901          break;
902      case MEMPROT_PERI1_RTCSLOW:
903          esp_memprot_peri1_rtcslow_set_write_perm(lw, hw);
904          break;
905      case MEMPROT_PERI2_RTCSLOW_0:
906          esp_memprot_peri2_rtcslow_0_set_write_perm(lw, hw);
907          break;
908      case MEMPROT_PERI2_RTCSLOW_1:
909          esp_memprot_peri2_rtcslow_1_set_write_perm(lw, hw);
910          break;
911      default:
912          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
913          abort();
914      }
915  }
916  
917  void esp_memprot_set_exec_perm(mem_type_prot_t mem_type, bool lx, bool hx)
918  {
919      switch (mem_type) {
920      case MEMPROT_IRAM0_SRAM:
921          esp_memprot_iram0_sram_set_exec_perm(lx, hx);
922          break;
923      case MEMPROT_IRAM0_RTCFAST:
924          esp_memprot_iram0_rtcfast_set_exec_perm(lx, hx);
925          break;
926      case MEMPROT_PERI2_RTCSLOW_0:
927          esp_memprot_peri2_rtcslow_0_set_exec_perm(lx, hx);
928          break;
929      case MEMPROT_PERI2_RTCSLOW_1:
930          esp_memprot_peri2_rtcslow_1_set_exec_perm(lx, hx);
931          break;
932      default:
933          ESP_LOGE(TAG, "Invalid mem_type %d", mem_type);
934          abort();
935      }
936  }