1*18ebffe4SIulian Olaru // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2*18ebffe4SIulian Olaru // 3*18ebffe4SIulian Olaru // Copyright 2020 NXP 4*18ebffe4SIulian Olaru // 5*18ebffe4SIulian Olaru // Common helpers for the audio DSP on i.MX8 6*18ebffe4SIulian Olaru 7*18ebffe4SIulian Olaru #include <sound/sof/xtensa.h> 8*18ebffe4SIulian Olaru #include "../ops.h" 9*18ebffe4SIulian Olaru 10*18ebffe4SIulian Olaru #include "imx-common.h" 11*18ebffe4SIulian Olaru 12*18ebffe4SIulian Olaru /** 13*18ebffe4SIulian Olaru * imx8_get_registers() - This function is called in case of DSP oops 14*18ebffe4SIulian Olaru * in order to gather information about the registers, filename and 15*18ebffe4SIulian Olaru * linenumber and stack. 16*18ebffe4SIulian Olaru * @sdev: SOF device 17*18ebffe4SIulian Olaru * @xoops: Stores information about registers. 18*18ebffe4SIulian Olaru * @panic_info: Stores information about filename and line number. 19*18ebffe4SIulian Olaru * @stack: Stores the stack dump. 20*18ebffe4SIulian Olaru * @stack_words: Size of the stack dump. 21*18ebffe4SIulian Olaru */ 22*18ebffe4SIulian Olaru void imx8_get_registers(struct snd_sof_dev *sdev, 23*18ebffe4SIulian Olaru struct sof_ipc_dsp_oops_xtensa *xoops, 24*18ebffe4SIulian Olaru struct sof_ipc_panic_info *panic_info, 25*18ebffe4SIulian Olaru u32 *stack, size_t stack_words) 26*18ebffe4SIulian Olaru { 27*18ebffe4SIulian Olaru u32 offset = sdev->dsp_oops_offset; 28*18ebffe4SIulian Olaru 29*18ebffe4SIulian Olaru /* first read registers */ 30*18ebffe4SIulian Olaru sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops)); 31*18ebffe4SIulian Olaru 32*18ebffe4SIulian Olaru /* then get panic info */ 33*18ebffe4SIulian Olaru if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) { 34*18ebffe4SIulian Olaru dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n", 35*18ebffe4SIulian Olaru xoops->arch_hdr.totalsize); 36*18ebffe4SIulian Olaru return; 37*18ebffe4SIulian Olaru } 38*18ebffe4SIulian Olaru offset += xoops->arch_hdr.totalsize; 39*18ebffe4SIulian Olaru sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info)); 40*18ebffe4SIulian Olaru 41*18ebffe4SIulian Olaru /* then get the stack */ 42*18ebffe4SIulian Olaru offset += sizeof(*panic_info); 43*18ebffe4SIulian Olaru sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32)); 44*18ebffe4SIulian Olaru } 45*18ebffe4SIulian Olaru 46*18ebffe4SIulian Olaru /** 47*18ebffe4SIulian Olaru * imx8_dump() - This function is called when a panic message is 48*18ebffe4SIulian Olaru * received from the firmware. 49*18ebffe4SIulian Olaru */ 50*18ebffe4SIulian Olaru void imx8_dump(struct snd_sof_dev *sdev, u32 flags) 51*18ebffe4SIulian Olaru { 52*18ebffe4SIulian Olaru struct sof_ipc_dsp_oops_xtensa xoops; 53*18ebffe4SIulian Olaru struct sof_ipc_panic_info panic_info; 54*18ebffe4SIulian Olaru u32 stack[IMX8_STACK_DUMP_SIZE]; 55*18ebffe4SIulian Olaru u32 status; 56*18ebffe4SIulian Olaru 57*18ebffe4SIulian Olaru /* Get information about the panic status from the debug box area. 58*18ebffe4SIulian Olaru * Compute the trace point based on the status. 59*18ebffe4SIulian Olaru */ 60*18ebffe4SIulian Olaru sof_mailbox_read(sdev, sdev->debug_box.offset + 0x4, &status, 4); 61*18ebffe4SIulian Olaru 62*18ebffe4SIulian Olaru /* Get information about the registers, the filename and line 63*18ebffe4SIulian Olaru * number and the stack. 64*18ebffe4SIulian Olaru */ 65*18ebffe4SIulian Olaru imx8_get_registers(sdev, &xoops, &panic_info, stack, 66*18ebffe4SIulian Olaru IMX8_STACK_DUMP_SIZE); 67*18ebffe4SIulian Olaru 68*18ebffe4SIulian Olaru /* Print the information to the console */ 69*18ebffe4SIulian Olaru snd_sof_get_status(sdev, status, status, &xoops, &panic_info, stack, 70*18ebffe4SIulian Olaru IMX8_STACK_DUMP_SIZE); 71*18ebffe4SIulian Olaru } 72*18ebffe4SIulian Olaru EXPORT_SYMBOL(imx8_dump); 73