forked from espressif/esp-idf
feat(freertos): Enable Amazon FreeRTOS SMP kernel for esp32c5 and esp32c61
This commit enables the Amazon SMP port for FreeRTOS for the esp32c5 and esp32c61 targets.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -78,9 +78,6 @@ typedef uint32_t TickType_t;
|
||||
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
|
||||
|
||||
// interrupt module will mask interrupt with priority less than threshold
|
||||
#define RVHAL_EXCM_LEVEL 4
|
||||
|
||||
/* ----------------------------------------------- Port Configurations -------------------------------------------------
|
||||
* - Configurations values supplied by each port
|
||||
* - Required by FreeRTOS
|
||||
@@ -191,9 +188,22 @@ void vPortTCBPreDeleteHook( void *pxTCB );
|
||||
// --------------------- Interrupts ------------------------
|
||||
|
||||
#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask()
|
||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(1)
|
||||
#if !SOC_INT_CLIC_SUPPORTED
|
||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(RVHAL_INTR_ENABLE_THRESH)
|
||||
#else
|
||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask(RVHAL_INTR_ENABLE_THRESH_CLIC)
|
||||
#endif /* !SOC_INT_CLIC_SUPPORTED */
|
||||
#define portRESTORE_INTERRUPTS(x) vPortClearInterruptMask(x)
|
||||
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ({ \
|
||||
unsigned int cur_level; \
|
||||
cur_level = ulPortSetInterruptMask(); \
|
||||
cur_level; \
|
||||
})
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portRESTORE_INTERRUPTS(x)
|
||||
#define portSET_INTERRUPT_MASK() portSET_INTERRUPT_MASK_FROM_ISR()
|
||||
#define portCLEAR_INTERRUPT_MASK(x) portCLEAR_INTERRUPT_MASK_FROM_ISR(x)
|
||||
|
||||
/**
|
||||
* @brief Assert if in ISR context
|
||||
*
|
||||
@@ -226,16 +236,8 @@ extern void vTaskExitCritical( void );
|
||||
#define portEXIT_CRITICAL(...) CHOOSE_MACRO_VA_ARG(portEXIT_CRITICAL_IDF, portEXIT_CRITICAL_SMP, ##__VA_ARGS__)(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ({ \
|
||||
unsigned int cur_level; \
|
||||
cur_level = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG); \
|
||||
vTaskEnterCritical(); \
|
||||
cur_level; \
|
||||
})
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) ({ \
|
||||
vTaskExitCritical(); \
|
||||
portRESTORE_INTERRUPTS(x); \
|
||||
})
|
||||
#define portENTER_CRITICAL_FROM_ISR() vTaskEnterCriticalFromISR()
|
||||
#define portEXIT_CRITICAL_FROM_ISR(x) vTaskExitCriticalFromISR(x)
|
||||
|
||||
// ---------------------- Yielding -------------------------
|
||||
|
||||
@@ -328,21 +330,26 @@ void vPortExitCritical(void);
|
||||
|
||||
static inline bool IRAM_ATTR xPortCanYield(void)
|
||||
{
|
||||
uint32_t threshold = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG);
|
||||
#if SOC_INT_CLIC_SUPPORTED
|
||||
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.
|
||||
/* 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.
|
||||
*/
|
||||
return (threshold == 0);
|
||||
#endif /* SOC_INT_CLIC_SUPPORTED */
|
||||
uint32_t threshold = rv_utils_get_interrupt_threshold();
|
||||
uint32_t intr_level = rv_utils_get_interrupt_level();
|
||||
return ((intr_level == 0) && (threshold == 0));
|
||||
#else/* !SOC_INT_CLIC_SUPPORTED */
|
||||
uint32_t threshold = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG);
|
||||
/* when enter critical code, FreeRTOS will mask threshold to RVHAL_EXCM_LEVEL
|
||||
* and exit critical code, will recover threshold value (1). so threshold <= 1
|
||||
* means not in critical code
|
||||
*/
|
||||
return (threshold <= 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Defined even for configNUMBER_OF_CORES > 1 for IDF compatibility
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -126,24 +126,14 @@ void vPortSetStackWatchpoint(void *pxStackStart)
|
||||
|
||||
UBaseType_t ulPortSetInterruptMask(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned old_xstatus;
|
||||
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
old_xstatus = RV_CLEAR_CSR(ustatus, USTATUS_UIE);
|
||||
UBaseType_t prev_int_level = 0, int_level = 0;
|
||||
#if !SOC_INT_CLIC_SUPPORTED
|
||||
int_level = RVHAL_EXCM_LEVEL;
|
||||
#else
|
||||
// For non-secure configuration
|
||||
old_xstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
|
||||
int_level = RVHAL_EXCM_LEVEL_CLIC;
|
||||
#endif
|
||||
|
||||
ret = REG_READ(INTERRUPT_CURRENT_CORE_INT_THRESH_REG);
|
||||
REG_WRITE(INTERRUPT_CURRENT_CORE_INT_THRESH_REG, RVHAL_EXCM_LEVEL);
|
||||
|
||||
#if CONFIG_SECURE_ENABLE_TEE
|
||||
RV_SET_CSR(ustatus, old_xstatus & USTATUS_UIE);
|
||||
#else
|
||||
RV_SET_CSR(mstatus, old_xstatus & MSTATUS_MIE);
|
||||
#endif
|
||||
prev_int_level = rv_utils_set_intlevel_regval(int_level);
|
||||
/**
|
||||
* In theory, this function should not return immediately as there is a
|
||||
* delay between the moment we mask the interrupt threshold register and
|
||||
@@ -155,12 +145,12 @@ UBaseType_t ulPortSetInterruptMask(void)
|
||||
* followed by two instructions: `ret` and `csrrs` (RV_SET_CSR).
|
||||
* That's why we don't need any additional nop instructions here.
|
||||
*/
|
||||
return ret;
|
||||
return prev_int_level;
|
||||
}
|
||||
|
||||
void vPortClearInterruptMask(UBaseType_t mask)
|
||||
{
|
||||
REG_WRITE(INTERRUPT_CURRENT_CORE_INT_THRESH_REG, mask);
|
||||
rv_utils_restore_intlevel_regval(mask);
|
||||
/**
|
||||
* The delay between the moment we unmask the interrupt threshold register
|
||||
* and the moment the potential requested interrupt is triggered is not
|
||||
@@ -312,7 +302,7 @@ BaseType_t xPortStartScheduler(void)
|
||||
/* Setup the hardware to generate the tick. */
|
||||
vPortSetupTimer();
|
||||
|
||||
esprv_int_set_threshold(1); /* set global INTC masking level */
|
||||
esprv_int_set_threshold(RVHAL_INTR_ENABLE_THRESH); /* set global interrupt masking level */
|
||||
rv_utils_intr_global_enable();
|
||||
|
||||
vPortYield();
|
||||
|
Reference in New Issue
Block a user