forked from espressif/esp-idf
Merge branch 'bugfix/interrupt_context_for_p4' into 'master'
fix(freertos): Fixed xPortCanYield to correctly determine ISR context on esp32p4 See merge request espressif/esp-idf!26161
This commit is contained in:
@@ -645,13 +645,18 @@ FORCE_INLINE_ATTR bool xPortCanYield(void)
|
|||||||
{
|
{
|
||||||
uint32_t threshold = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG);
|
uint32_t threshold = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG);
|
||||||
#if SOC_INT_CLIC_SUPPORTED
|
#if SOC_INT_CLIC_SUPPORTED
|
||||||
|
/* When CLIC is supported:
|
||||||
|
* - The lowest interrupt threshold level is 0. Therefore, an interrupt threshold level above 0 would mean that we
|
||||||
|
* are in a critical section.
|
||||||
|
* - Since CLIC enables HW interrupt nesting, we do not have the updated interrupt level in the
|
||||||
|
* INTERRUPT_CURRENT_CORE_INT_THRESH_REG register when nested interrupts occur. To know the current interrupt
|
||||||
|
* level, we read the machine-mode interrupt level (mil) field from the mintstatus CSR. A non-zero value indicates
|
||||||
|
* that we are in an interrupt context.
|
||||||
|
*/
|
||||||
|
uint32_t intr_level = rv_utils_get_interrupt_level();
|
||||||
threshold = threshold >> (CLIC_CPU_INT_THRESH_S + (8 - NLBITS));
|
threshold = threshold >> (CLIC_CPU_INT_THRESH_S + (8 - NLBITS));
|
||||||
|
|
||||||
/* When CLIC is supported, the lowest interrupt threshold level is 0.
|
return ((intr_level == 0) && (threshold == 0));
|
||||||
* Therefore, an interrupt threshold level above 0 would mean that we
|
|
||||||
* are either in a critical section or in an ISR.
|
|
||||||
*/
|
|
||||||
return (threshold == 0);
|
|
||||||
#endif /* SOC_INT_CLIC_SUPPORTED */
|
#endif /* SOC_INT_CLIC_SUPPORTED */
|
||||||
/* when enter critical code, FreeRTOS will mask threshold to RVHAL_EXCM_LEVEL
|
/* when enter critical code, FreeRTOS will mask threshold to RVHAL_EXCM_LEVEL
|
||||||
* and exit critical code, will recover threshold value (1). so threshold <= 1
|
* and exit critical code, will recover threshold value (1). so threshold <= 1
|
||||||
|
@@ -113,6 +113,20 @@ FORCE_INLINE_ATTR void rv_utils_set_mtvec(uint32_t mtvec_val)
|
|||||||
RV_WRITE_CSR(mtvec, mtvec_val);
|
RV_WRITE_CSR(mtvec, mtvec_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOC_INT_CLIC_SUPPORTED
|
||||||
|
FORCE_INLINE_ATTR __attribute__((pure)) uint32_t rv_utils_get_interrupt_level(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32P4
|
||||||
|
// As per CLIC specs, mintstatus CSR should be at 0xFB1, however esp32p4 implements it at 0x346
|
||||||
|
#define MINTSTATUS 0x346
|
||||||
|
#else
|
||||||
|
#error "rv_utils_get_mintstatus() is not implemented. Check for correct mintstatus register address."
|
||||||
|
#endif /* CONFIG_IDF_TARGET_ESP32P4 */
|
||||||
|
uint32_t mintstatus = RV_READ_CSR(MINTSTATUS);
|
||||||
|
return ((mintstatus >> 24) & 0xFF); // Return the mintstatus[31:24] bits to get the mil field
|
||||||
|
}
|
||||||
|
#endif /* SOC_INT_CLIC_SUPPORTED */
|
||||||
|
|
||||||
// ------------------ Interrupt Control --------------------
|
// ------------------ Interrupt Control --------------------
|
||||||
|
|
||||||
FORCE_INLINE_ATTR void rv_utils_intr_enable(uint32_t intr_mask)
|
FORCE_INLINE_ATTR void rv_utils_intr_enable(uint32_t intr_mask)
|
||||||
|
Reference in New Issue
Block a user