From 5986e63c47578369dadd802c44307c9a1ee2603c Mon Sep 17 00:00:00 2001 From: Armando Date: Tue, 18 Jul 2023 14:38:41 +0800 Subject: [PATCH] change(riscv): added fence after CLIC_INT_THRESH_REG is set --- .../FreeRTOS-Kernel/portable/riscv/port.c | 10 ++++++++++ components/riscv/include/riscv/rv_utils.h | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c index 9ea3244250..6933664a95 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c @@ -439,6 +439,16 @@ int vPortSetInterruptMask(void) #define RVHAL_EXCM_THRESHOLD_VALUE (((RVHAL_EXCM_LEVEL << (8 - NLBITS)) | 0x1f) << CLIC_CPU_INT_THRESH_S) REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, RVHAL_EXCM_THRESHOLD_VALUE); + /** + * TODO: IDF-7898 + * Here is an issue that, + * 1. Set the CLIC_INT_THRESH_REG to mask off interrupts whose level is lower than `intlevel`. + * 2. Set MSTATUS_MIE (global interrupt), then program may jump to interrupt vector. + * 3. The register value change in Step 1 may happen during Step 2. + * + * To prevent this, here a fence is used + */ + rv_utils_memory_barrier(); RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE); #endif /** diff --git a/components/riscv/include/riscv/rv_utils.h b/components/riscv/include/riscv/rv_utils.h index baa5b7de26..247ff54971 100644 --- a/components/riscv/include/riscv/rv_utils.h +++ b/components/riscv/include/riscv/rv_utils.h @@ -36,6 +36,15 @@ FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_wait_for_intr(voi asm volatile ("wfi\n"); } +/* ------------------------------------------------- Memory Barrier ---------------------------------------------------- + * + * ------------------------------------------------------------------------------------------------------------------ */ +//TODO: IDF-7898 +FORCE_INLINE_ATTR void rv_utils_memory_barrier(void) +{ + asm volatile("fence iorw, iorw" : : : "memory"); +} + /* -------------------------------------------------- CPU Registers ---------------------------------------------------- * * ------------------------------------------------------------------------------------------------------------------ */ @@ -139,6 +148,16 @@ FORCE_INLINE_ATTR uint32_t __attribute__((always_inline)) rv_utils_set_intlevel( old_thresh = old_thresh >> (24 + (8 - NLBITS)); REG_SET_FIELD(CLIC_INT_THRESH_REG, CLIC_CPU_INT_THRESH, ((intlevel << (8 - NLBITS))) | 0x1f); + /** + * TODO: IDF-7898 + * Here is an issue that, + * 1. Set the CLIC_INT_THRESH_REG to mask off interrupts whose level is lower than `intlevel`. + * 2. Set MSTATUS_MIE (global interrupt), then program may jump to interrupt vector. + * 3. The register value change in Step 1 may happen during Step 2. + * + * To prevent this, here a fence is used + */ + rv_utils_memory_barrier(); RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE); return old_thresh;