From a7adfb0b15933ce80d2cd9189bfc0a535cee5eae Mon Sep 17 00:00:00 2001 From: Marc Herbert Date: Fri, 25 Jun 2021 05:37:55 +0000 Subject: [PATCH] panic: add comments, especially link to dump corruption bug #1346 Zero functional change. These comments would have saved me at least a day. Signed-off-by: Marc Herbert --- src/arch/xtensa/include/arch/debug/panic.h | 6 ++++ src/debug/panic.c | 35 ++++++++++++++-------- src/include/ipc/trace.h | 1 + src/include/sof/debug/panic.h | 5 +++- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/arch/xtensa/include/arch/debug/panic.h b/src/arch/xtensa/include/arch/debug/panic.h index 558964514809..7e353fa5e85e 100644 --- a/src/arch/xtensa/include/arch/debug/panic.h +++ b/src/arch/xtensa/include/arch/debug/panic.h @@ -42,6 +42,12 @@ static inline void fill_core_dump(struct sof_ipc_dsp_oops_xtensa *oops, if (epc1) oops->epc1 = *epc1; + /* With crosstool-ng gcc on some platforms this corrupts most of + * the other panic information, including the precious line + * number. See https://github.com/thesofproject/sof/issues/1346 + * Commenting this out loses the registers but avoids the + * corruption of the rest. + */ arch_dump_regs_a((void *)&oops->exccause); } diff --git a/src/debug/panic.c b/src/debug/panic.c index 22c6003ac2ee..0b07b1e2bb2a 100644 --- a/src/debug/panic.c +++ b/src/debug/panic.c @@ -31,7 +31,11 @@ void dump_panicinfo(void *addr, struct sof_ipc_panic_info *panic_info) dcache_writeback_region(addr, sizeof(struct sof_ipc_panic_info)); } -/* dump stack as part of panic */ +/** Dumps stack as part of panic. + * + * \return SOF_IPC_PANIC_STACK if offset is off the stack_limit, + * unchanged 'p' panic code input otherwise. + */ static uint32_t dump_stack(uint32_t p, void *addr, size_t offset, size_t limit, uintptr_t *stack_ptr) { @@ -62,34 +66,41 @@ static uint32_t dump_stack(uint32_t p, void *addr, size_t offset, return p; } +/** Copy registers, panic_info and current stack to mailbox exception + * window. Opaque 'data' (e.g.: optional epc1) is passed to + * arch_dump_regs(). + */ void panic_dump(uint32_t p, struct sof_ipc_panic_info *panic_info, uintptr_t *data) { char *ext_offset; - size_t count; + size_t avail; uintptr_t stack_ptr; /* disable all IRQs */ interrupt_global_disable(); + /* ARCH_OOPS_SIZE is platform-dependent */ ext_offset = (char *)mailbox_get_exception_base() + ARCH_OOPS_SIZE; - /* dump panic info, filename ane linenum */ + /* dump panic info, filename and linenum */ dump_panicinfo(ext_offset, panic_info); ext_offset += sizeof(struct sof_ipc_panic_info); - count = MAILBOX_EXCEPTION_SIZE - - (size_t)(ext_offset - (char *)mailbox_get_exception_base()); - #if CONFIG_TRACE trace_flush_dma_to_mbox(); #endif - /* dump stack frames */ - p = dump_stack(p, ext_offset, 0, count, &stack_ptr); + /* Dump stack frames and override panic code 'p' if ext_offset is + * off stack_limit. Find stack_ptr. + */ + avail = MAILBOX_EXCEPTION_SIZE - + (size_t)(ext_offset - (char *)mailbox_get_exception_base()); + p = dump_stack(p, ext_offset, 0, avail, &stack_ptr); - /* dump DSP core registers - * after arch_dump_regs() use only inline funcs if needed + /* Write oops.arch_hdr and oops.plat_hdr headers and dump DSP core + * registers. After arch_dump_regs() use only inline funcs if + * needed. */ arch_dump_regs((void *)mailbox_get_exception_base(), stack_ptr, data); @@ -101,7 +112,7 @@ void panic_dump(uint32_t p, struct sof_ipc_panic_info *panic_info, ; } -void __panic(uint32_t p, char *filename, uint32_t linenum) +void __panic(uint32_t panic_code, char *filename, uint32_t linenum) { struct sof_ipc_panic_info panicinfo = { .linenum = linenum }; int strlen; @@ -139,5 +150,5 @@ void __panic(uint32_t p, char *filename, uint32_t linenum) "a3", "memory"); #endif - panic_dump(p, &panicinfo, NULL); + panic_dump(panic_code, &panicinfo, NULL); } diff --git a/src/include/ipc/trace.h b/src/include/ipc/trace.h index c7f6258f386c..3f79e025edd0 100644 --- a/src/include/ipc/trace.h +++ b/src/include/ipc/trace.h @@ -91,6 +91,7 @@ struct sof_ipc_trace_filter { #define SOF_IPC_PANIC_MAGIC 0x0dead000 #define SOF_IPC_PANIC_MAGIC_MASK 0x0ffff000 #define SOF_IPC_PANIC_CODE_MASK 0x00000fff + #define SOF_IPC_PANIC_MEM (SOF_IPC_PANIC_MAGIC | 0x0) #define SOF_IPC_PANIC_WORK (SOF_IPC_PANIC_MAGIC | 0x1) #define SOF_IPC_PANIC_IPC (SOF_IPC_PANIC_MAGIC | 0x2) diff --git a/src/include/sof/debug/panic.h b/src/include/sof/debug/panic.h index 14cda116448d..e23e5af8372f 100644 --- a/src/include/sof/debug/panic.h +++ b/src/include/sof/debug/panic.h @@ -43,7 +43,10 @@ void panic_dump(uint32_t p, struct sof_ipc_panic_info *panic_info, void __panic(uint32_t p, char *filename, uint32_t linenum) SOF_NORETURN; -/* panic dump filename and linenumber of the call */ +/** panic dump filename and linenumber of the call + * + * \param x panic code defined in ipc/trace.h + */ #define panic(x) __panic((x), (RELATIVE_FILE), (__LINE__)) /* runtime assertion */