test_memprot.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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 <unistd.h>
  8. #include <assert.h>
  9. #include <string.h>
  10. #include "esp_err.h"
  11. #include "esp_system.h"
  12. #include "esp_log.h"
  13. #include "soc/soc.h"
  14. #include "test_memprot.h"
  15. #define RND_VAL (0xA5A5A5A5)
  16. #define SPIN_ITER (16)
  17. extern int _iram_start;
  18. extern int _iram_text_start;
  19. extern int _iram_text_end;
  20. /* NOTE: Naming conventions for RTC_FAST_MEM are
  21. * different for ESP32-C3 and other RISC-V targets
  22. */
  23. #if CONFIG_SOC_RTC_FAST_MEM_SUPPORTED
  24. #if CONFIG_IDF_TARGET_ARCH_RISCV
  25. extern int _rtc_fast_start;
  26. #else
  27. extern int _rtc_text_start;
  28. #endif
  29. extern int _rtc_text_end;
  30. extern int _rtc_force_fast_start;
  31. #endif
  32. #if CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED
  33. extern int _rtc_force_slow_start;
  34. extern int _rtc_data_start;
  35. #endif
  36. /* ---------------------------------------------------- DCACHE Violation Checks ---------------------------------------------------- */
  37. #if SOC_DCACHE_SUPPORTED
  38. /* DCACHE: Internal cache memory accessed via DBUS */
  39. static uint32_t* get_test_dcache_addr(void)
  40. {
  41. uint32_t *dcache_addr = NULL;
  42. #if !CONFIG_ESP32S2_DATA_CACHE_0KB
  43. dcache_addr = (uint32_t *)MAP_IRAM_TO_DRAM((uint32_t)&_iram_start - 0x04);
  44. #endif
  45. return dcache_addr;
  46. }
  47. void test_dcache_read_violation(void)
  48. {
  49. uint32_t *test_addr = get_test_dcache_addr();
  50. printf("DCACHE: Read operation | Address: %p\n", test_addr);
  51. printf("Value : 0x%" PRIx32 "\n", *test_addr);
  52. }
  53. void test_dcache_write_violation(void)
  54. {
  55. uint32_t *test_addr = get_test_dcache_addr();
  56. printf("DCACHE: Write operation | Address: %p\n", test_addr);
  57. *test_addr = RND_VAL;
  58. }
  59. #endif
  60. /* ---------------------------------------------------- IRAM Violation Checks ---------------------------------------------------- */
  61. /* IRAM: I/DCACHE boundary region */
  62. void test_iram_reg1_write_violation(void)
  63. {
  64. uint32_t *test_addr = (uint32_t *)((uint32_t)(&_iram_start) - 0x04);
  65. printf("IRAM: Write operation | Address: %p\n", test_addr);
  66. *test_addr = RND_VAL;
  67. }
  68. /* IRAM: Interrupt vector table region */
  69. void test_iram_reg2_write_violation(void)
  70. {
  71. uint32_t *test_addr = (uint32_t *)((uint32_t)(&_iram_text_start) - 0x04);
  72. printf("IRAM: Write operation | Address: %p\n", test_addr);
  73. *test_addr = RND_VAL;
  74. }
  75. /* IRAM: Text (and data) region */
  76. void test_iram_reg3_write_violation(void)
  77. {
  78. uint32_t *test_addr = (uint32_t *)((uint32_t)(&_iram_text_end) - 0x04);
  79. printf("IRAM: Write operation | Address: %p\n", test_addr);
  80. *test_addr = RND_VAL;
  81. }
  82. /* IRAM: Through the data bus */
  83. void test_iram_reg4_write_violation(void)
  84. {
  85. uint32_t *test_addr = (uint32_t *)MAP_IRAM_TO_DRAM((uint32_t)&_iram_text_end - 0x04);
  86. printf("IRAM: Write operation | Address: %p\n", test_addr);
  87. *test_addr = RND_VAL;
  88. }
  89. /* ---------------------------------------------------- DRAM Violation Checks ---------------------------------------------------- */
  90. static void foo_d(void)
  91. {
  92. for(int i = 0; i < SPIN_ITER; i++)
  93. __asm__ __volatile__("NOP");
  94. }
  95. static DRAM_ATTR uint8_t s_dram_buf[1024];
  96. /* DRAM: Data region (DRAM_ATTR tagged) */
  97. void test_dram_reg1_execute_violation(void)
  98. {
  99. memcpy(&s_dram_buf, &foo_d, sizeof(s_dram_buf));
  100. void (*func_ptr)(void);
  101. func_ptr = (void(*)(void))&s_dram_buf;
  102. printf("DRAM: Execute operation | Address: %p\n", &s_dram_buf);
  103. func_ptr();
  104. }
  105. /* DRAM: Heap region */
  106. void test_dram_reg2_execute_violation(void)
  107. {
  108. uint8_t *instr = calloc(1024, sizeof(uint8_t));
  109. assert(instr != NULL);
  110. printf("DRAM: Execute operation | Address: %p\n", instr);
  111. memcpy(instr, &foo_d, 1024);
  112. void (*func_ptr)(void);
  113. func_ptr = (void(*)(void))instr;
  114. func_ptr();
  115. }
  116. /* ---------------------------------------------------- RTC Violation Checks ---------------------------------------------------- */
  117. #if CONFIG_SOC_RTC_FAST_MEM_SUPPORTED
  118. static RTC_FAST_ATTR uint32_t var_f = RND_VAL;
  119. static RTC_IRAM_ATTR void foo_f(void)
  120. {
  121. for(int i = 0; i < SPIN_ITER; i++)
  122. __asm__ __volatile__("NOP");
  123. }
  124. /* RTC_FAST_MEM: .text section start */
  125. void test_rtc_fast_reg1_execute_violation(void)
  126. {
  127. #if CONFIG_IDF_TARGET_ARCH_RISCV
  128. void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_fast_start);
  129. #else
  130. void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_text_start);
  131. #endif
  132. printf("RTC_MEM (Fast): Execute operation | Address: %p\n", test_addr);
  133. test_addr();
  134. }
  135. /* RTC_FAST_MEM: .text section boundary */
  136. void test_rtc_fast_reg2_execute_violation(void)
  137. {
  138. void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_text_end - 0x04);
  139. printf("RTC_MEM (Fast): Execute operation | Address: %p\n", test_addr);
  140. test_addr();
  141. }
  142. /* RTC_FAST_MEM: .data section */
  143. void test_rtc_fast_reg3_execute_violation(void)
  144. {
  145. void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_force_fast_start + 0x04);
  146. printf("RTC_MEM (Fast): Execute operation | Address: %p\n", test_addr);
  147. test_addr();
  148. }
  149. #endif
  150. #if CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED
  151. static RTC_SLOW_ATTR uint32_t var_s = RND_VAL;
  152. static RTC_SLOW_ATTR void foo_s(void)
  153. {
  154. for(int i = 0; i < SPIN_ITER; i++)
  155. __asm__ __volatile__("NOP");
  156. }
  157. /* RTC_SLOW_MEM: Data tagged with RTC_SLOW_ATTR */
  158. void test_rtc_slow_reg1_execute_violation(void)
  159. {
  160. void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_force_slow_start);
  161. printf("RTC_MEM (Slow): Execute operation | Address: %p\n", test_addr);
  162. test_addr();
  163. }
  164. /* RTC_SLOW_MEM: Region start */
  165. void test_rtc_slow_reg2_execute_violation(void)
  166. {
  167. void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_data_start);
  168. printf("RTC_MEM (Slow): Execute operation | Address: %p\n", test_addr);
  169. test_addr();
  170. }
  171. #endif
  172. static void __attribute__((constructor)) test_print_rtc_var_func(void)
  173. {
  174. #if CONFIG_SOC_RTC_FAST_MEM_SUPPORTED
  175. printf("foo_f: %p | var_f: %p\n", &foo_f, &var_f);
  176. #endif
  177. #if CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED
  178. printf("foo_s: %p | var_s: %p\n", &foo_s, &var_s);
  179. #endif
  180. }