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:
Sudeep Mohanty
2025-03-20 16:43:14 +01:00
parent 0be20a5f22
commit 1742a982d5
2 changed files with 39 additions and 42 deletions

View File

@@ -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

View File

@@ -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();