fix(esp32p4): Fixed interrupt handling to use the CLIC controller

This commit is contained in:
Omar Chebib
2023-08-14 15:44:24 +08:00
parent eb8883cc20
commit 8ca191e4c1
27 changed files with 822 additions and 510 deletions
@@ -0,0 +1,35 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* The interrupt bit in `mcause` register is always bit 31 regardless of the interrupt controller used
*/
#define VECTORS_MCAUSE_INTBIT_MASK (0x80000000)
#if SOC_INT_CLIC_SUPPORTED
/* When using the CLIC as their interrupt controller, the `mcause` register contains more information than
* the interrupt bit and cause:
* MINHV[30]: CPU is fetching vector interrupt entry address or not
* MPP[29:28]: MSTATUS.MPP[1:0]
* MPIL[23:16]: interrupt level before entering interrupt ISR
*
* Define the mask that will only keep the cause.
*/
#define VECTORS_MCAUSE_REASON_MASK (0x00000fff)
#else // !if SOC_INT_CLIC_SUPPORTED
/**
* For targets that use the former INTC or CLINT/PLIC, the `mcause` shouldn't contain any more information
* but let's be safe and keep the 32 possible cause values.
*/
#define VECTORS_MCAUSE_REASON_MASK (0x0000001f)
#endif
+22 -1
View File
@@ -1,11 +1,13 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -124,6 +126,25 @@ void esprv_intc_int_set_threshold(int priority_threshold);
*/
uint32_t esprv_intc_get_interrupt_unmask(void);
/**
* @brief Check if the given interrupt is hardware vectored
*
* @param rv_int_num Interrupt number
*
* @return true if the interrupt is vectored, false if it is not.
*/
bool esprv_intc_int_is_vectored(int rv_int_num);
/**
* @brief Set interrupt vectored
*
* Configure the given interrupt number to hardware vectored or non-vectored.
*
* @param rv_int_num Interrupt number
* @param vectored True to set it to vectored, false to set it to non-vectored
*/
void esprv_intc_int_set_vectored(int rv_int_num, bool vectored);
#ifdef __cplusplus
}
#endif
+9 -11
View File
@@ -133,8 +133,9 @@ FORCE_INLINE_ATTR void rv_utils_intr_disable(uint32_t intr_mask)
RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
}
//TODO: IDF-7795, clic related
#if (SOC_CPU_CORES_NUM > 1)
#if SOC_INT_CLIC_SUPPORTED
FORCE_INLINE_ATTR void __attribute__((always_inline)) rv_utils_restore_intlevel(uint32_t restoreval)
{
REG_SET_FIELD(CLIC_INT_THRESH_REG, CLIC_CPU_INT_THRESH, ((restoreval << (8 - NLBITS))) | 0x1f);
@@ -145,8 +146,10 @@ FORCE_INLINE_ATTR uint32_t __attribute__((always_inline)) rv_utils_set_intlevel(
uint32_t old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
uint32_t old_thresh;
old_thresh = REG_READ(CLIC_INT_THRESH_REG);
old_thresh = old_thresh >> (24 + (8 - NLBITS));
old_thresh = REG_GET_FIELD(CLIC_INT_THRESH_REG, CLIC_CPU_INT_THRESH);
old_thresh = (old_thresh >> (8 - NLBITS));
/* Upper bits should already be 0, but let's be safe and keep NLBITS */
old_thresh &= BIT(NLBITS) - 1;
REG_SET_FIELD(CLIC_INT_THRESH_REG, CLIC_CPU_INT_THRESH, ((intlevel << (8 - NLBITS))) | 0x1f);
/**
@@ -166,19 +169,15 @@ FORCE_INLINE_ATTR uint32_t __attribute__((always_inline)) rv_utils_set_intlevel(
FORCE_INLINE_ATTR uint32_t __attribute__((always_inline)) rv_utils_mask_int_level_lower_than(uint32_t intlevel)
{
#if SOC_INT_CLIC_SUPPORTED
/* CLIC's set interrupt level is inclusive, i.e. it does mask the set level */
return rv_utils_set_intlevel(intlevel - 1);
#else
return rv_utils_set_intlevel(intlevel);
#endif /* SOC_INT_CLIC_SUPPORTED */
}
#endif //#if (SOC_CPU_CORES_NUM > 1)
#endif /* SOC_INT_CLIC_SUPPORTED */
FORCE_INLINE_ATTR uint32_t rv_utils_intr_get_enabled_mask(void)
{
//TODO: IDF-7795
#if SOC_INT_CLIC_SUPPORTED
unsigned intr_ena_mask = 0;
unsigned intr_num;
@@ -194,7 +193,6 @@ FORCE_INLINE_ATTR uint32_t rv_utils_intr_get_enabled_mask(void)
FORCE_INLINE_ATTR void rv_utils_intr_edge_ack(unsigned int intr_num)
{
//TODO: IDF-7795
#if SOC_INT_CLIC_SUPPORTED
REG_SET_BIT(CLIC_INT_CTRL_REG(intr_num + CLIC_EXT_INTR_NUM_OFFSET) , CLIC_INT_IP);
#else