diff --git a/components/esp_hw_support/include/soc/esp32s3/soc_memprot_types.h b/components/esp_hw_support/include/soc/esp32s3/soc_memprot_types.h index a5e2351a6c4..c8e79e49399 100644 --- a/components/esp_hw_support/include/soc/esp32s3/soc_memprot_types.h +++ b/components/esp_hw_support/include/soc/esp32s3/soc_memprot_types.h @@ -62,6 +62,8 @@ typedef enum { MEMPROT_PMS_AREA_DRAM0_3 = 0x00000080, MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO = 0x00000100, MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI = 0x00000200, + MEMPROT_PMS_AREA_ICACHE_0 = 0x00000400, + MEMPROT_PMS_AREA_ICACHE_1 = 0x00000800, MEMPROT_PMS_AREA_ALL = 0x7FFFFFFF, MEMPROT_PMS_AREA_INVALID = 0x80000000 } esp_mprot_pms_area_t; @@ -195,6 +197,10 @@ static inline const char *esp_mprot_pms_area_to_str(const esp_mprot_pms_area_t a return "PMS_AREA_IRAM0_RTCFAST_LO"; case MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI: return "PMS_AREA_IRAM0_RTCFAST_HI"; + case MEMPROT_PMS_AREA_ICACHE_0: + return "PMS_AREA_ICACHE_0"; + case MEMPROT_PMS_AREA_ICACHE_1: + return "PMS_AREA_ICACHE_1"; case MEMPROT_PMS_AREA_ALL: return "PMS_AREA_ALL"; default: diff --git a/components/esp_hw_support/port/esp32s3/esp_memprot.c b/components/esp_hw_support/port/esp32s3/esp_memprot.c index be41906b6e4..4c17741b4cc 100644 --- a/components/esp_hw_support/port/esp32s3/esp_memprot.c +++ b/components/esp_hw_support/port/esp32s3/esp_memprot.c @@ -334,6 +334,12 @@ esp_err_t esp_mprot_set_pms_area(const esp_mprot_pms_area_t area_type, const uin ESP_MEMPROT_ERR_CHECK(err, esp_mprot_cpuid_valid(core)) ESP_MEMPROT_ERR_CHECK(err, esp_mprot_ll_err_to_esp_err(memprot_ll_rtcfast_set_pms_area(core, r, w, x, MEMP_HAL_WORLD_0, MEMP_HAL_AREA_HIGH))) break; + case MEMPROT_PMS_AREA_ICACHE_0: + memprot_ll_icache_set_pms_area_0(r, w, x); + break; + case MEMPROT_PMS_AREA_ICACHE_1: + memprot_ll_icache_set_pms_area_1(r, w, x); + break; default: return ESP_ERR_NOT_SUPPORTED; } @@ -385,6 +391,12 @@ esp_err_t esp_mprot_get_pms_area(const esp_mprot_pms_area_t area_type, uint32_t ESP_MEMPROT_ERR_CHECK(err, esp_mprot_cpuid_valid(core)) ESP_MEMPROT_ERR_CHECK(err, esp_mprot_ll_err_to_esp_err(memprot_ll_rtcfast_get_pms_area(core, &r, &w, &x, MEMP_HAL_WORLD_0, MEMP_HAL_AREA_HIGH))) break; + case MEMPROT_PMS_AREA_ICACHE_0: + memprot_ll_icache_get_pms_area_0(&r, &w, &x); + break; + case MEMPROT_PMS_AREA_ICACHE_1: + memprot_ll_icache_get_pms_area_1(&r, &w, &x); + break; default: return ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID; } @@ -955,6 +967,12 @@ esp_err_t esp_mprot_set_prot(const esp_memp_config_t *memp_config) //set permissions if (use_iram0) { ret = ESP_OK; + ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_ICACHE_0, MEMPROT_OP_NONE, DEFAULT_CPU_NUM)); +#if CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB + ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_ICACHE_1, MEMPROT_OP_READ | MEMPROT_OP_EXEC, DEFAULT_CPU_NUM)); +#else + ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_ICACHE_1, MEMPROT_OP_NONE, DEFAULT_CPU_NUM)); +#endif ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_0, MEMPROT_OP_READ | MEMPROT_OP_EXEC, DEFAULT_CPU_NUM)) ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_1, MEMPROT_OP_READ | MEMPROT_OP_EXEC, DEFAULT_CPU_NUM)) ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_2, MEMPROT_OP_READ | MEMPROT_OP_EXEC, DEFAULT_CPU_NUM)) diff --git a/components/hal/esp32s3/include/hal/memprot_ll.h b/components/hal/esp32s3/include/hal/memprot_ll.h index 748591b5d79..f4528c53577 100644 --- a/components/hal/esp32s3/include/hal/memprot_ll.h +++ b/components/hal/esp32s3/include/hal/memprot_ll.h @@ -25,16 +25,16 @@ extern "C" { #endif - //highest address of each Level slot in the SRAM's 3rd memory region (I/D access, 416kB) +//highest address of each Level slot in the SRAM's 3rd memory region (I/D access, 416kB) //quick resolver of split-address category bits static const intptr_t sram_rg3_level_hlimits[] = { 0x4037FFFF, //level 2 (32KB) 0x4038FFFF, //level 3 (64KB) 0x4039FFFF, //level 4 (64KB) - 0x403A0000, //level 5 (64KB) - 0x403B0000, //level 6 (64KB) - 0x403C0000, //level 7 (64KB) - 0x403D0000 //level 8 (64KB) + 0x403AFFFF, //level 5 (64KB) + 0x403BFFFF, //level 6 (64KB) + 0x403CFFFF, //level 7 (64KB) + 0x403DFFFF //level 8 (64KB) }; /* ****************************************************************************************************** @@ -81,6 +81,62 @@ static inline void *memprot_ll_get_split_addr_from_reg(const uint32_t regval, co return (void *)(base + level_off + off); } +/* ****************************************************************************************************** + * *** ICACHE *** + * ******************************************************************************************************/ +static inline uint32_t memprot_ll_icache_set_permissions(const bool r, const bool w, const bool x) +{ + uint32_t permissions = 0; + if (r) { + permissions |= SENSITIVE_CORE_X_ICACHE_PMS_CONSTRAIN_SRAM_WORLD_X_R; + } + if (w) { + permissions |= SENSITIVE_CORE_X_ICACHE_PMS_CONSTRAIN_SRAM_WORLD_X_W; + } + if (x) { + permissions |= SENSITIVE_CORE_X_ICACHE_PMS_CONSTRAIN_SRAM_WORLD_X_F; + } + + return permissions; +} + +static inline void memprot_ll_icache_set_pms_area_0(const bool r, const bool w, const bool x) +{ + REG_SET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_CACHEDATAARRAY_PMS_0, memprot_ll_icache_set_permissions(r, w, x)); +#ifdef PMS_DEBUG_ASSERTIONS + uint32_t expected = REG_GET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_CACHEDATAARRAY_PMS_0); + HAL_ASSERT((expected == memprot_ll_icache_set_permissions(r, w, x)) && "Value not stored to required register"); +#endif +} + +static inline void memprot_ll_icache_set_pms_area_1(const bool r, const bool w, const bool x) +{ + REG_SET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_CACHEDATAARRAY_PMS_1, memprot_ll_icache_set_permissions(r, w, x)); +#ifdef PMS_DEBUG_ASSERTIONS + uint32_t expected = REG_GET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_CACHEDATAARRAY_PMS_1); + HAL_ASSERT((expected == memprot_ll_icache_set_permissions(r, w, x)) && "Value not stored to required register"); +#endif +} + +static inline void memprot_ll_icache_get_permissions(const uint32_t perms, bool *r, bool *w, bool *x) +{ + *r = perms & SENSITIVE_CORE_X_ICACHE_PMS_CONSTRAIN_SRAM_WORLD_X_R; + *w = perms & SENSITIVE_CORE_X_ICACHE_PMS_CONSTRAIN_SRAM_WORLD_X_W; + *x = perms & SENSITIVE_CORE_X_ICACHE_PMS_CONSTRAIN_SRAM_WORLD_X_F; +} + +static inline void memprot_ll_icache_get_pms_area_0(bool *r, bool *w, bool *x) +{ + uint32_t permissions = REG_GET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_CACHEDATAARRAY_PMS_0); + memprot_ll_icache_get_permissions(permissions, r, w, x); +} + +static inline void memprot_ll_icache_get_pms_area_1(bool *r, bool *w, bool *x) +{ + uint32_t permissions = REG_GET_FIELD(SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_2_REG, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_0_CACHEDATAARRAY_PMS_1); + memprot_ll_icache_get_permissions(permissions, r, w, x); +} + /* ****************************************************************************************************** * *** IRAM0 *** * ******************************************************************************************************/ @@ -571,7 +627,7 @@ static inline memprot_hal_err_t memprot_ll_iram0_get_monitor_status_fault_addr(c return MEMP_HAL_ERR_CORE_INVALID; } - *addr = (void*)(reg_off > 0 ? (reg_off << I_D_FAULT_ADDR_SHIFT) + IRAM0_ADDRESS_LOW : 0); + *addr = (void*)(reg_off > 0 ? (reg_off << I_FAULT_ADDR_SHIFT) + IRAM0_ADDRESS_LOW : 0); return MEMP_HAL_OK; } @@ -1590,7 +1646,7 @@ static inline memprot_hal_err_t memprot_ll_dram0_get_monitor_status_fault_addr(c return MEMP_HAL_ERR_CORE_INVALID; } - *addr = (void*)(reg_off > 0 ? (reg_off << I_D_FAULT_ADDR_SHIFT) + IRAM0_ADDRESS_LOW : 0); + *addr = (void*)(reg_off > 0 ? (reg_off << D_FAULT_ADDR_SHIFT) + DRAM0_ADDRESS_LOW : 0); return MEMP_HAL_OK; } diff --git a/components/soc/esp32s3/include/soc/memprot_defs.h b/components/soc/esp32s3/include/soc/memprot_defs.h index 1aa97de1670..86dbf1a753c 100644 --- a/components/soc/esp32s3/include/soc/memprot_defs.h +++ b/components/soc/esp32s3/include/soc/memprot_defs.h @@ -39,7 +39,13 @@ typedef union { #define I_D_SRAM_SEGMENT_SIZE 0x10000 #define I_D_SPLIT_LINE_ALIGN 0x100 #define I_D_SPLIT_LINE_SHIFT 0x8 -#define I_D_FAULT_ADDR_SHIFT 0x2 +#define I_FAULT_ADDR_SHIFT 0x2 +#define D_FAULT_ADDR_SHIFT 0x4 + +//Icache +#define SENSITIVE_CORE_X_ICACHE_PMS_CONSTRAIN_SRAM_WORLD_X_R 0x1 +#define SENSITIVE_CORE_X_ICACHE_PMS_CONSTRAIN_SRAM_WORLD_X_W 0x2 +#define SENSITIVE_CORE_X_ICACHE_PMS_CONSTRAIN_SRAM_WORLD_X_F 0x4 //IRAM0 #define SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_X_R 0x1