memprot.c 30 KB

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