kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'bugfix/esp32p4_remove_fence' into 'master'
fix(riscv): Remove the memory barrier when changing interrupt threshold Closes IDF-7898 See merge request espressif/esp-idf!29119pull/13294/head
commit
345bf79b4e
|
@ -60,15 +60,6 @@ FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_wait_for_intr(voi
|
||||||
asm volatile ("wfi\n");
|
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 ----------------------------------------------------
|
/* -------------------------------------------------- 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);
|
REG_SET_FIELD(CLIC_INT_THRESH_REG, CLIC_CPU_INT_THRESH, ((intlevel << (8 - NLBITS))) | 0x1f);
|
||||||
/**
|
/**
|
||||||
* TODO: IDF-7898
|
* After writing the threshold register, the new threshold is not directly taken into account by the CPU.
|
||||||
* Here is an issue that,
|
* By executing ~8 nop instructions, or by performing a memory load right now, the previous memory write
|
||||||
* 1. Set the CLIC_INT_THRESH_REG to mask off interrupts whose level is lower than `intlevel`.
|
* operations is forced, making the new threshold active. It is then safe to re-enable MIE bit in mstatus.
|
||||||
* 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();
|
REG_READ(CLIC_INT_THRESH_REG);
|
||||||
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
|
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
|
||||||
|
|
||||||
return old_thresh;
|
return old_thresh;
|
||||||
|
|
Ładowanie…
Reference in New Issue