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
|
#ifdef BOOTLOADER_BUILD
|
||||||
// Without L bit set
|
// Without L bit set
|
||||||
#define CONDITIONAL_NONE 0x0
|
#define CONDITIONAL_NONE 0x0
|
||||||
|
#define CONDITIONAL_R PMP_R
|
||||||
#define CONDITIONAL_RX PMP_R | PMP_X
|
#define CONDITIONAL_RX PMP_R | PMP_X
|
||||||
#define CONDITIONAL_RW PMP_R | PMP_W
|
#define CONDITIONAL_RW PMP_R | PMP_W
|
||||||
#define CONDITIONAL_RWX PMP_R | PMP_W | PMP_X
|
#define CONDITIONAL_RWX PMP_R | PMP_W | PMP_X
|
||||||
#else
|
#else
|
||||||
// With L bit set
|
// With L bit set
|
||||||
#define CONDITIONAL_NONE NONE
|
#define CONDITIONAL_NONE NONE
|
||||||
|
#define CONDITIONAL_R R
|
||||||
#define CONDITIONAL_RX RX
|
#define CONDITIONAL_RX RX
|
||||||
#define CONDITIONAL_RW RW
|
#define CONDITIONAL_RW RW
|
||||||
#define CONDITIONAL_RWX RWX
|
#define CONDITIONAL_RWX RWX
|
||||||
#endif
|
#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)
|
static void esp_cpu_configure_invalid_regions(void)
|
||||||
{
|
{
|
||||||
const unsigned PMA_NONE = PMA_L | PMA_EN;
|
const unsigned PMA_NONE = PMA_L | PMA_EN;
|
||||||
@ -155,15 +183,30 @@ void esp_cpu_configure_region_protection(void)
|
|||||||
#endif
|
#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)
|
// 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);
|
PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | RX);
|
||||||
_Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I_Cache region");
|
|
||||||
|
|
||||||
// 5. D_Cache (flash)
|
// 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);
|
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
|
// 6. LP memory
|
||||||
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||||
|
@ -13,17 +13,45 @@
|
|||||||
#ifdef BOOTLOADER_BUILD
|
#ifdef BOOTLOADER_BUILD
|
||||||
// Without L bit set
|
// Without L bit set
|
||||||
#define CONDITIONAL_NONE 0x0
|
#define CONDITIONAL_NONE 0x0
|
||||||
|
#define CONDITIONAL_R PMP_R
|
||||||
#define CONDITIONAL_RX PMP_R | PMP_X
|
#define CONDITIONAL_RX PMP_R | PMP_X
|
||||||
#define CONDITIONAL_RW PMP_R | PMP_W
|
#define CONDITIONAL_RW PMP_R | PMP_W
|
||||||
#define CONDITIONAL_RWX PMP_R | PMP_W | PMP_X
|
#define CONDITIONAL_RWX PMP_R | PMP_W | PMP_X
|
||||||
#else
|
#else
|
||||||
// With L bit set
|
// With L bit set
|
||||||
#define CONDITIONAL_NONE NONE
|
#define CONDITIONAL_NONE NONE
|
||||||
|
#define CONDITIONAL_R R
|
||||||
#define CONDITIONAL_RX RX
|
#define CONDITIONAL_RX RX
|
||||||
#define CONDITIONAL_RW RW
|
#define CONDITIONAL_RW RW
|
||||||
#define CONDITIONAL_RWX RWX
|
#define CONDITIONAL_RWX RWX
|
||||||
#endif
|
#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)
|
static void esp_cpu_configure_invalid_regions(void)
|
||||||
{
|
{
|
||||||
const unsigned PMA_NONE = PMA_L | PMA_EN;
|
const unsigned PMA_NONE = PMA_L | PMA_EN;
|
||||||
@ -155,15 +183,30 @@ void esp_cpu_configure_region_protection(void)
|
|||||||
#endif
|
#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)
|
// 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);
|
PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | RX);
|
||||||
_Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I_Cache region");
|
|
||||||
|
|
||||||
// 5. D_Cache (flash)
|
// 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);
|
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
|
// 6. LP memory
|
||||||
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD
|
||||||
|
Loading…
x
Reference in New Issue
Block a user