refactor(riscv): refactor crosscore interrupt

pull/13090/head
Omar Chebib 2023-12-11 19:37:30 +08:00
rodzic 298931596a
commit 5cdf145f55
13 zmienionych plików z 415 dodań i 68 usunięć

Wyświetl plik

@ -10,7 +10,7 @@
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
#include "esp_debug_helpers.h" #include "esp_debug_helpers.h"
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include "hal/crosscore_int_ll.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h" #include "freertos/portmacro.h"
@ -19,15 +19,6 @@
#include "esp_gdbstub.h" #include "esp_gdbstub.h"
#endif #endif
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
#include "soc/dport_reg.h"
#else
#include "soc/system_reg.h"
#endif
#if CONFIG_IDF_TARGET_ESP32P4
#include "soc/hp_system_reg.h"
#endif
#define REASON_YIELD BIT(0) #define REASON_YIELD BIT(0)
#define REASON_FREQ_SWITCH BIT(1) #define REASON_FREQ_SWITCH BIT(1)
#define REASON_PRINT_BACKTRACE BIT(2) #define REASON_PRINT_BACKTRACE BIT(2)
@ -53,29 +44,7 @@ static void IRAM_ATTR esp_crosscore_isr(void *arg) {
volatile uint32_t *my_reason=arg; volatile uint32_t *my_reason=arg;
//Clear the interrupt first. //Clear the interrupt first.
#if CONFIG_IDF_TARGET_ESP32 crosscore_int_ll_clear_interrupt(esp_cpu_get_core_id());
if (esp_cpu_get_core_id()==0) {
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0);
} else {
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0);
}
#elif CONFIG_IDF_TARGET_ESP32S2
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0);
#elif CONFIG_IDF_TARGET_ESP32S3
if (esp_cpu_get_core_id()==0) {
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0);
} else {
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, 0);
}
#elif CONFIG_IDF_TARGET_ESP32P4
if (esp_cpu_get_core_id() == 0) {
WRITE_PERI_REG(HP_SYSTEM_CPU_INT_FROM_CPU_0_REG, 0);
} else {
WRITE_PERI_REG(HP_SYSTEM_CPU_INT_FROM_CPU_1_REG, 0);
}
#elif CONFIG_IDF_TARGET_ARCH_RISCV
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0);
#endif
//Grab the reason and clear it. //Grab the reason and clear it.
portENTER_CRITICAL_ISR(&reason_spinlock); portENTER_CRITICAL_ISR(&reason_spinlock);
@ -142,29 +111,7 @@ static void IRAM_ATTR esp_crosscore_int_send(int core_id, uint32_t reason_mask)
reason[core_id] |= reason_mask; reason[core_id] |= reason_mask;
portEXIT_CRITICAL_ISR(&reason_spinlock); portEXIT_CRITICAL_ISR(&reason_spinlock);
//Poke the other CPU. //Poke the other CPU.
#if CONFIG_IDF_TARGET_ESP32 crosscore_int_ll_trigger_interrupt(core_id);
if (core_id==0) {
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0);
} else {
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, DPORT_CPU_INTR_FROM_CPU_1);
}
#elif CONFIG_IDF_TARGET_ESP32S2
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0);
#elif CONFIG_IDF_TARGET_ESP32S3
if (core_id==0) {
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, SYSTEM_CPU_INTR_FROM_CPU_0);
} else {
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, SYSTEM_CPU_INTR_FROM_CPU_1);
}
#elif CONFIG_IDF_TARGET_ESP32P4
if (core_id==0) {
WRITE_PERI_REG(HP_SYSTEM_CPU_INT_FROM_CPU_0_REG, HP_SYSTEM_CPU_INT_FROM_CPU_0);
} else {
WRITE_PERI_REG(HP_SYSTEM_CPU_INT_FROM_CPU_1_REG, HP_SYSTEM_CPU_INT_FROM_CPU_1);
}
#elif CONFIG_IDF_TARGET_ARCH_RISCV
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, SYSTEM_CPU_INTR_FROM_CPU_0);
#endif
} }
void IRAM_ATTR esp_crosscore_int_send_yield(int core_id) void IRAM_ATTR esp_crosscore_int_send_yield(int core_id)

Wyświetl plik

@ -50,7 +50,7 @@ void esp_crosscore_int_send_freq_switch(int core_id);
void esp_crosscore_int_send_gdb_call(int core_id); void esp_crosscore_int_send_gdb_call(int core_id);
#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32C2 && !CONFIG_IDF_TARGET_ESP32C6 && !CONFIG_IDF_TARGET_ESP32H2 #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
/** /**
* Send an interrupt to a CPU indicating it should print its current backtrace * Send an interrupt to a CPU indicating it should print its current backtrace
* *
@ -75,7 +75,7 @@ void esp_crosscore_int_send_print_backtrace(int core_id);
void esp_crosscore_int_send_twdt_abort(int core_id); void esp_crosscore_int_send_twdt_abort(int core_id);
#endif // CONFIG_ESP_TASK_WDT_EN #endif // CONFIG_ESP_TASK_WDT_EN
#endif // !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32C2 && !CONFIG_IDF_TARGET_ESP32C6 #endif // !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
#ifdef __cplusplus #ifdef __cplusplus
} }

Wyświetl plik

@ -9,7 +9,7 @@
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "soc/periph_defs.h" #include "soc/periph_defs.h"
#include "soc/system_reg.h" #include "soc/system_reg.h"
#include "soc/interrupt_reg.h" #include "hal/crosscore_int_ll.h"
#include "hal/systimer_hal.h" #include "hal/systimer_hal.h"
#include "hal/systimer_ll.h" #include "hal/systimer_ll.h"
#include "riscv/rvruntime-frames.h" #include "riscv/rvruntime-frames.h"
@ -184,6 +184,9 @@ void IRAM_ATTR vPortReleaseLock( portMUX_TYPE *lock )
void vPortYield(void) void vPortYield(void)
{ {
// TODO: IDF-8113
const int core_id = 0;
if (uxInterruptNesting) { if (uxInterruptNesting) {
vPortYieldFromISR(); vPortYieldFromISR();
} else { } else {
@ -199,7 +202,7 @@ void vPortYield(void)
for an instant yield, and if that happens then the WFI would be for an instant yield, and if that happens then the WFI would be
waiting for the next interrupt to occur...) waiting for the next interrupt to occur...)
*/ */
while (uxSchedulerRunning && REG_READ(SYSTEM_CPU_INTR_FROM_CPU_0_REG) != 0) {} while (uxSchedulerRunning && crosscore_int_ll_get_state(core_id) != 0) {}
} }
} }

Wyświetl plik

@ -46,6 +46,7 @@
#include "riscv/rv_utils.h" #include "riscv/rv_utils.h"
#include "riscv/interrupt.h" #include "riscv/interrupt.h"
#include "esp_private/crosscore_int.h" #include "esp_private/crosscore_int.h"
#include "hal/crosscore_int_ll.h"
#include "esp_attr.h" #include "esp_attr.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_intr_alloc.h" #include "esp_intr_alloc.h"
@ -623,13 +624,6 @@ void vPortExitCritical(void)
void vPortYield(void) void vPortYield(void)
{ {
BaseType_t coreID = xPortGetCoreID(); BaseType_t coreID = xPortGetCoreID();
int system_cpu_int_reg;
#if !CONFIG_IDF_TARGET_ESP32P4
system_cpu_int_reg = SYSTEM_CPU_INTR_FROM_CPU_0_REG;
#else
system_cpu_int_reg = HP_SYSTEM_CPU_INT_FROM_CPU_0_REG;
#endif /* !CONFIG_IDF_TARGET_ESP32P4 */
if (port_uxInterruptNesting[coreID]) { if (port_uxInterruptNesting[coreID]) {
vPortYieldFromISR(); vPortYieldFromISR();
@ -645,7 +639,7 @@ void vPortYield(void)
for an instant yield, and if that happens then the WFI would be for an instant yield, and if that happens then the WFI would be
waiting for the next interrupt to occur...) waiting for the next interrupt to occur...)
*/ */
while (port_xSchedulerRunning[coreID] && port_uxCriticalNesting[coreID] == 0 && REG_READ(system_cpu_int_reg + 4 * coreID) != 0) {} while (port_xSchedulerRunning[coreID] && port_uxCriticalNesting[coreID] == 0 && crosscore_int_ll_get_state(coreID) != 0) {}
} }
} }

Wyświetl plik

@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_attr.h"
#include "soc/dport_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Clear the crosscore interrupt that just occurred on the current core
*/
FORCE_INLINE_ATTR void crosscore_int_ll_clear_interrupt(int core_id)
{
if (core_id == 0) {
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0);
} else {
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0);
}
}
/**
* @brief Trigger a crosscore interrupt on the given core
*
* @param core_id Core to trigger an interrupt on. Ignored on single core targets.
*/
FORCE_INLINE_ATTR void crosscore_int_ll_trigger_interrupt(int core_id)
{
if (core_id == 0) {
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0);
} else {
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, DPORT_CPU_INTR_FROM_CPU_1);
}
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,52 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "esp_attr.h"
#include "soc/system_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Clear the crosscore interrupt that just occurred on the current core
*/
FORCE_INLINE_ATTR void crosscore_int_ll_clear_interrupt(int core_id)
{
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0);
}
/**
* @brief Trigger a crosscore interrupt on the given core
*
* @param core_id Core to trigger an interrupt on. Ignored on single core targets.
*/
FORCE_INLINE_ATTR void crosscore_int_ll_trigger_interrupt(int core_id)
{
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, SYSTEM_CPU_INTR_FROM_CPU_0);
}
/**
* @brief Get the state of the crosscore interrupt register for the given core
*
* @param core_id Core to get the crosscore interrupt state of. Ignored on single core targets.
*
* @return Non zero value if a software interrupt is pending on the given core,
* 0 if no software interrupt is pending.
*/
FORCE_INLINE_ATTR uint32_t crosscore_int_ll_get_state(int core_id)
{
return REG_READ(SYSTEM_CPU_INTR_FROM_CPU_0_REG);
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,52 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "esp_attr.h"
#include "soc/system_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Clear the crosscore interrupt that just occurred on the current core
*/
FORCE_INLINE_ATTR void crosscore_int_ll_clear_interrupt(int core_id)
{
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0);
}
/**
* @brief Trigger a crosscore interrupt on the given core
*
* @param core_id Core to trigger an interrupt on. Ignored on single core targets.
*/
FORCE_INLINE_ATTR void crosscore_int_ll_trigger_interrupt(int core_id)
{
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, SYSTEM_CPU_INTR_FROM_CPU_0);
}
/**
* @brief Get the state of the crosscore interrupt register for the given core
*
* @param core_id Core to get the crosscore interrupt state of. Ignored on single core targets.
*
* @return Non zero value if a software interrupt is pending on the given core,
* 0 if no software interrupt is pending.
*/
FORCE_INLINE_ATTR uint32_t crosscore_int_ll_get_state(int core_id)
{
return REG_READ(SYSTEM_CPU_INTR_FROM_CPU_0_REG);
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,52 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "esp_attr.h"
#include "soc/intpri_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Clear the crosscore interrupt that just occurred on the current core
*/
FORCE_INLINE_ATTR void crosscore_int_ll_clear_interrupt(int core_id)
{
WRITE_PERI_REG(INTPRI_CPU_INTR_FROM_CPU_0_REG, 0);
}
/**
* @brief Trigger a crosscore interrupt on the given core
*
* @param core_id Core to trigger an interrupt on. Ignored on single core targets.
*/
FORCE_INLINE_ATTR void crosscore_int_ll_trigger_interrupt(int core_id)
{
WRITE_PERI_REG(INTPRI_CPU_INTR_FROM_CPU_0_REG, INTPRI_CPU_INTR_FROM_CPU_0);
}
/**
* @brief Get the state of the crosscore interrupt register for the given core
*
* @param core_id Core to get the crosscore interrupt state of. Ignored on single core targets.
*
* @return Non zero value if a software interrupt is pending on the given core,
* 0 if no software interrupt is pending.
*/
FORCE_INLINE_ATTR uint32_t crosscore_int_ll_get_state(int core_id)
{
return REG_READ(INTPRI_CPU_INTR_FROM_CPU_0_REG);
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,52 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "esp_attr.h"
#include "soc/intpri_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Clear the crosscore interrupt that just occurred on the current core
*/
FORCE_INLINE_ATTR void crosscore_int_ll_clear_interrupt(int core_id)
{
WRITE_PERI_REG(INTPRI_CPU_INTR_FROM_CPU_0_REG, 0);
}
/**
* @brief Trigger a crosscore interrupt on the given core
*
* @param core_id Core to trigger an interrupt on. Ignored on single core targets.
*/
FORCE_INLINE_ATTR void crosscore_int_ll_trigger_interrupt(int core_id)
{
WRITE_PERI_REG(INTPRI_CPU_INTR_FROM_CPU_0_REG, INTPRI_CPU_INTR_FROM_CPU_0);
}
/**
* @brief Get the state of the crosscore interrupt register for the given core
*
* @param core_id Core to get the crosscore interrupt state of. Ignored on single core targets.
*
* @return Non zero value if a software interrupt is pending on the given core,
* 0 if no software interrupt is pending.
*/
FORCE_INLINE_ATTR uint32_t crosscore_int_ll_get_state(int core_id)
{
return REG_READ(INTPRI_CPU_INTR_FROM_CPU_0_REG);
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,68 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include "esp_attr.h"
#include "soc/hp_system_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Clear the crosscore interrupt that just occurred on the current core
*/
FORCE_INLINE_ATTR void crosscore_int_ll_clear_interrupt(int core_id)
{
if (core_id == 0) {
WRITE_PERI_REG(HP_SYSTEM_CPU_INT_FROM_CPU_0_REG, 0);
} else {
WRITE_PERI_REG(HP_SYSTEM_CPU_INT_FROM_CPU_1_REG, 0);
}
}
/**
* @brief Trigger a crosscore interrupt on the given core
*
* @param core_id Core to trigger an interrupt on. Ignored on single core targets.
*/
FORCE_INLINE_ATTR void crosscore_int_ll_trigger_interrupt(int core_id)
{
if (core_id == 0) {
WRITE_PERI_REG(HP_SYSTEM_CPU_INT_FROM_CPU_0_REG, HP_SYSTEM_CPU_INT_FROM_CPU_0);
} else {
WRITE_PERI_REG(HP_SYSTEM_CPU_INT_FROM_CPU_1_REG, HP_SYSTEM_CPU_INT_FROM_CPU_1);
}
}
/**
* @brief Get the state of the crosscore interrupt register for the given core
*
* @param core_id Core to get the crosscore interrupt state of. Ignored on single core targets.
*
* @return Non zero value if a software interrupt is pending on the given core,
* 0 if no software interrupt is pending.
*/
FORCE_INLINE_ATTR uint32_t crosscore_int_ll_get_state(int core_id)
{
uint32_t reg = 0;
if (core_id == 0) {
reg = REG_READ(HP_SYSTEM_CPU_INT_FROM_CPU_0_REG);
} else {
reg = REG_READ(HP_SYSTEM_CPU_INT_FROM_CPU_1_REG);
}
return reg;
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/dport_reg.h"
#include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Clear the crosscore interrupt that just occurred on the current core
*/
static inline void crosscore_int_ll_clear_interrupt(int core_id)
{
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0);
}
/**
* @brief Trigger a crosscore interrupt on the given core
*
* @param core_id Core to trigger an interrupt on. Ignored on single core targets.
*/
static inline void crosscore_int_ll_trigger_interrupt(int core_id)
{
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0);
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,44 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/system_reg.h"
#include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Clear the crosscore interrupt that just occurred on the current core
*/
FORCE_INLINE_ATTR void crosscore_int_ll_clear_interrupt(int core_id)
{
if (core_id == 0) {
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0);
} else {
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, 0);
}
}
/**
* @brief Trigger a crosscore interrupt on the given core
*
* @param core_id Core to trigger an interrupt on.
*/
FORCE_INLINE_ATTR void crosscore_int_ll_trigger_interrupt(int core_id)
{
if (core_id == 0) {
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, SYSTEM_CPU_INTR_FROM_CPU_0);
} else {
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, SYSTEM_CPU_INTR_FROM_CPU_1);
}
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -6,6 +6,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "xtensa/config/core-isa.h" #include "xtensa/config/core-isa.h"
#include "xtensa/config/core.h" #include "xtensa/config/core.h"