mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-23 17:24:44 +00:00
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:
@@ -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
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
Reference in New Issue
Block a user