Skip to content

Commit

Permalink
Merge branch 'fix/esp32s3_memprot_v5.0' into 'release/v5.0'
Browse files Browse the repository at this point in the history
ESP32S3: Add memory protection for Icache region (v5.0)

See merge request espressif/esp-idf!21359
  • Loading branch information
igrr committed Dec 1, 2022
2 parents b447086 + af773c0 commit 5afd0f5
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down
18 changes: 18 additions & 0 deletions components/esp_hw_support/port/esp32s3/esp_memprot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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))
Expand Down
70 changes: 63 additions & 7 deletions components/hal/esp32s3/include/hal/memprot_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
};

/* ******************************************************************************************************
Expand Down Expand Up @@ -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 ***
* ******************************************************************************************************/
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
8 changes: 7 additions & 1 deletion components/soc/esp32s3/include/soc/memprot_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 5afd0f5

Please sign in to comment.