feat(cache): supported cache panic on p4

This commit is contained in:
Armando 2024-07-11 15:25:18 +08:00
parent c880f697da
commit 564b74a9c0
5 changed files with 79 additions and 26 deletions

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -20,19 +20,24 @@
static const char *TAG = "CACHE_ERR";
//TODO: IDF-7515
const char cache_error_msg[] = "Cache access error";
const char *esp_cache_err_panic_string(void)
{
return NULL;
uint32_t access_err_status = cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK) | cache_ll_l2_get_access_error_intr_status(0, CACHE_LL_L2_ACCESS_EVENT_MASK);
/* Return the error string if a cache error is active */
const char* err_str = access_err_status ? cache_error_msg : NULL;
return err_str;
}
//TODO: IDF-7515
bool esp_cache_err_has_active_err(void)
{
return false;
bool has_active_err = cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_ACCESS_EVENT_MASK) | cache_ll_l2_get_access_error_intr_status(0, CACHE_LL_L2_ACCESS_EVENT_MASK);
return has_active_err;
}
//TODO: IDF-7515
void esp_cache_err_int_init(void)
{
const uint32_t core_id = 0;
@ -56,10 +61,13 @@ void esp_cache_err_int_init(void)
esprv_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);
/* On the hardware side, start by clearing all the bits reponsible for cache access error */
/* On the hardware side, start by clearing all the bits responsible for cache access error */
cache_ll_l1_clear_access_error_intr(0, CACHE_LL_L1_ACCESS_EVENT_MASK);
cache_ll_l2_clear_access_error_intr(0, CACHE_LL_L2_ACCESS_EVENT_MASK);
/* Then enable cache access error interrupts. */
cache_ll_l1_enable_access_error_intr(0, CACHE_LL_L1_ACCESS_EVENT_MASK);
cache_ll_l2_enable_access_error_intr(0, CACHE_LL_L2_ACCESS_EVENT_MASK);
/* Enable the interrupts for cache error. */
ESP_INTR_ENABLE(ETS_CACHEERR_INUM);
@ -67,7 +75,11 @@ void esp_cache_err_int_init(void)
int esp_cache_err_get_cpuid(void)
{
//TODO: IDF-7515
//Should return hart ID according to the cache error
return 0;
if (cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_CORE0_EVENT_MASK)) {
return 0;
} else if (cache_ll_l1_get_access_error_intr_status(0, CACHE_LL_L1_CORE1_EVENT_MASK)) {
return 1;
} else {
return -1;
}
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -10,6 +10,7 @@
#include <stdbool.h>
#include "soc/cache_reg.h"
#include "soc/cache_struct.h"
#include "soc/ext_mem_defs.h"
#include "hal/cache_types.h"
#include "hal/assert.h"
@ -47,8 +48,10 @@ extern "C" {
#define CACHE_LL_DEFAULT_IBUS_MASK (CACHE_BUS_IBUS0 | CACHE_BUS_IBUS1 | CACHE_BUS_IBUS2)
#define CACHE_LL_DEFAULT_DBUS_MASK (CACHE_BUS_DBUS0 | CACHE_BUS_DBUS1 | CACHE_BUS_DBUS2)
//TODO: IDF-7515
#define CACHE_LL_L1_ACCESS_EVENT_MASK (0x3f)
#define CACHE_LL_L1_ACCESS_EVENT_MASK (0x1f)
#define CACHE_LL_L2_ACCESS_EVENT_MASK (1<<6)
#define CACHE_LL_L1_CORE0_EVENT_MASK (1<<0)
#define CACHE_LL_L1_CORE1_EVENT_MASK (1<<1)
/*------------------------------------------------------------------------------
* Autoload
@ -1019,27 +1022,29 @@ static inline bool cache_ll_vaddr_to_cache_level_id(uint32_t vaddr_start, uint32
* Interrupt
*----------------------------------------------------------------------------*/
/**
* @brief Enable Cache access error interrupt
* @brief Enable L1 Cache access error interrupt
*
* @param cache_id Cache ID
* @param mask Interrupt mask
*/
static inline void cache_ll_l1_enable_access_error_intr(uint32_t cache_id, uint32_t mask)
{
CACHE.l1_cache_acs_fail_int_ena.val |= mask;
}
/**
* @brief Clear Cache access error interrupt status
* @brief Clear L1 Cache access error interrupt status
*
* @param cache_id Cache ID
* @param mask Interrupt mask
*/
static inline void cache_ll_l1_clear_access_error_intr(uint32_t cache_id, uint32_t mask)
{
CACHE.l1_cache_acs_fail_int_clr.val = mask;
}
/**
* @brief Get Cache access error interrupt status
* @brief Get L1 Cache access error interrupt status
*
* @param cache_id Cache ID
* @param mask Interrupt mask
@ -1048,7 +1053,42 @@ 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)
{
return 0;
return CACHE.l1_cache_acs_fail_int_st.val & mask;
}
/**
* @brief Enable L2 Cache access error interrupt
*
* @param cache_id Cache ID
* @param mask Interrupt mask
*/
static inline void cache_ll_l2_enable_access_error_intr(uint32_t cache_id, uint32_t mask)
{
CACHE.l2_cache_acs_fail_int_ena.val |= mask;
}
/**
* @brief Clear L2 Cache access error interrupt status
*
* @param cache_id Cache ID
* @param mask Interrupt mask
*/
static inline void cache_ll_l2_clear_access_error_intr(uint32_t cache_id, uint32_t mask)
{
CACHE.l2_cache_acs_fail_int_clr.val = mask;
}
/**
* @brief Get L2 Cache access error interrupt status
*
* @param cache_id Cache ID
* @param mask Interrupt mask
*
* @return Status mask
*/
static inline uint32_t cache_ll_l2_get_access_error_intr_status(uint32_t cache_id, uint32_t mask)
{
return CACHE.l2_cache_acs_fail_int_st.val & mask;
}
#ifdef __cplusplus

View File

@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -5269,12 +5269,12 @@ typedef union {
struct {
/** l1_icache0_unalloc_clr : R/W; bitpos: [0]; default: 0;
* The bit is used to clear the unallocate request buffer of l1 icache0 where the
* unallocate request is responsed but not completed.
* unallocate request is responded but not completed.
*/
uint32_t l1_icache0_unalloc_clr:1;
/** l1_icache1_unalloc_clr : R/W; bitpos: [1]; default: 0;
* The bit is used to clear the unallocate request buffer of l1 icache1 where the
* unallocate request is responsed but not completed.
* unallocate request is responded but not completed.
*/
uint32_t l1_icache1_unalloc_clr:1;
/** l1_icache2_unalloc_clr : HRO; bitpos: [2]; default: 0;
@ -5287,7 +5287,7 @@ typedef union {
uint32_t l1_icache3_unalloc_clr:1;
/** l1_dcache_unalloc_clr : R/W; bitpos: [4]; default: 0;
* The bit is used to clear the unallocate request buffer of l1 dcache where the
* unallocate request is responsed but not completed.
* unallocate request is responded but not completed.
*/
uint32_t l1_dcache_unalloc_clr:1;
uint32_t reserved_5:27;
@ -5303,7 +5303,7 @@ typedef union {
uint32_t reserved_0:5;
/** l2_cache_unalloc_clr : R/W; bitpos: [5]; default: 0;
* The bit is used to clear the unallocate request buffer of l2 icache where the
* unallocate request is responsed but not completed.
* unallocate request is responded but not completed.
*/
uint32_t l2_cache_unalloc_clr:1;
uint32_t reserved_6:26;
@ -5548,7 +5548,7 @@ typedef union {
} cache_date_reg_t;
typedef struct {
typedef struct cache_dev_t {
volatile cache_l1_icache_ctrl_reg_t l1_icache_ctrl;
volatile cache_l1_dcache_ctrl_reg_t l1_dcache_ctrl;
volatile cache_l1_bypass_cache_conf_reg_t l1_bypass_cache_conf;
@ -5799,6 +5799,7 @@ typedef struct {
volatile cache_date_reg_t date;
} cache_dev_t;
extern cache_dev_t CACHE;
#ifndef __cplusplus
_Static_assert(sizeof(cache_dev_t) == 0x400, "Invalid size of cache_dev_t structure");

View File

@ -117,3 +117,5 @@ PROVIDE ( USB_UTMI = 0x5009C000 );
PROVIDE ( EMAC_MAC = 0x50098000 );
PROVIDE ( EMAC_DMA = 0x50099000 );
PROVIDE ( CACHE = 0x3FF10000);

View File

@ -299,14 +299,12 @@ def test_cache_error(dut: PanicTestDut, config: str, test_func_name: str) -> Non
if dut.target in ['esp32c3', 'esp32c2']:
dut.expect_gme('Cache error')
dut.expect_exact('Cached memory region accessed while ibus or cache is disabled')
elif dut.target in ['esp32c6', 'esp32h2']:
elif dut.target in ['esp32c6', 'esp32h2', 'esp32p4']:
dut.expect_gme('Cache error')
dut.expect_exact('Cache access error')
elif dut.target in ['esp32s2']:
# Cache error interrupt is not enabled, IDF-1558
dut.expect_gme('IllegalInstruction')
elif dut.target in ['esp32p4']: # TODO IDF-7515
dut.expect_gme('Instruction access fault')
else:
dut.expect_gme('Cache disabled but cached memory region accessed')
dut.expect_reg_dump(0)