mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
fix(esp_hw_support): Fix the I/DCACHE region PMP protection
This commit is contained in:
parent
929a8449bd
commit
5173ba1777
@ -13,17 +13,45 @@
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
// Without L bit set
|
||||
#define CONDITIONAL_NONE 0x0
|
||||
#define CONDITIONAL_R PMP_R
|
||||
#define CONDITIONAL_RX PMP_R | PMP_X
|
||||
#define CONDITIONAL_RW PMP_R | PMP_W
|
||||
#define CONDITIONAL_RWX PMP_R | PMP_W | PMP_X
|
||||
#else
|
||||
// With L bit set
|
||||
#define CONDITIONAL_NONE NONE
|
||||
#define CONDITIONAL_R R
|
||||
#define CONDITIONAL_RX RX
|
||||
#define CONDITIONAL_RW RW
|
||||
#define CONDITIONAL_RWX RWX
|
||||
#endif
|
||||
|
||||
#define ALIGN_UP_TO_MMU_PAGE_SIZE(addr) (((addr) + (SOC_MMU_PAGE_SIZE) - 1) & ~((SOC_MMU_PAGE_SIZE) - 1))
|
||||
#define ALIGN_DOWN_TO_MMU_PAGE_SIZE(addr) ((addr) & ~((SOC_MMU_PAGE_SIZE) - 1))
|
||||
|
||||
/**
|
||||
* @brief Generate the PMP address field value for PMPCFG.A == NAPOT
|
||||
*
|
||||
* NOTE: Here, (end-start) must be a power of 2 size and start must
|
||||
* be aligned to this size. This API returns UINT32_MAX on failing
|
||||
* these conditions, which when plugged into the PMP entry registers
|
||||
* does nothing. This skips the corresponding region's protection.
|
||||
*
|
||||
* @param start Region starting address
|
||||
* @param end Region ending address
|
||||
*
|
||||
* @return uint32_t PMP address field value
|
||||
*/
|
||||
static inline uint32_t pmpaddr_napot(uint32_t start, uint32_t end)
|
||||
{
|
||||
uint32_t size = end - start;
|
||||
if ((size & (size - 1)) || (start % size)) {
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
return start | ((size - 1) >> 1);
|
||||
}
|
||||
|
||||
static void esp_cpu_configure_invalid_regions(void)
|
||||
{
|
||||
const unsigned PMA_NONE = PMA_L | PMA_EN;
|
||||
@ -155,15 +183,30 @@ void esp_cpu_configure_region_protection(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||
extern int _instruction_reserved_end;
|
||||
extern int _rodata_reserved_start;
|
||||
extern int _rodata_reserved_end;
|
||||
|
||||
const uint32_t irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_instruction_reserved_end));
|
||||
const uint32_t drom_resv_start = ALIGN_DOWN_TO_MMU_PAGE_SIZE((uint32_t)(&_rodata_reserved_start));
|
||||
const uint32_t drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_rodata_reserved_end));
|
||||
|
||||
// 4. I_Cache (flash)
|
||||
const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH);
|
||||
PMP_ENTRY_CFG_RESET(8);
|
||||
const uint32_t pmpaddr8 = pmpaddr_napot(SOC_IROM_LOW, irom_resv_end);
|
||||
PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | RX);
|
||||
_Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I_Cache region");
|
||||
|
||||
// 5. D_Cache (flash)
|
||||
const uint32_t pmpaddr9 = PMPADDR_NAPOT(SOC_DROM_LOW, SOC_DROM_HIGH);
|
||||
PMP_ENTRY_CFG_RESET(9);
|
||||
const uint32_t pmpaddr9 = pmpaddr_napot(drom_resv_start, drom_resv_end);
|
||||
PMP_ENTRY_SET(9, pmpaddr9, PMP_NAPOT | R);
|
||||
_Static_assert(SOC_DROM_LOW < SOC_DROM_HIGH, "Invalid D_Cache region");
|
||||
#else
|
||||
// 4. I_Cache / D_Cache (flash)
|
||||
const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH);
|
||||
PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | CONDITIONAL_RX);
|
||||
_Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I/D_Cache region");
|
||||
#endif
|
||||
|
||||
// 6. LP memory
|
||||
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||
|
@ -13,17 +13,45 @@
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
// Without L bit set
|
||||
#define CONDITIONAL_NONE 0x0
|
||||
#define CONDITIONAL_R PMP_R
|
||||
#define CONDITIONAL_RX PMP_R | PMP_X
|
||||
#define CONDITIONAL_RW PMP_R | PMP_W
|
||||
#define CONDITIONAL_RWX PMP_R | PMP_W | PMP_X
|
||||
#else
|
||||
// With L bit set
|
||||
#define CONDITIONAL_NONE NONE
|
||||
#define CONDITIONAL_R R
|
||||
#define CONDITIONAL_RX RX
|
||||
#define CONDITIONAL_RW RW
|
||||
#define CONDITIONAL_RWX RWX
|
||||
#endif
|
||||
|
||||
#define ALIGN_UP_TO_MMU_PAGE_SIZE(addr) (((addr) + (SOC_MMU_PAGE_SIZE) - 1) & ~((SOC_MMU_PAGE_SIZE) - 1))
|
||||
#define ALIGN_DOWN_TO_MMU_PAGE_SIZE(addr) ((addr) & ~((SOC_MMU_PAGE_SIZE) - 1))
|
||||
|
||||
/**
|
||||
* @brief Generate the PMP address field value for PMPCFG.A == NAPOT
|
||||
*
|
||||
* NOTE: Here, (end-start) must be a power of 2 size and start must
|
||||
* be aligned to this size. This API returns UINT32_MAX on failing
|
||||
* these conditions, which when plugged into the PMP entry registers
|
||||
* does nothing. This skips the corresponding region's protection.
|
||||
*
|
||||
* @param start Region starting address
|
||||
* @param end Region ending address
|
||||
*
|
||||
* @return uint32_t PMP address field value
|
||||
*/
|
||||
static inline uint32_t pmpaddr_napot(uint32_t start, uint32_t end)
|
||||
{
|
||||
uint32_t size = end - start;
|
||||
if ((size & (size - 1)) || (start % size)) {
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
return start | ((size - 1) >> 1);
|
||||
}
|
||||
|
||||
static void esp_cpu_configure_invalid_regions(void)
|
||||
{
|
||||
const unsigned PMA_NONE = PMA_L | PMA_EN;
|
||||
@ -155,15 +183,30 @@ void esp_cpu_configure_region_protection(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||
extern int _instruction_reserved_end;
|
||||
extern int _rodata_reserved_start;
|
||||
extern int _rodata_reserved_end;
|
||||
|
||||
const uint32_t irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_instruction_reserved_end));
|
||||
const uint32_t drom_resv_start = ALIGN_DOWN_TO_MMU_PAGE_SIZE((uint32_t)(&_rodata_reserved_start));
|
||||
const uint32_t drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_rodata_reserved_end));
|
||||
|
||||
// 4. I_Cache (flash)
|
||||
const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH);
|
||||
PMP_ENTRY_CFG_RESET(8);
|
||||
const uint32_t pmpaddr8 = pmpaddr_napot(SOC_IROM_LOW, irom_resv_end);
|
||||
PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | RX);
|
||||
_Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I_Cache region");
|
||||
|
||||
// 5. D_Cache (flash)
|
||||
const uint32_t pmpaddr9 = PMPADDR_NAPOT(SOC_DROM_LOW, SOC_DROM_HIGH);
|
||||
PMP_ENTRY_CFG_RESET(9);
|
||||
const uint32_t pmpaddr9 = pmpaddr_napot(drom_resv_start, drom_resv_end);
|
||||
PMP_ENTRY_SET(9, pmpaddr9, PMP_NAPOT | R);
|
||||
_Static_assert(SOC_DROM_LOW < SOC_DROM_HIGH, "Invalid D_Cache region");
|
||||
#else
|
||||
// 4. I_Cache / D_Cache (flash)
|
||||
const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH);
|
||||
PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | CONDITIONAL_RX);
|
||||
_Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I/D_Cache region");
|
||||
#endif
|
||||
|
||||
// 6. LP memory
|
||||
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||
|
Loading…
x
Reference in New Issue
Block a user