mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(cpu_region_protect): Extend PMP memprot for ESP32-P4 V3
This commit is contained in:
@@ -15,6 +15,9 @@
|
|||||||
#include "esp_private/esp_psram_extram.h"
|
#include "esp_private/esp_psram_extram.h"
|
||||||
#endif /* CONFIG_SPIRAM */
|
#endif /* CONFIG_SPIRAM */
|
||||||
|
|
||||||
|
#include "soc/chip_revision.h"
|
||||||
|
#include "hal/config.h"
|
||||||
|
|
||||||
#ifdef BOOTLOADER_BUILD
|
#ifdef BOOTLOADER_BUILD
|
||||||
// Without L bit set
|
// Without L bit set
|
||||||
#define CONDITIONAL_NONE 0x0
|
#define CONDITIONAL_NONE 0x0
|
||||||
@@ -82,70 +85,160 @@ static void esp_cpu_configure_invalid_regions(void)
|
|||||||
PMA_RESET_AND_ENTRY_SET_TOR(15, UINT32_MAX, PMA_TOR | PMA_NONE);
|
PMA_RESET_AND_ENTRY_SET_TOR(15, UINT32_MAX, PMA_TOR | PMA_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void esp_cpu_configure_region_protection(void)
|
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||||
{
|
// Helper macro to set both cached and non-cached PMP entries with the same permissions
|
||||||
/* Notes on implementation:
|
#define PMP_ENTRY_SET_CACHED_AND_UNCACHED(cached_entry, non_cached_entry, addr, perm) \
|
||||||
*
|
do { \
|
||||||
* 1) Note: ESP32-P4 CPU support overlapping PMP regions, configuration is based on static priority
|
PMP_RESET_AND_ENTRY_SET(cached_entry, addr, perm); \
|
||||||
* feature (lowest numbered entry has highest priority).
|
PMP_RESET_AND_ENTRY_SET(non_cached_entry, CACHE_LL_L2MEM_NON_CACHE_ADDR(addr), perm); \
|
||||||
*
|
} while(0)
|
||||||
* 2) ESP32-P4 supports 16 PMA regions so we use this feature to block the invalid address ranges.
|
|
||||||
* However the entries are not sufficient to block all reserved memory ranges and the excluded sections are:
|
|
||||||
* a. Region between LP ROM and LP SRAM
|
|
||||||
* b. Region between LP peripherals and External flash (direct access)
|
|
||||||
* c. Region between External flash (direct access) and External RAM (direct access)
|
|
||||||
* d. Region between External RAM (direct access) and HP ROM (direct access)
|
|
||||||
* e. Region between HP ROM (direct access) and HP L2MEM (direct access)
|
|
||||||
*
|
|
||||||
* 3) We use combination of NAPOT (Naturally Aligned Power Of Two) and TOR (top of range)
|
|
||||||
* entries to map all the valid address space, bottom to top. This leaves us with some extra PMP entries
|
|
||||||
* which can be used to provide more granular access
|
|
||||||
*
|
|
||||||
* 4) Entries are grouped in order with some static asserts to try and verify everything is
|
|
||||||
* correct.
|
|
||||||
*
|
|
||||||
* 5) No explicit permission specified in PMP (default all permissions) for following regions due to
|
|
||||||
* limited entries:
|
|
||||||
* a. External RAM
|
|
||||||
* b. LP ROM, LP Peripherals, LP SRAM
|
|
||||||
* c. External flash, External RAM, HP ROM, HP L2MEM (direct access)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* There are 4 configuration scenarios for SRAM
|
static void esp_cpu_configure_region_protection_rev_v3(void)
|
||||||
*
|
{
|
||||||
* 1. Bootloader build:
|
|
||||||
* - We cannot set the lock bit as we need to reconfigure it again for the application.
|
|
||||||
* We configure PMP to cover entire valid IRAM and DRAM range.
|
|
||||||
*
|
|
||||||
* 2. Application build with CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT enabled
|
|
||||||
* - We split the SRAM into IRAM and DRAM such that IRAM region cannot be written to
|
|
||||||
* and DRAM region cannot be executed. We use _iram_text_end and _data_start markers to set the boundaries.
|
|
||||||
* We also lock these entries so the R/W/X permissions are enforced even for machine mode
|
|
||||||
*
|
|
||||||
* 3. Application build with CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT disabled
|
|
||||||
* - The IRAM-DRAM split is not enabled so we just need to ensure that access to only valid address ranges are successful
|
|
||||||
* so for that we set PMP to cover entire valid IRAM and DRAM region.
|
|
||||||
* We also lock these entries so the R/W/X permissions are enforced even for machine mode
|
|
||||||
*
|
|
||||||
* 4. CPU is in OCD debug mode
|
|
||||||
* - The IRAM-DRAM split is not enabled so that OpenOCD can write and execute from IRAM.
|
|
||||||
* We set PMP to cover entire valid IRAM and DRAM region.
|
|
||||||
* We also lock these entries so the R/W/X permissions are enforced even for machine mode
|
|
||||||
*/
|
|
||||||
const unsigned NONE = PMP_L;
|
const unsigned NONE = PMP_L;
|
||||||
__attribute__((unused)) const unsigned R = PMP_L | PMP_R;
|
__attribute__((unused)) const unsigned R = PMP_L | PMP_R;
|
||||||
const unsigned RW = PMP_L | PMP_R | PMP_W;
|
const unsigned RW = PMP_L | PMP_R | PMP_W;
|
||||||
const unsigned RX = PMP_L | PMP_R | PMP_X;
|
const unsigned RX = PMP_L | PMP_R | PMP_X;
|
||||||
const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X;
|
const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X;
|
||||||
|
|
||||||
//
|
// 1. CPU Subsystem region - contains debug mode code and interrupt config registers
|
||||||
// Configure all the invalid address regions using PMA
|
const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_CPU_SUBSYSTEM_LOW, SOC_CPU_SUBSYSTEM_HIGH);
|
||||||
//
|
PMP_RESET_AND_ENTRY_SET(0, pmpaddr0, PMP_NAPOT | RW);
|
||||||
esp_cpu_configure_invalid_regions();
|
_Static_assert(SOC_CPU_SUBSYSTEM_LOW < SOC_CPU_SUBSYSTEM_HIGH, "Invalid CPU subsystem region");
|
||||||
|
|
||||||
//
|
// 2. HP-CPU TCM
|
||||||
// Configure all the valid address regions using PMP
|
// The default memory permissions are RWX and TCM should be RWX, so we can skip configuring it
|
||||||
//
|
|
||||||
|
// 3. CPU Peripherals
|
||||||
|
const uint32_t pmpaddr1 = PMPADDR_NAPOT(CPU_PERIPH_LOW, CPU_PERIPH_HIGH);
|
||||||
|
PMP_RESET_AND_ENTRY_SET(1, pmpaddr1, PMP_NAPOT | RW);
|
||||||
|
_Static_assert(CPU_PERIPH_LOW < CPU_PERIPH_HIGH, "Invalid CPU peripheral region");
|
||||||
|
|
||||||
|
// 4. I/D-ROM
|
||||||
|
const uint32_t pmpaddr2 = PMPADDR_NAPOT(SOC_IROM_MASK_LOW, SOC_IROM_MASK_HIGH);
|
||||||
|
PMP_RESET_AND_ENTRY_SET(2, pmpaddr2, PMP_NAPOT | RX);
|
||||||
|
|
||||||
|
const uint32_t pmpaddr3 = PMPADDR_NAPOT(CACHE_LL_L2MEM_NON_CACHE_ADDR(SOC_IROM_MASK_LOW), CACHE_LL_L2MEM_NON_CACHE_ADDR(SOC_IROM_MASK_HIGH));
|
||||||
|
PMP_RESET_AND_ENTRY_SET(3, pmpaddr3, PMP_NAPOT | RX);
|
||||||
|
|
||||||
|
_Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I/D-ROM region");
|
||||||
|
|
||||||
|
// 5. IRAM and DRAM
|
||||||
|
if (esp_cpu_dbgr_is_attached()) {
|
||||||
|
// Anti-FI check that cpu is really in ocd mode
|
||||||
|
ESP_FAULT_ASSERT(esp_cpu_dbgr_is_attached());
|
||||||
|
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(4, 6, SOC_IRAM_LOW, NONE);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(5, 7, SOC_IRAM_HIGH, PMP_TOR | RWX);
|
||||||
|
|
||||||
|
_Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region");
|
||||||
|
} else {
|
||||||
|
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||||
|
extern int _iram_text_end;
|
||||||
|
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(4, 7, SOC_IRAM_LOW, NONE);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(5, 8, (int)&_iram_text_end, PMP_TOR | RX);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(6, 9, SOC_DRAM_HIGH, PMP_TOR | RW);
|
||||||
|
#else
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(4, 6, SOC_IRAM_LOW, CONDITIONAL_NONE);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(5, 7, SOC_IRAM_HIGH, PMP_TOR | CONDITIONAL_RWX);
|
||||||
|
_Static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid RAM region");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||||
|
extern int _instruction_reserved_end;
|
||||||
|
extern int _rodata_reserved_end;
|
||||||
|
|
||||||
|
const uint32_t page_aligned_irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_instruction_reserved_end));
|
||||||
|
__attribute__((unused)) const uint32_t page_aligned_drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_rodata_reserved_end));
|
||||||
|
|
||||||
|
// 6. I_EXTRAM / D_EXTRAM (SPIRAM)
|
||||||
|
#if CONFIG_SPIRAM && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION
|
||||||
|
|
||||||
|
const size_t available_psram_heap = esp_psram_get_heap_size_to_protect();
|
||||||
|
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(10, 15, SOC_EXTRAM_LOW, NONE);
|
||||||
|
|
||||||
|
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && CONFIG_SPIRAM_RODATA
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(11, 16, (uint32_t)(&_instruction_reserved_end), PMP_TOR | RX);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(12, 17, page_aligned_irom_resv_end, PMP_TOR | RW);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(13, 18, (uint32_t)(&_rodata_reserved_end), PMP_TOR | R);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(14, 19, ALIGN_UP((uint32_t)(&_rodata_reserved_end) + available_psram_heap, SOC_CPU_PMP_REGION_GRANULARITY), PMP_TOR | RW);
|
||||||
|
|
||||||
|
#elif CONFIG_SPIRAM_FETCH_INSTRUCTIONS
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(11, 16, (uint32_t)(&_instruction_reserved_end), PMP_TOR | RX);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(12, 17, page_aligned_irom_resv_end, PMP_TOR | RW);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(13, 18, ALIGN_UP(page_aligned_irom_resv_end + available_psram_heap, SOC_CPU_PMP_REGION_GRANULARITY), PMP_TOR | RW);
|
||||||
|
|
||||||
|
#elif CONFIG_SPIRAM_RODATA
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(11, 16, (uint32_t)(&_rodata_reserved_end), PMP_TOR | R);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(12, 17, ALIGN_UP((uint32_t)(&_rodata_reserved_end) + available_psram_heap, SOC_CPU_PMP_REGION_GRANULARITY), PMP_TOR | RW);
|
||||||
|
|
||||||
|
#else
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(11, 16, ALIGN_UP(SOC_EXTRAM_LOW + available_psram_heap, SOC_CPU_PMP_REGION_GRANULARITY), PMP_TOR | RW);
|
||||||
|
#endif
|
||||||
|
#endif /* CONFIG_SPIRAM && CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION */
|
||||||
|
|
||||||
|
// ESP32-P4 V3's 24th PMP entry cannot be used as a TOR entry // DIG-752
|
||||||
|
// 7. I_Cache / D_Cache (flash)
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(20, 24, SOC_IROM_LOW, NONE);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(21, 25, page_aligned_irom_resv_end, PMP_TOR | RX);
|
||||||
|
PMP_ENTRY_SET_CACHED_AND_UNCACHED(22, 26, page_aligned_drom_resv_end, PMP_TOR | R);
|
||||||
|
|
||||||
|
#else
|
||||||
|
#if CONFIG_SPIRAM
|
||||||
|
const uint32_t pmpaddr10 = PMPADDR_NAPOT(SOC_EXTRAM_LOW, SOC_EXTRAM_HIGH);
|
||||||
|
PMP_RESET_AND_ENTRY_SET(10, pmpaddr10, PMP_NAPOT | CONDITIONAL_RWX);
|
||||||
|
|
||||||
|
const uint32_t pmpaddr11 = PMPADDR_NAPOT(CACHE_LL_L2MEM_NON_CACHE_ADDR(SOC_EXTRAM_LOW), CACHE_LL_L2MEM_NON_CACHE_ADDR(SOC_EXTRAM_HIGH));
|
||||||
|
PMP_RESET_AND_ENTRY_SET(11, pmpaddr11, PMP_NAPOT | CONDITIONAL_RWX);
|
||||||
|
_Static_assert(SOC_EXTRAM_LOW < SOC_EXTRAM_HIGH, "Invalid I/D_EXTRAM region");
|
||||||
|
#endif /* CONFIG_SPIRAM */
|
||||||
|
|
||||||
|
const uint32_t pmpaddr12 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH);
|
||||||
|
PMP_RESET_AND_ENTRY_SET(12, pmpaddr12, PMP_NAPOT | CONDITIONAL_RX);
|
||||||
|
|
||||||
|
const uint32_t pmpaddr13 = PMPADDR_NAPOT(CACHE_LL_L2MEM_NON_CACHE_ADDR(SOC_IROM_LOW), CACHE_LL_L2MEM_NON_CACHE_ADDR(SOC_IROM_HIGH));
|
||||||
|
PMP_RESET_AND_ENTRY_SET(13, pmpaddr13, PMP_NAPOT | CONDITIONAL_RX);
|
||||||
|
_Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I/D_Cache region");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 8. Peripheral addresses
|
||||||
|
const uint32_t pmpaddr27 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH);
|
||||||
|
PMP_RESET_AND_ENTRY_SET(27, pmpaddr27, PMP_NAPOT | RW);
|
||||||
|
_Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region");
|
||||||
|
|
||||||
|
// 9. LP memory
|
||||||
|
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||||
|
extern int _rtc_text_start;
|
||||||
|
extern int _rtc_text_end;
|
||||||
|
|
||||||
|
// ESP32-P4 V3's 28th PMP entry cannot be used as a TOR entry // DIG-752
|
||||||
|
PMP_RESET_AND_ENTRY_SET(28, SOC_RTC_IRAM_LOW, NONE);
|
||||||
|
// First part of LP mem is reserved for RTC reserved mem (shared between bootloader and app)
|
||||||
|
// as well as memory for ULP coprocessor
|
||||||
|
#if CONFIG_ESP_SYSTEM_PMP_LP_CORE_RESERVE_MEM_EXECUTABLE
|
||||||
|
PMP_RESET_AND_ENTRY_SET(29, (int)&_rtc_text_start, PMP_TOR | RWX);
|
||||||
|
#else
|
||||||
|
PMP_RESET_AND_ENTRY_SET(29, (int)&_rtc_text_start, PMP_TOR | RW);
|
||||||
|
#endif
|
||||||
|
PMP_RESET_AND_ENTRY_SET(30, (int)&_rtc_text_end, PMP_TOR | RX);
|
||||||
|
PMP_RESET_AND_ENTRY_SET(31, SOC_RTC_IRAM_HIGH, PMP_TOR | RW);
|
||||||
|
#else
|
||||||
|
const uint32_t pmpaddr28 = PMPADDR_NAPOT(SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH);
|
||||||
|
PMP_RESET_AND_ENTRY_SET(28, pmpaddr28, PMP_NAPOT | CONDITIONAL_RWX);
|
||||||
|
_Static_assert(SOC_RTC_IRAM_LOW < SOC_RTC_IRAM_HIGH, "Invalid RTC IRAM region");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void esp_cpu_configure_region_protection_rev_less_than_v3(void)
|
||||||
|
{
|
||||||
|
const unsigned NONE = PMP_L;
|
||||||
|
__attribute__((unused)) const unsigned R = PMP_L | PMP_R;
|
||||||
|
const unsigned RW = PMP_L | PMP_R | PMP_W;
|
||||||
|
const unsigned RX = PMP_L | PMP_R | PMP_X;
|
||||||
|
const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X;
|
||||||
|
|
||||||
// 1. CPU Subsystem region - contains debug mode code and interrupt config registers
|
// 1. CPU Subsystem region - contains debug mode code and interrupt config registers
|
||||||
const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_CPU_SUBSYSTEM_LOW, SOC_CPU_SUBSYSTEM_HIGH);
|
const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_CPU_SUBSYSTEM_LOW, SOC_CPU_SUBSYSTEM_HIGH);
|
||||||
@@ -262,3 +355,71 @@ void esp_cpu_configure_region_protection(void)
|
|||||||
PMP_ENTRY_SET(15, pmpaddr15, PMP_NAPOT | RW);
|
PMP_ENTRY_SET(15, pmpaddr15, PMP_NAPOT | RW);
|
||||||
_Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region");
|
_Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void esp_cpu_configure_region_protection(void)
|
||||||
|
{
|
||||||
|
/* Notes on implementation:
|
||||||
|
*
|
||||||
|
* 1) Note: ESP32-P4 CPU support overlapping PMP regions, configuration is based on static priority
|
||||||
|
* feature (lowest numbered entry has highest priority).
|
||||||
|
*
|
||||||
|
* 2) ESP32-P4 supports 16 PMA regions so we use this feature to block the invalid address ranges.
|
||||||
|
* However the entries are not sufficient to block all reserved memory ranges and the excluded sections are:
|
||||||
|
* a. Region between LP ROM and LP SRAM
|
||||||
|
* b. Region between LP peripherals and External flash (direct access)
|
||||||
|
* c. Region between External flash (direct access) and External RAM (direct access)
|
||||||
|
* d. Region between External RAM (direct access) and HP ROM (direct access)
|
||||||
|
* e. Region between HP ROM (direct access) and HP L2MEM (direct access)
|
||||||
|
*
|
||||||
|
* 3) We use combination of NAPOT (Naturally Aligned Power Of Two) and TOR (top of range)
|
||||||
|
* entries to map all the valid address space, bottom to top. This leaves us with some extra PMP entries
|
||||||
|
* which can be used to provide more granular access
|
||||||
|
*
|
||||||
|
* 4) Entries are grouped in order with some static asserts to try and verify everything is
|
||||||
|
* correct.
|
||||||
|
*
|
||||||
|
* 5) For ESP32-P4's versions less than v3, no explicit permissions are specified in PMP (default all permissions) for following regions:
|
||||||
|
* limited entries:
|
||||||
|
* a. External RAM
|
||||||
|
* b. LP ROM, LP Peripherals, LP SRAM
|
||||||
|
* c. External flash, External RAM, HP ROM, HP L2MEM (direct access)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* There are 4 configuration scenarios for SRAM
|
||||||
|
*
|
||||||
|
* 1. Bootloader build:
|
||||||
|
* - We cannot set the lock bit as we need to reconfigure it again for the application.
|
||||||
|
* We configure PMP to cover entire valid IRAM and DRAM range.
|
||||||
|
*
|
||||||
|
* 2. Application build with CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT enabled
|
||||||
|
* - We split the SRAM into IRAM and DRAM such that IRAM region cannot be written to
|
||||||
|
* and DRAM region cannot be executed. We use _iram_text_end and _data_start markers to set the boundaries.
|
||||||
|
* We also lock these entries so the R/W/X permissions are enforced even for machine mode
|
||||||
|
*
|
||||||
|
* 3. Application build with CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT disabled
|
||||||
|
* - The IRAM-DRAM split is not enabled so we just need to ensure that access to only valid address ranges are successful
|
||||||
|
* so for that we set PMP to cover entire valid IRAM and DRAM region.
|
||||||
|
* We also lock these entries so the R/W/X permissions are enforced even for machine mode
|
||||||
|
*
|
||||||
|
* 4. CPU is in OCD debug mode
|
||||||
|
* - The IRAM-DRAM split is not enabled so that OpenOCD can write and execute from IRAM.
|
||||||
|
* We set PMP to cover entire valid IRAM and DRAM region.
|
||||||
|
* We also lock these entries so the R/W/X permissions are enforced even for machine mode
|
||||||
|
*/
|
||||||
|
//
|
||||||
|
// Configure all the invalid address regions using PMA
|
||||||
|
//
|
||||||
|
esp_cpu_configure_invalid_regions();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure all the valid address regions using PMP
|
||||||
|
//
|
||||||
|
|
||||||
|
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||||
|
esp_cpu_configure_region_protection_rev_v3();
|
||||||
|
#else
|
||||||
|
esp_cpu_configure_region_protection_rev_less_than_v3();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,4 +16,4 @@ CONFIG_PARTITION_TABLE_OFFSET=0xF000
|
|||||||
|
|
||||||
# Increasing TEE I/DRAM size
|
# Increasing TEE I/DRAM size
|
||||||
CONFIG_SECURE_TEE_IRAM_SIZE=0x8800
|
CONFIG_SECURE_TEE_IRAM_SIZE=0x8800
|
||||||
CONFIG_SECURE_TEE_DRAM_SIZE=0x4c00
|
CONFIG_SECURE_TEE_DRAM_SIZE=0x5800
|
||||||
|
|||||||
@@ -123,19 +123,31 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define PMP_ENTRY_SET(ENTRY, ADDR, CFG) do { \
|
#define PMP_ENTRY_SET(ENTRY, ADDR, CFG) do { \
|
||||||
RV_WRITE_CSR((CSR_PMPADDR0) + (ENTRY), (ADDR) >> (PMP_SHIFT)); \
|
RV_WRITE_CSR((CSR_PMPADDR0) + (ENTRY), (ADDR) >> (PMP_SHIFT)); \
|
||||||
RV_SET_CSR((CSR_PMPCFG0) + (ENTRY)/4, ((CFG)&0xFF) << (ENTRY%4)*8); \
|
PMP_ENTRY_CFG_SET(ENTRY, CFG); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/*Only set PMPCFG entries*/
|
/*Only set PMPCFG entries*/
|
||||||
#define PMP_ENTRY_CFG_SET(ENTRY, CFG) do {\
|
#define PMP_ENTRY_CFG_SET(ENTRY, CFG) \
|
||||||
RV_SET_CSR((CSR_PMPCFG0) + (ENTRY)/4, ((CFG)&0xFF) << (ENTRY%4)*8); \
|
RV_SET_CSR((CSR_PMPCFG0) + (ENTRY)/4, ((CFG)&0xFF) << (ENTRY%4)*8)
|
||||||
} while(0)
|
|
||||||
|
|
||||||
/*Reset all permissions of a particular PMPCFG entry*/
|
/*Reset all permissions of a particular PMPCFG entry*/
|
||||||
#define PMP_ENTRY_CFG_RESET(ENTRY) do {\
|
#define PMP_ENTRY_CFG_RESET(ENTRY) do {\
|
||||||
|
RV_WRITE_CSR((CSR_PMPADDR0) + (ENTRY), 0); \
|
||||||
RV_CLEAR_CSR((CSR_PMPCFG0) + (ENTRY)/4, (0xFF) << (ENTRY%4)*8); \
|
RV_CLEAR_CSR((CSR_PMPCFG0) + (ENTRY)/4, (0xFF) << (ENTRY%4)*8); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/*Read configuration of a particular PMPCFG entry*/
|
||||||
|
#define PMP_ENTRY_CFG_READ(ENTRY) \
|
||||||
|
((RV_READ_CSR((CSR_PMPCFG0) + (ENTRY)/4) >> ((ENTRY%4)*8)) & 0xFF)
|
||||||
|
|
||||||
|
#define PMP_ENTRY_ADDR_READ(ENTRY) \
|
||||||
|
(RV_READ_CSR((CSR_PMPADDR0) + (ENTRY)) << (PMP_SHIFT))
|
||||||
|
|
||||||
|
#define PMP_RESET_AND_ENTRY_SET(ENTRY, ADDR, CFG) do {\
|
||||||
|
PMP_ENTRY_CFG_RESET(ENTRY); \
|
||||||
|
PMP_ENTRY_SET(ENTRY, ADDR, CFG); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/*Reset all permissions of a particular PMACFG entry*/
|
/*Reset all permissions of a particular PMACFG entry*/
|
||||||
#define PMA_ENTRY_CFG_RESET(ENTRY) do {\
|
#define PMA_ENTRY_CFG_RESET(ENTRY) do {\
|
||||||
RV_WRITE_CSR((CSR_PMACFG0) + (ENTRY) , 0); \
|
RV_WRITE_CSR((CSR_PMACFG0) + (ENTRY) , 0); \
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG=y
|
|||||||
CONFIG_BOOTLOADER_LOG_LEVEL=4
|
CONFIG_BOOTLOADER_LOG_LEVEL=4
|
||||||
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||||
# Bootloader overlapped with partition table after we enabled LOGD for bootloader. Move the partition table a bit to fix the issue on CI.
|
# Bootloader overlapped with partition table after we enabled LOGD for bootloader. Move the partition table a bit to fix the issue on CI.
|
||||||
CONFIG_PARTITION_TABLE_OFFSET=0x9000
|
CONFIG_PARTITION_TABLE_OFFSET=0xA000
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -26,12 +28,25 @@ void test_iram_reg2_write_violation(void);
|
|||||||
|
|
||||||
void test_iram_reg3_write_violation(void);
|
void test_iram_reg3_write_violation(void);
|
||||||
|
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
void test_non_cache_iram_reg1_write_violation(void);
|
||||||
|
void test_non_cache_iram_reg2_write_violation(void);
|
||||||
|
void test_non_cache_iram_reg3_write_violation(void);
|
||||||
|
void test_non_cache_iram_reg4_write_violation(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
void test_iram_reg4_write_violation(void);
|
void test_iram_reg4_write_violation(void);
|
||||||
|
|
||||||
void test_dram_reg1_execute_violation(void);
|
void test_dram_reg1_execute_violation(void);
|
||||||
|
|
||||||
void test_dram_reg2_execute_violation(void);
|
void test_dram_reg2_execute_violation(void);
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
void test_non_cache_dram_reg1_execute_violation(void);
|
||||||
|
void test_non_cache_dram_reg2_execute_violation(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
void test_rtc_fast_reg1_execute_violation(void);
|
void test_rtc_fast_reg1_execute_violation(void);
|
||||||
|
|
||||||
void test_rtc_fast_reg2_execute_violation(void);
|
void test_rtc_fast_reg2_execute_violation(void);
|
||||||
@@ -52,6 +67,15 @@ void test_drom_reg_write_violation(void);
|
|||||||
|
|
||||||
void test_drom_reg_execute_violation(void);
|
void test_drom_reg_execute_violation(void);
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
void test_non_cache_irom_reg_write_violation(void);
|
||||||
|
void test_non_cache_drom_reg_write_violation(void);
|
||||||
|
void test_non_cache_drom_reg_execute_violation(void);
|
||||||
|
|
||||||
|
void test_non_cache_spiram_xip_irom_alignment_reg_execute_violation(void);
|
||||||
|
void test_non_cache_spiram_xip_drom_alignment_reg_execute_violation(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
void test_invalid_memory_region_write_violation(void);
|
void test_invalid_memory_region_write_violation(void);
|
||||||
|
|
||||||
void test_invalid_memory_region_execute_violation(void);
|
void test_invalid_memory_region_execute_violation(void);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -146,6 +146,13 @@ void app_main(void)
|
|||||||
HANDLE_TEST(test_name, test_iram_reg2_write_violation);
|
HANDLE_TEST(test_name, test_iram_reg2_write_violation);
|
||||||
HANDLE_TEST(test_name, test_iram_reg3_write_violation);
|
HANDLE_TEST(test_name, test_iram_reg3_write_violation);
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
HANDLE_TEST(test_name, test_non_cache_iram_reg1_write_violation);
|
||||||
|
HANDLE_TEST(test_name, test_non_cache_iram_reg2_write_violation);
|
||||||
|
HANDLE_TEST(test_name, test_non_cache_iram_reg3_write_violation);
|
||||||
|
HANDLE_TEST(test_name, test_non_cache_iram_reg4_write_violation);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TODO: IDF-6820: ESP32-S2 -> Fix incorrect panic reason: Unhandled debug exception */
|
/* TODO: IDF-6820: ESP32-S2 -> Fix incorrect panic reason: Unhandled debug exception */
|
||||||
HANDLE_TEST(test_name, test_iram_reg4_write_violation);
|
HANDLE_TEST(test_name, test_iram_reg4_write_violation);
|
||||||
|
|
||||||
@@ -154,6 +161,11 @@ void app_main(void)
|
|||||||
|
|
||||||
HANDLE_TEST(test_name, test_dram_reg2_execute_violation);
|
HANDLE_TEST(test_name, test_dram_reg2_execute_violation);
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
HANDLE_TEST(test_name, test_non_cache_dram_reg1_execute_violation);
|
||||||
|
HANDLE_TEST(test_name, test_non_cache_dram_reg2_execute_violation);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SOC_RTC_FAST_MEM_SUPPORTED
|
#if CONFIG_SOC_RTC_FAST_MEM_SUPPORTED
|
||||||
HANDLE_TEST(test_name, test_rtc_fast_reg1_execute_violation);
|
HANDLE_TEST(test_name, test_rtc_fast_reg1_execute_violation);
|
||||||
HANDLE_TEST(test_name, test_rtc_fast_reg2_execute_violation);
|
HANDLE_TEST(test_name, test_rtc_fast_reg2_execute_violation);
|
||||||
@@ -178,13 +190,26 @@ void app_main(void)
|
|||||||
HANDLE_TEST(test_name, test_irom_reg_write_violation);
|
HANDLE_TEST(test_name, test_irom_reg_write_violation);
|
||||||
HANDLE_TEST(test_name, test_drom_reg_write_violation);
|
HANDLE_TEST(test_name, test_drom_reg_write_violation);
|
||||||
HANDLE_TEST(test_name, test_drom_reg_execute_violation);
|
HANDLE_TEST(test_name, test_drom_reg_execute_violation);
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
HANDLE_TEST(test_name, test_non_cache_irom_reg_write_violation);
|
||||||
|
HANDLE_TEST(test_name, test_non_cache_drom_reg_write_violation);
|
||||||
|
HANDLE_TEST(test_name, test_non_cache_drom_reg_execute_violation);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED
|
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED
|
||||||
HANDLE_TEST(test_name, test_spiram_xip_irom_alignment_reg_execute_violation);
|
HANDLE_TEST(test_name, test_spiram_xip_irom_alignment_reg_execute_violation);
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
HANDLE_TEST(test_name, test_non_cache_spiram_xip_irom_alignment_reg_execute_violation);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2
|
||||||
HANDLE_TEST(test_name, test_spiram_xip_drom_alignment_reg_execute_violation);
|
HANDLE_TEST(test_name, test_spiram_xip_drom_alignment_reg_execute_violation);
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
HANDLE_TEST(test_name, test_non_cache_spiram_xip_drom_alignment_reg_execute_violation);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SOC_CPU_HAS_PMA
|
#ifdef CONFIG_SOC_CPU_HAS_PMA
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -18,6 +18,10 @@
|
|||||||
#include "test_memprot.h"
|
#include "test_memprot.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
#include "hal/cache_ll.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RND_VAL (0xA5A5A5A5)
|
#define RND_VAL (0xA5A5A5A5)
|
||||||
#define SPIN_ITER (16)
|
#define SPIN_ITER (16)
|
||||||
|
|
||||||
@@ -112,6 +116,40 @@ void test_iram_reg4_write_violation(void)
|
|||||||
*test_addr = RND_VAL;
|
*test_addr = RND_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
/* IRAM: I/DCACHE boundary region */
|
||||||
|
void test_non_cache_iram_reg1_write_violation(void)
|
||||||
|
{
|
||||||
|
uint32_t *test_addr = (uint32_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR((uint32_t)(&_iram_start) - 0x04));
|
||||||
|
printf("IRAM: Non-cacheable Write operation | Address: %p\n", test_addr);
|
||||||
|
*test_addr = RND_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IRAM: Interrupt vector table region */
|
||||||
|
void test_non_cache_iram_reg2_write_violation(void)
|
||||||
|
{
|
||||||
|
uint32_t *test_addr = (uint32_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR((uint32_t)(&_iram_text_start) - 0x04));
|
||||||
|
printf("IRAM: Non-cacheable Write operation | Address: %p\n", test_addr);
|
||||||
|
*test_addr = RND_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IRAM: Text (and data) region */
|
||||||
|
void test_non_cache_iram_reg3_write_violation(void)
|
||||||
|
{
|
||||||
|
uint32_t *test_addr = (uint32_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR((uint32_t)(&_iram_text_end) - 0x04));
|
||||||
|
printf("IRAM: Non-cacheable Write operation | Address: %p\n", test_addr);
|
||||||
|
*test_addr = RND_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IRAM: Through the data bus */
|
||||||
|
void test_non_cache_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;
|
||||||
|
}
|
||||||
|
#endif /* SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE */
|
||||||
|
|
||||||
/* ---------------------------------------------------- DRAM Violation Checks ---------------------------------------------------- */
|
/* ---------------------------------------------------- DRAM Violation Checks ---------------------------------------------------- */
|
||||||
|
|
||||||
static void foo_d(void)
|
static void foo_d(void)
|
||||||
@@ -144,6 +182,30 @@ void test_dram_reg2_execute_violation(void)
|
|||||||
run_function(test_addr);
|
run_function(test_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
/* DRAM: Data region (DRAM_ATTR tagged) */
|
||||||
|
void test_non_cache_dram_reg1_execute_violation(void)
|
||||||
|
{
|
||||||
|
memcpy(&s_dram_buf, &foo_d, sizeof(s_dram_buf));
|
||||||
|
void *test_addr = (void *)(CACHE_LL_L2MEM_NON_CACHE_ADDR(&s_dram_buf));
|
||||||
|
printf("DRAM: Non-cacheable Execute operation | Address: %p\n", &s_dram_buf);
|
||||||
|
run_function(test_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DRAM: Heap region */
|
||||||
|
void test_non_cache_dram_reg2_execute_violation(void)
|
||||||
|
{
|
||||||
|
uint8_t *instr = calloc(1024, sizeof(uint8_t));
|
||||||
|
assert(instr != NULL);
|
||||||
|
|
||||||
|
printf("DRAM: Non-cacheable Execute operation | Address: %p\n", instr);
|
||||||
|
|
||||||
|
memcpy(instr, &foo_d, 1024);
|
||||||
|
void *test_addr = (void *)(CACHE_LL_L2MEM_NON_CACHE_ADDR(instr));
|
||||||
|
run_function(test_addr);
|
||||||
|
}
|
||||||
|
#endif /* SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE */
|
||||||
|
|
||||||
/* ---------------------------------------------------- RTC Violation Checks ---------------------------------------------------- */
|
/* ---------------------------------------------------- RTC Violation Checks ---------------------------------------------------- */
|
||||||
|
|
||||||
#if CONFIG_SOC_RTC_FAST_MEM_SUPPORTED
|
#if CONFIG_SOC_RTC_FAST_MEM_SUPPORTED
|
||||||
@@ -251,6 +313,30 @@ void test_drom_reg_execute_violation(void)
|
|||||||
run_function(test_addr);
|
run_function(test_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
void test_non_cache_irom_reg_write_violation(void)
|
||||||
|
{
|
||||||
|
extern int _instruction_reserved_end;
|
||||||
|
uint32_t *test_addr = (uint32_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR((uint32_t)(&_instruction_reserved_end - 0x100)));
|
||||||
|
printf("Flash (IROM): Non-cacheable Write operation | Address: %p\n", test_addr);
|
||||||
|
*test_addr = RND_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_non_cache_drom_reg_write_violation(void)
|
||||||
|
{
|
||||||
|
uint32_t *test_addr = (uint32_t *)CACHE_LL_L2MEM_NON_CACHE_ADDR(((uint32_t)(foo_buf)));
|
||||||
|
printf("Flash (DROM): Non-cacheable Write operation | Address: %p\n", test_addr);
|
||||||
|
*test_addr = RND_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_non_cache_drom_reg_execute_violation(void)
|
||||||
|
{
|
||||||
|
void *test_addr = (void *)CACHE_LL_L2MEM_NON_CACHE_ADDR((void *)foo_buf);
|
||||||
|
printf("Flash (DROM): Non-cacheable Execute operation | Address: %p\n", test_addr);
|
||||||
|
run_function(test_addr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check if the memory alignment gaps added to the heap are correctly configured
|
// Check if the memory alignment gaps added to the heap are correctly configured
|
||||||
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED
|
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED
|
||||||
void test_spiram_xip_irom_alignment_reg_execute_violation(void)
|
void test_spiram_xip_irom_alignment_reg_execute_violation(void)
|
||||||
@@ -264,6 +350,20 @@ void test_spiram_xip_irom_alignment_reg_execute_violation(void)
|
|||||||
printf("SPIRAM (IROM): IROM alignment gap not added into heap\n");
|
printf("SPIRAM (IROM): IROM alignment gap not added into heap\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
void test_non_cache_spiram_xip_irom_alignment_reg_execute_violation(void)
|
||||||
|
{
|
||||||
|
extern int _instruction_reserved_end;
|
||||||
|
if (ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_instruction_reserved_end)) - (uint32_t)(&_instruction_reserved_end) >= 4) {
|
||||||
|
void *test_addr = (void *)CACHE_LL_L2MEM_NON_CACHE_ADDR(&_instruction_reserved_end + 1);
|
||||||
|
printf("SPIRAM (IROM): Non-cacheable Execute operation | Address: %p\n", test_addr);
|
||||||
|
run_function(test_addr);
|
||||||
|
} else {
|
||||||
|
printf("SPIRAM (IROM): Non-cacheable IROM alignment gap not added into heap\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif /* CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED */
|
#endif /* CONFIG_SPIRAM_FETCH_INSTRUCTIONS && SOC_MMU_DI_VADDR_SHARED */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -279,6 +379,20 @@ void test_spiram_xip_drom_alignment_reg_execute_violation(void)
|
|||||||
printf("SPIRAM (DROM): DROM alignment gap not added into heap\n");
|
printf("SPIRAM (DROM): DROM alignment gap not added into heap\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
void test_non_cache_spiram_xip_drom_alignment_reg_execute_violation(void)
|
||||||
|
{
|
||||||
|
extern int _rodata_reserved_end;
|
||||||
|
if (ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_rodata_reserved_end)) - (uint32_t)(&_rodata_reserved_end) >= 4) {
|
||||||
|
void *test_addr = (void *)CACHE_LL_L2MEM_NON_CACHE_ADDR(&_rodata_reserved_end + 0x4);
|
||||||
|
printf("SPIRAM (DROM): Non-cacheable Execute operation | Address: %p\n", test_addr);
|
||||||
|
run_function(test_addr);
|
||||||
|
} else {
|
||||||
|
printf("SPIRAM (DROM): Non-cacheable DROM alignment gap not added into heap\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif /* CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2 */
|
#endif /* CONFIG_SPIRAM_RODATA && !CONFIG_IDF_TARGET_ESP32S2 */
|
||||||
|
|
||||||
#ifdef CONFIG_SOC_CPU_HAS_PMA
|
#ifdef CONFIG_SOC_CPU_HAS_PMA
|
||||||
|
|||||||
@@ -695,6 +695,8 @@ CONFIGS_MEMPROT_IDRAM = list(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CONFIGS_MEMPROT_IDRAM_L2_MEM_NON_CACHE = list(itertools.chain(itertools.product(['memprot_esp32p4'], ['esp32p4'])))
|
||||||
|
|
||||||
CONFIGS_MEMPROT_DCACHE = list(itertools.chain(itertools.product(['memprot_esp32s2'], ['esp32s2'])))
|
CONFIGS_MEMPROT_DCACHE = list(itertools.chain(itertools.product(['memprot_esp32s2'], ['esp32s2'])))
|
||||||
|
|
||||||
CONFIGS_MEMPROT_RTC_FAST_MEM = list(
|
CONFIGS_MEMPROT_RTC_FAST_MEM = list(
|
||||||
@@ -725,6 +727,8 @@ CONFIGS_MEMPROT_FLASH_IDROM = list(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CONFIGS_MEMPROT_FLASH_IDROM_L2_NON_CACHE = list(zip(['memprot_esp32p4'], ['esp32p4']))
|
||||||
|
|
||||||
CONFIGS_MEMPROT_SPIRAM_XIP_IROM_ALIGNMENT_HEAP = list(
|
CONFIGS_MEMPROT_SPIRAM_XIP_IROM_ALIGNMENT_HEAP = list(
|
||||||
itertools.chain(
|
itertools.chain(
|
||||||
zip(
|
zip(
|
||||||
@@ -734,6 +738,14 @@ CONFIGS_MEMPROT_SPIRAM_XIP_IROM_ALIGNMENT_HEAP = list(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CONFIGS_MEMPROT_SPIRAM_XIP_IROM_ALIGNMENT_HEAP_L2_NON_CACHE = list(
|
||||||
|
zip(
|
||||||
|
['memprot_spiram_xip_esp32p4'],
|
||||||
|
['esp32p4'],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
CONFIGS_MEMPROT_SPIRAM_XIP_DROM_ALIGNMENT_HEAP = list(
|
CONFIGS_MEMPROT_SPIRAM_XIP_DROM_ALIGNMENT_HEAP = list(
|
||||||
itertools.chain(
|
itertools.chain(
|
||||||
zip(
|
zip(
|
||||||
@@ -748,6 +760,13 @@ CONFIGS_MEMPROT_SPIRAM_XIP_DROM_ALIGNMENT_HEAP = list(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CONFIGS_MEMPROT_SPIRAM_XIP_DROM_ALIGNMENT_HEAP_L2_NON_CACHE = list(
|
||||||
|
zip(
|
||||||
|
['memprot_spiram_xip_esp32p4'],
|
||||||
|
['esp32p4'],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
CONFIGS_MEMPROT_INVALID_REGION_PROTECTION_USING_PMA = list(
|
CONFIGS_MEMPROT_INVALID_REGION_PROTECTION_USING_PMA = list(
|
||||||
itertools.chain(
|
itertools.chain(
|
||||||
zip(
|
zip(
|
||||||
@@ -779,9 +798,7 @@ def test_dcache_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
|||||||
dut.expect_cpu_reset()
|
dut.expect_cpu_reset()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
def iram_reg1_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
|
||||||
def test_iram_reg1_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
|
||||||
dut.run_test_func(test_func_name)
|
dut.run_test_func(test_func_name)
|
||||||
|
|
||||||
if dut.target == 'esp32s2':
|
if dut.target == 'esp32s2':
|
||||||
@@ -801,7 +818,55 @@ def test_iram_reg1_write_violation(dut: PanicTestDut, test_func_name: str) -> No
|
|||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
||||||
|
def test_iram_reg1_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
iram_reg1_write_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM_L2_MEM_NON_CACHE, indirect=['config', 'target'])
|
||||||
|
def test_non_cache_iram_reg1_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
if dut.target == 'esp32p4' and not dut.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
|
iram_reg1_write_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
def iram_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
dut.run_test_func(test_func_name)
|
||||||
|
|
||||||
|
if dut.target == 'esp32s2':
|
||||||
|
dut.expect_gme('Memory protection fault')
|
||||||
|
dut.expect(r'Write operation at address [0-9xa-f]+ not permitted \((\S+)\)')
|
||||||
|
dut.expect_reg_dump(0)
|
||||||
|
dut.expect_backtrace()
|
||||||
|
elif dut.target == 'esp32c3':
|
||||||
|
dut.expect_gme('Memory protection fault')
|
||||||
|
dut.expect(r' memory type: (\S+)')
|
||||||
|
dut.expect(r' faulting address: [0-9xa-f]+')
|
||||||
|
dut.expect(r' operation type: (\S+)')
|
||||||
|
dut.expect_reg_dump(0)
|
||||||
|
dut.expect_stack_dump()
|
||||||
|
else:
|
||||||
|
dut.expect_gme('Store access fault')
|
||||||
|
dut.expect_reg_dump(0)
|
||||||
|
dut.expect_stack_dump()
|
||||||
|
|
||||||
|
dut.expect_cpu_reset()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@pytest.mark.temp_skip_ci(targets=['esp32h21'], reason='lack of runners')
|
||||||
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
||||||
def test_iram_reg2_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
def test_iram_reg2_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
iram_reg_write_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM_L2_MEM_NON_CACHE, indirect=['config', 'target'])
|
||||||
|
def test_non_cache_iram_reg2_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
if dut.target == 'esp32p4' and not dut.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
|
iram_reg_write_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
def iram_reg3_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
dut.run_test_func(test_func_name)
|
dut.run_test_func(test_func_name)
|
||||||
|
|
||||||
if dut.target == 'esp32s2':
|
if dut.target == 'esp32s2':
|
||||||
@@ -827,6 +892,17 @@ def test_iram_reg2_write_violation(dut: PanicTestDut, test_func_name: str) -> No
|
|||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
||||||
def test_iram_reg3_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
def test_iram_reg3_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
iram_reg_write_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM_L2_MEM_NON_CACHE, indirect=['config', 'target'])
|
||||||
|
def test_non_cache_iram_reg3_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
if dut.target == 'esp32p4' and not dut.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
|
iram_reg_write_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
def iram_reg4_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
dut.run_test_func(test_func_name)
|
dut.run_test_func(test_func_name)
|
||||||
|
|
||||||
if dut.target == 'esp32s2':
|
if dut.target == 'esp32s2':
|
||||||
@@ -854,35 +930,17 @@ def test_iram_reg3_write_violation(dut: PanicTestDut, test_func_name: str) -> No
|
|||||||
@pytest.mark.xfail('config.getvalue("target") == "esp32s2"', reason='Incorrect panic reason may be observed', run=False)
|
@pytest.mark.xfail('config.getvalue("target") == "esp32s2"', reason='Incorrect panic reason may be observed', run=False)
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
||||||
def test_iram_reg4_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
def test_iram_reg4_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
dut.run_test_func(test_func_name)
|
iram_reg_write_violation(dut, test_func_name)
|
||||||
|
|
||||||
if dut.target == 'esp32s2':
|
|
||||||
dut.expect_gme('Memory protection fault')
|
|
||||||
dut.expect(r'Write operation at address [0-9xa-f]+ not permitted \((\S+)\)')
|
|
||||||
dut.expect_reg_dump(0)
|
|
||||||
dut.expect_backtrace()
|
|
||||||
elif dut.target == 'esp32c3':
|
|
||||||
dut.expect_gme('Memory protection fault')
|
|
||||||
dut.expect(r' memory type: (\S+)')
|
|
||||||
dut.expect(r' faulting address: [0-9xa-f]+')
|
|
||||||
dut.expect(r' operation type: (\S+)')
|
|
||||||
dut.expect_reg_dump(0)
|
|
||||||
dut.expect_stack_dump()
|
|
||||||
else:
|
|
||||||
dut.expect_gme('Store access fault')
|
|
||||||
dut.expect_reg_dump(0)
|
|
||||||
dut.expect_stack_dump()
|
|
||||||
|
|
||||||
dut.expect_cpu_reset()
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: IDF-6820: ESP32-S2 -> Fix multiple panic reasons in different runs
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@pytest.mark.xfail(
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM_L2_MEM_NON_CACHE, indirect=['config', 'target'])
|
||||||
'config.getvalue("target") == "esp32s2"', reason='Multiple panic reasons for the same test may surface', run=False
|
def test_non_cache_iram_reg4_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
)
|
if dut.target == 'esp32p4' and not dut.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
iram_reg_write_violation(dut, test_func_name)
|
||||||
def test_dram_reg1_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
|
||||||
|
|
||||||
|
def dram_reg1_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
dut.run_test_func(test_func_name)
|
dut.run_test_func(test_func_name)
|
||||||
|
|
||||||
if dut.target == 'esp32s2':
|
if dut.target == 'esp32s2':
|
||||||
@@ -904,7 +962,18 @@ def test_dram_reg1_execute_violation(dut: PanicTestDut, test_func_name: str) ->
|
|||||||
'config.getvalue("target") == "esp32s2"', reason='Multiple panic reasons for the same test may surface', run=False
|
'config.getvalue("target") == "esp32s2"', reason='Multiple panic reasons for the same test may surface', run=False
|
||||||
)
|
)
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
||||||
def test_dram_reg2_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
def test_dram_reg1_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
dram_reg1_execute_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM_L2_MEM_NON_CACHE, indirect=['config', 'target'])
|
||||||
|
def test_non_cache_dram_reg1_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
if dut.target == 'esp32p4' and not dut.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
|
dram_reg1_execute_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
def dram_reg2_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
dut.run_test_func(test_func_name)
|
dut.run_test_func(test_func_name)
|
||||||
|
|
||||||
if dut.target == 'esp32s2':
|
if dut.target == 'esp32s2':
|
||||||
@@ -919,6 +988,24 @@ def test_dram_reg2_execute_violation(dut: PanicTestDut, test_func_name: str) ->
|
|||||||
dut.expect_cpu_reset()
|
dut.expect_cpu_reset()
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: IDF-6820: ESP32-S2 -> Fix multiple panic reasons in different runs
|
||||||
|
@pytest.mark.generic
|
||||||
|
@pytest.mark.xfail(
|
||||||
|
'config.getvalue("target") == "esp32s2"', reason='Multiple panic reasons for the same test may surface', run=False
|
||||||
|
)
|
||||||
|
@pytest.mark.temp_skip_ci(targets=['esp32h21'], reason='lack of runners')
|
||||||
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM, indirect=['config', 'target'])
|
||||||
|
def test_dram_reg2_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
dram_reg2_execute_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_IDRAM_L2_MEM_NON_CACHE, indirect=['config', 'target'])
|
||||||
|
def test_non_cache_dram_reg2_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
if dut.target == 'esp32p4' and not dut.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
|
dram_reg2_execute_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_RTC_FAST_MEM, indirect=['config', 'target'])
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_RTC_FAST_MEM, indirect=['config', 'target'])
|
||||||
def test_rtc_fast_reg1_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
def test_rtc_fast_reg1_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
@@ -1000,9 +1087,27 @@ def test_rtc_slow_reg2_execute_violation(dut: PanicTestDut, test_func_name: str)
|
|||||||
dut.expect_cpu_reset()
|
dut.expect_cpu_reset()
|
||||||
|
|
||||||
|
|
||||||
|
def irom_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
dut.run_test_func(test_func_name)
|
||||||
|
dut.expect_gme('Store access fault')
|
||||||
|
dut.expect_reg_dump(0)
|
||||||
|
dut.expect_cpu_reset()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_FLASH_IDROM, indirect=['config', 'target'])
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_FLASH_IDROM, indirect=['config', 'target'])
|
||||||
def test_irom_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
def test_irom_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
irom_reg_write_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_FLASH_IDROM_L2_NON_CACHE, indirect=['config', 'target'])
|
||||||
|
def test_non_cache_irom_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
if dut.target == 'esp32p4' and not dut.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
|
irom_reg_write_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
def drom_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
dut.run_test_func(test_func_name)
|
dut.run_test_func(test_func_name)
|
||||||
dut.expect_gme('Store access fault')
|
dut.expect_gme('Store access fault')
|
||||||
dut.expect_reg_dump(0)
|
dut.expect_reg_dump(0)
|
||||||
@@ -1012,15 +1117,17 @@ def test_irom_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> Non
|
|||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_FLASH_IDROM, indirect=['config', 'target'])
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_FLASH_IDROM, indirect=['config', 'target'])
|
||||||
def test_drom_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
def test_drom_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
dut.run_test_func(test_func_name)
|
drom_reg_write_violation(dut, test_func_name)
|
||||||
dut.expect_gme('Store access fault')
|
|
||||||
dut.expect_reg_dump(0)
|
|
||||||
dut.expect_cpu_reset()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_FLASH_IDROM, indirect=['config', 'target'])
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_FLASH_IDROM_L2_NON_CACHE, indirect=['config', 'target'])
|
||||||
def test_drom_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
def test_non_cache_drom_reg_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
if dut.target == 'esp32p4' and not dut.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
|
drom_reg_write_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
def drom_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
dut.run_test_func(test_func_name)
|
dut.run_test_func(test_func_name)
|
||||||
dut.expect_gme('Instruction access fault')
|
dut.expect_gme('Instruction access fault')
|
||||||
dut.expect_reg_dump(0)
|
dut.expect_reg_dump(0)
|
||||||
@@ -1028,8 +1135,19 @@ def test_drom_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> N
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_SPIRAM_XIP_IROM_ALIGNMENT_HEAP, indirect=['config', 'target'])
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_FLASH_IDROM, indirect=['config', 'target'])
|
||||||
def test_spiram_xip_irom_alignment_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
def test_drom_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
drom_reg_execute_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_FLASH_IDROM_L2_NON_CACHE, indirect=['config', 'target'])
|
||||||
|
def test_non_cache_drom_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
if dut.target == 'esp32p4' and not dut.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
|
drom_reg_execute_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
def spiram_xip_irom_alignment_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
dut.run_test_func(test_func_name)
|
dut.run_test_func(test_func_name)
|
||||||
try:
|
try:
|
||||||
dut.expect_gme('Instruction access fault')
|
dut.expect_gme('Instruction access fault')
|
||||||
@@ -1040,8 +1158,21 @@ def test_spiram_xip_irom_alignment_reg_execute_violation(dut: PanicTestDut, test
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_SPIRAM_XIP_DROM_ALIGNMENT_HEAP, indirect=['config', 'target'])
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_SPIRAM_XIP_IROM_ALIGNMENT_HEAP, indirect=['config', 'target'])
|
||||||
def test_spiram_xip_drom_alignment_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
def test_spiram_xip_irom_alignment_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
spiram_xip_irom_alignment_reg_execute_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize(
|
||||||
|
'config, target', CONFIGS_MEMPROT_SPIRAM_XIP_IROM_ALIGNMENT_HEAP_L2_NON_CACHE, indirect=['config', 'target']
|
||||||
|
)
|
||||||
|
def test_non_cache_spiram_xip_irom_alignment_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
if dut.target == 'esp32p4' and not dut.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
|
spiram_xip_irom_alignment_reg_execute_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
def spiram_xip_drom_alignment_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
dut.run_test_func(test_func_name)
|
dut.run_test_func(test_func_name)
|
||||||
try:
|
try:
|
||||||
if dut.target == 'esp32s3':
|
if dut.target == 'esp32s3':
|
||||||
@@ -1055,6 +1186,22 @@ def test_spiram_xip_drom_alignment_reg_execute_violation(dut: PanicTestDut, test
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_SPIRAM_XIP_DROM_ALIGNMENT_HEAP, indirect=['config', 'target'])
|
||||||
|
def test_spiram_xip_drom_alignment_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
spiram_xip_drom_alignment_reg_execute_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@idf_parametrize(
|
||||||
|
'config, target', CONFIGS_MEMPROT_SPIRAM_XIP_DROM_ALIGNMENT_HEAP_L2_NON_CACHE, indirect=['config', 'target']
|
||||||
|
)
|
||||||
|
def test_non_cache_spiram_xip_drom_alignment_reg_execute_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
|
if dut.target == 'esp32p4' and not dut.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
|
spiram_xip_drom_alignment_reg_execute_violation(dut, test_func_name)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.generic
|
||||||
|
@pytest.mark.temp_skip_ci(targets=['esp32h21'], reason='lack of runners')
|
||||||
@idf_parametrize('config, target', CONFIGS_MEMPROT_INVALID_REGION_PROTECTION_USING_PMA, indirect=['config', 'target'])
|
@idf_parametrize('config, target', CONFIGS_MEMPROT_INVALID_REGION_PROTECTION_USING_PMA, indirect=['config', 'target'])
|
||||||
def test_invalid_memory_region_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
def test_invalid_memory_region_write_violation(dut: PanicTestDut, test_func_name: str) -> None:
|
||||||
dut.run_test_func(test_func_name)
|
dut.run_test_func(test_func_name)
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ class PanicTestDut(IdfDut):
|
|||||||
return self.target in ['esp32', 'esp32s3', 'esp32p4']
|
return self.target in ['esp32', 'esp32s3', 'esp32p4']
|
||||||
|
|
||||||
def run_test_func(self, test_func_name: str) -> None:
|
def run_test_func(self, test_func_name: str) -> None:
|
||||||
|
if self.target == 'esp32p4' and not self.app.sdkconfig.get('ESP32P4_SELECTS_REV_LESS_V3'):
|
||||||
|
self.write('\n')
|
||||||
self.expect_exact('Enter test name:')
|
self.expect_exact('Enter test name:')
|
||||||
self.write(test_func_name)
|
self.write(test_func_name)
|
||||||
self.expect_exact('Got test name: ' + test_func_name)
|
self.expect_exact('Got test name: ' + test_func_name)
|
||||||
|
|||||||
Reference in New Issue
Block a user