mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-31 11:01:19 +00:00
Support saving panic data for nds32 core. Signed-off-by: Dino Li <dino.li@ite.com.tw> BRANCH=none BUG=none TEST=1. console commands 'crash' and 'panicinfo'. 2. ectool command 'panicinfo' crash assert ASSERTION FAILURE '0' in command_crash() at common/panic_output.c:162 === EXCEP: ITYPE=1 === R0 00000000 R1 000000a2 R2 00000060 R3 00000000 R4 00080c40 R5 00000000 R6 dead6663 R7 000000a2 R8 00000002 R9 00000000 R10 00081960 R15 00000000 FP 00000000 GP 000818d8 LP 0000079a SP 00080c60 IPC 000007a2 IPSW 70009 SWID of ITYPE: 0 Software panic reason PANIC_SW_ASSERT Software panic info 0xa2 Rebooting... panicinfo Saved panic data: (NEW) === EXCEP: ITYPE=1 === R0 00000000 R1 000000a2 R2 00000060 R3 00000000 R4 00080c40 R5 00000000 R6 dead6663 R7 000000a2 R8 00000002 R9 00000000 R10 00081960 R15 00000000 FP 00000000 GP 000818d8 LP 0000079a SP 00080c60 IPC 000007a2 IPSW 70009 SWID of ITYPE: 0 Software panic reason PANIC_SW_ASSERT Software panic info 0xa2 > crash divzero === EXCEP: ITYPE=10003 === R0 00000000 R1 00f02705 R2 00000060 R3 00081a09 R4 00000000 R5 00000000 R6 00000001 R7 00080cc0 R8 00000002 R9 00000000 R10 00081961 R15 00000000 FP 00000000 GP 000818d8 LP 00009bce SP 00080c90 IPC 00009bee IPSW 70009 SWID of ITYPE: 1 Exception type: General exception [Arithmetic] Exception is caused by a data memory access Rebooting... panicinfo Saved panic data: (NEW) === EXCEP: ITYPE=10003 === R0 00000000 R1 00f02705 R2 00000060 R3 00081a09 R4 00000000 R5 00000000 R6 00000001 R7 00080cc0 R8 00000002 R9 00000000 R10 00081961 R15 00000000 FP 00000000 GP 000818d8 LP 00009bce SP 00080c90 IPC 00009bee IPSW 70009 SWID of ITYPE: 1 Exception type: General exception [Arithmetic] Exception is caused by a data memory access > crash stack +1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17 Stack overflow in CONSOLE task! === EXCEP: ITYPE=8 === R0 00000002 R1 00000002 R2 00000060 R3 00080458 R4 0000ebdd R5 00000000 R6 dead6661 R7 00000002 R8 00000bc8 R9 00000002 R10 00000000 R15 00000000 FP 00000000 GP 000818d8 LP 0000079a SP 00080448 IPC 00000a92 IPSW 70009 SWID of ITYPE: 0 Software panic reason PANIC_SW_STACK_OVERFLOW Software panic info 0x2 Rebooting... panicinfo Saved panic data: (NEW) === EXCEP: ITYPE=8 === R0 00000002 R1 00000002 R2 00000060 R3 00080458 R4 0000ebdd R5 00000000 R6 dead6661 R7 00000002 R8 00000bc8 R9 00000002 R10 00000000 R15 00000000 FP 00000000 GP 000818d8 LP 0000079a SP 00080448 IPC 00000a92 IPSW 70009 SWID of ITYPE: 0 Software panic reason PANIC_SW_STACK_OVERFLOW Software panic info 0x2 > crash watchdog Pre-watchdog warning! IPC: 00009c6c panicinfo Saved panic data: (NEW) === EXCEP: ITYPE=0 === R0 00000000 R1 00000000 R2 00000000 R3 00000000 R4 00000000 R5 00000000 R6 dead6664 R7 00000000 R8 00000000 R9 00000000 R10 00000000 R15 00000000 FP 00000000 GP 00000000 LP 00000000 SP 00000000 IPC 00009c6c IPSW 00000 SWID of ITYPE: 0 Software panic reason PANIC_SW_WATCHDOG Software panic info 0x0 > Change-Id: I3d491ecd0789335db4633f9bf2ca09cf85503ed9 Reviewed-on: https://chromium-review.googlesource.com/303286 Commit-Ready: Dino Li <dino.li@ite.com.tw> Tested-by: Dino Li <dino.li@ite.com.tw> Reviewed-by: Randall Spangler <rspangler@chromium.org>
213 lines
5.5 KiB
C
213 lines
5.5 KiB
C
/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "common.h"
|
|
#include "console.h"
|
|
#include "cpu.h"
|
|
#include "panic.h"
|
|
#include "printf.h"
|
|
#include "system.h"
|
|
#include "task.h"
|
|
#include "timer.h"
|
|
#include "util.h"
|
|
|
|
/* General purpose register (r6) for saving software panic reason */
|
|
#define SOFT_PANIC_GPR_REASON 6
|
|
/* General purpose register (r7) for saving software panic information */
|
|
#define SOFT_PANIC_GPR_INFO 7
|
|
|
|
/* Panic data goes at the end of RAM. */
|
|
static struct panic_data * const pdata_ptr = PANIC_DATA_PTR;
|
|
|
|
#ifdef CONFIG_DEBUG_EXCEPTIONS
|
|
/**
|
|
* bit[4] @ ITYPE, Indicates if an exception is caused by an instruction fetch
|
|
* or a data memory access for the following exceptions:
|
|
* -TLB fill
|
|
* -TLB VLPT miss
|
|
* -TLB read protection
|
|
* -TLB write protection
|
|
* -TLB non-executable page
|
|
* -TLB page modified
|
|
* -TLB Access bit
|
|
* -PTE not present (all)
|
|
* -Reserved PTE Attribute
|
|
* -Alignment check
|
|
* -Branch target alignment
|
|
* -Machine error
|
|
* -Precise bus error
|
|
* -Imprecise bus error
|
|
* -Nonexistent local memory address
|
|
* -MPZIU Control
|
|
* -Cache locking error
|
|
* -TLB locking error
|
|
* -TLB multiple hit
|
|
* -Parity/ECC error
|
|
* All other exceptions not in the abovetable should have the INST field of
|
|
* the ITYPE register set to 0.
|
|
*/
|
|
static const char * const itype_inst[2] = {
|
|
"a data memory access",
|
|
"an instruction fetch access",
|
|
};
|
|
|
|
/**
|
|
* bit[3-0] @ ITYPE, general exception type information.
|
|
*/
|
|
static const char * const itype_exc_type[16] = {
|
|
"Alignment check",
|
|
"Reserved instruction",
|
|
"Trap",
|
|
"Arithmetic",
|
|
"Precise bus error",
|
|
"Imprecise bus error",
|
|
"Coprocessor",
|
|
"Privileged instruction",
|
|
|
|
"Reserved value",
|
|
"Nonexistent local memory address",
|
|
"MPZIU Control",
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
};
|
|
#endif /* CONFIG_DEBUG_EXCEPTIONS */
|
|
|
|
#ifdef CONFIG_SOFTWARE_PANIC
|
|
/* Software panic reasons */
|
|
static const char * const panic_sw_reasons[8] = {
|
|
"PANIC_SW_DIV_ZERO",
|
|
"PANIC_SW_STACK_OVERFLOW",
|
|
"PANIC_SW_PD_CRASH",
|
|
"PANIC_SW_ASSERT",
|
|
"PANIC_SW_WATCHDOG",
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
};
|
|
|
|
void software_panic(uint32_t reason, uint32_t info)
|
|
{
|
|
asm volatile ("mov55 $r6, %0" : : "r"(reason));
|
|
asm volatile ("mov55 $r7, %0" : : "r"(info));
|
|
if (in_interrupt_context())
|
|
asm("j excep_handler");
|
|
else
|
|
asm("trap 0");
|
|
}
|
|
|
|
void panic_set_reason(uint32_t reason, uint32_t info, uint8_t exception)
|
|
{
|
|
uint32_t *regs = pdata_ptr->nds_n8.regs;
|
|
uint32_t warning_ipc;
|
|
|
|
/* Setup panic data structure */
|
|
if (reason != PANIC_SW_WATCHDOG) {
|
|
memset(pdata_ptr, 0, sizeof(*pdata_ptr));
|
|
} else {
|
|
warning_ipc = pdata_ptr->nds_n8.ipc;
|
|
memset(pdata_ptr, 0, sizeof(*pdata_ptr));
|
|
pdata_ptr->nds_n8.ipc = warning_ipc;
|
|
}
|
|
pdata_ptr->magic = PANIC_DATA_MAGIC;
|
|
pdata_ptr->struct_size = sizeof(*pdata_ptr);
|
|
pdata_ptr->struct_version = 2;
|
|
pdata_ptr->arch = PANIC_ARCH_NDS32_N8;
|
|
|
|
/* Log panic cause */
|
|
pdata_ptr->nds_n8.itype = exception;
|
|
regs[SOFT_PANIC_GPR_REASON] = reason;
|
|
regs[SOFT_PANIC_GPR_INFO] = info;
|
|
}
|
|
|
|
void panic_get_reason(uint32_t *reason, uint32_t *info, uint8_t *exception)
|
|
{
|
|
uint32_t *regs = pdata_ptr->nds_n8.regs;
|
|
|
|
if (pdata_ptr->magic == PANIC_DATA_MAGIC &&
|
|
pdata_ptr->struct_version == 2) {
|
|
*exception = pdata_ptr->nds_n8.itype;
|
|
*reason = regs[SOFT_PANIC_GPR_REASON];
|
|
*info = regs[SOFT_PANIC_GPR_INFO];
|
|
} else {
|
|
*exception = *reason = *info = 0;
|
|
}
|
|
}
|
|
#endif /* CONFIG_SOFTWARE_PANIC */
|
|
|
|
static void print_panic_information(uint32_t *regs, uint32_t itype,
|
|
uint32_t ipc, uint32_t ipsw)
|
|
{
|
|
panic_printf("=== EXCEP: ITYPE=%x ===\n", itype);
|
|
panic_printf("R0 %08x R1 %08x R2 %08x R3 %08x\n",
|
|
regs[0], regs[1], regs[2], regs[3]);
|
|
panic_printf("R4 %08x R5 %08x R6 %08x R7 %08x\n",
|
|
regs[4], regs[5], regs[6], regs[7]);
|
|
panic_printf("R8 %08x R9 %08x R10 %08x R15 %08x\n",
|
|
regs[8], regs[9], regs[10], regs[11]);
|
|
panic_printf("FP %08x GP %08x LP %08x SP %08x\n",
|
|
regs[12], regs[13], regs[14], regs[15]);
|
|
panic_printf("IPC %08x IPSW %05x\n", ipc, ipsw);
|
|
if ((ipsw & PSW_INTL_MASK) == (2 << PSW_INTL_SHIFT)) {
|
|
/* 2nd level exception */
|
|
uint32_t oipc;
|
|
|
|
asm volatile("mfsr %0, $OIPC" : "=r"(oipc));
|
|
panic_printf("OIPC %08x\n", oipc);
|
|
}
|
|
|
|
#ifdef CONFIG_DEBUG_EXCEPTIONS
|
|
panic_printf("SWID of ITYPE: %x\n", ((itype >> 16) & 0x7fff));
|
|
if ((regs[SOFT_PANIC_GPR_REASON] & 0xfffffff0) == PANIC_SW_BASE) {
|
|
#ifdef CONFIG_SOFTWARE_PANIC
|
|
panic_printf("Software panic reason %s\n",
|
|
panic_sw_reasons[(regs[SOFT_PANIC_GPR_REASON] & 0x7)]);
|
|
panic_printf("Software panic info 0x%x\n",
|
|
regs[SOFT_PANIC_GPR_INFO]);
|
|
#endif
|
|
} else {
|
|
panic_printf("Exception type: General exception [%s]\n",
|
|
itype_exc_type[(itype & 0xf)]);
|
|
panic_printf("Exception is caused by %s\n",
|
|
itype_inst[(itype & (1 << 4))]);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void report_panic(uint32_t *regs, uint32_t itype)
|
|
{
|
|
int i;
|
|
struct panic_data *pdata = pdata_ptr;
|
|
|
|
pdata->magic = PANIC_DATA_MAGIC;
|
|
pdata->struct_size = sizeof(*pdata);
|
|
pdata->struct_version = 2;
|
|
pdata->arch = PANIC_ARCH_NDS32_N8;
|
|
pdata->flags = 0;
|
|
pdata->reserved = 0;
|
|
|
|
pdata->nds_n8.itype = itype;
|
|
for (i = 0; i < 16; i++)
|
|
pdata->nds_n8.regs[i] = regs[i];
|
|
pdata->nds_n8.ipc = regs[16];
|
|
pdata->nds_n8.ipsw = regs[17];
|
|
|
|
print_panic_information(regs, itype, regs[16], regs[17]);
|
|
panic_reboot();
|
|
}
|
|
|
|
void panic_data_print(const struct panic_data *pdata)
|
|
{
|
|
uint32_t itype, *regs, ipc, ipsw;
|
|
itype = pdata->nds_n8.itype;
|
|
regs = (uint32_t *)pdata->nds_n8.regs;
|
|
ipc = pdata->nds_n8.ipc;
|
|
ipsw = pdata->nds_n8.ipsw;
|
|
|
|
print_panic_information(regs, itype, ipc, ipsw);
|
|
}
|