mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 09:39:10 -04:00
Merge branch 'feature/support_c6_cache' into 'master'
cache: support c6/h2 cache error Closes IDF-5342, IDF-5656, and IDF-6255 See merge request espressif/esp-idf!22078
This commit is contained in:
commit
dc76dde79f
@ -307,8 +307,8 @@ static inline void * cpu_domain_intpri_sleep_frame_alloc_and_init(void)
|
||||
static inline void * cpu_domain_cache_config_sleep_frame_alloc_and_init(void)
|
||||
{
|
||||
const static cpu_domain_dev_regs_region_t regions[] = {
|
||||
{ .start = EXTMEM_DCACHE_CTRL_REG, .end = EXTMEM_DCACHE_CTRL_REG + 4 },
|
||||
{ .start = EXTMEM_CACHE_WRAP_AROUND_CTRL_REG, .end = EXTMEM_CACHE_WRAP_AROUND_CTRL_REG + 4 }
|
||||
{ .start = EXTMEM_L1_CACHE_CTRL_REG, .end = EXTMEM_L1_CACHE_CTRL_REG + 4 },
|
||||
{ .start = EXTMEM_L1_CACHE_WRAP_AROUND_CTRL_REG, .end = EXTMEM_L1_CACHE_WRAP_AROUND_CTRL_REG + 4 }
|
||||
};
|
||||
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -22,8 +22,6 @@ static const char *TAG = "CACHE_ERR";
|
||||
|
||||
void esp_cache_err_int_init(void)
|
||||
{
|
||||
ESP_EARLY_LOGW(TAG, "esp_cache_err_int_init() has not been implemented yet");
|
||||
#if 0 // TODO: IDF-5656
|
||||
const uint32_t core_id = 0;
|
||||
|
||||
/* Disable cache interrupts if enabled. */
|
||||
@ -32,27 +30,13 @@ void esp_cache_err_int_init(void)
|
||||
/**
|
||||
* Bind all cache errors to ETS_CACHEERR_INUM interrupt. we will deal with
|
||||
* them in handler by different types
|
||||
* I) Cache access error
|
||||
* 1. dbus trying to write to icache
|
||||
* 2. dbus authentication fail
|
||||
* 3. cpu access icache while dbus is disabled [1]
|
||||
* 4. ibus authentication fail
|
||||
* 5. ibus trying to write icache
|
||||
* 6. cpu access icache while ibus is disabled
|
||||
* II) Cache illegal error
|
||||
* 1. dbus counter overflow
|
||||
* 2. ibus counter overflow
|
||||
* 3. mmu entry fault
|
||||
* 4. icache preload configurations fault
|
||||
* 5. icache sync configuration fault
|
||||
*
|
||||
* [1]: On ESP32C6 boards, the caches are shared but buses are still
|
||||
* distinct. So, we have an ibus and a dbus sharing the same cache.
|
||||
* This error can occur if the dbus performs a request but the icache
|
||||
* (or simply cache) is disabled.
|
||||
* On ESP32C6 boards, the cache is a shared one but buses are still
|
||||
* distinct. So, we have an bus0 and a bus1 sharing the same cache.
|
||||
* This error can occur if a bus performs a request but the cache
|
||||
* is disabled.
|
||||
*/
|
||||
esp_rom_route_intr_matrix(core_id, ETS_CACHE_IA_INTR_SOURCE, ETS_CACHEERR_INUM);
|
||||
esp_rom_route_intr_matrix(core_id, ETS_CACHE_CORE0_ACS_INTR_SOURCE, ETS_CACHEERR_INUM);
|
||||
esp_rom_route_intr_matrix(core_id, ETS_CACHE_INTR_SOURCE, ETS_CACHEERR_INUM);
|
||||
|
||||
/* Set the type and priority to cache error interrupts. */
|
||||
esprv_intc_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL);
|
||||
@ -64,15 +48,8 @@ void esp_cache_err_int_init(void)
|
||||
/* Then enable cache access error interrupts. */
|
||||
cache_ll_l1_enable_access_error_intr(0, CACHE_LL_L1_ACCESS_EVENT_MASK);
|
||||
|
||||
/* Same goes for cache illegal error: start by clearing the bits and then
|
||||
* set them back. */
|
||||
ESP_DRAM_LOGV(TAG, "illegal error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ILG_EVENT_MASK);
|
||||
cache_ll_l1_clear_illegal_error_intr(0, CACHE_LL_L1_ILG_EVENT_MASK);
|
||||
cache_ll_l1_enable_illegal_error_intr(0, CACHE_LL_L1_ILG_EVENT_MASK);
|
||||
|
||||
/* Enable the interrupts for cache error. */
|
||||
ESP_INTR_ENABLE(ETS_CACHEERR_INUM);
|
||||
#endif
|
||||
}
|
||||
|
||||
int IRAM_ATTR esp_cache_err_get_cpuid(void)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -22,8 +22,6 @@ static const char *TAG = "CACHE_ERR";
|
||||
|
||||
void esp_cache_err_int_init(void)
|
||||
{
|
||||
ESP_EARLY_LOGW(TAG, "esp_cache_err_int_init() has not been implemented yet");
|
||||
#if 0// ESP32H2-TODO : IDF-5656
|
||||
const uint32_t core_id = 0;
|
||||
|
||||
/* Disable cache interrupts if enabled. */
|
||||
@ -32,30 +30,16 @@ void esp_cache_err_int_init(void)
|
||||
/**
|
||||
* Bind all cache errors to ETS_CACHEERR_INUM interrupt. we will deal with
|
||||
* them in handler by different types
|
||||
* I) Cache access error
|
||||
* 1. dbus trying to write to icache
|
||||
* 2. dbus authentication fail
|
||||
* 3. cpu access icache while dbus is disabled [1]
|
||||
* 4. ibus authentication fail
|
||||
* 5. ibus trying to write icache
|
||||
* 6. cpu access icache while ibus is disabled
|
||||
* II) Cache illegal error
|
||||
* 1. dbus counter overflow
|
||||
* 2. ibus counter overflow
|
||||
* 3. mmu entry fault
|
||||
* 4. icache preload configurations fault
|
||||
* 5. icache sync configuration fault
|
||||
*
|
||||
* [1]: On ESP32H2 boards, the caches are shared but buses are still
|
||||
* distinct. So, we have an ibus and a dbus sharing the same cache.
|
||||
* This error can occur if the dbus performs a request but the icache
|
||||
* (or simply cache) is disabled.
|
||||
* On ESP32H2 boards, the cache is a shared one but buses are still
|
||||
* distinct. So, we have an bus0 and a bus1 sharing the same cache.
|
||||
* This error can occur if a bus performs a request but the cache
|
||||
* is disabled.
|
||||
*/
|
||||
esp_rom_route_intr_matrix(core_id, ETS_CACHE_IA_INTR_SOURCE, ETS_CACHEERR_INUM);
|
||||
esp_rom_route_intr_matrix(core_id, ETS_CACHE_CORE0_ACS_INTR_SOURCE, ETS_CACHEERR_INUM);
|
||||
esp_rom_route_intr_matrix(core_id, ETS_CACHE_INTR_SOURCE, ETS_CACHEERR_INUM);
|
||||
|
||||
/* Set the type and priority to cache error interrupts. */
|
||||
esprv_intc_int_set_type(BIT(ETS_CACHEERR_INUM), INTR_TYPE_LEVEL);
|
||||
esprv_intc_int_set_type(ETS_CACHEERR_INUM, INTR_TYPE_LEVEL);
|
||||
esprv_intc_int_set_priority(ETS_CACHEERR_INUM, SOC_INTERRUPT_LEVEL_MEDIUM);
|
||||
|
||||
ESP_DRAM_LOGV(TAG, "access error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ACCESS_EVENT_MASK);
|
||||
@ -64,15 +48,8 @@ void esp_cache_err_int_init(void)
|
||||
/* Then enable cache access error interrupts. */
|
||||
cache_ll_l1_enable_access_error_intr(0, CACHE_LL_L1_ACCESS_EVENT_MASK);
|
||||
|
||||
/* Same goes for cache illegal error: start by clearing the bits and then
|
||||
* set them back. */
|
||||
ESP_DRAM_LOGV(TAG, "illegal error intr clr & ena mask is: 0x%x", CACHE_LL_L1_ILG_EVENT_MASK);
|
||||
cache_ll_l1_clear_illegal_error_intr(0, CACHE_LL_L1_ILG_EVENT_MASK);
|
||||
cache_ll_l1_enable_illegal_error_intr(0, CACHE_LL_L1_ILG_EVENT_MASK);
|
||||
|
||||
/* Enable the interrupts for cache error. */
|
||||
ESP_INTR_ENABLE(ETS_CACHEERR_INUM);
|
||||
#endif
|
||||
}
|
||||
|
||||
int IRAM_ATTR esp_cache_err_get_cpuid(void)
|
||||
|
@ -21,18 +21,8 @@ extern "C" {
|
||||
#define CACHE_LL_DEFAULT_IBUS_MASK CACHE_BUS_IBUS0
|
||||
#define CACHE_LL_DEFAULT_DBUS_MASK CACHE_BUS_DBUS0
|
||||
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_MASK (0x3f)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_DBUS_WR_IC (1<<5)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_DBUS_REJECT (1<<4)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_DBUS_ACS_MSK_IC (1<<3)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_IBUS_REJECT (1<<2)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_IBUS_WR_IC (1<<1)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_IBUS_ACS_MSK_IC (1<<0)
|
||||
|
||||
#define CACHE_LL_L1_ILG_EVENT_MASK (0x23)
|
||||
#define CACHE_LL_L1_ILG_EVENT_MMU_ENTRY_FAULT (1<<5)
|
||||
#define CACHE_LL_L1_ILG_EVENT_PRELOAD_OP_FAULT (1<<1)
|
||||
#define CACHE_LL_L1_ILG_EVENT_SYNC_OP_FAULT (1<<0)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_MASK (1<<4)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_CACHE_FAIL (1<<4)
|
||||
|
||||
|
||||
/**
|
||||
@ -55,9 +45,8 @@ static inline cache_bus_mask_t cache_ll_l1_get_bus(uint32_t cache_id, uint32_t v
|
||||
|
||||
uint32_t vaddr_end = vaddr_start + len - 1;
|
||||
if (vaddr_start >= IRAM0_CACHE_ADDRESS_LOW && vaddr_end < IRAM0_CACHE_ADDRESS_HIGH) {
|
||||
mask |= CACHE_BUS_IBUS0;
|
||||
} else if (vaddr_start >= DRAM0_CACHE_ADDRESS_LOW && vaddr_end < DRAM0_CACHE_ADDRESS_HIGH) {
|
||||
mask |= CACHE_BUS_DBUS0;
|
||||
//c6 the I/D bus memory are shared, so we always return `CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0`
|
||||
mask |= CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0;
|
||||
} else {
|
||||
HAL_ASSERT(0); //Out of region
|
||||
}
|
||||
@ -77,16 +66,16 @@ __attribute__((always_inline))
|
||||
static inline void cache_ll_l1_enable_bus(uint32_t cache_id, cache_bus_mask_t mask)
|
||||
{
|
||||
HAL_ASSERT(cache_id == 0);
|
||||
//On esp32c3, 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);
|
||||
//On esp32c6, 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);
|
||||
|
||||
uint32_t ibus_mask = 0;
|
||||
ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_DCACHE_SHUT_DBUS0 : 0;
|
||||
REG_CLR_BIT(EXTMEM_ICACHE_CTRL_REG, ibus_mask);
|
||||
ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_L1_CACHE_SHUT_IBUS : 0;
|
||||
REG_CLR_BIT(EXTMEM_L1_CACHE_CTRL_REG, ibus_mask);
|
||||
|
||||
uint32_t dbus_mask = 0;
|
||||
dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_DCACHE_SHUT_DBUS1 : 0;
|
||||
REG_CLR_BIT(EXTMEM_ICACHE_CTRL_REG, dbus_mask);
|
||||
dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_L1_CACHE_SHUT_DBUS : 0;
|
||||
REG_CLR_BIT(EXTMEM_L1_CACHE_CTRL_REG, dbus_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,16 +88,16 @@ __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);
|
||||
//On esp32c3, 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);
|
||||
//On esp32c6, 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);
|
||||
|
||||
uint32_t ibus_mask = 0;
|
||||
ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_DCACHE_SHUT_DBUS0 : 0;
|
||||
REG_SET_BIT(EXTMEM_ICACHE_CTRL_REG, ibus_mask);
|
||||
ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_L1_CACHE_SHUT_IBUS : 0;
|
||||
REG_SET_BIT(EXTMEM_L1_CACHE_CTRL_REG, ibus_mask);
|
||||
|
||||
uint32_t dbus_mask = 0;
|
||||
dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_DCACHE_SHUT_DBUS1 : 0;
|
||||
REG_SET_BIT(EXTMEM_ICACHE_CTRL_REG, dbus_mask);
|
||||
dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_L1_CACHE_SHUT_DBUS : 0;
|
||||
REG_SET_BIT(EXTMEM_L1_CACHE_CTRL_REG, dbus_mask);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
@ -122,8 +111,7 @@ static inline void cache_ll_l1_disable_bus(uint32_t cache_id, cache_bus_mask_t m
|
||||
*/
|
||||
static inline void cache_ll_l1_enable_access_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// TODO: IDF-5656
|
||||
// SET_PERI_REG_MASK(EXTMEM_CORE0_ACS_CACHE_INT_ENA_REG, mask);
|
||||
SET_PERI_REG_MASK(EXTMEM_L1_CACHE_ACS_FAIL_INT_ENA_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,8 +122,7 @@ static inline void cache_ll_l1_enable_access_error_intr(uint32_t cache_id, uint3
|
||||
*/
|
||||
static inline void cache_ll_l1_clear_access_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// TODO: IDF-5656
|
||||
// SET_PERI_REG_MASK(EXTMEM_CORE0_ACS_CACHE_INT_CLR_REG, mask);
|
||||
SET_PERI_REG_MASK(EXTMEM_L1_CACHE_ACS_FAIL_INT_CLR_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,48 +135,7 @@ static inline void cache_ll_l1_clear_access_error_intr(uint32_t cache_id, uint32
|
||||
*/
|
||||
static inline uint32_t cache_ll_l1_get_access_error_intr_status(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// TODO: IDF-5656
|
||||
// return GET_PERI_REG_MASK(EXTMEM_CORE0_ACS_CACHE_INT_ST_REG, mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Cache illegal error interrupt
|
||||
*
|
||||
* @param cache_id Cache ID, not used on C3. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_enable_illegal_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// TODO: IDF-5656
|
||||
// SET_PERI_REG_MASK(EXTMEM_CACHE_ILG_INT_ENA_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear Cache illegal error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID, not used on C3. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_clear_illegal_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// TODO: IDF-5656
|
||||
// SET_PERI_REG_MASK(EXTMEM_CACHE_ILG_INT_CLR_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get Cache illegal error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID, not used on C3. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*
|
||||
* @return Status mask
|
||||
*/
|
||||
static inline uint32_t cache_ll_l1_get_illegal_error_intr_status(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// TODO: IDF-5656
|
||||
// return GET_PERI_REG_MASK(EXTMEM_CACHE_ILG_INT_ST_REG, mask);
|
||||
return 0;
|
||||
return GET_PERI_REG_MASK(EXTMEM_L1_CACHE_ACS_FAIL_INT_ST_REG, mask);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -21,18 +21,8 @@ extern "C" {
|
||||
#define CACHE_LL_DEFAULT_IBUS_MASK CACHE_BUS_IBUS0
|
||||
#define CACHE_LL_DEFAULT_DBUS_MASK CACHE_BUS_DBUS0
|
||||
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_MASK (0x3f)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_DBUS_WR_IC (1<<5)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_DBUS_REJECT (1<<4)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_DBUS_ACS_MSK_IC (1<<3)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_IBUS_REJECT (1<<2)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_IBUS_WR_IC (1<<1)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_IBUS_ACS_MSK_IC (1<<0)
|
||||
|
||||
#define CACHE_LL_L1_ILG_EVENT_MASK (0x23)
|
||||
#define CACHE_LL_L1_ILG_EVENT_MMU_ENTRY_FAULT (1<<5)
|
||||
#define CACHE_LL_L1_ILG_EVENT_PRELOAD_OP_FAULT (1<<1)
|
||||
#define CACHE_LL_L1_ILG_EVENT_SYNC_OP_FAULT (1<<0)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_MASK (1<<4)
|
||||
#define CACHE_LL_L1_ACCESS_EVENT_CACHE_FAIL (1<<4)
|
||||
|
||||
|
||||
/**
|
||||
@ -55,9 +45,8 @@ static inline cache_bus_mask_t cache_ll_l1_get_bus(uint32_t cache_id, uint32_t v
|
||||
|
||||
uint32_t vaddr_end = vaddr_start + len - 1;
|
||||
if (vaddr_start >= IRAM0_CACHE_ADDRESS_LOW && vaddr_end < IRAM0_CACHE_ADDRESS_HIGH) {
|
||||
mask |= CACHE_BUS_IBUS0;
|
||||
} else if (vaddr_start >= DRAM0_CACHE_ADDRESS_LOW && vaddr_end < DRAM0_CACHE_ADDRESS_HIGH) {
|
||||
mask |= CACHE_BUS_DBUS0;
|
||||
//h2 the I/D bus memory are shared, so we always return `CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0`
|
||||
mask |= CACHE_BUS_IBUS0 | CACHE_BUS_DBUS0;
|
||||
} else {
|
||||
HAL_ASSERT(0); //Out of region
|
||||
}
|
||||
@ -78,15 +67,15 @@ static inline void cache_ll_l1_enable_bus(uint32_t cache_id, cache_bus_mask_t ma
|
||||
{
|
||||
HAL_ASSERT(cache_id == 0);
|
||||
//On esp32h2, 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);
|
||||
HAL_ASSERT((mask & (CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2 | CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2)) == 0);
|
||||
|
||||
uint32_t ibus_mask = 0;
|
||||
ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_DCACHE_SHUT_DBUS0 : 0;
|
||||
REG_CLR_BIT(EXTMEM_ICACHE_CTRL_REG, ibus_mask);
|
||||
ibus_mask |= (mask & CACHE_BUS_IBUS0) ? CACHE_L1_CACHE_SHUT_BUS0 : 0;
|
||||
REG_CLR_BIT(CACHE_L1_CACHE_CTRL_REG, ibus_mask);
|
||||
|
||||
uint32_t dbus_mask = 0;
|
||||
dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_DCACHE_SHUT_DBUS1 : 0;
|
||||
REG_CLR_BIT(EXTMEM_ICACHE_CTRL_REG, dbus_mask);
|
||||
dbus_mask |= (mask & CACHE_BUS_DBUS0) ? CACHE_L1_CACHE_SHUT_BUS1 : 0;
|
||||
REG_CLR_BIT(CACHE_L1_CACHE_CTRL_REG, dbus_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,15 +89,15 @@ static inline void cache_ll_l1_disable_bus(uint32_t cache_id, cache_bus_mask_t m
|
||||
{
|
||||
HAL_ASSERT(cache_id == 0);
|
||||
//On esp32h2, 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);
|
||||
HAL_ASSERT((mask & (CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2 | CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2)) == 0);
|
||||
|
||||
uint32_t ibus_mask = 0;
|
||||
ibus_mask |= (mask & CACHE_BUS_IBUS0) ? EXTMEM_DCACHE_SHUT_DBUS0 : 0;
|
||||
REG_SET_BIT(EXTMEM_ICACHE_CTRL_REG, ibus_mask);
|
||||
ibus_mask |= (mask & CACHE_BUS_IBUS0) ? CACHE_L1_CACHE_SHUT_BUS0 : 0;
|
||||
REG_SET_BIT(CACHE_L1_CACHE_CTRL_REG, ibus_mask);
|
||||
|
||||
uint32_t dbus_mask = 0;
|
||||
dbus_mask |= (mask & CACHE_BUS_DBUS0) ? EXTMEM_DCACHE_SHUT_DBUS1 : 0;
|
||||
REG_SET_BIT(EXTMEM_ICACHE_CTRL_REG, dbus_mask);
|
||||
dbus_mask |= (mask & CACHE_BUS_DBUS0) ? CACHE_L1_CACHE_SHUT_BUS1 : 0;
|
||||
REG_SET_BIT(CACHE_L1_CACHE_CTRL_REG, dbus_mask);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
@ -117,79 +106,36 @@ static inline void cache_ll_l1_disable_bus(uint32_t cache_id, cache_bus_mask_t m
|
||||
/**
|
||||
* @brief Enable Cache access error interrupt
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H2. For compabitlity
|
||||
* @param cache_id Cache ID, not used on C3. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_enable_access_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// ESP32H2-TODO
|
||||
// SET_PERI_REG_MASK(EXTMEM_CORE0_ACS_CACHE_INT_ENA_REG, mask);
|
||||
SET_PERI_REG_MASK(CACHE_L1_CACHE_ACS_FAIL_INT_ENA_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear Cache access error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H2. For compabitlity
|
||||
* @param cache_id Cache ID, not used on C3. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_clear_access_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-6255
|
||||
// SET_PERI_REG_MASK(EXTMEM_CORE0_ACS_CACHE_INT_CLR_REG, mask);
|
||||
SET_PERI_REG_MASK(CACHE_L1_CACHE_ACS_FAIL_INT_CLR_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get Cache access error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H2. For compabitlity
|
||||
* @param cache_id Cache ID, not used on C3. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*
|
||||
* @return Status mask
|
||||
*/
|
||||
static inline uint32_t cache_ll_l1_get_access_error_intr_status(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-6255
|
||||
// return GET_PERI_REG_MASK(EXTMEM_CORE0_ACS_CACHE_INT_ST_REG, mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable Cache illegal error interrupt
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H2. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_enable_illegal_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-6255
|
||||
// SET_PERI_REG_MASK(EXTMEM_CACHE_ILG_INT_ENA_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear Cache illegal error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H2. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*/
|
||||
static inline void cache_ll_l1_clear_illegal_error_intr(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-6255
|
||||
// SET_PERI_REG_MASK(EXTMEM_CACHE_ILG_INT_CLR_REG, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get Cache illegal error interrupt status
|
||||
*
|
||||
* @param cache_id Cache ID, not used on H2. For compabitlity
|
||||
* @param mask Interrupt mask
|
||||
*
|
||||
* @return Status mask
|
||||
*/
|
||||
static inline uint32_t cache_ll_l1_get_illegal_error_intr_status(uint32_t cache_id, uint32_t mask)
|
||||
{
|
||||
// ESP32H2-TODO: IDF-6255
|
||||
// return GET_PERI_REG_MASK(EXTMEM_CACHE_ILG_INT_ST_REG, mask);
|
||||
return 0;
|
||||
return GET_PERI_REG_MASK(CACHE_L1_CACHE_ACS_FAIL_INT_ST_REG, mask);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -65,6 +65,6 @@
|
||||
#define DR_REG_TRACE_BASE 0x600C0000
|
||||
#define DR_REG_ASSIST_DEBUG_BASE 0x600C2000
|
||||
#define DR_REG_INTPRI_BASE 0x600C5000
|
||||
#define DR_REG_EXTMEM_BASE 0x600C8000
|
||||
#define DR_REG_CACHE_BASE 0x600C8000
|
||||
|
||||
#define PWDET_CONF_REG 0x600A8010
|
||||
|
@ -75,8 +75,12 @@ static __attribute__((unused)) const char *TAG = "cache";
|
||||
#define DPORT_CACHE_GET_VAL(cpuid) (cpuid == 0) ? DPORT_CACHE_VAL(PRO) : DPORT_CACHE_VAL(APP)
|
||||
#define DPORT_CACHE_GET_MASK(cpuid) (cpuid == 0) ? DPORT_CACHE_MASK(PRO) : DPORT_CACHE_MASK(APP)
|
||||
|
||||
static void spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state);
|
||||
static void spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state);
|
||||
/**
|
||||
* These two shouldn't be declared as static otherwise if `CONFIG_SPI_FLASH_ROM_IMPL` is enabled,
|
||||
* they won't get replaced by the rom version
|
||||
*/
|
||||
void spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state);
|
||||
void spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state);
|
||||
|
||||
static uint32_t s_flash_op_cache_state[2];
|
||||
|
||||
@ -357,7 +361,7 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os(void)
|
||||
* function in ROM. They are used to work around a bug where Cache_Read_Disable requires a call to
|
||||
* Cache_Flush before Cache_Read_Enable, even if cached data was not modified.
|
||||
*/
|
||||
static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state)
|
||||
void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t ret = 0;
|
||||
@ -398,7 +402,7 @@ static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_st
|
||||
#endif
|
||||
}
|
||||
|
||||
static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state)
|
||||
void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
const uint32_t cache_mask = DPORT_CACHE_GET_MASK(cpuid);
|
||||
@ -938,7 +942,7 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2
|
||||
|
||||
static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache)
|
||||
{
|
||||
@ -979,7 +983,7 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable)
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6
|
||||
#endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C2
|
||||
|
||||
void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid)
|
||||
{
|
||||
|
@ -19,7 +19,8 @@
|
||||
|
||||
#include "esp_private/cache_utils.h"
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2)
|
||||
//TODO: IDF-6730, migrate this test to test_app
|
||||
|
||||
static QueueHandle_t result_queue;
|
||||
|
||||
static IRAM_ATTR void cache_test_task(void *arg)
|
||||
@ -61,6 +62,11 @@ TEST_CASE("spi_flash_cache_enabled() works on both CPUs", "[spi_flash][esp_flash
|
||||
|
||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
|
||||
|
||||
#define C6_H2_ROM_IMPL (CONFIG_SPI_FLASH_ROM_IMPL && (CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2))
|
||||
|
||||
#if !C6_H2_ROM_IMPL
|
||||
//TODO: IDF-6931
|
||||
|
||||
// This needs to sufficiently large array, otherwise it may end up in
|
||||
// DRAM (e.g. size <= 8 bytes && ARCH == RISCV)
|
||||
static const uint32_t s_in_rodata[8] = { 0x12345678, 0xfedcba98 };
|
||||
@ -83,10 +89,12 @@ static void IRAM_ATTR cache_access_test_func(void* arg)
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define CACHE_ERROR_REASON "Cache disabled,SW_RESET"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4 || CONFIG_IDF_TARGET_ESP32C6
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4
|
||||
#define CACHE_ERROR_REASON "Cache error,RTC_SW_CPU_RST"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#define CACHE_ERROR_REASON "Cache disabled,RTC_SW_CPU_RST"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
|
||||
#define CACHE_ERROR_REASON "Cache error,SW_CPU"
|
||||
#endif
|
||||
|
||||
// These tests works properly if they resets the chip with the
|
||||
@ -96,6 +104,7 @@ TEST_CASE("invalid access to cache raises panic (PRO CPU)", "[spi_flash][reset="
|
||||
xTaskCreatePinnedToCore(&cache_access_test_func, "ia", 2048, NULL, 5, NULL, 0);
|
||||
vTaskDelay(1000/portTICK_PERIOD_MS);
|
||||
}
|
||||
#endif //#if !C6_H2_ROM_IMPL
|
||||
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
|
||||
@ -107,4 +116,3 @@ TEST_CASE("invalid access to cache raises panic (APP CPU)", "[spi_flash][reset="
|
||||
|
||||
#endif // !CONFIG_FREERTOS_UNICORE
|
||||
#endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
|
||||
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2)
|
||||
|
Loading…
x
Reference in New Issue
Block a user