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