fix(esp32p4): Fixed interrupt handling to use the CLIC controller
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user