kopia lustrzana https://github.com/espressif/esp-idf
fix(freertos): Fixed xPortCanYield to correctly determine ISR context on esp32p4
This commit fixes an issue where xPortCanYield() function may not be able to detect an ISR context when HW interrupt nesting is active on a CLIC interrupt controller such as on esp32p4.pull/12486/head
rodzic
54f0517724
commit
cf55ab899a
|
@ -645,13 +645,18 @@ FORCE_INLINE_ATTR bool xPortCanYield(void)
|
|||
{
|
||||
uint32_t threshold = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG);
|
||||
#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));
|
||||
|
||||
/* When CLIC is supported, the lowest interrupt threshold level is 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);
|
||||
return ((intr_level == 0) && (threshold == 0));
|
||||
#endif /* SOC_INT_CLIC_SUPPORTED */
|
||||
/* when enter critical code, FreeRTOS will mask threshold to RVHAL_EXCM_LEVEL
|
||||
* 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);
|
||||
}
|
||||
|
||||
#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 --------------------
|
||||
|
||||
FORCE_INLINE_ATTR void rv_utils_intr_enable(uint32_t intr_mask)
|
||||
|
|
Ładowanie…
Reference in New Issue