diff --git a/components/esp_hw_support/include/esp_cpu.h b/components/esp_hw_support/include/esp_cpu.h index f0f441b713..369066f8fc 100644 --- a/components/esp_hw_support/include/esp_cpu.h +++ b/components/esp_hw_support/include/esp_cpu.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -247,6 +247,16 @@ FORCE_INLINE_ATTR void esp_cpu_intr_set_mtvt_addr(const void *mtvt_addr) } #endif //#if SOC_INT_CLIC_SUPPORTED +#if SOC_CPU_SUPPORT_WFE +/** + * @brief Disable the WFE (wait for event) feature for CPU. + */ +FORCE_INLINE_ATTR void rv_utils_disable_wfe_mode(void) +{ + rv_utils_wfe_mode_enable(false); +} +#endif + #if SOC_CPU_HAS_FLEXIBLE_INTC /** * @brief Set the interrupt type of a particular interrupt diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 97281e98fe..74c20e315a 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -218,7 +218,9 @@ void IRAM_ATTR call_start_cpu1(void) */ esp_cpu_intr_set_mtvt_addr(&_mtvt_table); #endif - +#if SOC_CPU_SUPPORT_WFE + rv_utils_disable_wfe_mode(); +#endif ets_set_appcpu_boot_addr(0); bootloader_init_mem(); @@ -419,6 +421,9 @@ void IRAM_ATTR call_start_cpu0(void) */ esp_cpu_intr_set_mtvt_addr(&_mtvt_table); #endif +#if SOC_CPU_SUPPORT_WFE + rv_utils_disable_wfe_mode(); +#endif rst_reas[0] = esp_rom_get_reset_reason(0); #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE diff --git a/components/riscv/include/esp_private/interrupt_clic.h b/components/riscv/include/esp_private/interrupt_clic.h index 524427d6c1..8f0981b781 100644 --- a/components/riscv/include/esp_private/interrupt_clic.h +++ b/components/riscv/include/esp_private/interrupt_clic.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -148,6 +148,20 @@ FORCE_INLINE_ATTR void rv_utils_set_mtvt(uint32_t mtvt_val) RV_WRITE_CSR(MTVT_CSR, mtvt_val); } +#if SOC_CPU_SUPPORT_WFE +/** + * @brief Set the MEXSTATUS_WFFEN value, used to enable/disable wait for event mode. + */ +FORCE_INLINE_ATTR void rv_utils_wfe_mode_enable(bool en) +{ + if (en) { + RV_SET_CSR(MEXSTATUS, MEXSTATUS_WFFEN); + } else { + RV_CLEAR_CSR(MEXSTATUS, MEXSTATUS_WFFEN); + } +} +#endif + /** * @brief Get the current CPU raw interrupt level */ diff --git a/components/riscv/include/riscv/encoding.h b/components/riscv/include/riscv/encoding.h index 91c92a696f..50ceb2da6d 100644 --- a/components/riscv/include/riscv/encoding.h +++ b/components/riscv/include/riscv/encoding.h @@ -53,6 +53,14 @@ #define MSTATUS_SXL 0x0000000C00000000 #define MSTATUS64_SD 0x8000000000000000 +#define MEXSTATUS_SOFT_RST 0x00000003 +#define MEXSTATUS_LPMD 0x0000000C +#define MEXSTATUS_WFFEN 0x00000010 +#define MEXSTATUS_EXPT_VLD 0x00000020 +#define MEXSTATUS_LOCKUP 0x00000040 +#define MEXSTATUS_NMISTS 0x00000080 +#define MEXSTATUS_BUSEER 0x00000100 + #define SSTATUS_UIE 0x00000001 #define SSTATUS_SIE 0x00000002 #define SSTATUS_UPIE 0x00000010 diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index e09a1bb829..9d46108b6a 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -379,6 +379,10 @@ config SOC_CPU_HAS_FLEXIBLE_INTC bool default y +config SOC_CPU_SUPPORT_WFE + bool + default y + config SOC_INT_CLIC_SUPPORTED bool default y diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index 8d9061cebd..91f4cdffbe 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -153,6 +153,7 @@ #define SOC_CPU_CORES_NUM (1U) #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FLEXIBLE_INTC 1 +#define SOC_CPU_SUPPORT_WFE 1 #define SOC_INT_CLIC_SUPPORTED 1 #define SOC_INT_HW_NESTED_SUPPORTED 1 // Support for hardware interrupts nesting #define SOC_BRANCH_PREDICTOR_SUPPORTED 1 diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index be1be3c29a..182eb1f5c0 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -215,6 +215,10 @@ config SOC_CPU_HAS_FLEXIBLE_INTC bool default y +config SOC_CPU_SUPPORT_WFE + bool + default y + config SOC_INT_PLIC_SUPPORTED bool default n diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index 752257f17d..870120e684 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -126,6 +126,7 @@ #define SOC_CPU_CORES_NUM (1U) #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FLEXIBLE_INTC 1 +#define SOC_CPU_SUPPORT_WFE 1 #define SOC_INT_PLIC_SUPPORTED 0 //riscv platform-level interrupt controller #define SOC_INT_CLIC_SUPPORTED 1 #define SOC_INT_HW_NESTED_SUPPORTED 1 // Support for hardware interrupts nesting