From 2217854092ba729ad1a2016053129bb2366d863d Mon Sep 17 00:00:00 2001 From: Omar Chebib Date: Tue, 20 Feb 2024 12:19:08 +0800 Subject: [PATCH] fix(riscv): Remove the memory barrier when changing interrupt threshold --- components/riscv/include/riscv/rv_utils.h | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/components/riscv/include/riscv/rv_utils.h b/components/riscv/include/riscv/rv_utils.h index 82df03daf9..be0f8372c2 100644 --- a/components/riscv/include/riscv/rv_utils.h +++ b/components/riscv/include/riscv/rv_utils.h @@ -60,15 +60,6 @@ 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 ---------------------------------------------------- * * ------------------------------------------------------------------------------------------------------------------ */ @@ -191,15 +182,11 @@ FORCE_INLINE_ATTR uint32_t __attribute__((always_inline)) rv_utils_set_intlevel( 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 + * After writing the threshold register, the new threshold is not directly taken into account by the CPU. + * By executing ~8 nop instructions, or by performing a memory load right now, the previous memory write + * operations is forced, making the new threshold active. It is then safe to re-enable MIE bit in mstatus. */ - rv_utils_memory_barrier(); + REG_READ(CLIC_INT_THRESH_REG); RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE); return old_thresh;