mcu_hi3321_watch/middleware/utils/dfx/preserve/private/preserve.c
2025-05-26 20:15:20 +08:00

580 lines
20 KiB
C

/*
* Copyright (c) @CompanyNameMagicTag 2018-2020. All rights reserved.
* Description:PRESERVE INTERFACE for security core
* Author: @CompanyNameTag
* Create:
*/
#include "preserve.h"
#include "securec.h"
#if defined(BUILD_APPLICATION_STANDARD)
#include "log_printf.h"
#include "systick.h"
#include "log_oam_logger.h"
#include "log_def.h"
#endif
#include "debug_print.h"
#include "hal_reboot.h"
#define RIGHT_SHIFT_32BITS 32
#define WORD_MASK_VALUE 0xFFFFFFFF
#define TIME_S_TO_MS 1000
#define RESERVED_PC_INDEX 0
#define RESERVED_LR_INDEX 1
#define RESERVED_SP_INDEX 2
#define BTRACE_ADDR_EXEC 0x5900E000
#define BTRACE_ADDR_EXEC_LEN 0X1FF8
// all security core preserve data here, if want to add new,should add tail for compatible befor version
#pragma pack(4)
typedef struct {
#if (ARCH == RISCV31) || (ARCH == RISCV70)
exc_context_t exc_context;
#else
exception_stack_frame_t exception_stack_frame; // 32
#endif
exception_info_t exception_info; // 52
panic_desc_t last_panic; // 12
uint32_t entry_sleep_time[2]; // The size of the array is 2, which stores the high and low bits of sleep time.
uint32_t rtc_delay_count[2]; // The size of the array is 2, which stores the high and low bits of rtc delay count.
uint32_t excepted_delay_time;
uint32_t exception_time_s;
uint32_t reserved[3]; // The size of the reserved array n is 3, total 12 bytes.
reboot_cause_t cpu_utils_reset_cause; // 4
bool update_reset_cause_on_boot; // 4
unsigned long fault_reason; // 4
unsigned long fault_address; // 4
uint32_t intid; // error int num
uint32_t magic; // exception flag
uint32_t reboot_status;
unsigned int reboot_count; // reboot count since coldboot
unsigned int ep_reboot_count; // exception reboot count continuously
unsigned int enable_sha_check; // total size until here: 172 Byte
} preserve_data_t;
#pragma pack()
typedef struct {
uint32_t pc;
uint32_t lr;
uint32_t sp;
} preserve_cpu_info_t;
#ifdef __ICCARM__
#pragma location=PRESERVED_REGION_ORIGIN
__no_init preserve_data_t g_preserve_data_lib;
#else
PRESERVE preserve_data_t g_preserve_data_lib;
#endif
static preserve_data_t g_preserve_data_lib_ram;
#if !defined(BUILD_APPLICATION_ROM)
static preserve_data_t *g_preserve_data_lib_ptr = (preserve_data_t *)(uintptr_t)(PRESERVED_REGION_ORIGIN);
#endif
static void duplicate_preserve_mem(void)
{
UNUSED(g_preserve_data_lib_ram);
#if CORE == MASTER_BY_ALL
memcpy_s((void *)&g_preserve_data_lib_ram, sizeof(g_preserve_data_lib_ram), (void *)&g_preserve_data_lib,
sizeof(g_preserve_data_lib_ram));
#endif
}
static inline void set_chip_system_boot_magic(uint32_t magic)
{
g_preserve_data_lib.magic = magic;
}
static void system_set_reboot_status_by_crash_cause(void)
{
reboot_cause_t cause = g_preserve_data_lib.cpu_utils_reset_cause;
if ((REBOOT_CAUSE_BT_RESET_UNKNOWN <= cause && cause <= REBOOT_CAUSE_BT_END) ||
(REBOOT_CAUSE_GNSS_GLOBAL <= cause && cause <= REBOOT_CAUSE_GNSS_END) ||
(REBOOT_CAUSE_PROTOCOL_GLOBAL <= cause && cause <= REBOOT_CAUSE_PROTOCOL_END)) {
g_preserve_data_lib.reboot_status = REBOOT_OTHER_CORE_ABNORMAL_TRIGER_STATUS;
} else if (cause == REBOOT_CAUSE_APPLICATION_HARDFAULT) {
g_preserve_data_lib.reboot_status = REBOOT_HARD_FAULT_TRIGER_STATUS;
} else if (cause == REBOOT_CAUSE_APPLICATION_XIP_CTRL) {
g_preserve_data_lib.reboot_status = REBOOT_NMI_XIP_CTRL_TRIGER_STATUS;
} else if (cause == REBOOT_CAUSE_APPLICATION_XIP_CACHE) {
g_preserve_data_lib.reboot_status = REBOOT_NMI_XIP_CACHE_TRIGGER_STATUS;
} else if (cause == REBOOT_CAUSE_APPLICATION_CHIP_WDT) {
g_preserve_data_lib.reboot_status = REBOOT_NMI_WDGTIMEOUT_TRIGGER_STATUS;
} else if (cause == REBOOT_CAUSE_APPLICATION_PANIC) {
g_preserve_data_lib.reboot_status = REBOOT_SOFT_PANIC_TRIGGER_STATUS;
}
}
#if defined(SAVE_EXC_INFO) && (CONFIG_DFX_SUPPORT_FILE_SYSTEM == DFX_YES)
#if !defined(BUILD_RECOVERY_IMAGE)
void save_preserve_file_to_fs(void)
{
const char *preserve_info_ex_path = "/user/exc/preserve.bin";
int32_t ret = exc_info_write(preserve_info_ex_path, 0, (uint8_t *)&g_preserve_data_lib, sizeof(preserve_data_t));
PRINT("save_preserve_file_to_fs ret:%d.\r\n", ret);
}
void save_btram_file_to_fs(void)
{
const char *btram_info_path = "/user/exc/bt_ram_info.bin";
int32_t ret =
exc_info_write(btram_info_path, 0, (uint8_t *)BT_RAM_ORIGIN_APP_MAPPING, BT_RAM_ORIGIN_APP_MAPPING_LENGTH);
PRINT("save_btram_file_to_fs ret:%d.\r\n", ret);
}
void save_btrace_file_to_fs(void)
{
const char *btrace_info_path = "/user/exc/btrace_info.bin";
int32_t ret = exc_info_write(btrace_info_path, 0, (uint8_t *)BTRACE_ADDR_EXEC, BTRACE_ADDR_EXEC_LEN);
PRINT("save_btrace_file_to_fs ret:%d.\r\n", ret);
}
#endif
#endif
#ifdef weak
weak void watchdog_porting_pmu_reboot(void)
{
}
#else
__attribute__((weak)) void watchdog_porting_pmu_reboot(void)
{
}
#endif
void system_boot_status_init(void)
{
bool is_hardwdg_timeout = false;
if (!hal_reboot_get_ulp_aon_no_poweroff_flag()) {
hal_reboot_set_first_power_on_flag();
hal_reboot_set_ulp_aon_no_poweroff_flag();
memset_s((void *)&g_preserve_data_lib, sizeof(g_preserve_data_lib), 0, sizeof(g_preserve_data_lib));
} else {
hal_reboot_clear_first_power_on_flag();
}
if (g_preserve_data_lib.magic == 0) { // Hard power-off restart
g_preserve_data_lib.reboot_status = REBOOT_POWER_ON_TRIGGER_STATUS;
g_preserve_data_lib.cpu_utils_reset_cause = REBOOT_CAUSE_POWER_ON;
watchdog_porting_pmu_reboot();
}
is_hardwdg_timeout = hal_reboot_hard_wdg_timeout((uint16_t)g_preserve_data_lib.cpu_utils_reset_cause);
if (is_hardwdg_timeout) { // hard watchdog tiemout
set_update_reset_cause_on_boot(false);
g_preserve_data_lib.reboot_status = REBOOT_HARD_WDGTIMEOUT_TRIGER_STATUS;
g_preserve_data_lib.cpu_utils_reset_cause = REBOOT_CAUSE_APPLICATION_STD_CHIP_WDT_FRST;
} else { // normal soft restart
if (g_preserve_data_lib.magic == STANDARD_REBOOT_MAGIC) {
g_preserve_data_lib.reboot_status = REBOOT_SOFT_RESET_TRIGER_STATUS;
g_preserve_data_lib.cpu_utils_reset_cause = REBOOT_CAUSE_APPLICATION_SYSRESETREQ;
} else {
system_set_reboot_status_by_crash_cause();
}
}
if (g_preserve_data_lib.reboot_status != REBOOT_POWER_ON_TRIGGER_STATUS) {
g_preserve_data_lib.reboot_count++;
if (g_preserve_data_lib.reboot_status == REBOOT_SOFT_RESET_TRIGER_STATUS) {
g_preserve_data_lib.ep_reboot_count = 0;
g_preserve_data_lib.enable_sha_check = 0;
} else {
g_preserve_data_lib.ep_reboot_count++;
}
} else {
g_preserve_data_lib.reboot_status = REBOOT_POWER_ON_TRIGGER_STATUS;
g_preserve_data_lib.cpu_utils_reset_cause = REBOOT_CAUSE_POWER_ON;
}
g_preserve_data_lib.magic = STANDARD_REBOOT_MAGIC;
}
unsigned int get_system_boot_status(void)
{
return g_preserve_data_lib.reboot_status;
}
uint32_t get_system_magic(void)
{
return g_preserve_data_lib.magic;
}
void set_cpu_utils_system_boot_magic(void)
{
unsigned int magic = STANDARD_REBOOT_MAGIC;
switch (get_cpu_utils_reset_cause()) {
case REBOOT_CAUSE_BT_SYSRESETREQ:
case REBOOT_CAUSE_PROTOCOL_SYSRESETREQ:
case REBOOT_CAUSE_APPLICATION_SYSRESETREQ:
case REBOOT_CAUSE_UNKNOWN:
case REBOOT_CAUSE_POWER_ON:
magic = STANDARD_REBOOT_MAGIC;
break;
default:
/* unidentified normal reboot cause */
magic = ABNORMAL_REBOOT_MAGIC;
break;
}
set_chip_system_boot_magic(magic);
}
void set_cpu_utils_reset_cause(reboot_cause_t reset_cause)
{
g_preserve_data_lib.cpu_utils_reset_cause = reset_cause;
duplicate_preserve_mem();
}
unsigned int get_cpu_utils_reset_count(void)
{
return g_preserve_data_lib.reboot_count;
}
unsigned int get_cpu_utils_epreset_count(void)
{
return g_preserve_data_lib.ep_reboot_count;
}
reboot_cause_t get_cpu_utils_reset_cause(void)
{
return g_preserve_data_lib.cpu_utils_reset_cause;
}
void set_update_reset_cause_on_boot(bool reset_cause_on_boot)
{
g_preserve_data_lib.update_reset_cause_on_boot = reset_cause_on_boot;
}
bool get_update_reset_cause_on_boot(void)
{
return g_preserve_data_lib.update_reset_cause_on_boot;
}
uint32_t get_cpu_utils_check_sha_value(void)
{
return g_preserve_data_lib.enable_sha_check;
}
void set_cpu_utils_check_sha_fault_value(void)
{
g_preserve_data_lib.enable_sha_check = 0;
}
uint8_t get_last_panic_id(void)
{
return g_preserve_data_lib.last_panic.origin;
}
uint32_t get_last_panic_code(void)
{
return g_preserve_data_lib.last_panic.code;
}
uint32_t get_last_panic_caller(void)
{
return g_preserve_data_lib.last_panic.caller;
}
void set_entry_sleep_time(uint64_t time)
{
g_preserve_data_lib.entry_sleep_time[0] = (uint32_t)(time & WORD_MASK_VALUE);
g_preserve_data_lib.entry_sleep_time[1] = (uint32_t)((time >> RIGHT_SHIFT_32BITS) & WORD_MASK_VALUE);
}
void set_rtc_delay_count(uint64_t time)
{
if ((get_system_boot_status() == REBOOT_POWER_ON_TRIGGER_STATUS) ||
(get_system_boot_status() == REBOOT_SOFT_RESET_TRIGER_STATUS)) {
g_preserve_data_lib.rtc_delay_count[0] = (uint32_t)(time & WORD_MASK_VALUE);
g_preserve_data_lib.rtc_delay_count[1] = (uint32_t)((time >> RIGHT_SHIFT_32BITS) & WORD_MASK_VALUE);
}
}
void set_excepted_sleep_time(uint32_t time)
{
g_preserve_data_lib.excepted_delay_time = time;
}
void set_exception_time_stamp(void)
{
#if defined(BUILD_APPLICATION_STANDARD)
g_preserve_data_lib.exception_time_s = (uint32_t)((uapi_systick_get_ms() + get_log_basetime_ms()) / TIME_S_TO_MS);
#endif
}
void set_system_boot_status(unsigned int reboot_status)
{
g_preserve_data_lib.reboot_status = reboot_status;
}
panic_desc_t *get_last_panic_handle(void)
{
return &g_preserve_data_lib.last_panic;
}
void set_last_panic(panic_desc_t last_panic)
{
memcpy_s((void *)&g_preserve_data_lib.last_panic, sizeof(panic_desc_t), (void *)&last_panic, sizeof(panic_desc_t));
duplicate_preserve_mem();
}
#if (ARCH == RISCV31) || (ARCH == RISCV70)
void set_exception_info_riscv(exc_context_t *exc_data)
{
memcpy_s((void *)&g_preserve_data_lib.exc_context, sizeof(exc_context_t),
(void *)exc_data, sizeof(exc_context_t));
duplicate_preserve_mem();
}
task_context_t *get_exception_info_riscv(void)
{
return &g_preserve_data_lib.exc_context.task_context;
}
#else
exception_stack_frame_t *get_exception_stack_frame_handle(void)
{
return &g_preserve_data_lib.exception_stack_frame;
}
exception_info_t *get_exception_info(void)
{
return &g_preserve_data_lib.exception_info;
}
#endif
void set_exception_info(exception_info_t *exception_info)
{
if (exception_info == NULL) {
return;
}
memcpy_s((void *)&g_preserve_data_lib.exception_info, sizeof(exception_info_t),
(void *)exception_info, sizeof(exception_info_t));
duplicate_preserve_mem();
}
void set_exception_stack_frame(exception_stack_frame_t exception_stack_frame_src)
{
#if (ARCH == RISCV31) || (ARCH == RISCV70)
g_preserve_data_lib.exc_context.task_context.ra = (uint32_t)exception_stack_frame_src.stacked_lr;
g_preserve_data_lib.exc_context.task_context.mepc = (uint32_t)exception_stack_frame_src.stacked_pc;
#else
memcpy_s((void *)&g_preserve_data_lib.exception_stack_frame, sizeof(exception_stack_frame_t),
(void *)&exception_stack_frame_src, sizeof(exception_stack_frame_t));
#endif
duplicate_preserve_mem();
}
void set_fault_address(uint32_t address)
{
g_preserve_data_lib.fault_address = address;
duplicate_preserve_mem();
}
uint32_t get_fault_address(void)
{
return (uint32_t)g_preserve_data_lib.fault_address;
}
void set_fault_reason(uint32_t reason)
{
g_preserve_data_lib.fault_reason = reason;
duplicate_preserve_mem();
}
void set_fault_intid(uint32_t intid)
{
g_preserve_data_lib.intid = intid;
duplicate_preserve_mem();
}
uint32_t get_fault_reason(void)
{
return (uint32_t)g_preserve_data_lib.fault_reason;
}
void set_pc_lr_sp_value(uint32_t pc_value, uint32_t lr_value, uint32_t sp_value)
{
g_preserve_data_lib.reserved[RESERVED_PC_INDEX] = pc_value;
g_preserve_data_lib.reserved[RESERVED_LR_INDEX] = lr_value;
g_preserve_data_lib.reserved[RESERVED_SP_INDEX] = sp_value;
}
void get_pc_lr_sp_value(uint32_t *pc_value, uint32_t *lr_value, uint32_t *sp_value)
{
if (pc_value == NULL || lr_value == NULL || sp_value == NULL) {
return;
}
*pc_value = g_preserve_data_lib.reserved[RESERVED_PC_INDEX];
*lr_value = g_preserve_data_lib.reserved[RESERVED_LR_INDEX];
*sp_value = g_preserve_data_lib.reserved[RESERVED_SP_INDEX];
}
#if !defined(BUILD_APPLICATION_ROM)
uint8_t get_last_slave_panic_id(cores_t core)
{
UNUSED(core);
return g_preserve_data_lib_ptr->last_panic.origin;
}
uint32_t get_last_slave_panic_code(cores_t core)
{
UNUSED(core);
return g_preserve_data_lib_ptr->last_panic.code;
}
uint32_t get_last_slave_panic_caller(cores_t core)
{
UNUSED(core);
return g_preserve_data_lib_ptr->last_panic.caller;
}
#endif
#if defined(BUILD_APPLICATION_STANDARD)
static preserve_cpu_info_t get_cpu_info(void)
{
preserve_cpu_info_t temp;
#if (ARCH == RISCV31) || (ARCH == RISCV70)
temp.pc = g_preserve_data_lib.exc_context.task_context.mepc;
temp.lr = g_preserve_data_lib.exc_context.task_context.ra;
temp.sp = g_preserve_data_lib.exc_context.task_context.sp;
#else
temp.pc = g_preserve_data_lib.exception_stack_frame.stacked_pc;
temp.lr = g_preserve_data_lib.exception_stack_frame.stacked_lr;
temp.sp = g_preserve_data_lib.exception_stack_frame.stacked_psr;
#endif
return temp;
}
void system_boot_reason_print(void)
{
switch (get_system_boot_status()) {
case REBOOT_SOFT_RESET_TRIGER_STATUS:
oml_pf_log_print0(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO, "System Boot Normal");
break;
case REBOOT_NMI_WDGTIMEOUT_TRIGGER_STATUS:
oml_pf_log_print0(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO, \
"System Boot Abnoraml, watchdog timeout");
break;
case REBOOT_SOFT_PANIC_TRIGGER_STATUS:
/* reboot from cpu fault & wdt int etc. */
oml_pf_log_print0(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO, "System Boot Panic");
break;
case REBOOT_NMI_XIP_CTRL_TRIGER_STATUS:
case REBOOT_NMI_XIP_CACHE_TRIGGER_STATUS:
oml_pf_log_print0(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO, \
"System Boot Abnoraml, xip crash");
break;
case REBOOT_HARD_FAULT_TRIGER_STATUS:
oml_pf_log_print0(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO, \
"System Boot Abnoraml, hard fault crash");
break;
case REBOOT_POWER_ON_TRIGGER_STATUS:
/* first power on, vsys power reset or power_on reset */
oml_pf_log_print0(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO, "System Power On");
break;
case REBOOT_OTHER_CORE_ABNORMAL_TRIGER_STATUS:
oml_pf_log_print0(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO,
"System Boot Abnoraml, other core crash");
break;
default:
oml_pf_log_print1(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO, \
"Unkown Sytem Boot Type:0x%x", get_system_boot_status());
break;
}
}
void system_boot_reason_process(void)
{
unsigned int reset_cause = (unsigned int)get_cpu_utils_reset_cause();
unsigned int reset_count = get_cpu_utils_reset_count();
unsigned int ep_reboot_count = get_cpu_utils_epreset_count();
oml_pf_log_print3(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO,\
"System Reboot cause:0x%x , total reboot count:%u, exception reboot count:%u",\
reset_cause, reset_count, ep_reboot_count);
switch (reset_cause) {
case REBOOT_CAUSE_BT_PANIC:
oml_pf_log_print3(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO,"panic id:0x%x, \
panic code: 0x%x, panic caller: 0x%x" , get_last_slave_panic_id(CORES_BT_CORE), \
get_last_slave_panic_code(CORES_BT_CORE), get_last_slave_panic_caller(CORES_BT_CORE));
break;
case REBOOT_CAUSE_APPLICATION_PANIC:
oml_pf_log_print3(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO,"panic id:0x%x, \
panic code: 0x%x, panic caller: 0x%x" , get_last_panic_id(), \
get_last_panic_code(), get_last_panic_caller());
break;
case REBOOT_CAUSE_APPLICATION_STD_CHIP_WDT_FRST:
panic(PANIC_CHIP_WDT_FRST, 0);
break;
case REBOOT_CAUSE_BT_WATCHDOG:
case REBOOT_CAUSE_BT_HARDFAULT:
case REBOOT_CAUSE_BT_NNMIFAULT:
oml_pf_log_print2(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO, \
"bt exception reboot with pc:0x%x, lr: 0x%x" , \
get_cpu_info().pc, get_cpu_info().lr);
break;
case REBOOT_CAUSE_APPLICATION_HARDFAULT:
case REBOOT_CAUSE_APPLICATION_NNMIFAULT:
case REBOOT_CAUSE_APPLICATION_CHIP_WDT:
case REBOOT_CAUSE_APPLICATION_XIP_CTRL:
case REBOOT_CAUSE_APPLICATION_XIP_CACHE:
case REBOOT_CAUSE_APPLICATION_MDMA:
case REBOOT_CAUSE_APPLICATION_SMDMA:
oml_pf_log_print2(LOG_BCORE_PLT_DRIVER_REBOOT, LOG_NUM_DRIVER_REBOOT, LOG_LEVEL_INFO, \
"app exception reboot pc:0x%x, lr: 0x%x" , \
get_cpu_info().pc, get_cpu_info().lr);
break;
default:
break;
}
}
#endif
static void print_system_boot_status(void)
{
unsigned int reset_cause = (unsigned int)get_cpu_utils_reset_cause();
switch (get_system_boot_status()) {
case REBOOT_SOFT_RESET_TRIGER_STATUS:
PRINT("System Boot Noraml" NEWLINE);
break;
case REBOOT_NMI_WDGTIMEOUT_TRIGGER_STATUS:
PRINT("System Boot watchdog timeout" NEWLINE);
break;
case REBOOT_NMI_XIP_CTRL_TRIGER_STATUS:
case REBOOT_NMI_XIP_CACHE_TRIGGER_STATUS:
PRINT("System Boot Abnoraml, XIP crash" NEWLINE);
break;
case REBOOT_HARD_FAULT_TRIGER_STATUS:
PRINT("System Boot Abnoraml, hard fault crash" NEWLINE);
break;
case REBOOT_POWER_ON_TRIGGER_STATUS:
/* normal system reboot, except reboot */
PRINT("System Power On" NEWLINE);
break;
case REBOOT_SOFT_PANIC_TRIGGER_STATUS:
PRINT("System Boot Abnoraml, panic crash" NEWLINE);
break;
case REBOOT_OTHER_CORE_ABNORMAL_TRIGER_STATUS:
PRINT("System Boot Abnoraml, other core crash" NEWLINE);
break;
case REBOOT_HARD_WDGTIMEOUT_TRIGER_STATUS:
PRINT("System Boot Abnoraml, chip watchdog timeout" NEWLINE);
break;
default:
PRINT("Unkown Sytem Boot Type 0x%x" NEWLINE, get_system_boot_status());
break;
}
PRINT("System Reboot cause:0x%x, total reboot count:%u, exception reboot count:%u\r\n",\
reset_cause, get_cpu_utils_reset_count(), get_cpu_utils_epreset_count());
if (reset_cause == REBOOT_CAUSE_BT_PANIC) {
PRINT("panic id:0x%x, panic code: 0x%x, panic caller: 0x%x\r\n", get_last_slave_panic_id(CORES_BT_CORE), \
get_last_slave_panic_code(CORES_BT_CORE), get_last_slave_panic_caller(CORES_BT_CORE));
} else if (reset_cause == REBOOT_CAUSE_APPLICATION_PANIC) {
PRINT("panic id:0x%x, panic code: 0x%x, panic caller: 0x%x\r\n", get_last_panic_id(), \
get_last_panic_code(), get_last_panic_caller());
}
}
void show_reboot_info(void)
{
system_boot_status_init();
print_system_boot_status();
}