From 8a608da2b0a3d2c732742fb264c1a978e1887ddf Mon Sep 17 00:00:00 2001 From: Xiaoyu Liu Date: Wed, 14 Aug 2024 16:12:24 +0800 Subject: [PATCH] refactor(intr): add plic and intc interrupt rv util apis refactor(intr): remove the extra instructions in plic and intc --- .../include/esp_private/interrupt_intc.h | 28 +++++++++++++++++++ .../include/esp_private/interrupt_plic.h | 28 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/components/riscv/include/esp_private/interrupt_intc.h b/components/riscv/include/esp_private/interrupt_intc.h index dc8f47b590..262a60285c 100644 --- a/components/riscv/include/esp_private/interrupt_intc.h +++ b/components/riscv/include/esp_private/interrupt_intc.h @@ -11,6 +11,7 @@ #include "esp_attr.h" #include "soc/interrupt_reg.h" #include "soc/soc_caps.h" +#include "riscv/csr.h" #if !SOC_INT_CLIC_SUPPORTED && !SOC_INT_PLIC_SUPPORTED @@ -63,6 +64,33 @@ FORCE_INLINE_ATTR void rv_utils_intr_edge_ack(uint32_t intr_num) REG_SET_BIT(INTERRUPT_CORE0_CPU_INT_CLEAR_REG, intr_num); } +/** + * @brief Restore the CPU interrupt level to the value returned by `rv_utils_set_intlevel_regval`. + * + * @param restoreval Former raw interrupt level, it is NOT necessarily a value between 0 and 7, this is hardware and configuration dependent. + */ +FORCE_INLINE_ATTR void rv_utils_restore_intlevel_regval(uint32_t restoreval) +{ + REG_WRITE(INTERRUPT_CURRENT_CORE_INT_THRESH_REG, restoreval); +} + +/** + * @brief Set the interrupt threshold to `intlevel` while getting the current level. + * + * @param intlevel New raw interrupt level, it is NOT necessarily a value between 0 and 7, this is hardware and configuration dependent. + * + * @return Current raw interrupt level, can be restored by calling `rv_utils_restore_intlevel_regval`. + */ +FORCE_INLINE_ATTR uint32_t rv_utils_set_intlevel_regval(uint32_t intlevel) +{ + uint32_t old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE); + uint32_t old_thresh = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG); + rv_utils_restore_intlevel_regval(intlevel); + RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE); + + return old_thresh; +} + #ifdef __cplusplus } diff --git a/components/riscv/include/esp_private/interrupt_plic.h b/components/riscv/include/esp_private/interrupt_plic.h index a6f1e302a8..4d1fbba34e 100644 --- a/components/riscv/include/esp_private/interrupt_plic.h +++ b/components/riscv/include/esp_private/interrupt_plic.h @@ -11,6 +11,7 @@ #include "esp_attr.h" #include "soc/interrupt_reg.h" #include "soc/soc_caps.h" +#include "riscv/csr.h" #if SOC_INT_PLIC_SUPPORTED @@ -64,6 +65,33 @@ FORCE_INLINE_ATTR void rv_utils_intr_edge_ack(uint32_t intr_num) REG_SET_BIT(INTERRUPT_CORE0_CPU_INT_CLEAR_REG, intr_num); } +/** + * @brief Restore the CPU interrupt level to the value returned by `rv_utils_set_intlevel_regval`. + * + * @param restoreval Former raw interrupt level, it is NOT necessarily a value between 0 and 7, this is hardware and configuration dependent. + */ +FORCE_INLINE_ATTR void rv_utils_restore_intlevel_regval(uint32_t restoreval) +{ + REG_WRITE(INTERRUPT_CURRENT_CORE_INT_THRESH_REG, restoreval); +} + +/** + * @brief Set the interrupt threshold to `intlevel` while getting the current level. + * + * @param intlevel New raw interrupt level, it is NOT necessarily a value between 0 and 7, this is hardware and configuration dependent. + * + * @return Current raw interrupt level, can be restored by calling `rv_utils_restore_intlevel_regval`. + */ +FORCE_INLINE_ATTR uint32_t rv_utils_set_intlevel_regval(uint32_t intlevel) +{ + uint32_t old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE); + uint32_t old_thresh = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG); + rv_utils_restore_intlevel_regval(intlevel); + RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE); + + return old_thresh; +} + #ifdef __cplusplus }