memprot.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  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. /* INTERNAL API
  15. * implementation of PMS memory protection features
  16. */
  17. #include <stdio.h>
  18. #include "sdkconfig.h"
  19. #include "soc/sensitive_reg.h"
  20. #include "soc/dport_access.h"
  21. #include "soc/periph_defs.h"
  22. #include "esp_intr_alloc.h"
  23. #include "hal/memprot_ll.h"
  24. #include "esp32h2/memprot.h"
  25. #include "riscv/interrupt.h"
  26. #include "esp32h2/rom/ets_sys.h"
  27. #include "esp_log.h"
  28. extern int _iram_text_end;
  29. static const char *TAG = "memprot";
  30. const char *esp_memprot_mem_type_to_str(mem_type_prot_t mem_type)
  31. {
  32. switch (mem_type) {
  33. case MEMPROT_NONE:
  34. return "NONE";
  35. case MEMPROT_IRAM0_SRAM:
  36. return "IRAM0_SRAM";
  37. case MEMPROT_DRAM0_SRAM:
  38. return "DRAM0_SRAM";
  39. case MEMPROT_ALL:
  40. return "ALL";
  41. default:
  42. return "UNKNOWN";
  43. }
  44. }
  45. const char *esp_memprot_split_line_to_str(split_line_t line_type)
  46. {
  47. switch (line_type) {
  48. case MEMPROT_IRAM0_DRAM0_SPLITLINE:
  49. return "MEMPROT_IRAM0_DRAM0_SPLITLINE";
  50. case MEMPROT_IRAM0_LINE_0_SPLITLINE:
  51. return "MEMPROT_IRAM0_LINE_0_SPLITLINE";
  52. case MEMPROT_IRAM0_LINE_1_SPLITLINE:
  53. return "MEMPROT_IRAM0_LINE_1_SPLITLINE";
  54. case MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE:
  55. return "MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE";
  56. case MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE:
  57. return "MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE";
  58. default:
  59. return "UNKNOWN";
  60. }
  61. }
  62. const char *esp_memprot_pms_to_str(pms_area_t area_type)
  63. {
  64. switch (area_type) {
  65. case MEMPROT_IRAM0_PMS_AREA_0:
  66. return "MEMPROT_IRAM0_PMS_AREA_0";
  67. case MEMPROT_IRAM0_PMS_AREA_1:
  68. return "MEMPROT_IRAM0_PMS_AREA_1";
  69. case MEMPROT_IRAM0_PMS_AREA_2:
  70. return "MEMPROT_IRAM0_PMS_AREA_2";
  71. case MEMPROT_IRAM0_PMS_AREA_3:
  72. return "MEMPROT_IRAM0_PMS_AREA_3";
  73. case MEMPROT_DRAM0_PMS_AREA_0:
  74. return "MEMPROT_DRAM0_PMS_AREA_0";
  75. case MEMPROT_DRAM0_PMS_AREA_1:
  76. return "MEMPROT_DRAM0_PMS_AREA_1";
  77. case MEMPROT_DRAM0_PMS_AREA_2:
  78. return "MEMPROT_DRAM0_PMS_AREA_2";
  79. case MEMPROT_DRAM0_PMS_AREA_3:
  80. return "MEMPROT_DRAM0_PMS_AREA_3";
  81. default:
  82. return "UNKNOWN";
  83. }
  84. }
  85. /* split lines */
  86. void *esp_memprot_get_default_main_split_addr()
  87. {
  88. return &_iram_text_end;
  89. }
  90. uint32_t *esp_memprot_get_split_addr(split_line_t line_type)
  91. {
  92. switch ( line_type ) {
  93. case MEMPROT_IRAM0_DRAM0_SPLITLINE:
  94. return memprot_ll_get_iram0_split_line_main_I_D();
  95. case MEMPROT_IRAM0_LINE_0_SPLITLINE:
  96. return memprot_ll_get_iram0_split_line_I_0();
  97. case MEMPROT_IRAM0_LINE_1_SPLITLINE:
  98. return memprot_ll_get_iram0_split_line_I_1();
  99. case MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE:
  100. return memprot_ll_get_dram0_split_line_D_0();
  101. case MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE:
  102. return memprot_ll_get_dram0_split_line_D_1();
  103. default:
  104. abort();
  105. }
  106. }
  107. void esp_memprot_set_split_line_lock()
  108. {
  109. memprot_ll_set_iram0_dram0_split_line_lock();
  110. }
  111. bool esp_memprot_get_split_line_lock()
  112. {
  113. return memprot_ll_get_iram0_dram0_split_line_lock();
  114. }
  115. void esp_memprot_set_split_line(split_line_t line_type, const void *line_addr)
  116. {
  117. ESP_EARLY_LOGD(TAG, "Setting split line %s, addr: 0x%08X", esp_memprot_split_line_to_str(line_type), (uint32_t)line_addr);
  118. //split-line must be divisible by 512 (PMS module restriction)
  119. assert( ((uint32_t)line_addr) % 0x200 == 0 );
  120. switch ( line_type ) {
  121. case MEMPROT_IRAM0_DRAM0_SPLITLINE:
  122. memprot_ll_set_iram0_split_line_main_I_D(line_addr);
  123. break;
  124. case MEMPROT_IRAM0_LINE_0_SPLITLINE:
  125. memprot_ll_set_iram0_split_line_I_0(line_addr);
  126. break;
  127. case MEMPROT_IRAM0_LINE_1_SPLITLINE:
  128. memprot_ll_set_iram0_split_line_I_1(line_addr);
  129. break;
  130. case MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE:
  131. memprot_ll_set_dram0_split_line_D_0(line_addr);
  132. break;
  133. case MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE:
  134. memprot_ll_set_dram0_split_line_D_1(line_addr);
  135. break;
  136. default:
  137. ESP_EARLY_LOGE(TAG, "Invalid split line type, aborting: 0x%08X", (uint32_t)line_addr);
  138. abort();
  139. }
  140. }
  141. /* PMS */
  142. void esp_memprot_set_pms_lock(mem_type_prot_t mem_type)
  143. {
  144. ESP_EARLY_LOGD(TAG, "esp_memprot_set_pms_lock(%s)", esp_memprot_mem_type_to_str(mem_type));
  145. switch ( mem_type ) {
  146. case MEMPROT_IRAM0_SRAM:
  147. memprot_ll_iram0_set_pms_lock();
  148. break;
  149. case MEMPROT_DRAM0_SRAM:
  150. memprot_ll_dram0_set_pms_lock();
  151. break;
  152. default:
  153. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  154. abort();
  155. }
  156. }
  157. bool esp_memprot_get_pms_lock(mem_type_prot_t mem_type)
  158. {
  159. ESP_EARLY_LOGD(TAG, "esp_memprot_get_pms_lock(%s)", esp_memprot_mem_type_to_str(mem_type));
  160. switch ( mem_type ) {
  161. case MEMPROT_IRAM0_SRAM:
  162. return memprot_ll_iram0_get_pms_lock();
  163. case MEMPROT_DRAM0_SRAM:
  164. return memprot_ll_dram0_get_pms_lock();
  165. default:
  166. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  167. abort();
  168. }
  169. }
  170. void esp_memprot_iram_set_pms_area(pms_area_t area_type, bool r, bool w, bool x)
  171. {
  172. ESP_EARLY_LOGD(TAG, "esp_memprot_iram_set_pms_area(area:%s r:%u w:%u, x:%u)", esp_memprot_pms_to_str(area_type), r, w, x);
  173. switch ( area_type ) {
  174. case MEMPROT_IRAM0_PMS_AREA_0:
  175. memprot_ll_iram0_set_pms_area_0(r, w, x);
  176. break;
  177. case MEMPROT_IRAM0_PMS_AREA_1:
  178. memprot_ll_iram0_set_pms_area_1(r, w, x);
  179. break;
  180. case MEMPROT_IRAM0_PMS_AREA_2:
  181. memprot_ll_iram0_set_pms_area_2(r, w, x);
  182. break;
  183. case MEMPROT_IRAM0_PMS_AREA_3:
  184. memprot_ll_iram0_set_pms_area_3(r, w, x);
  185. break;
  186. default:
  187. ESP_EARLY_LOGE(TAG, "Invalid area_type %d", esp_memprot_pms_to_str(area_type));
  188. abort();
  189. }
  190. }
  191. void esp_memprot_iram_get_pms_area(pms_area_t area_type, bool *r, bool *w, bool *x)
  192. {
  193. ESP_EARLY_LOGD(TAG, "esp_memprot_iram_get_pms_area(area:%s r:%u w:%u)", esp_memprot_pms_to_str(area_type), r, w);
  194. switch ( area_type ) {
  195. case MEMPROT_IRAM0_PMS_AREA_0:
  196. memprot_ll_iram0_get_pms_area_0(r, w, x);
  197. break;
  198. case MEMPROT_IRAM0_PMS_AREA_1:
  199. memprot_ll_iram0_get_pms_area_1(r, w, x);
  200. break;
  201. case MEMPROT_IRAM0_PMS_AREA_2:
  202. memprot_ll_iram0_get_pms_area_2(r, w, x);
  203. break;
  204. case MEMPROT_IRAM0_PMS_AREA_3:
  205. memprot_ll_iram0_get_pms_area_3(r, w, x);
  206. break;
  207. default:
  208. ESP_EARLY_LOGE(TAG, "Invalid area_type %d", esp_memprot_pms_to_str(area_type));
  209. abort();
  210. }
  211. }
  212. void esp_memprot_dram_set_pms_area(pms_area_t area_type, bool r, bool w)
  213. {
  214. ESP_EARLY_LOGD(TAG, "esp_memprot_dram_set_pms_area(area:%s r:%u w:%u)", esp_memprot_pms_to_str(area_type), r, w);
  215. switch ( area_type ) {
  216. case MEMPROT_DRAM0_PMS_AREA_0:
  217. memprot_ll_dram0_set_pms_area_0(r, w);
  218. break;
  219. case MEMPROT_DRAM0_PMS_AREA_1:
  220. memprot_ll_dram0_set_pms_area_1(r, w);
  221. break;
  222. case MEMPROT_DRAM0_PMS_AREA_2:
  223. memprot_ll_dram0_set_pms_area_2(r, w);
  224. break;
  225. case MEMPROT_DRAM0_PMS_AREA_3:
  226. memprot_ll_dram0_set_pms_area_3(r, w);
  227. break;
  228. default:
  229. ESP_EARLY_LOGE(TAG, "Invalid area_type %d", esp_memprot_pms_to_str(area_type));
  230. abort();
  231. }
  232. }
  233. void esp_memprot_dram_get_pms_area(pms_area_t area_type, bool *r, bool *w)
  234. {
  235. ESP_EARLY_LOGD(TAG, "esp_memprot_dram_get_pms_area(area:%s r:%u w:%u)", esp_memprot_pms_to_str(area_type), r, w);
  236. switch ( area_type ) {
  237. case MEMPROT_DRAM0_PMS_AREA_0:
  238. memprot_ll_dram0_get_pms_area_0(r, w);
  239. break;
  240. case MEMPROT_DRAM0_PMS_AREA_1:
  241. memprot_ll_dram0_get_pms_area_1(r, w);
  242. break;
  243. case MEMPROT_DRAM0_PMS_AREA_2:
  244. memprot_ll_dram0_get_pms_area_2(r, w);
  245. break;
  246. case MEMPROT_DRAM0_PMS_AREA_3:
  247. memprot_ll_dram0_get_pms_area_3(r, w);
  248. break;
  249. default:
  250. ESP_EARLY_LOGE(TAG, "Invalid area_type %d", esp_memprot_pms_to_str(area_type));
  251. abort();
  252. }
  253. }
  254. /* monitor */
  255. void esp_memprot_set_monitor_lock(mem_type_prot_t mem_type)
  256. {
  257. ESP_EARLY_LOGD(TAG, "esp_memprot_set_monitor_lock(%s)", esp_memprot_mem_type_to_str(mem_type));
  258. switch ( mem_type ) {
  259. case MEMPROT_IRAM0_SRAM:
  260. memprot_ll_iram0_set_monitor_lock();
  261. break;
  262. case MEMPROT_DRAM0_SRAM:
  263. memprot_ll_dram0_set_monitor_lock();
  264. break;
  265. default:
  266. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  267. abort();
  268. }
  269. }
  270. bool esp_memprot_get_monitor_lock(mem_type_prot_t mem_type)
  271. {
  272. ESP_EARLY_LOGD(TAG, "esp_memprot_get_monitor_lock(%s)", esp_memprot_mem_type_to_str(mem_type));
  273. switch ( mem_type ) {
  274. case MEMPROT_IRAM0_SRAM:
  275. return memprot_ll_iram0_get_monitor_lock();
  276. case MEMPROT_DRAM0_SRAM:
  277. return memprot_ll_dram0_get_monitor_lock();
  278. default:
  279. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  280. abort();
  281. }
  282. }
  283. void esp_memprot_set_monitor_en(mem_type_prot_t mem_type, bool enable)
  284. {
  285. ESP_EARLY_LOGD(TAG, "esp_memprot_set_monitor_en(%s)", esp_memprot_mem_type_to_str(mem_type));
  286. switch ( mem_type ) {
  287. case MEMPROT_IRAM0_SRAM:
  288. memprot_ll_iram0_set_monitor_en(enable);
  289. break;
  290. case MEMPROT_DRAM0_SRAM:
  291. memprot_ll_dram0_set_monitor_en(enable);
  292. break;
  293. default:
  294. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  295. abort();
  296. }
  297. }
  298. bool esp_memprot_get_monitor_en(mem_type_prot_t mem_type)
  299. {
  300. ESP_EARLY_LOGD(TAG, "esp_memprot_set_monitor_en(%s)", esp_memprot_mem_type_to_str(mem_type));
  301. switch ( mem_type ) {
  302. case MEMPROT_IRAM0_SRAM:
  303. return memprot_ll_iram0_get_monitor_en();
  304. case MEMPROT_DRAM0_SRAM:
  305. return memprot_ll_dram0_get_monitor_en();
  306. default:
  307. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  308. abort();
  309. }
  310. }
  311. bool esp_memprot_is_intr_ena_any()
  312. {
  313. return esp_memprot_get_monitor_en(MEMPROT_IRAM0_SRAM) || esp_memprot_get_monitor_en(MEMPROT_DRAM0_SRAM);
  314. }
  315. void esp_memprot_monitor_clear_intr(mem_type_prot_t mem_type)
  316. {
  317. ESP_EARLY_LOGD(TAG, "esp_memprot_monitor_clear_intr(%s)", esp_memprot_mem_type_to_str(mem_type));
  318. switch ( mem_type ) {
  319. case MEMPROT_IRAM0_SRAM:
  320. memprot_ll_iram0_clear_monitor_intr();
  321. memprot_ll_iram0_reset_clear_monitor_intr();
  322. break;
  323. case MEMPROT_DRAM0_SRAM:
  324. memprot_ll_dram0_clear_monitor_intr();
  325. memprot_ll_dram0_reset_clear_monitor_intr();
  326. break;
  327. default:
  328. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  329. abort();
  330. }
  331. }
  332. mem_type_prot_t esp_memprot_get_active_intr_memtype()
  333. {
  334. if ( memprot_ll_iram0_get_monitor_status_intr() > 0 ) {
  335. return MEMPROT_IRAM0_SRAM;
  336. } else if ( memprot_ll_dram0_get_monitor_status_intr() ) {
  337. return MEMPROT_DRAM0_SRAM;
  338. }
  339. return MEMPROT_NONE;
  340. }
  341. bool esp_memprot_is_locked_any()
  342. {
  343. return
  344. esp_memprot_get_split_line_lock() ||
  345. esp_memprot_get_pms_lock(MEMPROT_IRAM0_SRAM) ||
  346. esp_memprot_get_pms_lock(MEMPROT_DRAM0_SRAM) ||
  347. esp_memprot_get_monitor_lock(MEMPROT_IRAM0_SRAM) ||
  348. esp_memprot_get_monitor_lock(MEMPROT_DRAM0_SRAM);
  349. }
  350. bool esp_memprot_get_violate_intr_on(mem_type_prot_t mem_type)
  351. {
  352. switch ( mem_type ) {
  353. case MEMPROT_IRAM0_SRAM:
  354. return memprot_ll_iram0_get_monitor_status_intr() == 1;
  355. case MEMPROT_DRAM0_SRAM:
  356. return memprot_ll_dram0_get_monitor_status_intr() == 1;
  357. default:
  358. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  359. abort();
  360. }
  361. }
  362. uint32_t esp_memprot_get_violate_addr(mem_type_prot_t mem_type)
  363. {
  364. switch ( mem_type ) {
  365. case MEMPROT_IRAM0_SRAM:
  366. return memprot_ll_iram0_get_monitor_status_fault_addr();
  367. case MEMPROT_DRAM0_SRAM:
  368. return memprot_ll_dram0_get_monitor_status_fault_addr();
  369. default:
  370. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  371. abort();
  372. }
  373. }
  374. pms_world_t esp_memprot_get_violate_world(mem_type_prot_t mem_type)
  375. {
  376. uint32_t world = 0;
  377. switch ( mem_type ) {
  378. case MEMPROT_IRAM0_SRAM:
  379. world = memprot_ll_iram0_get_monitor_status_fault_world();
  380. break;
  381. case MEMPROT_DRAM0_SRAM:
  382. world = memprot_ll_dram0_get_monitor_status_fault_world();
  383. break;
  384. default:
  385. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  386. abort();
  387. }
  388. switch ( world ) {
  389. case 0x01: return MEMPROT_PMS_WORLD_0;
  390. case 0x10: return MEMPROT_PMS_WORLD_1;
  391. default: return MEMPROT_PMS_WORLD_INVALID;
  392. }
  393. }
  394. pms_operation_type_t esp_memprot_get_violate_wr(mem_type_prot_t mem_type)
  395. {
  396. switch ( mem_type ) {
  397. case MEMPROT_IRAM0_SRAM:
  398. return memprot_ll_iram0_get_monitor_status_fault_wr() == 1 ? MEMPROT_PMS_OP_WRITE : MEMPROT_PMS_OP_READ;
  399. case MEMPROT_DRAM0_SRAM:
  400. return memprot_ll_dram0_get_monitor_status_fault_wr() == 1 ? MEMPROT_PMS_OP_WRITE : MEMPROT_PMS_OP_READ;
  401. default:
  402. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  403. abort();
  404. }
  405. }
  406. bool esp_memprot_get_violate_loadstore(mem_type_prot_t mem_type)
  407. {
  408. switch ( mem_type ) {
  409. case MEMPROT_IRAM0_SRAM:
  410. return memprot_ll_iram0_get_monitor_status_fault_loadstore() == 1;
  411. default:
  412. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  413. abort();
  414. }
  415. }
  416. uint32_t esp_memprot_get_violate_byte_en(mem_type_prot_t mem_type)
  417. {
  418. switch ( mem_type ) {
  419. case MEMPROT_DRAM0_SRAM:
  420. return memprot_ll_dram0_get_monitor_status_fault_byte_en();
  421. default:
  422. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  423. abort();
  424. }
  425. }
  426. int esp_memprot_intr_get_cpuid()
  427. {
  428. return PRO_CPU_NUM;
  429. }
  430. void esp_memprot_set_intr_matrix(mem_type_prot_t mem_type)
  431. {
  432. ESP_EARLY_LOGD(TAG, "esp_memprot_set_intr_matrix(%s)", esp_memprot_mem_type_to_str(mem_type));
  433. ESP_INTR_DISABLE(ETS_MEMPROT_ERR_INUM);
  434. switch (mem_type) {
  435. case MEMPROT_IRAM0_SRAM:
  436. intr_matrix_set(esp_memprot_intr_get_cpuid(), memprot_ll_iram0_get_intr_source_num(), ETS_MEMPROT_ERR_INUM);
  437. break;
  438. case MEMPROT_DRAM0_SRAM:
  439. intr_matrix_set(esp_memprot_intr_get_cpuid(), memprot_ll_dram0_get_intr_source_num(), ETS_MEMPROT_ERR_INUM);
  440. break;
  441. default:
  442. ESP_EARLY_LOGE(TAG, "Invalid mem_type (%s), aborting", esp_memprot_mem_type_to_str(mem_type));
  443. abort();
  444. }
  445. /* Set the type and priority to cache error interrupts. */
  446. esprv_intc_int_set_type(BIT(ETS_MEMPROT_ERR_INUM), INTR_TYPE_LEVEL);
  447. esprv_intc_int_set_priority(ETS_MEMPROT_ERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM);
  448. ESP_INTR_ENABLE(ETS_MEMPROT_ERR_INUM);
  449. }
  450. void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask)
  451. {
  452. esp_memprot_set_prot_int(invoke_panic_handler, lock_feature, NULL, mem_type_mask);
  453. }
  454. void esp_memprot_set_prot_int(bool invoke_panic_handler, bool lock_feature, void *split_addr, uint32_t *mem_type_mask)
  455. {
  456. ESP_EARLY_LOGD(TAG, "esp_memprot_set_prot(panic_handler: %u, lock: %u, split.addr: 0x%08X, mem.types: 0x%08X", invoke_panic_handler, lock_feature, (uint32_t)split_addr, (uint32_t)mem_type_mask);
  457. uint32_t required_mem_prot = mem_type_mask == NULL ? (uint32_t)MEMPROT_ALL : *mem_type_mask;
  458. bool use_iram0 = required_mem_prot & MEMPROT_IRAM0_SRAM;
  459. bool use_dram0 = required_mem_prot & MEMPROT_DRAM0_SRAM;
  460. if (required_mem_prot == MEMPROT_NONE) {
  461. return;
  462. }
  463. //disable protection
  464. if (use_iram0) {
  465. esp_memprot_set_monitor_en(MEMPROT_IRAM0_SRAM, false);
  466. }
  467. if (use_dram0) {
  468. esp_memprot_set_monitor_en(MEMPROT_DRAM0_SRAM, false);
  469. }
  470. //panic handling
  471. if (invoke_panic_handler) {
  472. if (use_iram0) {
  473. esp_memprot_set_intr_matrix(MEMPROT_IRAM0_SRAM);
  474. }
  475. if (use_dram0) {
  476. esp_memprot_set_intr_matrix(MEMPROT_DRAM0_SRAM);
  477. }
  478. }
  479. //set split lines (must-have for all mem_types)
  480. const void *line_addr = split_addr == NULL ? esp_memprot_get_default_main_split_addr() : split_addr;
  481. esp_memprot_set_split_line(MEMPROT_IRAM0_LINE_1_SPLITLINE, line_addr);
  482. esp_memprot_set_split_line(MEMPROT_IRAM0_LINE_0_SPLITLINE, line_addr);
  483. esp_memprot_set_split_line(MEMPROT_IRAM0_DRAM0_SPLITLINE, line_addr);
  484. esp_memprot_set_split_line(MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE, (void *)(MAP_IRAM_TO_DRAM((uint32_t)line_addr)));
  485. esp_memprot_set_split_line(MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE, (void *)(MAP_IRAM_TO_DRAM((uint32_t)line_addr)));
  486. //set permissions
  487. if (required_mem_prot & MEMPROT_IRAM0_SRAM) {
  488. esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_0, true, false, true);
  489. esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_1, true, false, true);
  490. esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_2, true, false, true);
  491. esp_memprot_iram_set_pms_area(MEMPROT_IRAM0_PMS_AREA_3, true, true, false);
  492. }
  493. if (required_mem_prot & MEMPROT_DRAM0_SRAM) {
  494. esp_memprot_dram_set_pms_area( MEMPROT_DRAM0_PMS_AREA_0, true, false );
  495. esp_memprot_dram_set_pms_area(MEMPROT_DRAM0_PMS_AREA_1, true, true);
  496. esp_memprot_dram_set_pms_area(MEMPROT_DRAM0_PMS_AREA_2, true, true);
  497. esp_memprot_dram_set_pms_area(MEMPROT_DRAM0_PMS_AREA_3, true, true);
  498. }
  499. //reenable protection
  500. if (use_iram0) {
  501. esp_memprot_monitor_clear_intr(MEMPROT_IRAM0_SRAM);
  502. esp_memprot_set_monitor_en(MEMPROT_IRAM0_SRAM, true);
  503. }
  504. if (use_dram0) {
  505. esp_memprot_monitor_clear_intr(MEMPROT_DRAM0_SRAM);
  506. esp_memprot_set_monitor_en(MEMPROT_DRAM0_SRAM, true);
  507. }
  508. //lock if required
  509. if (lock_feature) {
  510. esp_memprot_set_split_line_lock();
  511. if (use_iram0) {
  512. esp_memprot_set_pms_lock(MEMPROT_IRAM0_SRAM);
  513. esp_memprot_set_monitor_lock(MEMPROT_IRAM0_SRAM);
  514. }
  515. if (use_dram0) {
  516. esp_memprot_set_pms_lock(MEMPROT_DRAM0_SRAM);
  517. esp_memprot_set_monitor_lock(MEMPROT_DRAM0_SRAM);
  518. }
  519. }
  520. }
  521. uint32_t esp_memprot_get_dram_status_reg_1()
  522. {
  523. return memprot_ll_dram0_get_monitor_status_register_1();
  524. }
  525. uint32_t esp_memprot_get_dram_status_reg_2()
  526. {
  527. return memprot_ll_dram0_get_monitor_status_register_2();
  528. }
  529. uint32_t esp_memprot_get_iram_status_reg()
  530. {
  531. return memprot_ll_iram0_get_monitor_status_register();
  532. }
  533. uint32_t esp_memprot_get_monitor_enable_reg(mem_type_prot_t mem_type)
  534. {
  535. switch (mem_type) {
  536. case MEMPROT_IRAM0_SRAM:
  537. return memprot_ll_iram0_get_monitor_enable_register();
  538. case MEMPROT_DRAM0_SRAM:
  539. return memprot_ll_dram0_get_monitor_enable_register();
  540. default:
  541. abort();
  542. }
  543. }