feat(wdt): add multicore support for WDTs on RISCV

This commit is contained in:
Marius Vikhammer
2023-10-23 18:26:08 +08:00
parent 51434a8367
commit 22091c8744
8 changed files with 126 additions and 98 deletions
@@ -41,6 +41,7 @@ if(CONFIG_IDF_TARGET_ARCH_XTENSA)
elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
list(APPEND srcs "arch/riscv/expression_with_stack.c"
"arch/riscv/panic_arch.c"
"arch/riscv/debug_helpers.c"
"arch/riscv/debug_stubs.c")
endif()
@@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_debug_helpers.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_private/freertos_debug.h"
#include "esp_err.h"
#include "esp_attr.h"
#include "riscv/rvruntime-frames.h"
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
#include "esp_private/eh_frame_parser.h"
#endif // CONFIG_ESP_SYSTEM_USE_EH_FRAME
#if !CONFIG_ESP_SYSTEM_USE_EH_FRAME
/* Function used to print all the registers pointed by the given frame .*/
extern void panic_print_registers(const void *frame, int core);
#endif // !CONFIG_ESP_SYSTEM_USE_EH_FRAME
/* Targets based on a RISC-V CPU cannot perform backtracing that easily.
* We have two options here:
* - Perform backtracing at runtime.
* - Let IDF monitor do the backtracing for us. Used during panic already.
* This could be configurable, choosing one or the other depending on
* CONFIG_ESP_SYSTEM_USE_EH_FRAME configuration option.
*
* In both cases, this takes time, and we might be in an ISR, we must
* exit this handler as fast as possible, then we will simply print
* the interruptee's registers.
*/
esp_err_t IRAM_ATTR esp_backtrace_print(int depth)
{
(void)depth;
const int current_core = xPortGetCoreID();
TaskSnapshot_t snapshot = { 0 };
BaseType_t ret = vTaskGetSnapshot(xTaskGetCurrentTaskHandleForCPU(current_core), &snapshot);
if (ret != pdTRUE) {
return ESP_ERR_NOT_FOUND;
}
void *frame = snapshot.pxTopOfStack;
#if CONFIG_ESP_SYSTEM_USE_EH_FRAME
esp_rom_printf("Print CPU %d (current core) backtrace\n", current_core);
esp_eh_frame_print_backtrace(frame);
#else // CONFIG_ESP_SYSTEM_USE_EH_FRAME
esp_rom_printf("Print CPU %d (current core) registers\n", current_core);
panic_print_registers(frame, current_core);
esp_rom_printf("\r\n");
#endif // CONFIG_ESP_SYSTEM_USE_EH_FRAME
return ESP_OK;
}
@@ -13,6 +13,7 @@
#else
#include "soc/extmem_reg.h"
#endif
#include "soc/soc_caps.h"
#include "esp_private/panic_internal.h"
#include "esp_private/panic_reason.h"
#include "riscv/rvruntime-frames.h"
@@ -276,8 +277,6 @@ static void panic_print_register_array(const char* names[], const uint32_t* regs
void panic_print_registers(const void *f, int core)
{
const RvExcFrame *frame = (RvExcFrame *)f;
/**
* General Purpose context, only print ABI name
*/
@@ -290,7 +289,7 @@ void panic_print_registers(const void *f, int core)
};
panic_print_str("Core ");
panic_print_dec(frame->mhartid);
panic_print_dec(core);
panic_print_str(" register dump:");
panic_print_register_array(desc, f, DIM(desc));
}
@@ -319,23 +318,21 @@ void panic_soc_fill_info(void *f, panic_info_t *info)
info->reason = "Cache error";
info->details = print_cache_err_details;
} else if (frame->mcause == ETS_INT_WDT_INUM) {
/* Watchdog interrupt occured, get the core on which it happened
* and update the reason/message accordingly. */
const int core = esp_cache_err_get_cpuid();
} else if (frame->mcause == PANIC_RSN_INTWDT_CPU0) {
const int core = 0;
info->core = core;
info->exception = PANIC_EXCEPTION_IWDT;
#if SOC_CPU_NUM > 1
#error "TODO: define PANIC_RSN_INTWDT_CPU1 in panic_reason.h"
_Static_assert(PANIC_RSN_INTWDT_CPU0 + 1 == PANIC_RSN_INTWDT_CPU1,
"PANIC_RSN_INTWDT_CPU1 must be equal to PANIC_RSN_INTWDT_CPU0 + 1");
info->reason = core == 0 ? "Interrupt wdt timeout on CPU0" : "Interrupt wdt timeout on CPU1";
#else
info->reason = "Interrupt wdt timeout on CPU0";
#endif
}
#if SOC_CPU_CORES_NUM > 1
else if (frame->mcause == PANIC_RSN_INTWDT_CPU1) {
const int core = 1;
info->core = core;
info->exception = PANIC_EXCEPTION_IWDT;
info->reason = "Interrupt wdt timeout on CPU1";
}
#endif
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
else if (frame->mcause == ETS_ASSIST_DEBUG_INUM) {
info->core = esp_cache_err_get_cpuid();