| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- /*
- * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <stdio.h>
- #include <unistd.h>
- #include <assert.h>
- #include <string.h>
- #include "esp_err.h"
- #include "esp_system.h"
- #include "esp_log.h"
- #include "soc/soc.h"
- #include "test_memprot.h"
- #define RND_VAL (0xA5A5A5A5)
- #define SPIN_ITER (16)
- extern int _iram_start;
- extern int _iram_text_start;
- extern int _iram_text_end;
- /* NOTE: Naming conventions for RTC_FAST_MEM are
- * different for ESP32-C3 and other RISC-V targets
- */
- #if CONFIG_SOC_RTC_FAST_MEM_SUPPORTED
- #if CONFIG_IDF_TARGET_ARCH_RISCV
- extern int _rtc_fast_start;
- #else
- extern int _rtc_text_start;
- #endif
- extern int _rtc_text_end;
- extern int _rtc_force_fast_start;
- #endif
- #if CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED
- extern int _rtc_force_slow_start;
- extern int _rtc_data_start;
- #endif
- /* ---------------------------------------------------- DCACHE Violation Checks ---------------------------------------------------- */
- #if SOC_DCACHE_SUPPORTED
- /* DCACHE: Internal cache memory accessed via DBUS */
- static uint32_t* get_test_dcache_addr(void)
- {
- uint32_t *dcache_addr = NULL;
- #if !CONFIG_ESP32S2_DATA_CACHE_0KB
- dcache_addr = (uint32_t *)MAP_IRAM_TO_DRAM((uint32_t)&_iram_start - 0x04);
- #endif
- return dcache_addr;
- }
- void test_dcache_read_violation(void)
- {
- uint32_t *test_addr = get_test_dcache_addr();
- printf("DCACHE: Read operation | Address: %p\n", test_addr);
- printf("Value : 0x%" PRIx32 "\n", *test_addr);
- }
- void test_dcache_write_violation(void)
- {
- uint32_t *test_addr = get_test_dcache_addr();
- printf("DCACHE: Write operation | Address: %p\n", test_addr);
- *test_addr = RND_VAL;
- }
- #endif
- /* ---------------------------------------------------- IRAM Violation Checks ---------------------------------------------------- */
- /* IRAM: I/DCACHE boundary region */
- void test_iram_reg1_write_violation(void)
- {
- uint32_t *test_addr = (uint32_t *)((uint32_t)(&_iram_start) - 0x04);
- printf("IRAM: Write operation | Address: %p\n", test_addr);
- *test_addr = RND_VAL;
- }
- /* IRAM: Interrupt vector table region */
- void test_iram_reg2_write_violation(void)
- {
- uint32_t *test_addr = (uint32_t *)((uint32_t)(&_iram_text_start) - 0x04);
- printf("IRAM: Write operation | Address: %p\n", test_addr);
- *test_addr = RND_VAL;
- }
- /* IRAM: Text (and data) region */
- void test_iram_reg3_write_violation(void)
- {
- uint32_t *test_addr = (uint32_t *)((uint32_t)(&_iram_text_end) - 0x04);
- printf("IRAM: Write operation | Address: %p\n", test_addr);
- *test_addr = RND_VAL;
- }
- /* IRAM: Through the data bus */
- void test_iram_reg4_write_violation(void)
- {
- uint32_t *test_addr = (uint32_t *)MAP_IRAM_TO_DRAM((uint32_t)&_iram_text_end - 0x04);
- printf("IRAM: Write operation | Address: %p\n", test_addr);
- *test_addr = RND_VAL;
- }
- /* ---------------------------------------------------- DRAM Violation Checks ---------------------------------------------------- */
- static void foo_d(void)
- {
- for(int i = 0; i < SPIN_ITER; i++)
- __asm__ __volatile__("NOP");
- }
- static DRAM_ATTR uint8_t s_dram_buf[1024];
- /* DRAM: Data region (DRAM_ATTR tagged) */
- void test_dram_reg1_execute_violation(void)
- {
- memcpy(&s_dram_buf, &foo_d, sizeof(s_dram_buf));
- void (*func_ptr)(void);
- func_ptr = (void(*)(void))&s_dram_buf;
- printf("DRAM: Execute operation | Address: %p\n", &s_dram_buf);
- func_ptr();
- }
- /* DRAM: Heap region */
- void test_dram_reg2_execute_violation(void)
- {
- uint8_t *instr = calloc(1024, sizeof(uint8_t));
- assert(instr != NULL);
- printf("DRAM: Execute operation | Address: %p\n", instr);
- memcpy(instr, &foo_d, 1024);
- void (*func_ptr)(void);
- func_ptr = (void(*)(void))instr;
- func_ptr();
- }
- /* ---------------------------------------------------- RTC Violation Checks ---------------------------------------------------- */
- #if CONFIG_SOC_RTC_FAST_MEM_SUPPORTED
- static RTC_FAST_ATTR uint32_t var_f = RND_VAL;
- static RTC_IRAM_ATTR void foo_f(void)
- {
- for(int i = 0; i < SPIN_ITER; i++)
- __asm__ __volatile__("NOP");
- }
- /* RTC_FAST_MEM: .text section start */
- void test_rtc_fast_reg1_execute_violation(void)
- {
- #if CONFIG_IDF_TARGET_ARCH_RISCV
- void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_fast_start);
- #else
- void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_text_start);
- #endif
- printf("RTC_MEM (Fast): Execute operation | Address: %p\n", test_addr);
- test_addr();
- }
- /* RTC_FAST_MEM: .text section boundary */
- void test_rtc_fast_reg2_execute_violation(void)
- {
- void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_text_end - 0x04);
- printf("RTC_MEM (Fast): Execute operation | Address: %p\n", test_addr);
- test_addr();
- }
- /* RTC_FAST_MEM: .data section */
- void test_rtc_fast_reg3_execute_violation(void)
- {
- void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_force_fast_start + 0x04);
- printf("RTC_MEM (Fast): Execute operation | Address: %p\n", test_addr);
- test_addr();
- }
- #endif
- #if CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED
- static RTC_SLOW_ATTR uint32_t var_s = RND_VAL;
- static RTC_SLOW_ATTR void foo_s(void)
- {
- for(int i = 0; i < SPIN_ITER; i++)
- __asm__ __volatile__("NOP");
- }
- /* RTC_SLOW_MEM: Data tagged with RTC_SLOW_ATTR */
- void test_rtc_slow_reg1_execute_violation(void)
- {
- void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_force_slow_start);
- printf("RTC_MEM (Slow): Execute operation | Address: %p\n", test_addr);
- test_addr();
- }
- /* RTC_SLOW_MEM: Region start */
- void test_rtc_slow_reg2_execute_violation(void)
- {
- void (*test_addr)(void) = (void(*)(void))((uint32_t)&_rtc_data_start);
- printf("RTC_MEM (Slow): Execute operation | Address: %p\n", test_addr);
- test_addr();
- }
- #endif
- static void __attribute__((constructor)) test_print_rtc_var_func(void)
- {
- #if CONFIG_SOC_RTC_FAST_MEM_SUPPORTED
- printf("foo_f: %p | var_f: %p\n", &foo_f, &var_f);
- #endif
- #if CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED
- printf("foo_s: %p | var_s: %p\n", &foo_s, &var_s);
- #endif
- }
|