mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Security: ESP32C3 memory protection feature (IRAM0/DRAM0)
Software support for PMS module. Allows controlled memory access to IRAM (R/W/X) and DRAM0 (R/W) On/locked by default, configurable in Kconfig (esp_system) Closes https://jira.espressif.com:8443/browse/IDF-2092
This commit is contained in:
@@ -22,6 +22,9 @@
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/cache_err_int.h"
|
||||
#endif
|
||||
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
|
||||
#include "esp32c3/memprot.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define DIM(array) (sizeof(array)/sizeof(*array))
|
||||
@@ -33,7 +36,7 @@
|
||||
*/
|
||||
typedef struct {
|
||||
const uint32_t bit;
|
||||
const char* msg;
|
||||
const char *msg;
|
||||
} register_bit_t;
|
||||
|
||||
/**
|
||||
@@ -45,8 +48,8 @@ typedef struct {
|
||||
* be set in the register will have its associated message printed.
|
||||
*/
|
||||
static inline bool test_and_print_register_bits(const uint32_t status,
|
||||
const register_bit_t* reg_bits,
|
||||
const uint32_t size)
|
||||
const register_bit_t *reg_bits,
|
||||
const uint32_t size)
|
||||
{
|
||||
/* Browse the flag/bit array and test each one with the given status
|
||||
* register. */
|
||||
@@ -69,7 +72,7 @@ static inline bool test_and_print_register_bits(const uint32_t status,
|
||||
* Function called when a cache error occurs. It prints details such as the
|
||||
* explanation of why the panic occured.
|
||||
*/
|
||||
static inline void print_cache_err_details(const void* frame)
|
||||
static inline void print_cache_err_details(const void *frame)
|
||||
{
|
||||
/* Define the array that contains the status (bits) to test on the register
|
||||
* EXTMEM_CORE0_ACS_CACHE_INT_ST_REG. each bit is accompanied by a small
|
||||
@@ -145,6 +148,47 @@ static inline void print_cache_err_details(const void* frame)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called when a memory protection error occurs (PMS). It prints details such as the
|
||||
* explanation of why the panic occured.
|
||||
*/
|
||||
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
|
||||
static inline void print_memprot_err_details(const void *frame)
|
||||
{
|
||||
//common memprot fault info
|
||||
mem_type_prot_t mem_type = esp_memprot_get_active_intr_memtype();
|
||||
panic_print_str( " memory type: ");
|
||||
panic_print_str( mem_type_to_str(mem_type) );
|
||||
panic_print_str( "\r\n faulting address: ");
|
||||
panic_print_hex( esp_memprot_get_violate_addr(mem_type) );
|
||||
panic_print_str( "\r\n world: ");
|
||||
panic_print_hex( esp_memprot_get_violate_world(mem_type) );
|
||||
|
||||
char operation = 0;
|
||||
// IRAM fault: check instruction-fetch flag
|
||||
if ( mem_type == MEMPROT_IRAM0_SRAM ) {
|
||||
if ( esp_memprot_get_violate_loadstore(mem_type) == 1 ) {
|
||||
operation = 'X';
|
||||
}
|
||||
}
|
||||
// W/R - common
|
||||
if ( operation == 0 ) {
|
||||
operation = esp_memprot_get_violate_wr(mem_type) == 1 ? 'W' : 'R';
|
||||
}
|
||||
panic_print_str( "\r\n operation type: ");
|
||||
panic_print_char( operation );
|
||||
|
||||
// DRAM/DMA fault: check byte-enables
|
||||
if ( mem_type == MEMPROT_DRAM0_SRAM ) {
|
||||
panic_print_str("\r\n byte-enables: " );
|
||||
panic_print_hex(esp_memprot_get_violate_byte_en(mem_type));
|
||||
}
|
||||
|
||||
panic_print_str("\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void panic_print_registers(const void *f, int core)
|
||||
{
|
||||
uint32_t *regs = (uint32_t *)f;
|
||||
@@ -190,7 +234,10 @@ void panic_soc_fill_info(void *f, panic_info_t *info)
|
||||
#if SOC_CPU_NUM > 1
|
||||
"Interrupt wdt timeout on CPU1",
|
||||
#endif
|
||||
"Cache error"
|
||||
"Cache error",
|
||||
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
|
||||
"Memory protection fault",
|
||||
#endif
|
||||
};
|
||||
|
||||
info->reason = pseudo_reason[0];
|
||||
@@ -204,14 +251,16 @@ void panic_soc_fill_info(void *f, panic_info_t *info)
|
||||
* assign function print_cache_err_details to our structure's
|
||||
* details field. As its name states, it will give more details
|
||||
* about why the error happened. */
|
||||
|
||||
info->core = esp_cache_err_get_cpuid();
|
||||
info->reason = pseudo_reason[PANIC_RSN_CACHEERR];
|
||||
info->details = print_cache_err_details;
|
||||
|
||||
} else if (frame->mcause == ETS_T1_WDT_INUM) {
|
||||
/* Watchdog interrupt occured, get the core on which it happened
|
||||
* and update the reason/message accordingly. */
|
||||
const int core = esp_cache_err_get_cpuid();
|
||||
|
||||
const int core = esp_cache_err_get_cpuid();
|
||||
info->core = core;
|
||||
info->exception = PANIC_EXCEPTION_IWDT;
|
||||
|
||||
@@ -221,6 +270,14 @@ void panic_soc_fill_info(void *f, panic_info_t *info)
|
||||
#endif
|
||||
info->reason = pseudo_reason[PANIC_RSN_INTWDT_CPU0 + core];
|
||||
}
|
||||
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
|
||||
else if ( frame->mcause == ETS_MEMPROT_ERR_INUM ) {
|
||||
|
||||
info->core = esp_memprot_intr_get_cpuid();
|
||||
info->reason = pseudo_reason[PANIC_RSN_MEMPROT];
|
||||
info->details = print_memprot_err_details;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void panic_arch_fill_info(void *frame, panic_info_t *info)
|
||||
|
||||
@@ -31,11 +31,15 @@
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/cache_err_int.h"
|
||||
#ifdef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
|
||||
#include "esp32s2/memprot.h"
|
||||
#endif
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/cache_err_int.h"
|
||||
#ifdef CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
|
||||
#include "esp32s3/memprot.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif // CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
void panic_print_registers(const void *f, int core)
|
||||
@@ -261,6 +265,7 @@ static inline void print_cache_err_details(const void *f)
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
|
||||
static inline void print_memprot_err_details(const void *f)
|
||||
{
|
||||
uint32_t *fault_addr;
|
||||
@@ -278,6 +283,7 @@ static inline void print_memprot_err_details(const void *f)
|
||||
panic_print_hex( (uint32_t)fault_addr );
|
||||
panic_print_str(" not permitted.\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
static inline void print_cache_err_details(const void* f)
|
||||
@@ -346,10 +352,6 @@ static inline void print_cache_err_details(const void* f)
|
||||
}
|
||||
panic_print_str("\r\n");
|
||||
}
|
||||
|
||||
static inline void print_memprot_err_details(const void *f)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -429,10 +431,13 @@ void panic_soc_fill_info(void *f, panic_info_t *info)
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
if (frame->exccause == PANIC_RSN_CACHEERR) {
|
||||
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE
|
||||
if ( esp_memprot_is_intr_ena_any() ) {
|
||||
info->details = print_memprot_err_details;
|
||||
info->reason = "Memory protection fault";
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
info->details = print_cache_err_details;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user