[Sound-open-firmware] [PATCH] apl: clk: clock data to be allocated in system heap.
Fix clock data to be allocated in the system heap like other system init data.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/platform/apollolake/clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/platform/apollolake/clk.c b/src/platform/apollolake/clk.c index a10805b..72d2e9f 100644 --- a/src/platform/apollolake/clk.c +++ b/src/platform/apollolake/clk.c @@ -197,7 +197,7 @@ uint64_t clock_time_elapsed(int clock, uint64_t previous, uint64_t *current)
void init_platform_clocks(void) { - clk_pdata = rmalloc(RZONE_RUNTIME, RFLAGS_NONE, sizeof(*clk_pdata)); + clk_pdata = rmalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*clk_pdata));
spinlock_init(&clk_pdata->clk[0].lock); spinlock_init(&clk_pdata->clk[1].lock);
Already declared in the platform timer queue data so reuse.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/platform/apollolake/platform.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/src/platform/apollolake/platform.c b/src/platform/apollolake/platform.c index 555f14f..3c1d76f 100644 --- a/src/platform/apollolake/platform.c +++ b/src/platform/apollolake/platform.c @@ -169,11 +169,6 @@ static void platform_memory_windows_init(void) | DMWBA_READONLY | DMWBA_ENABLE); }
-static struct timer platform_ext_timer = { - .id = TIMER3, - .irq = IRQ_EXT_TSTAMP0_LVL2(0), -}; - int platform_init(struct reef *reef) { struct dma *dmac; @@ -188,7 +183,7 @@ int platform_init(struct reef *reef)
/* init work queues and clocks */ trace_point(TRACE_BOOT_PLATFORM_TIMER); - platform_timer_start(&platform_ext_timer); + platform_timer_start(&platform_generic_queue.timer);
trace_point(TRACE_BOOT_PLATFORM_CLOCK); init_platform_clocks();
Add a sanity check to make sure that data/rodata contains expected values otherwise this can cause unpredictable behaviour that is difficult to later diagnose.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/lib/alloc.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/src/lib/alloc.c b/src/lib/alloc.c index 847cb93..1ae0c91 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -646,6 +646,10 @@ void init_heap(struct reef *reef) struct block_map *current_map; int i;
+ /* sanity check for malformed images or loader issues */ + if (memmap.system.heap != HEAP_SYSTEM_BASE) + panic(PANIC_MEM); + spinlock_init(&memmap.lock);
/* initialise buffer map */
Make sure we dont over write any ROM status and move "register" macros into memory.h.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/platform/apollolake/include/platform/memory.h | 6 ++++++ src/platform/apollolake/include/platform/platform.h | 14 ++------------ src/platform/cannonlake/include/platform/memory.h | 6 ++++++ src/platform/cannonlake/include/platform/platform.h | 16 +++------------- 4 files changed, 17 insertions(+), 25 deletions(-)
diff --git a/src/platform/apollolake/include/platform/memory.h b/src/platform/apollolake/include/platform/memory.h index eca9a53..157be82 100644 --- a/src/platform/apollolake/include/platform/memory.h +++ b/src/platform/apollolake/include/platform/memory.h @@ -244,6 +244,12 @@ #define SRAM_SW_REG_BASE (SRAM_INBOX_BASE + SRAM_INBOX_SIZE) #define SRAM_SW_REG_SIZE 0x1000
+/* SRAM window 0 FW "registers" */ +#define SRAM_REG_ROM_STATUS 0x0 +#define SRAM_REG_FW_STATUS 0x4 +#define SRAM_REG_FW_TRACEP 0x8 +#define SRAM_REG_FW_END 0xc + #define SRAM_OUTBOX_BASE (SRAM_SW_REG_BASE + SRAM_SW_REG_SIZE) #define SRAM_OUTBOX_SIZE 0x1000
diff --git a/src/platform/apollolake/include/platform/platform.h b/src/platform/apollolake/include/platform/platform.h index 4165b95..8e18d53 100644 --- a/src/platform/apollolake/include/platform/platform.h +++ b/src/platform/apollolake/include/platform/platform.h @@ -85,10 +85,6 @@ struct reef; /* Host finish work(drain from host to dai) timeout in microseconds */ #define PLATFORM_HOST_FINISH_TIMEOUT 50000
-// TODO: move to SW reg header -#define SW_REG_STATUS 0x0 -#define SW_REG_ERRCODE 0x04 - /* local buffer size of DMA tracing */ #define DMA_TRACE_LOCAL_SIZE HOST_PAGE_SIZE
@@ -109,17 +105,11 @@ struct reef;
/* Platform defined panic code */ #define platform_panic(__x) \ - sw_reg_write(SW_REG_STATUS, (0xdead000 | __x) & 0x3fffffff) + sw_reg_write(SRAM_REG_FW_STATUS, (0xdead000 | __x) & 0x3fffffff)
/* Platform defined trace code */ -#if USE_SW_REG_STATUS -#define platform_trace_point(__x) \ - sw_reg_write(SW_REG_STATUS, (0xace0000 | __x) & 0x3fffffff));\ - sw_reg_write(SW_REG_ERRCODE, __x) -#else //using SW_REG_STATUS may influence the ROM status, don't do that atm. #define platform_trace_point(__x) \ - sw_reg_write(SW_REG_ERRCODE, __x) -#endif + sw_reg_write(SRAM_REG_FW_TRACEP, __x)
struct timer *platform_timer;
diff --git a/src/platform/cannonlake/include/platform/memory.h b/src/platform/cannonlake/include/platform/memory.h index 06b27f3..7e7af82 100644 --- a/src/platform/cannonlake/include/platform/memory.h +++ b/src/platform/cannonlake/include/platform/memory.h @@ -189,6 +189,12 @@ #define SRAM_SW_REG_BASE (HP_SRAM_BASE + 0x4000) #define SRAM_SW_REG_SIZE 0x1000
+/* SRAM window 0 FW "registers" */ +#define SRAM_REG_ROM_STATUS 0x0 +#define SRAM_REG_FW_STATUS 0x4 +#define SRAM_REG_FW_TRACEP 0x8 +#define SRAM_REG_FW_END 0xc + #define SRAM_OUTBOX_BASE (SRAM_SW_REG_BASE + SRAM_SW_REG_SIZE) #define SRAM_OUTBOX_SIZE 0x1000
diff --git a/src/platform/cannonlake/include/platform/platform.h b/src/platform/cannonlake/include/platform/platform.h index f29af95..06a5599 100644 --- a/src/platform/cannonlake/include/platform/platform.h +++ b/src/platform/cannonlake/include/platform/platform.h @@ -89,10 +89,6 @@ struct reef; /* Host finish work(drain from host to dai) timeout in microseconds */ #define PLATFORM_HOST_FINISH_TIMEOUT 50000
-// TODO: move to SW reg header -#define SW_REG_STATUS 0x0 -#define SW_REG_ERRCODE 0x04 - /* local buffer size of DMA tracing */ #define DMA_TRACE_LOCAL_SIZE HOST_PAGE_SIZE
@@ -111,19 +107,13 @@ struct reef; /* DSP should be idle in this time frame */ #define PLATFORM_IDLE_TIME 750000
-/* Platform defined panic code */ +/* Platform defined trace code */ #define platform_panic(__x) \ - sw_reg_write(SW_REG_STATUS, (0xdead000 | __x) & 0x3fffffff) + sw_reg_write(SRAM_REG_FW_STATUS, (0xdead000 | __x) & 0x3fffffff)
/* Platform defined trace code */ -#if USE_SW_REG_STATUS #define platform_trace_point(__x) \ - sw_reg_write(SW_REG_STATUS, (0xace0000 | __x) & 0x3fffffff));\ - sw_reg_write(SW_REG_ERRCODE, __x) -#else //using SW_REG_STATUS may influence the ROM status, don't do that atm. -#define platform_trace_point(__x) \ - sw_reg_write(SW_REG_ERRCODE, __x) -#endif + sw_reg_write(SRAM_REG_FW_TRACEP, __x)
struct timer *platform_timer;
Make sure we validate all module sections against each other.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- rimage/elf.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/rimage/elf.c b/rimage/elf.c index 672d6e3..3f00f1d 100644 --- a/rimage/elf.c +++ b/rimage/elf.c @@ -314,9 +314,6 @@ int elf_validate_section(struct image *image, struct module *module, for (i = 0; i < image->num_modules; i++) { m = &image->module[i];
- if (m == module) - continue; - /* for each section */ for (j = 0; j < m->hdr.e_shnum; j++) { s = &m->section[j];
Improve the output from panic to include DSP registers and stack dump. Export panic codes to UAPI for host driver logging.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/arch/host/include/arch/reef.h | 32 ++++++++++++ src/arch/xtensa/boot_loader.c | 2 +- src/arch/xtensa/include/arch/reef.h | 63 ++++++++++++++++++++++- src/arch/xtensa/init.c | 89 ++------------------------------- src/include/reef/Makefile.am | 1 + src/include/reef/debug.h | 70 ++++++++++---------------- src/include/reef/lock.h | 2 +- src/include/reef/panic.h | 69 +++++++++++++++++++++++++ src/include/uapi/ipc.h | 46 +++++++++++++++++ src/init/init.c | 7 +-- src/lib/agent.c | 3 +- src/lib/alloc.c | 5 +- src/library/include/platform/platform.h | 1 + src/tasks/audio.c | 2 +- 14 files changed, 253 insertions(+), 139 deletions(-) create mode 100644 src/include/reef/panic.h
diff --git a/src/arch/host/include/arch/reef.h b/src/arch/host/include/arch/reef.h index 29090a2..c6e5629 100644 --- a/src/arch/host/include/arch/reef.h +++ b/src/arch/host/include/arch/reef.h @@ -33,9 +33,41 @@ #define __INCLUDE_ARCH_REEF__
#include <stdint.h> +#include <stdlib.h> #include <stddef.h> +#include <string.h> +#include <stdio.h> +#include <execinfo.h> + +/* architecture specific stack frames to dump */ +#define ARCH_STACK_DUMP_FRAMES 32
#define arch_memcpy(dest, src, size) \ memcpy(dest, src, size)
+static inline void *arch_get_stack_ptr(void) +{ + void *frames[ARCH_STACK_DUMP_FRAMES]; + size_t frame_count; + size_t i; + char **symbols; + + frame_count = backtrace(frames, ARCH_STACK_DUMP_FRAMES); + symbols = backtrace_symbols(frames, frame_count); + + fprintf(stderr, "Dumping %zd stack frames.\n", frame_count); + + for (i = 0; i < frame_count; i++) + fprintf(stderr, "\t%s\n", symbols[i]); + + free(symbols); + + return NULL; +} + +static inline void *arch_dump_regs(void) +{ + return NULL; +} + #endif diff --git a/src/arch/xtensa/boot_loader.c b/src/arch/xtensa/boot_loader.c index 5c5939c..862db45 100644 --- a/src/arch/xtensa/boot_loader.c +++ b/src/arch/xtensa/boot_loader.c @@ -190,7 +190,7 @@ void boot_pri_core(void) platform_trace_point(TRACE_BOOT_LDR_HPSRAM); result = hp_sram_init(); if (result < 0) { - platform_panic(PANIC_MEM); + platform_panic(SOF_IPC_PANIC_MEM); return; }
diff --git a/src/arch/xtensa/include/arch/reef.h b/src/arch/xtensa/include/arch/reef.h index 149de5d..592221e 100644 --- a/src/arch/xtensa/include/arch/reef.h +++ b/src/arch/xtensa/include/arch/reef.h @@ -34,15 +34,20 @@
#include <stdint.h> #include <stddef.h> +#include <reef/mailbox.h> +#include <uapi/ipc.h> + +/* architecture specific stack frames to dump */ +#define ARCH_STACK_DUMP_FRAMES 32
void *xthal_memcpy(void *dst, const void *src, size_t len);
#define arch_memcpy(dest, src, size) \ xthal_memcpy(dest, src, size)
-static inline size_t arch_get_stack_ptr(void) +static inline void *arch_get_stack_ptr(void) { - size_t ptr; + void *ptr;
/* stack pointer is in a1 */ __asm__ __volatile__ ("mov %0, a1" @@ -52,4 +57,58 @@ static inline size_t arch_get_stack_ptr(void) return ptr; }
+static inline void *arch_dump_regs(void) +{ + struct sof_ipc_dsp_oops_xtensa *x = + (struct sof_ipc_dsp_oops_xtensa *) mailbox_get_exception_base(); + + /* Exception Vector number - 0x0 */ + __asm__ __volatile__ ("rsr %0, EXCCAUSE" : "=a" (x->exccause) : : "memory"); + /* Exception Vector address - 0x4 */ + __asm__ __volatile__ ("rsr %0, EXCVADDR" : "=a" (x->excvaddr) : : "memory"); + /* Exception Processor State - 0x8 */ + __asm__ __volatile__ ("rsr %0, PS" : "=a" (x->ps) : : "memory"); + /* Level 1 Exception PC - 0xc */ + __asm__ __volatile__ ("rsr %0, EPC1" : "=a" (x->epc1) : : "memory"); + /* Level 2 Exception PC - 0x10 */ + __asm__ __volatile__ ("rsr %0, EPC2" : "=a" (x->epc2) : : "memory"); + /* Level 3 Exception PC - 0x14 */ + __asm__ __volatile__ ("rsr %0, EPC3" : "=a" (x->epc3) : : "memory"); + /* Level 4 Exception PC - 0x18 */ + __asm__ __volatile__ ("rsr %0, EPC4" : "=a" (x->epc4) : : "memory"); + /* Level 5 Exception PC - 0x1c */ + __asm__ __volatile__ ("rsr %0, EPC5" : "=a" (x->epc5) : : "memory"); + /* Level 6 Exception PC - 0x20 */ + __asm__ __volatile__ ("rsr %0, EPC6" : "=a" (x->epc6) : : "memory"); + /* Level 7 Exception PC - 0x24 */ + __asm__ __volatile__ ("rsr %0, EPC7" : "=a" (x->epc7) : : "memory"); + /* Level 2 Exception PS - 0x28 */ + __asm__ __volatile__ ("rsr %0, EPS2" : "=a" (x->eps2) : : "memory"); + /* Level 3 Exception PS - 0x2c */ + __asm__ __volatile__ ("rsr %0, EPS3" : "=a" (x->eps3) : : "memory"); + /* Level 4 Exception PS - 0x30 */ + __asm__ __volatile__ ("rsr %0, EPS4" : "=a" (x->eps4) : : "memory"); + /* Level 5 Exception PS - 0x34 */ + __asm__ __volatile__ ("rsr %0, EPS5" : "=a" (x->eps5) : : "memory"); + /* Level 6 Exception PS - 0x38 */ + __asm__ __volatile__ ("rsr %0, EPS6" : "=a" (x->eps6) : : "memory"); + /* Level 7 Exception PS - 0x3c */ + __asm__ __volatile__ ("rsr %0, EPS7" : "=a" (x->eps7) : : "memory"); + /* Double Exception program counter - 0x40 */ + __asm__ __volatile__ ("rsr %0, DEPC" : "=a" (x->depc) : : "memory"); + /* Interrupts Enabled - 0x44 */ + __asm__ __volatile__ ("rsr %0, INTENABLE" : "=a" (x->intenable) : : "memory"); + /* Interrupts Status - 0x48 */ + __asm__ __volatile__ ("rsr %0, INTERRUPT" : "=a" (x->interrupt) : : "memory"); + /* Shift register - 0x4c */ + __asm__ __volatile__ ("rsr %0, SAR" : "=a" (x->sar) : : "memory"); + /* Register A1 (stack) - 0x50 */ + __asm__ __volatile__ ("mov %0, a1" : "=a" (x->stack) : : "memory"); + + dcache_writeback_region((void *)x, sizeof(*x)); + + /* tell caller extended data can be placed hereafter */ + return (void *)(x + 1); +} + #endif diff --git a/src/arch/xtensa/init.c b/src/arch/xtensa/init.c index 44f7faf..0433854 100644 --- a/src/arch/xtensa/init.c +++ b/src/arch/xtensa/init.c @@ -35,7 +35,7 @@ #include <platform/interrupt.h> #include <reef/mailbox.h> #include <arch/task.h> -#include <reef/debug.h> +#include <reef/panic.h> #include <reef/init.h> #include <reef/lock.h> #include <stdint.h> @@ -45,92 +45,11 @@ uint32_t lock_dbg_atomic = 0; uint32_t lock_dbg_user[DBG_LOCK_USERS] = {0}; #endif
-/* TODO: this should be fixed by rotating the register Window on the stack and - * dumping the saved registers. - * TODO: we should also have different handlers for each type where we can take - * advantage of dumping further information. i.e. call stack and avoid - * clobbering some registers dumped below are clobbered */ - static void exception(void) { - volatile uint32_t *dump = (uint32_t*) mailbox_get_exception_base(); - - /* Exception Vector number - 0x0 */ - __asm__ __volatile__ ("rsr %0, EXCCAUSE" : "=a" (dump[0]) : : "memory"); - /* Exception Vector address - 0x4 */ - __asm__ __volatile__ ("rsr %0, EXCVADDR" : "=a" (dump[1]) : : "memory"); - /* Exception Processor State - 0x8 */ - __asm__ __volatile__ ("rsr %0, PS" : "=a" (dump[2]) : : "memory"); - /* Level 1 Exception PC - 0xc */ - __asm__ __volatile__ ("rsr %0, EPC1" : "=a" (dump[3]) : : "memory"); - /* Level 2 Exception PC - 0x10 */ - __asm__ __volatile__ ("rsr %0, EPC2" : "=a" (dump[4]) : : "memory"); - /* Level 3 Exception PC - 0x14 */ - __asm__ __volatile__ ("rsr %0, EPC3" : "=a" (dump[5]) : : "memory"); - /* Level 4 Exception PC - 0x18 */ - __asm__ __volatile__ ("rsr %0, EPC4" : "=a" (dump[6]) : : "memory"); - /* Level 5 Exception PC - 0x1c */ - __asm__ __volatile__ ("rsr %0, EPC5" : "=a" (dump[7]) : : "memory"); - /* Level 6 Exception PC - 0x20 */ - __asm__ __volatile__ ("rsr %0, EPC6" : "=a" (dump[8]) : : "memory"); - /* Level 7 Exception PC - 0x24 */ - __asm__ __volatile__ ("rsr %0, EPC7" : "=a" (dump[9]) : : "memory"); - /* Level 2 Exception PS - 0x28 */ - __asm__ __volatile__ ("rsr %0, EPS2" : "=a" (dump[10]) : : "memory"); - /* Level 3 Exception PS - 0x2c */ - __asm__ __volatile__ ("rsr %0, EPS3" : "=a" (dump[11]) : : "memory"); - /* Level 4 Exception PS - 0x30 */ - __asm__ __volatile__ ("rsr %0, EPS4" : "=a" (dump[12]) : : "memory"); - /* Level 5 Exception PS - 0x34 */ - __asm__ __volatile__ ("rsr %0, EPS5" : "=a" (dump[13]) : : "memory"); - /* Level 6 Exception PS - 0x38 */ - __asm__ __volatile__ ("rsr %0, EPS6" : "=a" (dump[14]) : : "memory"); - /* Level 7 Exception PS - 0x3c */ - __asm__ __volatile__ ("rsr %0, EPS7" : "=a" (dump[15]) : : "memory"); - /* Double Exception program counter - 0x40 */ - __asm__ __volatile__ ("rsr %0, DEPC" : "=a" (dump[16]) : : "memory"); - /* Register A0 - 0x44 */ - __asm__ __volatile__ ("mov %0, a0" : "=a" (dump[17]) : : "memory"); - /* Register A1 - 0x48 */ - __asm__ __volatile__ ("mov %0, a1" : "=a" (dump[18]) : : "memory"); - /* Register A2 - 0x4c */ - __asm__ __volatile__ ("mov %0, a2" : "=a" (dump[19]) : : "memory"); - /* Register A3 - 0x50 */ - __asm__ __volatile__ ("mov %0, a3" : "=a" (dump[20]) : : "memory"); - /* Register A4 - 0x54 */ - __asm__ __volatile__ ("mov %0, a4" : "=a" (dump[21]) : : "memory"); - /* Register A5 - 0x58 */ - __asm__ __volatile__ ("mov %0, a5" : "=a" (dump[22]) : : "memory"); - /* Register A6 - 0x5c */ - __asm__ __volatile__ ("mov %0, a6" : "=a" (dump[23]) : : "memory"); - /* Register A7 - 0x60 */ - __asm__ __volatile__ ("mov %0, a7" : "=a" (dump[24]) : : "memory"); - /* Register A8 - 0x64 */ - __asm__ __volatile__ ("mov %0, a8" : "=a" (dump[25]) : : "memory"); - /* Register A9 - 0x68 */ - __asm__ __volatile__ ("mov %0, a9" : "=a" (dump[26]) : : "memory"); - /* Register A10 - 0x6c */ - __asm__ __volatile__ ("mov %0, a10" : "=a" (dump[27]) : : "memory"); - /* Register A11 - 0x70 */ - __asm__ __volatile__ ("mov %0, a11" : "=a" (dump[28]) : : "memory"); - /* Register A12 - 0x74 */ - __asm__ __volatile__ ("mov %0, a12" : "=a" (dump[29]) : : "memory"); - /* Register A13 - 0x78 */ - __asm__ __volatile__ ("mov %0, a13" : "=a" (dump[30]) : : "memory"); - /* Register A14 - 0x7c */ - __asm__ __volatile__ ("mov %0, a14" : "=a" (dump[31]) : : "memory"); - /* Register A15 - 0x80 */ - __asm__ __volatile__ ("mov %0, a15" : "=a" (dump[32]) : : "memory"); - /* Interrupts Enabled - 0x84 */ - __asm__ __volatile__ ("rsr %0, INTENABLE" : "=a" (dump[33]) : : "memory"); - /* Interrupts Status - 0x88 */ - __asm__ __volatile__ ("rsr %0, INTERRUPT" : "=a" (dump[34]) : : "memory"); - /* Shift register - 0x8c */ - __asm__ __volatile__ ("rsr %0, SAR" : "=a" (dump[35]) : : "memory"); - - /* atm we loop forever */ - /* TODO: we should probably stall/HALT at this point or recover */ - panic(PANIC_EXCEPTION); + /* now panic and rewind 8 stack frames. */ + /* TODO: we could invoke a GDB stub here */ + panic_rewind(SOF_IPC_PANIC_EXCEPTION, 8 * sizeof(uint32_t)); }
static void register_exceptions(void) diff --git a/src/include/reef/Makefile.am b/src/include/reef/Makefile.am index f4d46f2..8b47664 100644 --- a/src/include/reef/Makefile.am +++ b/src/include/reef/Makefile.am @@ -23,6 +23,7 @@ include_HEADERS = \ lock.h \ mailbox.h \ notifier.h \ + panic.h \ reef.h \ schedule.h \ ssp.h \ diff --git a/src/include/reef/debug.h b/src/include/reef/debug.h index 2c5c573..9ffc6a8 100644 --- a/src/include/reef/debug.h +++ b/src/include/reef/debug.h @@ -32,22 +32,13 @@ #ifndef __INCLUDE_DEBUG__ #define __INCLUDE_DEBUG__
+#include <reef/reef.h> #include <reef/mailbox.h> +#include <uapi/ipc.h> #include <platform/platform.h> #include <stdint.h> #include <stdlib.h>
-/* panic reasons */ -#define PANIC_MEM 0 -#define PANIC_WORK 1 -#define PANIC_IPC 2 -#define PANIC_ARCH 3 -#define PANIC_PLATFORM 4 -#define PANIC_TASK 5 -#define PANIC_EXCEPTION 6 -#define PANIC_DEADLOCK 7 -#define PANIC_STACK 8 -#define PANIC_IDLE 9
#define DEBUG
@@ -136,38 +127,31 @@ #define dump_object_ptr(__o) #endif
-/* panic and stop executing any more code */ -#define panic(_p) \ - do { \ - interrupt_global_disable(); \ - dbg_val(0xdead0000 | _p) \ - platform_panic(_p); \ - while(1) {}; \ - } while (0); - /* dump stack as part of panic */ -#define panic_dump_stack(_p) \ - do { \ - extern uint32_t __stack; \ - extern uint32_t _stack_sentry; \ - uint32_t _stack_bottom = (uint32_t)&__stack; \ - uint32_t _stack_limit = (uint32_t)&_stack_sentry; \ - uint32_t _stack_top = arch_get_stack_ptr(); \ - uint32_t _size = _stack_bottom - _stack_top; \ - uint32_t _panic = _p; \ - dbg_val(0xdead0000 | _p) \ - dbg_val_at(_stack_top, 1) \ - dbg_val_at(_stack_bottom, 2) \ - /* is stack smashed ? */\ - if (_stack_bottom <= _stack_limit) { \ - dbg_val_at(0x51ac0000 | _p, 3); \ - _stack_bottom = _stack_limit; \ - _panic = PANIC_STACK; \ - } \ - platform_panic(_panic); \ - dump_at(_stack_top, (_size - sizeof(uint32_t)) >> 2, 4) \ - \ - while(1) {}; \ - } while (0); +static inline void dump_stack(uint32_t p, void *addr, size_t offset, + size_t limit) +{ + extern void *__stack; + extern void *_stack_sentry; + void *stack_bottom = (void *)&__stack; + void *stack_limit = (void *)&_stack_sentry; + void *stack_top = arch_get_stack_ptr() + offset; + size_t size = stack_bottom - stack_top; + + /* is stack smashed ? */ + if (stack_top - offset <= stack_limit) { + stack_bottom = stack_limit; + p = SOF_IPC_PANIC_STACK; + platform_panic(p); + } + + /* make sure stack size won't overflow dump area */ + if (size > limit) + size = limit; + + /* copy stack contents and writeback */ + rmemcpy(addr, stack_top, size - sizeof(void *)); + dcache_writeback_region(addr, size - sizeof(void *)); +}
#endif diff --git a/src/include/reef/lock.h b/src/include/reef/lock.h index fd415ae..d5518c9 100644 --- a/src/include/reef/lock.h +++ b/src/include/reef/lock.h @@ -116,7 +116,7 @@ extern uint32_t lock_dbg_user[DBG_LOCK_USERS]; trace_lock_error("DED"); \ trace_lock_value(__LINE__); \ trace_lock_value((lock)->user); \ - panic(PANIC_DEADLOCK); /* lock not acquired */ \ + panic(SOF_IPC_PANIC_DEADLOCK); /* lock not acquired */ \ } \ } while (0);
diff --git a/src/include/reef/panic.h b/src/include/reef/panic.h new file mode 100644 index 0000000..6466cc8 --- /dev/null +++ b/src/include/reef/panic.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Intel Corporation nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Author: Liam Girdwood liam.r.girdwood@linux.intel.com + */ + +#ifndef __INCLUDE_SOF_IPC_PANIC__ +#define __INCLUDE_SOF_IPC_PANIC__ + +#include <reef/reef.h> +#include <reef/mailbox.h> +#include <reef/interrupt.h> +#include <platform/platform.h> +#include <uapi/ipc.h> +#include <stdint.h> +#include <stdlib.h> + +/* panic and rewind stack */ +static inline void panic_rewind(uint32_t p, uint32_t stack_rewind_frames) +{ + void *ext_offset; + + /* disable all IRQs */ + interrupt_global_disable(); + + /* dump DSP core registers */ + ext_offset = arch_dump_regs(); + + /* dump stack frames */ + dump_stack(SOF_IPC_PANIC_EXCEPTION, ext_offset, stack_rewind_frames, + ARCH_STACK_DUMP_FRAMES * sizeof(uint32_t)); + + /* TODO: send IPC oops message to host */ + + /* panic and loop forever */ + platform_panic(p); + while (1) {}; +} + +static inline void panic(uint32_t p) +{ + panic_rewind(p, 0); +} + +#endif diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h index 7123c8e..87b01e3 100644 --- a/src/include/uapi/ipc.h +++ b/src/include/uapi/ipc.h @@ -126,6 +126,23 @@ /* maximum message size for mailbox Tx/Tx */ #define SOF_IPC_MSG_MAX_SIZE 128
+/* + * SOF panic codes + */ +#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 | 0) +#define SOF_IPC_PANIC_WORK (SOF_IPC_PANIC_MAGIC | 1) +#define SOF_IPC_PANIC_IPC (SOF_IPC_PANIC_MAGIC | 2) +#define SOF_IPC_PANIC_ARCH (SOF_IPC_PANIC_MAGIC | 3) +#define SOF_IPC_PANIC_PLATFORM (SOF_IPC_PANIC_MAGIC | 4) +#define SOF_IPC_PANIC_TASK (SOF_IPC_PANIC_MAGIC | 5) +#define SOF_IPC_PANIC_EXCEPTION (SOF_IPC_PANIC_MAGIC | 6) +#define SOF_IPC_PANIC_DEADLOCK (SOF_IPC_PANIC_MAGIC | 7) +#define SOF_IPC_PANIC_STACK (SOF_IPC_PANIC_MAGIC | 8) +#define SOF_IPC_PANIC_IDLE (SOF_IPC_PANIC_MAGIC | 9) + /* * Command Header - Header for all IPC. Identifies IPC message. * The size can be greater than the structure size and that means there is @@ -820,4 +837,33 @@ struct sof_ipc_dma_trace_posn { uint32_t messages; /* total trace messages */ } __attribute__((packed));
+/* + * Architecture specific debug + */ + +/* Xtensa Firmware Oops data */ +struct sof_ipc_dsp_oops_xtensa { + uint32_t exccause; + uint32_t excvaddr; + uint32_t ps; + uint32_t epc1; + uint32_t epc2; + uint32_t epc3; + uint32_t epc4; + uint32_t epc5; + uint32_t epc6; + uint32_t epc7; + uint32_t eps2; + uint32_t eps3; + uint32_t eps4; + uint32_t eps5; + uint32_t eps6; + uint32_t eps7; + uint32_t depc; + uint32_t intenable; + uint32_t interrupt; + uint32_t sar; + uint32_t stack; +} __attribute__((packed)); + #endif diff --git a/src/init/init.c b/src/init/init.c index 9cdd93f..03ac662 100644 --- a/src/init/init.c +++ b/src/init/init.c @@ -35,6 +35,7 @@ #include <reef/init.h> #include <reef/task.h> #include <reef/debug.h> +#include <reef/panic.h> #include <reef/alloc.h> #include <reef/notifier.h> #include <reef/work.h> @@ -59,7 +60,7 @@ int main(int argc, char *argv[]) trace_point(TRACE_BOOT_ARCH); err = arch_init(&reef); if (err < 0) - panic(PANIC_ARCH); + panic(SOF_IPC_PANIC_ARCH);
/* initialise system services */ trace_point(TRACE_BOOT_SYS_HEAP); @@ -76,7 +77,7 @@ int main(int argc, char *argv[]) /* init the platform */ err = platform_init(&reef); if (err < 0) - panic(PANIC_PLATFORM); + panic(SOF_IPC_PANIC_PLATFORM);
trace_point(TRACE_BOOT_PLATFORM);
@@ -84,6 +85,6 @@ int main(int argc, char *argv[]) err = do_task(&reef);
/* should never get here */ - panic_dump_stack(PANIC_TASK); + panic(SOF_IPC_PANIC_TASK); return err; } diff --git a/src/lib/agent.c b/src/lib/agent.c index 1ffee81..0a1ad42 100644 --- a/src/lib/agent.c +++ b/src/lib/agent.c @@ -37,6 +37,7 @@ #include <reef/reef.h> #include <reef/agent.h> #include <reef/debug.h> +#include <reef/panic.h> #include <reef/alloc.h> #include <reef/clock.h> #include <reef/trace.h> @@ -70,7 +71,7 @@ static uint64_t validate(void *data, uint64_t delay) if (delta > sa->ticks) { trace_sa("tim"); trace_sa_value(delta); - panic_dump_stack(PANIC_IDLE); + panic(SOF_IPC_PANIC_IDLE); }
return PLATFORM_IDLE_TIME; diff --git a/src/lib/alloc.c b/src/lib/alloc.c index 1ae0c91..803b7af 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -32,6 +32,7 @@ #include <reef/alloc.h> #include <reef/reef.h> #include <reef/debug.h> +#include <reef/panic.h> #include <reef/trace.h> #include <reef/lock.h> #include <platform/memory.h> @@ -216,7 +217,7 @@ static void *rmalloc_sys(size_t bytes) memmap.system.heap += bytes; if (memmap.system.heap >= HEAP_SYSTEM_BASE + HEAP_SYSTEM_SIZE) { trace_mem_error("eMd"); - panic(PANIC_MEM); + panic(SOF_IPC_PANIC_MEM); }
#if DEBUG_BLOCK_ALLOC @@ -648,7 +649,7 @@ void init_heap(struct reef *reef)
/* sanity check for malformed images or loader issues */ if (memmap.system.heap != HEAP_SYSTEM_BASE) - panic(PANIC_MEM); + panic(SOF_IPC_PANIC_MEM);
spinlock_init(&memmap.lock);
diff --git a/src/library/include/platform/platform.h b/src/library/include/platform/platform.h index a429e84..afd64d8 100644 --- a/src/library/include/platform/platform.h +++ b/src/library/include/platform/platform.h @@ -50,5 +50,6 @@ /* IPC page data copy timeout */ #define PLATFORM_IPC_DMA_TIMEOUT 2000
+static inline void platform_panic(uint32_t p) {}
#endif diff --git a/src/tasks/audio.c b/src/tasks/audio.c index 800aa36..55913f5 100644 --- a/src/tasks/audio.c +++ b/src/tasks/audio.c @@ -73,7 +73,7 @@ int do_task(struct reef *reef) /* init static pipeline */ pdata.p = init_static_pipeline(); if (pdata.p == NULL) - panic(PANIC_TASK); + panic(SOF_IPC_PANIC_TASK); #endif /* let host know DSP boot is complete */ platform_boot_complete(0);
This window is always available at all boot stages hence is ideal for exception data.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/platform/apollolake/include/platform/mailbox.h | 2 +- src/platform/cannonlake/include/platform/mailbox.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/platform/apollolake/include/platform/mailbox.h b/src/platform/apollolake/include/platform/mailbox.h index 8741f28..c166e90 100644 --- a/src/platform/apollolake/include/platform/mailbox.h +++ b/src/platform/apollolake/include/platform/mailbox.h @@ -62,7 +62,7 @@
#define MAILBOX_EXCEPTION_SIZE 0x100 #define MAILBOX_EXCEPTION_BASE \ - (MAILBOX_DEBUG_BASE + MAILBOX_DEBUG_SIZE) + (MAILBOX_SW_REG_BASE + SRAM_REG_FW_END)
/* window 1 inbox/downlink and FW registers */ #define MAILBOX_HOSTBOX_SIZE SRAM_INBOX_SIZE diff --git a/src/platform/cannonlake/include/platform/mailbox.h b/src/platform/cannonlake/include/platform/mailbox.h index 6724fe5..a3c4339 100644 --- a/src/platform/cannonlake/include/platform/mailbox.h +++ b/src/platform/cannonlake/include/platform/mailbox.h @@ -63,7 +63,7 @@
#define MAILBOX_EXCEPTION_SIZE 0x100 #define MAILBOX_EXCEPTION_BASE \ - (MAILBOX_DEBUG_BASE + MAILBOX_DEBUG_SIZE) + (MAILBOX_SW_REG_BASE + SRAM_REG_FW_END)
/* window 1 inbox/downlink and FW registers */ #define MAILBOX_HOSTBOX_SIZE SRAM_INBOX_SIZE
ECC parity handler already defined in ROM so no need to re-register.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/arch/xtensa/reset-vector.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/arch/xtensa/reset-vector.S b/src/arch/xtensa/reset-vector.S index f491b33..05f601d 100644 --- a/src/arch/xtensa/reset-vector.S +++ b/src/arch/xtensa/reset-vector.S @@ -514,7 +514,7 @@ unpackdone: // code memory, thus forcing memory error vector to be shared given // it is not VECBASE relative) to have the same memory error vector, // yet each have their own handler and associated data save area. -#if XCHAL_HAVE_MEM_ECC_PARITY +#if XCHAL_HAVE_MEM_ECC_PARITY_IGNORE movi a4, _MemErrorHandler wsr a4, MESAVE #endif
participants (1)
-
Liam Girdwood