xtensa/esp32[|s3]: re-enable cache during exception handler

This commit implements re-enabling the cache before the exception
handler for ESP32-S3 and removes unnecessary checks (cache should
always be re-enabled during an exception handler and disabled again
after processed, except for ESP32-S3 that implements no recoverable
exceptions).

Signed-off-by: Tiago Medicci Serrano <tiago.medicci@espressif.com>
This commit is contained in:
Tiago Medicci Serrano 2025-01-31 11:26:17 -03:00 committed by Alan C. Assis
parent 7ccd6e9041
commit 8956fc440f
5 changed files with 84 additions and 39 deletions

View file

@ -207,15 +207,6 @@ config ESP32_RUN_IRAM
This loads all of NuttX inside IRAM. Used to test somewhat small
images that can fit entirely in IRAM.
config ESP32_EXCEPTION_ENABLE_CACHE
bool
default y
depends on ESP32_SPIFLASH
---help---
When an exception triggers, the panic function reenables the SPI Flash
cache to allow functions that are located in SPI Flash to run.
Disable this option to save IRAM space.
menu "ESP32 Peripheral Selection"
source "arch/xtensa/src/common/espressif/Kconfig"

View file

@ -324,16 +324,19 @@ static void advance_pc(uint32_t *regs, int diff)
uint32_t *xtensa_user(int exccause, uint32_t *regs)
{
#ifdef CONFIG_ESP32_EXCEPTION_ENABLE_CACHE
#ifdef CONFIG_ESP32_SPIFLASH
bool is_cache_reenabled = false;
if (!spi_flash_cache_enabled())
{
is_cache_reenabled = true;
spi_enable_cache(0);
#ifdef CONFIG_SMP
# ifdef CONFIG_SMP
spi_enable_cache(1);
#endif
_err("\nERROR: Cache was disabled and re-enabled\n");
# endif
}
#endif
#endif /* CONFIG_ESP32_SPIFLASH */
#ifdef CONFIG_ARCH_USE_TEXT_HEAP
/* Emulate byte access for module text.
@ -375,7 +378,7 @@ uint32_t *xtensa_user(int exccause, uint32_t *regs)
store_uint8(((uint8_t *)regs[REG_A0 + s]) + imm8,
regs[REG_A0 + t]);
advance_pc(regs, 3);
return regs;
goto return_with_regs;
}
else if (decode_s16i(pc, &imm8, &s, &t))
{
@ -391,7 +394,7 @@ uint32_t *xtensa_user(int exccause, uint32_t *regs)
store_uint8((uint8_t *)va, regs[REG_A0 + t]);
store_uint8((uint8_t *)va + 1, regs[REG_A0 + t] >> 8);
advance_pc(regs, 3);
return regs;
goto return_with_regs;
}
else if (decode_l8ui(pc, &imm8, &s, &t))
{
@ -406,7 +409,7 @@ uint32_t *xtensa_user(int exccause, uint32_t *regs)
regs[REG_A0 + t] = load_uint8(((uint8_t *)regs[REG_A0 + s]) +
imm8);
advance_pc(regs, 3);
return regs;
goto return_with_regs;
}
else if (decode_l16si(pc, &imm8, &s, &t))
{
@ -423,7 +426,7 @@ uint32_t *xtensa_user(int exccause, uint32_t *regs)
uint8_t hi = load_uint8((uint8_t *)va + 1);
regs[REG_A0 + t] = (int16_t)((hi << 8) | lo);
advance_pc(regs, 3);
return regs;
goto return_with_regs;
}
else if (decode_l16ui(pc, &imm8, &s, &t))
{
@ -440,11 +443,29 @@ uint32_t *xtensa_user(int exccause, uint32_t *regs)
uint8_t hi = load_uint8((uint8_t *)va + 1);
regs[REG_A0 + t] = (hi << 8) | lo;
advance_pc(regs, 3);
return regs;
goto return_with_regs;
}
return_with_regs:
# ifdef CONFIG_ESP32_SPIFLASH
if (is_cache_reenabled)
{
spi_disable_cache(0);
# ifdef CONFIG_SMP
spi_disable_cache(1);
# endif
}
# endif /* CONFIG_ESP32_SPIFLASH */
return regs;
}
#else
# ifdef CONFIG_ESP32_SPIFLASH
UNUSED(is_cache_reenabled);
# endif
#endif
/* xtensa_user_panic never returns. */
xtensa_user_panic(exccause, regs);

View file

@ -251,26 +251,6 @@ static void spiflash_suspend_cache(void)
g_spi_flash_cache_suspended = true;
}
/****************************************************************************
* Name: spiflash_resume_cache
*
* Description:
* Resume CPU cache.
*
****************************************************************************/
static void spiflash_resume_cache(void)
{
int cpu = this_cpu();
#ifdef CONFIG_SMP
int other_cpu = cpu ? 0 : 1;
#endif
spi_flash_restore_cache();
g_spi_flash_cache_suspended = false;
}
/****************************************************************************
* Name: spiflash_start
*
@ -926,6 +906,32 @@ static int spiflash_init_spi_flash_op_block_task(int cpu)
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: spiflash_resume_cache
*
* Description:
* Resume CPU cache.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void spiflash_resume_cache(void)
{
int cpu = this_cpu();
#ifdef CONFIG_SMP
int other_cpu = cpu ? 0 : 1;
#endif
spi_flash_restore_cache();
g_spi_flash_cache_suspended = false;
}
/****************************************************************************
* Name: esp32s3_mmap
*

View file

@ -75,6 +75,22 @@ struct spiflash_map_req_s
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: spiflash_resume_cache
*
* Description:
* Resume CPU cache.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
void spiflash_resume_cache(void);
/****************************************************************************
* Name: esp32s3_mmap
*

View file

@ -27,6 +27,10 @@
#include <stdint.h>
#include "xtensa.h"
#ifdef CONFIG_ESP32S3_SPIFLASH
#include "rom/esp32s3_spiflash.h"
#include "esp32s3_spiflash.h"
#endif
/****************************************************************************
* Public Data
@ -61,6 +65,13 @@
uint32_t *xtensa_user(int exccause, uint32_t *regs)
{
#ifdef CONFIG_ESP32S3_SPIFLASH
if (!spi_flash_cache_enabled())
{
spiflash_resume_cache();
}
#endif /* CONFIG_ESP32S3_SPIFLASH */
/* xtensa_user_panic never returns. */
xtensa_user_panic(exccause, regs);