Merge branch 'feature/support_cache_p4' into 'master'

cache: support cache driver on esp32p4

Closes IDF-7516

See merge request espressif/esp-idf!25490
This commit is contained in:
Armando (Dou Yiwen)
2023-09-25 15:21:46 +08:00
46 changed files with 2233 additions and 558 deletions

View File

@@ -38,6 +38,11 @@ extern "C" {
#define CACHE_LL_L1_ILG_EVENT_ICACHE_PRELOAD_OP_FAULT (1<<1)
#define CACHE_LL_L1_ILG_EVENT_ICACHE_SYNC_OP_FAULT (1<<0)
#define CACHE_LL_ID_ALL 2 //All of the caches in a type and level, make this value greater than any id
#define CACHE_LL_LEVEL_INT_MEM 0 //Cache level for accessing internal mem
#define CACHE_LL_LEVEL_EXT_MEM 1 //Cache level for accessing external mem
#define CACHE_LL_LEVEL_ALL 2 //All of the cache levels, make this value greater than any level
#define CACHE_LL_LEVEL_NUMS 1 //Number of cache levels
#define CACHE_LL_L1_ICACHE_AUTOLOAD (1<<2)
#define CACHE_LL_L1_DCACHE_AUTOLOAD (1<<2)
@@ -72,15 +77,18 @@ static inline bool cache_ll_l1_is_dcache_autoload_enabled(void)
}
/**
* @brief Check if ICache or DCache auto preload is enabled or not
* @brief Check if Cache auto preload is enabled or not.
*
* @param type see `cache_type_t`
* @param cache_level level of the cache
* @param type see `cache_type_t`
* @param cache_id id of the cache in this type and level
*
* @return true: enabled; false: disabled
*/
__attribute__((always_inline))
static inline bool cache_ll_is_cache_autoload_enabled(cache_type_t type)
static inline bool cache_ll_is_cache_autoload_enabled(uint32_t cache_level, cache_type_t type, uint32_t cache_id)
{
HAL_ASSERT(cache_id <= CACHE_LL_ID_ALL);
bool enabled = false;
switch (type)
{
@@ -116,12 +124,14 @@ static inline void cache_ll_l1_disable_dcache(void)
}
/**
* @brief Disable ICache or DCache or both
* @brief Disable Cache
*
* @param type see `cache_type_t`
* @param cache_level level of the cache
* @param type see `cache_type_t`
* @param cache_id id of the cache in this type and level
*/
__attribute__((always_inline))
static inline void cache_ll_disable_cache(cache_type_t type)
static inline void cache_ll_disable_cache(uint32_t cache_level, cache_type_t type, uint32_t cache_id)
{
switch (type)
{
@@ -161,16 +171,16 @@ static inline void cache_ll_l1_enable_dcache(bool data_autoload_en)
}
/**
* @brief Enable ICache or DCache or both
* @brief Enable Cache
*
* @param type see `cache_type_t`
*
* @param data_autoload_en Dcache auto preload enabled
*
* @param inst_autoload_en Icache auto preload enabled
* @param cache_level level of the cache
* @param type see `cache_type_t`
* @param cache_id id of the cache in this type and level
* @param data_autoload_en data autoload enabled or not
* @param inst_autoload_en inst autoload enabled or not
*/
__attribute__((always_inline))
static inline void cache_ll_enable_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en)
static inline void cache_ll_enable_cache(uint32_t cache_level, cache_type_t type, uint32_t cache_id, bool inst_autoload_en, bool data_autoload_en)
{
switch (type)
{
@@ -206,12 +216,14 @@ static inline void cache_ll_l1_suspend_dcache(void)
}
/**
* @brief Suspend ICache or DCache or both
* @brief Suspend Cache
*
* @param type see `cache_type_t`
* @param cache_level level of the cache
* @param type see `cache_type_t`
* @param cache_id id of the cache in this type and level
*/
__attribute__((always_inline))
static inline void cache_ll_suspend_cache(cache_type_t type)
static inline void cache_ll_suspend_cache(uint32_t cache_level, cache_type_t type, uint32_t cache_id)
{
switch (type)
{
@@ -251,16 +263,16 @@ static inline void cache_ll_l1_resume_dcache(bool data_autoload_en)
}
/**
* @brief Resume ICache or DCache or both
* @brief Resume Cache
*
* @param type see `cache_type_t`
*
* @param data_autoload_en Dcache auto preload enabled
*
* @param inst_autoload_en Icache auto preload enabled
* @param cache_level level of the cache
* @param type see `cache_type_t`
* @param cache_id id of the cache in this type and level
* @param data_autoload_en data autoload enabled or not
* @param inst_autoload_en inst autoload enabled or not
*/
__attribute__((always_inline))
static inline void cache_ll_resume_cache(cache_type_t type, bool inst_autoload_en, bool data_autoload_en)
static inline void cache_ll_resume_cache(uint32_t cache_level, cache_type_t type, uint32_t cache_id, bool inst_autoload_en, bool data_autoload_en)
{
switch (type)
{
@@ -287,7 +299,7 @@ static inline void cache_ll_resume_cache(cache_type_t type, bool inst_autoload_e
__attribute__((always_inline))
static inline bool cache_ll_l1_is_icache_enabled(uint32_t cache_id)
{
HAL_ASSERT(cache_id == 0 || cache_id == 1);
HAL_ASSERT(cache_id <= CACHE_LL_ID_ALL);
return REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE);
}
@@ -301,7 +313,7 @@ static inline bool cache_ll_l1_is_icache_enabled(uint32_t cache_id)
__attribute__((always_inline))
static inline bool cache_ll_l1_is_dcache_enabled(uint32_t cache_id)
{
HAL_ASSERT(cache_id == 0 || cache_id == 1);
HAL_ASSERT(cache_id <= CACHE_LL_ID_ALL);
return REG_GET_BIT(EXTMEM_DCACHE_CTRL_REG, EXTMEM_DCACHE_ENABLE);
}
@@ -334,13 +346,16 @@ static inline bool cache_ll_is_cache_enabled(cache_type_t type)
/**
* @brief Invalidate cache supported addr
*
* Invalidate a Cache item for either ICache or DCache.
* Invalidate a cache item
*
* @param vaddr Start address of the region to be invalidated
* @param size Size of the region to be invalidated
* @param cache_level level of the cache
* @param type see `cache_type_t`
* @param cache_id id of the cache in this type and level
* @param vaddr start address of the region to be invalidated
* @param size size of the region to be invalidated
*/
__attribute__((always_inline))
static inline void cache_ll_invalidate_addr(uint32_t vaddr, uint32_t size)
static inline void cache_ll_invalidate_addr(uint32_t cache_level, cache_type_t type, uint32_t cache_id, uint32_t vaddr, uint32_t size)
{
Cache_Invalidate_Addr(vaddr, size);
}
@@ -348,13 +363,16 @@ static inline void cache_ll_invalidate_addr(uint32_t vaddr, uint32_t size)
/**
* @brief Writeback cache supported addr
*
* Writeback the DCache item to external memory
* Writeback a cache item
*
* @param vaddr Start address of the region to writeback
* @param size Size of the region to writeback
* @param cache_level level of the cache
* @param type see `cache_type_t`
* @param cache_id id of the cache in this type and level
* @param vaddr start address of the region to be written back
* @param size size of the region to be written back
*/
__attribute__((always_inline))
static inline void cache_ll_writeback_addr(uint32_t vaddr, uint32_t size)
static inline void cache_ll_writeback_addr(uint32_t cache_level, cache_type_t type, uint32_t cache_id, uint32_t vaddr, uint32_t size)
{
Cache_WriteBack_Addr(vaddr, size);
}
@@ -378,12 +396,14 @@ static inline void cache_ll_l1_freeze_dcache(void)
}
/**
* @brief Freeze ICache or DCache or both
* @brief Freeze Cache
*
* @param type see `cache_type_t`
* @param cache_level level of the cache
* @param type see `cache_type_t`
* @param cache_id id of the cache in this type and level
*/
__attribute__((always_inline))
static inline void cache_ll_freeze_cache(cache_type_t type)
static inline void cache_ll_freeze_cache(uint32_t cache_level, cache_type_t type, uint32_t cache_id)
{
switch (type)
{
@@ -419,12 +439,14 @@ static inline void cache_ll_l1_unfreeze_dcache(void)
}
/**
* @brief Unfreeze ICache or DCache or both
* @brief Unfreeze Cache
*
* @param type see `cache_type_t`
* @param cache_level level of the cache
* @param type see `cache_type_t`
* @param cache_id id of the cache in this type and level
*/
__attribute__((always_inline))
static inline void cache_ll_unfreeze_cache(cache_type_t type)
static inline void cache_ll_unfreeze_cache(uint32_t cache_level, cache_type_t type, uint32_t cache_id)
{
switch (type)
{
@@ -468,14 +490,16 @@ static inline uint32_t cache_ll_l1_dcache_get_line_size(void)
}
/**
* @brief Get ICache or DCache line size, in bytes
* @brief Get Cache line size, in bytes
*
* @param type see `cache_type_t`
* @param cache_level level of the cache
* @param type see `cache_type_t`
* @param cache_id id of the cache in this type and level
*
* @return ICache/DCache line size, in bytes
* @return Cache line size, in bytes
*/
__attribute__((always_inline))
static inline uint32_t cache_ll_get_line_size(cache_type_t type)
static inline uint32_t cache_ll_get_line_size(uint32_t cache_level, cache_type_t type, uint32_t cache_id)
{
uint32_t size = 0;
switch (type)
@@ -508,7 +532,7 @@ __attribute__((always_inline))
#endif
static inline cache_bus_mask_t cache_ll_l1_get_bus(uint32_t cache_id, uint32_t vaddr_start, uint32_t len)
{
HAL_ASSERT(cache_id == 0 || cache_id == 1);
HAL_ASSERT(cache_id <= CACHE_LL_ID_ALL);
cache_bus_mask_t mask = (cache_bus_mask_t)0;
uint32_t vaddr_end = vaddr_start + len - 1;
@@ -534,7 +558,7 @@ __attribute__((always_inline))
#endif
static inline void cache_ll_l1_enable_bus(uint32_t cache_id, cache_bus_mask_t mask)
{
HAL_ASSERT(cache_id == 0 || cache_id == 1);
HAL_ASSERT(cache_id <= CACHE_LL_ID_ALL);
//On esp32s3, only `CACHE_BUS_IBUS0` and `CACHE_BUS_DBUS0` are supported. Use `cache_ll_l1_get_bus()` to get your bus first
HAL_ASSERT((mask & (CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2| CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2)) == 0);
@@ -566,7 +590,7 @@ __attribute__((always_inline))
static inline cache_bus_mask_t cache_ll_l1_get_enabled_bus(uint32_t cache_id)
{
cache_bus_mask_t mask = (cache_bus_mask_t)0;
HAL_ASSERT(cache_id == 0 || cache_id == 1);
HAL_ASSERT(cache_id <= CACHE_LL_ID_ALL);
//On esp32s3, only `CACHE_BUS_IBUS0` and `CACHE_BUS_DBUS0` are supported. Use `cache_ll_l1_get_bus()` to get your bus first
uint32_t ibus_mask = REG_READ(EXTMEM_ICACHE_CTRL1_REG);
@@ -595,7 +619,7 @@ static inline cache_bus_mask_t cache_ll_l1_get_enabled_bus(uint32_t cache_id)
__attribute__((always_inline))
static inline void cache_ll_l1_disable_bus(uint32_t cache_id, cache_bus_mask_t mask)
{
HAL_ASSERT(cache_id == 0 || cache_id == 1);
HAL_ASSERT(cache_id <= CACHE_LL_ID_ALL);
//On esp32s3, only `CACHE_BUS_IBUS0` and `CACHE_BUS_DBUS0` are supported. Use `cache_ll_l1_get_bus()` to get your bus first
HAL_ASSERT((mask & (CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2| CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2)) == 0);
@@ -616,6 +640,33 @@ static inline void cache_ll_l1_disable_bus(uint32_t cache_id, cache_bus_mask_t m
REG_SET_BIT(EXTMEM_DCACHE_CTRL1_REG, dbus_mask);
}
/**
* @brief Get Cache level and the ID of the vaddr
*
* @param vaddr_start virtual address start
* @param len vaddr length
* @param out_level cache level
* @param out_id cache id
*
* @return true for valid
*/
__attribute__((always_inline))
static inline bool cache_ll_vaddr_to_cache_level_id(uint32_t vaddr_start, uint32_t len, uint32_t *out_level, uint32_t *out_id)
{
bool valid = false;
uint32_t vaddr_end = vaddr_start + len - 1;
valid |= (SOC_ADDRESS_IN_IRAM0_CACHE(vaddr_start) && SOC_ADDRESS_IN_IRAM0_CACHE(vaddr_end));
valid |= (SOC_ADDRESS_IN_DRAM0_CACHE(vaddr_start) && SOC_ADDRESS_IN_DRAM0_CACHE(vaddr_end));
if (valid) {
*out_level = 1;
*out_id = 0;
}
return valid;
}
/*------------------------------------------------------------------------------
* Interrupt
*----------------------------------------------------------------------------*/