memprot.c 20 KB

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