test_memprot_main.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "sdkconfig.h"
  9. #include "esp_attr.h"
  10. #include "hal/memprot_types.h"
  11. #include "soc/memprot_defs.h"
  12. #include "esp_private/esp_memprot_internal.h"
  13. #include "esp_memprot.h"
  14. #include "esp_rom_sys.h"
  15. /**
  16. * ESP32C3 MEMORY PROTECTION MODULE TEST
  17. * =====================================
  18. *
  19. * In order to safely test all the memprot features, this test application uses memprot default settings
  20. * plus proprietary testing buffers:
  21. * - s_iram_test_buffer (.iram_end_test, 1kB) - all IRAM/DRAM low region operations, test-only section
  22. * - s_dram_test_buffer (.dram0.data, 1kB) - all IRAM/DRAM high region operations, standard section
  23. * - s_rtc_text_test_buffer (.rtc_text_end_test, 1kB) - all RTCFAST low region operations, test-only section
  24. * - s_rtc_data_test_buffer (.rtc.data, 1kB) - all RTCFAST high region operations, standard section
  25. * Testing addresses are set to the middle of the testing buffers:
  26. * - test_ptr_low = (s_iram_test_buffer | s_rtc_text_test_buffer) + 0x200
  27. * - test_ptr_high = (s_dram_test_buffer | s_rtc_data_test_buffer) + 0x200
  28. * Each operation is tested at both low & high region addresses.
  29. * Each test result checked against expected status of PMS violation interrupt status and
  30. * against expected value stored in the memory tested (where applicable)
  31. *
  32. * Testing scheme is depicted below:
  33. *
  34. * DRam0/DMA IRam0
  35. * -----------------------------------------------
  36. * | IRam0_PMS_0 = IRam0_PMS_1 = IRam0_PMS_2 |
  37. * | DRam0_PMS_0 |
  38. * | |
  39. * | |
  40. * | - - - - - - - s_iram_test_buffer - - - - - -| IRam0_line1_Split_addr
  41. * DRam0_DMA_line0_Split_addr | -- test_ptr_low -- | =
  42. * = =============================================== IRam0_line0_Split_addr
  43. * DRam0_DMA_line1_Split_addr | | =
  44. * | - - - - - - - s_dram_test_buffer - - - - - --| IRam0_DRam0_Split_addr (main I/D)
  45. * | -- test_ptr_high -- |
  46. * | - - - - - - - - - - - - - - - - - - - - - - |
  47. * | |
  48. * | DRam0_PMS_1 = DRam0_PMS_2 = DRam0_PMS_3 |
  49. * | IRam0_PMS_3 |
  50. * | |
  51. * | ... |
  52. * | |
  53. * =============================================== SOC_RTC_IRAM_LOW (0x50000000)
  54. * | -- test_ptr_low -- |
  55. * | - - - - - - s_rtc_text_test_buffer - - - - -| RtcFast_Split_addr (_rtc_text_end)
  56. * | -- .rtc.dummy -- | (UNUSED - PADDING)
  57. * 8 kB | - - - - - - - - - - - - - - - - - - - - - - | [_rtc_dummy_end = _rtc_force_fast_start]
  58. * | -- .rtc.force_fast -- | (NOT USED IN THIS TEST)
  59. * | - - - - - - s_rtc_data_test_buffer - - - - -| [_rtc_force_fast_end = _rtc_data_start]
  60. * | -- test_ptr_high -- |
  61. * | - - - - - - - - - - - - - - - - - - - - - - |
  62. * =============================================== SOC_RTC_IRAM_HIGH (0x50001FFF)
  63. * | |
  64. * -----------------------------------------------
  65. */
  66. /* Binary code for the following asm [int func(int x) { return x+x; }]
  67. slli a0,a0,0x1
  68. ret
  69. */
  70. static uint8_t s_fnc_buff[] = { 0x06, 0x05, 0x82, 0x80 };
  71. typedef int (*fnc_ptr)(int);
  72. #define SRAM_TEST_BUFFER_SIZE 0x400
  73. #define SRAM_TEST_OFFSET 0x200
  74. static uint8_t __attribute__((section(".iram_end_test"))) s_iram_test_buffer[SRAM_TEST_BUFFER_SIZE] = {0};
  75. static uint8_t __attribute__((section(".rtc_text_end_test"))) s_rtc_text_test_buffer[SRAM_TEST_BUFFER_SIZE] = {0};
  76. static uint8_t RTC_DATA_ATTR s_rtc_data_test_buffer[SRAM_TEST_BUFFER_SIZE] = {0};
  77. static uint8_t s_dram_test_buffer[SRAM_TEST_BUFFER_SIZE] = {0};
  78. extern volatile bool g_override_illegal_instruction;
  79. static void *test_mprot_addr_low(esp_mprot_mem_t mem_type)
  80. {
  81. switch (mem_type) {
  82. case MEMPROT_TYPE_IRAM0_SRAM:
  83. return (void *)((uint32_t)s_iram_test_buffer + SRAM_TEST_OFFSET);
  84. case MEMPROT_TYPE_DRAM0_SRAM:
  85. return (void *)MAP_IRAM_TO_DRAM((uint32_t)s_iram_test_buffer + SRAM_TEST_OFFSET);
  86. case MEMPROT_TYPE_IRAM0_RTCFAST:
  87. return (void *)((uint32_t)s_rtc_text_test_buffer + SRAM_TEST_OFFSET);
  88. default:
  89. abort();
  90. }
  91. }
  92. static void *test_mprot_addr_high(esp_mprot_mem_t mem_type)
  93. {
  94. switch (mem_type) {
  95. case MEMPROT_TYPE_IRAM0_SRAM:
  96. return (void *)MAP_DRAM_TO_IRAM((uint32_t)s_dram_test_buffer + SRAM_TEST_OFFSET);
  97. case MEMPROT_TYPE_DRAM0_SRAM:
  98. return (void *)((uint32_t)s_dram_test_buffer + SRAM_TEST_OFFSET);
  99. case MEMPROT_TYPE_IRAM0_RTCFAST:
  100. return (void *)((uint32_t)s_rtc_data_test_buffer + SRAM_TEST_OFFSET);
  101. default:
  102. abort();
  103. }
  104. }
  105. static void __attribute__((unused)) test_mprot_dump_status_register(esp_mprot_mem_t mem_type)
  106. {
  107. esp_rom_printf("FAULT [");
  108. void *addr;
  109. esp_err_t err = esp_mprot_get_violate_addr(mem_type, &addr, DEFAULT_CPU_NUM);
  110. if (err == ESP_OK) {
  111. esp_rom_printf("fault addr: 0x%08X,", (uint32_t)addr);
  112. } else {
  113. esp_rom_printf("fault addr: N/A (%s),", esp_err_to_name(err));
  114. }
  115. esp_mprot_pms_world_t world;
  116. err = esp_mprot_get_violate_world(mem_type, &world, DEFAULT_CPU_NUM);
  117. if (err == ESP_OK) {
  118. esp_rom_printf(" world: %s,", esp_mprot_pms_world_to_str(world));
  119. } else {
  120. esp_rom_printf(" world: N/A (%s),", esp_err_to_name(err));
  121. }
  122. uint32_t oper;
  123. err = esp_mprot_get_violate_operation(mem_type, &oper, DEFAULT_CPU_NUM);
  124. if (err == ESP_OK) {
  125. esp_rom_printf(" operation: %s", esp_mprot_oper_type_to_str(oper));
  126. } else {
  127. esp_rom_printf(" operation: N/A (%s)", esp_err_to_name(err));
  128. }
  129. // DRAM/DMA fault: check byte-enables
  130. if (mem_type == MEMPROT_TYPE_DRAM0_SRAM) {
  131. uint32_t byteen;
  132. err = esp_mprot_get_violate_byte_enables(mem_type, &byteen, DEFAULT_CPU_NUM);
  133. if (err == ESP_OK) {
  134. esp_rom_printf(", byte en: 0x%08X", byteen);
  135. } else {
  136. esp_rom_printf(", byte en: N/A (%s)", esp_err_to_name(err));
  137. }
  138. }
  139. esp_rom_printf( "]\n" );
  140. }
  141. static void test_mprot_check_test_result(esp_mprot_mem_t mem_type, bool expected_status)
  142. {
  143. esp_memp_intr_source_t memp_intr;
  144. esp_err_t err = esp_mprot_get_active_intr(&memp_intr);
  145. if (err != ESP_OK) {
  146. esp_rom_printf("Error: esp_mprot_get_active_intr() failed (%s) - test_mprot_check_test_result\n", esp_err_to_name(err));
  147. return;
  148. }
  149. bool intr_on = memp_intr.mem_type == mem_type && memp_intr.core > -1;
  150. bool test_result = expected_status ? !intr_on : intr_on;
  151. if (test_result) {
  152. esp_rom_printf("OK\n");
  153. } else {
  154. test_mprot_dump_status_register(mem_type);
  155. }
  156. }
  157. static void test_mprot_clear_all_interrupts(void)
  158. {
  159. esp_err_t err = esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_SRAM, DEFAULT_CPU_NUM);
  160. if (err != ESP_OK) {
  161. esp_rom_printf("Error: esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_SRAM) failed (%s) - test_mprot_clear_all_interrupts\n", esp_err_to_name(err));
  162. }
  163. err = esp_mprot_monitor_clear_intr(MEMPROT_TYPE_DRAM0_SRAM, DEFAULT_CPU_NUM);
  164. if (err != ESP_OK) {
  165. esp_rom_printf("Error: esp_mprot_monitor_clear_intr(MEMPROT_TYPE_DRAM0_SRAM) failed (%s) - test_mprot_clear_all_interrupts\n", esp_err_to_name(err));
  166. }
  167. err = esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_RTCFAST, DEFAULT_CPU_NUM);
  168. if (err != ESP_OK) {
  169. esp_rom_printf("Error: esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_RTCFAST) failed (%s) - test_mprot_clear_all_interrupts\n", esp_err_to_name(err));
  170. }
  171. }
  172. static void test_mprot_get_permissions(bool low, esp_mprot_mem_t mem_type, bool *read, bool *write, bool *exec )
  173. {
  174. esp_mprot_pms_area_t area;
  175. switch (mem_type) {
  176. case MEMPROT_TYPE_IRAM0_SRAM:
  177. area = low ? MEMPROT_PMS_AREA_IRAM0_2 : MEMPROT_PMS_AREA_IRAM0_3;
  178. break;
  179. case MEMPROT_TYPE_DRAM0_SRAM:
  180. area = low ? MEMPROT_PMS_AREA_DRAM0_0 : MEMPROT_PMS_AREA_DRAM0_1;
  181. break;
  182. case MEMPROT_TYPE_IRAM0_RTCFAST:
  183. area = low ? MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO : MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI;
  184. break;
  185. default:
  186. abort();
  187. }
  188. uint32_t flags;
  189. esp_err_t err = esp_mprot_get_pms_area(area, &flags, DEFAULT_CPU_NUM);
  190. if (err != ESP_OK) {
  191. esp_rom_printf("Error: esp_mprot_get_pms_area() failed (%s) - test_mprot_get_permissions\n", esp_err_to_name(err));
  192. return;
  193. }
  194. if (read) {
  195. *read = flags & MEMPROT_OP_READ;
  196. }
  197. if (write) {
  198. *write = flags & MEMPROT_OP_WRITE;
  199. }
  200. if (exec) {
  201. *exec = flags & MEMPROT_OP_EXEC;
  202. }
  203. }
  204. static void test_mprot_set_permissions(bool low, esp_mprot_mem_t mem_type, bool read, bool write, bool *exec)
  205. {
  206. esp_err_t err;
  207. uint32_t flags = 0;
  208. if (read) {
  209. flags |= MEMPROT_OP_READ;
  210. }
  211. if (write) {
  212. flags |= MEMPROT_OP_WRITE;
  213. }
  214. if (exec && *exec) {
  215. flags |= MEMPROT_OP_EXEC;
  216. }
  217. switch (mem_type) {
  218. case MEMPROT_TYPE_IRAM0_SRAM: {
  219. if (low) {
  220. if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_0, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
  221. break;
  222. }
  223. if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_1, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
  224. break;
  225. }
  226. if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_2, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
  227. break;
  228. }
  229. } else {
  230. if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_3, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
  231. break;
  232. }
  233. }
  234. }
  235. break;
  236. case MEMPROT_TYPE_DRAM0_SRAM: {
  237. if (low) {
  238. if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_0, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
  239. break;
  240. }
  241. } else {
  242. if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_1, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
  243. break;
  244. }
  245. if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_2, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
  246. break;
  247. }
  248. if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_3, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
  249. break;
  250. }
  251. }
  252. }
  253. break;
  254. case MEMPROT_TYPE_IRAM0_RTCFAST: {
  255. if (low) {
  256. if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
  257. break;
  258. }
  259. } else {
  260. if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
  261. break;
  262. }
  263. }
  264. }
  265. break;
  266. default:
  267. abort();
  268. }
  269. if (err != ESP_OK) {
  270. esp_rom_printf("Error: esp_mprot_set_pms_area() failed (%s) - test_mprot_set_permissions\n", esp_err_to_name(err));
  271. }
  272. }
  273. static void test_mprot_read(esp_mprot_mem_t mem_type)
  274. {
  275. test_mprot_clear_all_interrupts();
  276. //get current permission settings
  277. bool write_perm_low, write_perm_high, read_perm_low, read_perm_high, exec_perm_low, exec_perm_high;
  278. bool is_exec_mem = mem_type & MEMPROT_TYPE_IRAM0_ANY;
  279. test_mprot_get_permissions(true, mem_type, &read_perm_low, &write_perm_low, is_exec_mem ? &exec_perm_low : NULL);
  280. test_mprot_get_permissions(false, mem_type, &read_perm_high, &write_perm_high, is_exec_mem ? &exec_perm_high : NULL);
  281. //get testing pointers for low & high regions
  282. volatile uint32_t *ptr_low = test_mprot_addr_low(mem_type);
  283. volatile uint32_t *ptr_high = test_mprot_addr_high(mem_type);
  284. const uint32_t test_val = 100;
  285. //temporarily allow WRITE for setting the test values
  286. esp_err_t err = esp_mprot_set_monitor_en(mem_type, false, DEFAULT_CPU_NUM);
  287. if (err != ESP_OK) {
  288. esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_read\n", esp_err_to_name(err));
  289. return;
  290. }
  291. test_mprot_set_permissions(true, mem_type, read_perm_low, true, is_exec_mem ? &exec_perm_low : NULL);
  292. test_mprot_set_permissions(false, mem_type, read_perm_high, true, is_exec_mem ? &exec_perm_high : NULL);
  293. //save testing values
  294. *ptr_low = test_val;
  295. *ptr_high = test_val + 1;
  296. //restore current PMS settings
  297. test_mprot_set_permissions(true, mem_type, read_perm_low, write_perm_low, is_exec_mem ? &exec_perm_low : NULL);
  298. test_mprot_set_permissions(false, mem_type, read_perm_high, write_perm_high, is_exec_mem ? &exec_perm_high : NULL);
  299. //reenable monitoring
  300. err = esp_mprot_set_monitor_en(mem_type, true, DEFAULT_CPU_NUM);
  301. if (err != ESP_OK) {
  302. esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_read\n", esp_err_to_name(err));
  303. return;
  304. }
  305. //perform READ test in low region
  306. esp_rom_printf("%s read low: ", esp_mprot_mem_type_to_str(mem_type));
  307. err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
  308. if (err != ESP_OK) {
  309. esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_read\n", esp_err_to_name(err));
  310. return;
  311. }
  312. volatile uint32_t val = *ptr_low;
  313. if (read_perm_low && val != test_val) {
  314. esp_rom_printf( "UNEXPECTED VALUE 0x%08X -", val );
  315. test_mprot_dump_status_register(mem_type);
  316. } else {
  317. test_mprot_check_test_result(mem_type, read_perm_low);
  318. }
  319. //perform READ in high region
  320. esp_rom_printf("%s read high: ", esp_mprot_mem_type_to_str(mem_type));
  321. err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
  322. if (err != ESP_OK) {
  323. esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_read\n", esp_err_to_name(err));
  324. return;
  325. }
  326. val = *ptr_high;
  327. if (read_perm_high && val != (test_val + 1)) {
  328. esp_rom_printf( "UNEXPECTED VALUE 0x%08X -", val);
  329. test_mprot_dump_status_register(mem_type);
  330. } else {
  331. test_mprot_check_test_result(mem_type, read_perm_high);
  332. }
  333. }
  334. static void test_mprot_write(esp_mprot_mem_t mem_type)
  335. {
  336. test_mprot_clear_all_interrupts();
  337. //get current READ & WRITE permission settings
  338. bool write_perm_low, write_perm_high, read_perm_low, read_perm_high, exec_perm_low, exec_perm_high;
  339. bool is_exec_mem = mem_type & MEMPROT_TYPE_IRAM0_ANY;
  340. test_mprot_get_permissions(true, mem_type, &read_perm_low, &write_perm_low, is_exec_mem ? &exec_perm_low : NULL);
  341. test_mprot_get_permissions(false, mem_type, &read_perm_high, &write_perm_high, is_exec_mem ? &exec_perm_high : NULL);
  342. //ensure READ enabled
  343. esp_err_t err = esp_mprot_set_monitor_en(mem_type, false, DEFAULT_CPU_NUM);
  344. if (err != ESP_OK) {
  345. esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
  346. return;
  347. }
  348. test_mprot_set_permissions(true, mem_type, true, write_perm_low, is_exec_mem ? &exec_perm_low : NULL);
  349. test_mprot_set_permissions(false, mem_type, true, write_perm_high, is_exec_mem ? &exec_perm_high : NULL);
  350. err = esp_mprot_set_monitor_en(mem_type, true, DEFAULT_CPU_NUM);
  351. if (err != ESP_OK) {
  352. esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
  353. return;
  354. }
  355. volatile uint32_t *ptr_low = test_mprot_addr_low(mem_type);
  356. volatile uint32_t *ptr_high = test_mprot_addr_high(mem_type);
  357. const uint32_t test_val = 10;
  358. //perform WRITE in low region
  359. esp_rom_printf("%s write low: ", esp_mprot_mem_type_to_str(mem_type));
  360. err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
  361. if (err != ESP_OK) {
  362. esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
  363. return;
  364. }
  365. volatile uint32_t val = 0;
  366. *ptr_low = test_val;
  367. val = *ptr_low;
  368. if (val != test_val && write_perm_low) {
  369. esp_rom_printf( "UNEXPECTED VALUE 0x%08X -", val);
  370. test_mprot_dump_status_register(mem_type);
  371. } else {
  372. test_mprot_check_test_result(mem_type, write_perm_low);
  373. }
  374. //perform WRITE in high region
  375. esp_rom_printf("%s write high: ", esp_mprot_mem_type_to_str(mem_type));
  376. err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
  377. if (err != ESP_OK) {
  378. esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
  379. return;
  380. }
  381. val = 0;
  382. *ptr_high = test_val + 1;
  383. val = *ptr_high;
  384. if (val != (test_val + 1) && write_perm_high) {
  385. esp_rom_printf( "UNEXPECTED VALUE 0x%08X -", val);
  386. test_mprot_dump_status_register(mem_type);
  387. } else {
  388. test_mprot_check_test_result(mem_type, write_perm_high);
  389. }
  390. //restore original permissions
  391. err = esp_mprot_set_monitor_en(mem_type, false, DEFAULT_CPU_NUM);
  392. if (err != ESP_OK) {
  393. esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
  394. return;
  395. }
  396. test_mprot_set_permissions(true, mem_type, read_perm_low, write_perm_low, is_exec_mem ? &exec_perm_low : NULL);
  397. test_mprot_set_permissions(false, mem_type, read_perm_high, write_perm_high, is_exec_mem ? &exec_perm_high : NULL);
  398. err = esp_mprot_set_monitor_en(mem_type, true, DEFAULT_CPU_NUM);
  399. if (err != ESP_OK) {
  400. esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
  401. return;
  402. }
  403. }
  404. static void test_mprot_exec(esp_mprot_mem_t mem_type)
  405. {
  406. if (!(mem_type & MEMPROT_TYPE_IRAM0_ANY)) {
  407. esp_rom_printf("Error: EXEC test available only for IRAM access.\n" );
  408. return;
  409. }
  410. test_mprot_clear_all_interrupts();
  411. bool write_perm_low, write_perm_high, read_perm_low, read_perm_high, exec_perm_low, exec_perm_high;
  412. //temporarily enable READ/WRITE
  413. test_mprot_get_permissions(true, mem_type, &read_perm_low, &write_perm_low, &exec_perm_low);
  414. test_mprot_get_permissions(false, mem_type, &read_perm_high, &write_perm_high, &exec_perm_high);
  415. esp_err_t err = esp_mprot_set_monitor_en(mem_type, false, DEFAULT_CPU_NUM);
  416. if (err != ESP_OK) {
  417. esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
  418. return;
  419. }
  420. test_mprot_set_permissions(true, mem_type, true, true, &exec_perm_low);
  421. test_mprot_set_permissions(false, mem_type, true, true, &exec_perm_high);
  422. err = esp_mprot_set_monitor_en(mem_type, true, DEFAULT_CPU_NUM);
  423. if (err != ESP_OK) {
  424. esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
  425. return;
  426. }
  427. //get testing pointers for low & high regions, zero 8B slot
  428. void *fnc_ptr_low = test_mprot_addr_low(mem_type);
  429. void *fnc_ptr_high = test_mprot_addr_high(mem_type);
  430. memset(fnc_ptr_low, 0, 8);
  431. memset(fnc_ptr_high, 0, 8);
  432. //inject the code to both low & high segments
  433. memcpy((void *)fnc_ptr_low, (const void *)s_fnc_buff, sizeof(s_fnc_buff));
  434. memcpy((void *)fnc_ptr_high, (const void *)s_fnc_buff, sizeof(s_fnc_buff));
  435. uint32_t res = 0;
  436. //LOW REGION: clear the intr flag & try to execute the code injected
  437. esp_rom_printf("%s exec low: ", esp_mprot_mem_type_to_str(mem_type));
  438. err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
  439. if (err != ESP_OK) {
  440. esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
  441. return;
  442. }
  443. fnc_ptr fnc = (fnc_ptr)fnc_ptr_low;
  444. g_override_illegal_instruction = true;
  445. res = fnc(5);
  446. g_override_illegal_instruction = false;
  447. //check results
  448. bool fnc_call_ok = res == 10;
  449. if (fnc_call_ok) {
  450. test_mprot_check_test_result(mem_type, exec_perm_low);
  451. } else {
  452. if (!exec_perm_low) {
  453. test_mprot_check_test_result(mem_type, false);
  454. } else {
  455. esp_rom_printf(" FAULT [injected code not executed]\n");
  456. }
  457. }
  458. //HIGH REGION: clear the intr-on flag & try to execute the code injected
  459. esp_rom_printf("%s exec high: ", esp_mprot_mem_type_to_str(mem_type));
  460. err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
  461. if (err != ESP_OK) {
  462. esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
  463. return;
  464. }
  465. fnc = (fnc_ptr)fnc_ptr_high;
  466. g_override_illegal_instruction = true;
  467. res = fnc(6);
  468. g_override_illegal_instruction = false;
  469. fnc_call_ok = res == 12;
  470. if (fnc_call_ok) {
  471. test_mprot_check_test_result(mem_type, exec_perm_high);
  472. } else {
  473. if (!exec_perm_high) {
  474. test_mprot_check_test_result(mem_type, false);
  475. } else {
  476. esp_rom_printf(" FAULT [injected code not executed]\n");
  477. }
  478. }
  479. //restore original permissions
  480. err = esp_mprot_set_monitor_en(mem_type, false, DEFAULT_CPU_NUM);
  481. if (err != ESP_OK) {
  482. esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
  483. return;
  484. }
  485. test_mprot_set_permissions(true, mem_type, read_perm_low, write_perm_low, &exec_perm_low);
  486. test_mprot_set_permissions(false, mem_type, read_perm_high, write_perm_high, &exec_perm_high);
  487. err = esp_mprot_set_monitor_en(mem_type, true, DEFAULT_CPU_NUM);
  488. if (err != ESP_OK) {
  489. esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
  490. return;
  491. }
  492. }
  493. /* ********************************************************************************************
  494. * main test runner
  495. */
  496. void app_main(void)
  497. {
  498. esp_memp_config_t memp_cfg = ESP_MEMPROT_DEFAULT_CONFIG();
  499. memp_cfg.invoke_panic_handler = false;
  500. memp_cfg.lock_feature = false;
  501. esp_err_t err = esp_mprot_set_prot(&memp_cfg);
  502. if (err != ESP_OK) {
  503. esp_rom_printf("Error: esp_mprot_set_prot() failed (%s) - app_main\n", esp_err_to_name(err));
  504. return;
  505. }
  506. test_mprot_read(MEMPROT_TYPE_IRAM0_SRAM);
  507. test_mprot_write(MEMPROT_TYPE_IRAM0_SRAM);
  508. test_mprot_exec(MEMPROT_TYPE_IRAM0_SRAM);
  509. test_mprot_read(MEMPROT_TYPE_DRAM0_SRAM);
  510. test_mprot_write(MEMPROT_TYPE_DRAM0_SRAM);
  511. test_mprot_read(MEMPROT_TYPE_IRAM0_RTCFAST);
  512. test_mprot_write(MEMPROT_TYPE_IRAM0_RTCFAST);
  513. test_mprot_exec(MEMPROT_TYPE_IRAM0_RTCFAST);
  514. }