test_memprot_main.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. /* MEMPROT IramDram testing code */
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "sdkconfig.h"
  5. #include "esp_log.h"
  6. #include "spi_flash_mmap.h"
  7. #include "esp32s2/memprot.h"
  8. #include "soc/soc.h"
  9. /*
  10. * ESP32S2 MEMORY PROTECTION MODULE TEST
  11. * =====================================
  12. *
  13. * In order to safely test all the mem_prot features configuration, this test uses a combination of
  14. * proprietary settings and ESP-IDF defaults.
  15. * Each operation is tested at both low region and high region testing address.
  16. * Complete testing scheme is depicted below:
  17. *
  18. * ********************************************************************************************
  19. *
  20. * IRAM0 SRAM (320kB) DRAM0
  21. * ===========================
  22. * | |
  23. * |-------------------------|
  24. * | iram_test_buffer (1kB) |
  25. * <---------- test addr low -------> iram_test_buffer + 0x200
  26. * | |
  27. * _iram_text_end <======== real splt.addr ========> _data_start (real splt.addr == test splt.addr)
  28. * | |
  29. * <---|-------------------------|-->
  30. * | dram_test_buffer (1kB) |
  31. * <--------- test addr high -------> dram_test_buffer + 0x200
  32. * | ... |
  33. * |-------------------------|
  34. * | |
  35. * ===========================
  36. *
  37. * RTC_FAST (8kB)
  38. * ===========================
  39. * _rtc_text_end <======== real splt.addr ========> _rtc_dummy_end
  40. * | rtcfast_dummy_buffer |
  41. * | (2kB) |
  42. * <---------- test addr low -------> test_buffer - 0x200
  43. * <-------- test splt.addr --------> test_buffer = rtcfast_dummy_buffer / 2
  44. * <---------- test addr low -------> test_buffer + 0x200
  45. * |-------------------------|
  46. * | |
  47. * ===========================
  48. *
  49. * ********************************************************************************************
  50. *
  51. * PERIBUS_1 RTC_SLOW (8/768kB) PERIBUS_2_0 PERIBUS_2_1
  52. * ===========================
  53. * | |
  54. * 0x3F421000 <======== real splt.addr ========> 0x50000000 0x60021000
  55. * | rtcslow_dummy_buffer |
  56. * | (2kB) |
  57. * <---------- test addr low -------> test_buffer - 0x200
  58. * <-------- test splt.addr --------> test_buffer = rtcslow_dummy_buffer / 2
  59. * <---------- test addr low -------> test_buffer + 0x200
  60. * |-------------------------|
  61. * | |
  62. * ===========================
  63. *
  64. * ********************************************************************************************
  65. */
  66. /* !!!IMPORTANT!!!
  67. * a0 needs to be saved/restored manually (not clobbered) to avoid return address corruption
  68. * caused by ASM block handling
  69. */
  70. #define CODE_EXEC(code_buf, param, res) \
  71. asm volatile ( \
  72. "mov a3, a0\n\t" \
  73. "movi a2," #param "\n\t" \
  74. "callx0 %1\n\t" \
  75. "mov %0,a2\n\t" \
  76. "mov a0, a3\n\t" \
  77. : "=r"(res) \
  78. : "r"(code_buf) \
  79. : "a2", "a3" );
  80. /* Binary code for the following asm:
  81. *
  82. .type _testfunc,@function
  83. .global _testfunc
  84. .align 4
  85. _testfunc:
  86. slli a2, a2, 1
  87. ret.n
  88. */
  89. static uint8_t fnc_call0_buff[] = {0xf0, 0x22, 0x11, 0x0d, 0xf0, 0x00, 0x00, 0x00};
  90. volatile bool g_override_illegal_instruction = false;
  91. #define SRAM_TEST_BUFFER_SIZE 0x400
  92. #define SRAM_TEST_OFFSET 0x200
  93. static uint8_t __attribute__((section(".iram_end_test"))) iram_test_buffer[SRAM_TEST_BUFFER_SIZE] = {0};
  94. static uint8_t dram_test_buffer[SRAM_TEST_BUFFER_SIZE] = {0};
  95. static uint8_t RTC_FAST_ATTR rtcfast_dummy_buffer[2 * SRAM_TEST_BUFFER_SIZE] = {0};
  96. static uint8_t RTC_SLOW_ATTR rtcslow_dummy_buffer[2 * SRAM_TEST_BUFFER_SIZE] = {0};
  97. /* ********************************************************************************************
  98. * testing regions and splitting address scheme
  99. *
  100. */
  101. static uint32_t *test_memprot_dram0_rtcfast_get_min_split_addr(void)
  102. {
  103. return (uint32_t *)(rtcfast_dummy_buffer + sizeof(rtcfast_dummy_buffer) / 2);
  104. }
  105. static uint32_t *test_memprot_iram0_rtcfast_get_min_split_addr(void)
  106. {
  107. return (uint32_t *)
  108. ((uint32_t)test_memprot_dram0_rtcfast_get_min_split_addr()
  109. + esp_memprot_get_low_limit(MEMPROT_IRAM0_RTCFAST)
  110. - esp_memprot_get_low_limit(MEMPROT_DRAM0_RTCFAST));
  111. }
  112. static uint32_t *test_memprot_peri2_rtcslow_0_get_min_split_addr(void)
  113. {
  114. return (uint32_t *)(rtcslow_dummy_buffer + sizeof(rtcslow_dummy_buffer) / 2);
  115. }
  116. static uint32_t *test_memprot_peri1_rtcslow_get_min_split_addr(void)
  117. {
  118. return (uint32_t *)
  119. ((uint32_t)test_memprot_peri2_rtcslow_0_get_min_split_addr()
  120. - (esp_memprot_get_low_limit(MEMPROT_PERI2_RTCSLOW_0)
  121. - esp_memprot_get_low_limit(MEMPROT_PERI1_RTCSLOW)));
  122. }
  123. static uint32_t *test_memprot_peri2_rtcslow_1_get_min_split_addr(void)
  124. {
  125. return (uint32_t *)
  126. ((uint32_t)test_memprot_peri2_rtcslow_0_get_min_split_addr()
  127. + esp_memprot_get_low_limit(MEMPROT_PERI2_RTCSLOW_1)
  128. - esp_memprot_get_low_limit(MEMPROT_PERI2_RTCSLOW_0));
  129. }
  130. static uint32_t *test_memprot_addr_low(mem_type_prot_t mem_type)
  131. {
  132. switch ( mem_type ) {
  133. case MEMPROT_IRAM0_SRAM:
  134. return (uint32_t *)((uint32_t)iram_test_buffer + SRAM_TEST_OFFSET);
  135. case MEMPROT_DRAM0_SRAM:
  136. return (uint32_t *)MAP_IRAM_TO_DRAM((uint32_t)iram_test_buffer + SRAM_TEST_OFFSET);
  137. case MEMPROT_IRAM0_RTCFAST:
  138. return (uint32_t *)((uint32_t)test_memprot_iram0_rtcfast_get_min_split_addr() - SRAM_TEST_OFFSET);
  139. case MEMPROT_DRAM0_RTCFAST:
  140. return (uint32_t *)((uint32_t)test_memprot_dram0_rtcfast_get_min_split_addr() - SRAM_TEST_OFFSET);
  141. case MEMPROT_PERI1_RTCSLOW:
  142. return (uint32_t *)((uint32_t)test_memprot_peri1_rtcslow_get_min_split_addr() - SRAM_TEST_OFFSET);
  143. case MEMPROT_PERI2_RTCSLOW_0:
  144. return (uint32_t *)((uint32_t)test_memprot_peri2_rtcslow_0_get_min_split_addr() - SRAM_TEST_OFFSET);
  145. case MEMPROT_PERI2_RTCSLOW_1:
  146. return (uint32_t *)((uint32_t)test_memprot_peri2_rtcslow_1_get_min_split_addr() - SRAM_TEST_OFFSET);
  147. default:
  148. abort();
  149. }
  150. }
  151. static uint32_t *test_memprot_addr_high(mem_type_prot_t mem_type)
  152. {
  153. switch ( mem_type ) {
  154. case MEMPROT_IRAM0_SRAM:
  155. return (uint32_t *)MAP_DRAM_TO_IRAM((uint32_t)dram_test_buffer + SRAM_TEST_OFFSET);
  156. case MEMPROT_DRAM0_SRAM:
  157. return (uint32_t *)((uint32_t)dram_test_buffer + SRAM_TEST_OFFSET);
  158. case MEMPROT_IRAM0_RTCFAST:
  159. return (uint32_t *)((uint32_t)test_memprot_iram0_rtcfast_get_min_split_addr() + SRAM_TEST_OFFSET);
  160. case MEMPROT_DRAM0_RTCFAST:
  161. return (uint32_t *)((uint32_t)test_memprot_dram0_rtcfast_get_min_split_addr() + SRAM_TEST_OFFSET);
  162. case MEMPROT_PERI1_RTCSLOW:
  163. return (uint32_t *)((uint32_t)test_memprot_peri1_rtcslow_get_min_split_addr() + SRAM_TEST_OFFSET);
  164. case MEMPROT_PERI2_RTCSLOW_0:
  165. return (uint32_t *)((uint32_t)test_memprot_peri2_rtcslow_0_get_min_split_addr() + SRAM_TEST_OFFSET);
  166. case MEMPROT_PERI2_RTCSLOW_1:
  167. return (uint32_t *)((uint32_t)test_memprot_peri2_rtcslow_1_get_min_split_addr() + SRAM_TEST_OFFSET);
  168. default:
  169. abort();
  170. }
  171. }
  172. static uint32_t *test_memprot_get_split_addr(mem_type_prot_t mem_type)
  173. {
  174. switch (mem_type) {
  175. case MEMPROT_IRAM0_SRAM:
  176. return esp_memprot_get_split_addr(MEMPROT_IRAM0_SRAM);
  177. case MEMPROT_DRAM0_SRAM:
  178. return esp_memprot_get_split_addr(MEMPROT_DRAM0_SRAM);
  179. case MEMPROT_IRAM0_RTCFAST:
  180. return test_memprot_iram0_rtcfast_get_min_split_addr();
  181. case MEMPROT_DRAM0_RTCFAST:
  182. return test_memprot_dram0_rtcfast_get_min_split_addr();
  183. case MEMPROT_PERI1_RTCSLOW:
  184. return test_memprot_peri1_rtcslow_get_min_split_addr();
  185. case MEMPROT_PERI2_RTCSLOW_0:
  186. return test_memprot_peri2_rtcslow_0_get_min_split_addr();
  187. case MEMPROT_PERI2_RTCSLOW_1:
  188. return test_memprot_peri2_rtcslow_1_get_min_split_addr();
  189. default:
  190. abort();
  191. }
  192. }
  193. /*
  194. * testing setup of the memory-protection module
  195. */
  196. static void test_memprot_set_prot(uint32_t *mem_type_mask, bool use_panic_handler)
  197. {
  198. //any IRAM0/DRAM0 enable/disable call applies to all memory modules connected
  199. uint32_t required_mem_prot = mem_type_mask == NULL ? (uint32_t)MEMPROT_ALL : *mem_type_mask;
  200. bool use_iram0 = required_mem_prot & MEMPROT_IRAM0_SRAM || required_mem_prot & MEMPROT_IRAM0_RTCFAST;
  201. bool use_dram0 = required_mem_prot & MEMPROT_DRAM0_SRAM || required_mem_prot & MEMPROT_DRAM0_RTCFAST;
  202. bool use_peri1 = required_mem_prot & MEMPROT_PERI1_RTCSLOW;
  203. bool use_peri2 = required_mem_prot & MEMPROT_PERI2_RTCSLOW_0 || required_mem_prot & MEMPROT_PERI2_RTCSLOW_1;
  204. //disable protection
  205. if (use_iram0) {
  206. esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, false);
  207. }
  208. if (use_dram0) {
  209. esp_memprot_intr_ena(MEMPROT_DRAM0_SRAM, false);
  210. }
  211. if (use_peri1) {
  212. esp_memprot_intr_ena(MEMPROT_PERI1_RTCSLOW, false);
  213. }
  214. if (use_peri2) {
  215. esp_memprot_intr_ena(MEMPROT_PERI2_RTCSLOW_0, false);
  216. }
  217. if ( use_panic_handler ) {
  218. if (use_iram0) {
  219. esp_memprot_intr_init(MEMPROT_IRAM0_SRAM);
  220. }
  221. if (use_dram0) {
  222. esp_memprot_intr_init(MEMPROT_DRAM0_SRAM);
  223. }
  224. if (use_peri1) {
  225. esp_memprot_intr_init(MEMPROT_PERI1_RTCSLOW);
  226. }
  227. if (use_peri2) {
  228. esp_memprot_intr_init(MEMPROT_PERI2_RTCSLOW_0);
  229. }
  230. }
  231. //set permissions
  232. if (required_mem_prot & MEMPROT_IRAM0_SRAM) {
  233. esp_memprot_set_prot_iram(MEMPROT_IRAM0_SRAM, DEF_SPLIT_LINE, WR_LOW_DIS, RD_LOW_ENA, EX_LOW_ENA, WR_HIGH_DIS, RD_HIGH_DIS, EX_HIGH_DIS);
  234. }
  235. if (required_mem_prot & MEMPROT_IRAM0_RTCFAST) {
  236. esp_memprot_set_prot_iram(MEMPROT_IRAM0_RTCFAST, test_memprot_iram0_rtcfast_get_min_split_addr(), WR_LOW_DIS, RD_LOW_ENA, EX_LOW_ENA, WR_HIGH_DIS, RD_HIGH_DIS, EX_HIGH_DIS);
  237. }
  238. if (required_mem_prot & MEMPROT_DRAM0_SRAM) {
  239. esp_memprot_set_prot_dram(MEMPROT_DRAM0_SRAM, DEF_SPLIT_LINE, WR_LOW_DIS, RD_LOW_ENA, WR_HIGH_ENA, RD_HIGH_ENA);
  240. }
  241. if (required_mem_prot & MEMPROT_DRAM0_RTCFAST) {
  242. esp_memprot_set_prot_dram(MEMPROT_DRAM0_RTCFAST, test_memprot_dram0_rtcfast_get_min_split_addr(), WR_LOW_DIS, RD_LOW_ENA, WR_HIGH_ENA, RD_HIGH_ENA);
  243. }
  244. if (required_mem_prot & MEMPROT_PERI1_RTCSLOW) {
  245. esp_memprot_set_prot_peri1(MEMPROT_PERI1_RTCSLOW, test_memprot_peri1_rtcslow_get_min_split_addr(), WR_LOW_DIS, RD_LOW_DIS, RD_HIGH_DIS, WR_HIGH_DIS);
  246. }
  247. if (required_mem_prot & MEMPROT_PERI2_RTCSLOW_0) {
  248. esp_memprot_set_prot_peri2(MEMPROT_PERI2_RTCSLOW_0, test_memprot_peri2_rtcslow_0_get_min_split_addr(), WR_LOW_ENA, RD_LOW_ENA, EX_LOW_DIS, WR_HIGH_ENA, RD_HIGH_ENA, EX_HIGH_DIS);
  249. }
  250. if (required_mem_prot & MEMPROT_PERI2_RTCSLOW_1) {
  251. esp_memprot_set_prot_peri2(MEMPROT_PERI2_RTCSLOW_1, test_memprot_peri2_rtcslow_1_get_min_split_addr(), WR_LOW_DIS, RD_LOW_DIS, EX_LOW_DIS, WR_HIGH_DIS, RD_HIGH_DIS, EX_HIGH_DIS);
  252. }
  253. //reenable protection (bus based)
  254. if (use_iram0) {
  255. esp_memprot_intr_ena(MEMPROT_IRAM0_SRAM, true);
  256. }
  257. if (use_dram0) {
  258. esp_memprot_intr_ena(MEMPROT_DRAM0_SRAM, true);
  259. }
  260. if (use_peri1) {
  261. esp_memprot_intr_ena(MEMPROT_PERI1_RTCSLOW, true);
  262. }
  263. if (use_peri2) {
  264. esp_memprot_intr_ena(MEMPROT_PERI2_RTCSLOW_0, true);
  265. }
  266. }
  267. /* ********************************************************************************************
  268. * auxiliary functions
  269. */
  270. static void __attribute__((unused)) dump_fnc_buff(uint32_t *buff)
  271. {
  272. esp_rom_printf( "0x%08X: 0x%08X-0x%08X\n", (uint32_t)buff, buff[0], buff[1] );
  273. }
  274. static void __attribute__((unused)) dump_bus_permissions(mem_type_prot_t mem_type)
  275. {
  276. bool write_perm_low, write_perm_high, read_perm_low, read_perm_high, exec_perm_low, exec_perm_high;
  277. esp_memprot_get_permissions(mem_type, &write_perm_low, &write_perm_high, &read_perm_low, &read_perm_high, &exec_perm_low, &exec_perm_high);
  278. esp_rom_printf("%s permissions: LW=%u LR=%u LX=%u HW=%u HR=%u HX=%u\n", esp_memprot_type_to_str(mem_type),
  279. write_perm_low, read_perm_low, exec_perm_low, write_perm_high, read_perm_high, exec_perm_high);
  280. }
  281. static void __attribute__((unused)) dump_status_register(mem_type_prot_t mem_type)
  282. {
  283. uint32_t *faulting_address, op_type, op_subtype;
  284. esp_err_t res = esp_memprot_get_fault_status(mem_type, &faulting_address, &op_type, &op_subtype);
  285. if ( res == ESP_OK ) {
  286. uint32_t fault_reg;
  287. res = esp_memprot_get_fault_reg(mem_type, &fault_reg);
  288. esp_rom_printf(
  289. " FAULT [split addr: 0x%08X, fault addr: 0x%08X, fault status: ",
  290. (uint32_t) test_memprot_get_split_addr(mem_type),
  291. (uint32_t) faulting_address
  292. );
  293. if ( res == ESP_OK ) {
  294. esp_rom_printf("0x%08X]\n", fault_reg );
  295. } else {
  296. esp_rom_printf("<failed, err: 0x%08X>]\n", res );
  297. }
  298. } else {
  299. esp_rom_printf(" FAULT [failed to get fault details, error 0x%08X]\n", res);
  300. }
  301. }
  302. /* ********************************************************************************************
  303. * testing functions
  304. */
  305. static void check_test_result(mem_type_prot_t mem_type, bool expected_status)
  306. {
  307. uint32_t fault;
  308. esp_err_t res = esp_memprot_get_fault_reg(mem_type, &fault);
  309. if ( res == ESP_OK ) {
  310. bool test_result = expected_status ? fault == 0 : fault != 0;
  311. if (test_result) {
  312. esp_rom_printf("OK\n");
  313. } else {
  314. dump_status_register(mem_type);
  315. }
  316. } else {
  317. esp_rom_printf(" FAULT [failed to get test results, error 0x%08X]\n", res);
  318. }
  319. }
  320. static void test_memprot_read(mem_type_prot_t mem_type)
  321. {
  322. //get current READ & WRITE permission settings
  323. bool write_perm_low, write_perm_high, read_perm_low, read_perm_high;
  324. esp_memprot_get_perm_write(mem_type, &write_perm_low, &write_perm_high);
  325. esp_memprot_get_perm_read(mem_type, &read_perm_low, &read_perm_high);
  326. volatile uint32_t *ptr_low = test_memprot_addr_low(mem_type);
  327. volatile uint32_t *ptr_high = test_memprot_addr_high(mem_type);
  328. //temporarily allow WRITE for setting the test values
  329. esp_memprot_set_write_perm(mem_type, true, true);
  330. const uint32_t test_val = 100;
  331. *ptr_low = test_val;
  332. *ptr_high = test_val + 1;
  333. esp_memprot_set_write_perm(mem_type, write_perm_low, write_perm_high);
  334. //perform READ in low region
  335. esp_rom_printf("%s read low: ", esp_memprot_type_to_str(mem_type));
  336. esp_memprot_clear_intr(mem_type);
  337. volatile uint32_t val = *ptr_low;
  338. if ( val != 0 && val != test_val ) {
  339. esp_rom_printf( "UNEXPECTED VALUE 0x%08X -", val );
  340. dump_status_register(mem_type);
  341. } else {
  342. check_test_result(mem_type, val == test_val);
  343. }
  344. //perform read in high region
  345. esp_rom_printf("%s read high: ", esp_memprot_type_to_str(mem_type));
  346. esp_memprot_clear_intr(mem_type);
  347. val = *ptr_high;
  348. if ( val != 0 && val != (test_val + 1) ) {
  349. esp_rom_printf( "UNEXPECTED VALUE 0x%08X -", val);
  350. dump_status_register(mem_type);
  351. } else {
  352. check_test_result(mem_type, val == (test_val + 1));
  353. }
  354. }
  355. static void test_memprot_write(mem_type_prot_t mem_type)
  356. {
  357. //get current READ & WRITE permission settings
  358. bool write_perm_low, write_perm_high, read_perm_low, read_perm_high;
  359. esp_memprot_get_perm_write(mem_type, &write_perm_low, &write_perm_high);
  360. esp_memprot_get_perm_read(mem_type, &read_perm_low, &read_perm_high);
  361. //temporarily allow READ operation
  362. esp_memprot_set_read_perm(mem_type, true, true);
  363. volatile uint32_t *ptr_low = test_memprot_addr_low(mem_type);
  364. volatile uint32_t *ptr_high = test_memprot_addr_high(mem_type);
  365. //perform WRITE in low region
  366. const uint32_t test_val = 10;
  367. esp_rom_printf("%s write low: ", esp_memprot_type_to_str(mem_type));
  368. esp_memprot_clear_intr(mem_type);
  369. volatile uint32_t val = 0;
  370. *ptr_low = test_val;
  371. val = *ptr_low;
  372. if ( val != test_val && write_perm_low ) {
  373. esp_rom_printf( "UNEXPECTED VALUE 0x%08X -", val);
  374. dump_status_register(mem_type);
  375. } else {
  376. check_test_result(mem_type, write_perm_low);
  377. }
  378. //perform WRITE in high region
  379. esp_rom_printf("%s write high: ", esp_memprot_type_to_str(mem_type));
  380. esp_memprot_clear_intr(mem_type);
  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. dump_status_register(mem_type);
  387. } else {
  388. check_test_result(mem_type, write_perm_high);
  389. }
  390. esp_memprot_set_read_perm(mem_type, read_perm_low, read_perm_high);
  391. }
  392. static void test_memprot_exec(mem_type_prot_t mem_type)
  393. {
  394. //store current write permissions
  395. bool write_perm_low, write_perm_high;
  396. esp_memprot_get_perm_write(mem_type, &write_perm_low, &write_perm_high);
  397. //get current EXEC permission settings
  398. bool exec_perm_low, exec_perm_high;
  399. esp_memprot_get_perm_exec(mem_type, &exec_perm_low, &exec_perm_high);
  400. volatile uint32_t *fnc_ptr_low = test_memprot_addr_low(mem_type);
  401. volatile uint32_t *fnc_ptr_high = test_memprot_addr_high(mem_type);
  402. //enable WRITE permission for both segments
  403. esp_memprot_set_write_perm(mem_type, true, true);
  404. //inject the code to both low & high segments
  405. memcpy( (void *)fnc_ptr_low, fnc_call0_buff, sizeof(fnc_call0_buff) );
  406. memcpy( (void *)fnc_ptr_high, fnc_call0_buff, sizeof(fnc_call0_buff) );
  407. //restore original WRITE perms
  408. esp_memprot_set_write_perm(mem_type, write_perm_low, write_perm_high);
  409. uint32_t res = 0;
  410. //LOW REGION: clear the intr flag & try to execute the code injected
  411. esp_memprot_clear_intr(mem_type);
  412. esp_rom_printf("%s exec low: ", esp_memprot_type_to_str(mem_type));
  413. g_override_illegal_instruction = true;
  414. CODE_EXEC(fnc_ptr_low, 5, res);
  415. g_override_illegal_instruction = false;
  416. //check results
  417. bool fnc_call_ok = res == 10;
  418. if ( fnc_call_ok ) {
  419. check_test_result(mem_type, exec_perm_low);
  420. } else {
  421. if ( !exec_perm_low ) {
  422. check_test_result(mem_type, false);
  423. } else {
  424. esp_rom_printf(" FAULT [injected code not executed]\n");
  425. }
  426. }
  427. //HIGH REGION: clear the intr flag & try to execute the code injected
  428. esp_memprot_clear_intr(mem_type);
  429. esp_rom_printf("%s exec high: ", esp_memprot_type_to_str(mem_type));
  430. g_override_illegal_instruction = true;
  431. CODE_EXEC(fnc_ptr_high, 6, res);
  432. g_override_illegal_instruction = false;
  433. fnc_call_ok = res == 12;
  434. if ( fnc_call_ok ) {
  435. check_test_result(mem_type, exec_perm_high);
  436. } else {
  437. if ( !exec_perm_high ) {
  438. check_test_result(mem_type, false);
  439. } else {
  440. esp_rom_printf(" FAULT [injected code not executed]\n");
  441. }
  442. }
  443. }
  444. /* ********************************************************************************************
  445. * main test runner
  446. */
  447. void app_main(void)
  448. {
  449. test_memprot_set_prot(NULL, false);
  450. test_memprot_read(MEMPROT_IRAM0_SRAM);
  451. test_memprot_write(MEMPROT_IRAM0_SRAM);
  452. test_memprot_exec(MEMPROT_IRAM0_SRAM);
  453. test_memprot_read(MEMPROT_IRAM0_RTCFAST);
  454. test_memprot_write(MEMPROT_IRAM0_RTCFAST);
  455. test_memprot_exec(MEMPROT_IRAM0_RTCFAST);
  456. test_memprot_read(MEMPROT_DRAM0_SRAM);
  457. test_memprot_write(MEMPROT_DRAM0_SRAM);
  458. test_memprot_read(MEMPROT_DRAM0_RTCFAST);
  459. test_memprot_write(MEMPROT_DRAM0_RTCFAST);
  460. test_memprot_read(MEMPROT_PERI1_RTCSLOW);
  461. test_memprot_write(MEMPROT_PERI1_RTCSLOW);
  462. test_memprot_read(MEMPROT_PERI2_RTCSLOW_0);
  463. test_memprot_write(MEMPROT_PERI2_RTCSLOW_0);
  464. test_memprot_exec(MEMPROT_PERI2_RTCSLOW_0);
  465. test_memprot_read(MEMPROT_PERI2_RTCSLOW_1);
  466. test_memprot_write(MEMPROT_PERI2_RTCSLOW_1);
  467. test_memprot_exec(MEMPROT_PERI2_RTCSLOW_1);
  468. }