summaryrefslogtreecommitdiff
path: root/sound/soc/sof/intel/telemetry.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2023-10-21 10:49:15 +0300
committerTakashi Iwai <tiwai@suse.de>2023-10-21 10:49:15 +0300
commit39cd06e3f7b75b629f2987aa51ab26fb820d167b (patch)
treec7215f6a63b2227584108043c623ff69c45cb236 /sound/soc/sof/intel/telemetry.c
parente6d0c13e9f46f9cf83f2f4946b0a2954599552a7 (diff)
parent45f1b12e0366a750d65e92307685964488a3b6f4 (diff)
downloadlinux-39cd06e3f7b75b629f2987aa51ab26fb820d167b.tar.xz
Merge tag 'asoc-v6.7' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v6.7 This is quite a large set of changes but mostly due to API cleanups and in driver specific ways rather than due to anything subsystem wide. Highlights include: - Standardisation of API prefixes on snd_soc_, removing asoc_. - GPIO API usage improvements. - Support for HDA patches. - Lots of work on SOF, including crash dump support. - Support for AMD platforms with es83xx, Awinc AT87390, many Intel platforms, many Mediatek platforms, Qualcomm SM6115, Richtek RTQ9128 and Texas Instruments TAS575x. [ the merge conflicts around SOF Intel HD-audio and CS35L41 subcodec drivers are resolved here -- tiwai ]
Diffstat (limited to 'sound/soc/sof/intel/telemetry.c')
-rw-r--r--sound/soc/sof/intel/telemetry.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/sound/soc/sof/intel/telemetry.c b/sound/soc/sof/intel/telemetry.c
new file mode 100644
index 000000000000..1a3b5c28a6f0
--- /dev/null
+++ b/sound/soc/sof/intel/telemetry.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2023 Intel Corporation. All rights reserved.
+
+/* telemetry data queried from debug window */
+
+#include <sound/sof/ipc4/header.h>
+#include <sound/sof/xtensa.h>
+#include "../ipc4-priv.h"
+#include "../sof-priv.h"
+#include "hda.h"
+#include "telemetry.h"
+
+void sof_ipc4_intel_dump_telemetry_state(struct snd_sof_dev *sdev, u32 flags)
+{
+ static const char invalid_slot_msg[] = "Core dump is not available due to";
+ struct sof_ipc4_telemetry_slot_data *telemetry_data;
+ struct sof_ipc_dsp_oops_xtensa *xoops;
+ struct xtensa_arch_block *block;
+ u32 slot_offset;
+ char *level;
+
+ level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR;
+
+ slot_offset = sof_ipc4_find_debug_slot_offset_by_type(sdev, SOF_IPC4_DEBUG_SLOT_TELEMETRY);
+ if (!slot_offset)
+ return;
+
+ telemetry_data = kmalloc(sizeof(*telemetry_data), GFP_KERNEL);
+ if (!telemetry_data)
+ return;
+ sof_mailbox_read(sdev, slot_offset, telemetry_data, sizeof(*telemetry_data));
+ if (telemetry_data->separator != XTENSA_CORE_DUMP_SEPARATOR) {
+ dev_err(sdev->dev, "%s invalid separator %#x\n", invalid_slot_msg,
+ telemetry_data->separator);
+ goto free_telemetry_data;
+ }
+
+ block = kmalloc(sizeof(*block), GFP_KERNEL);
+ if (!block)
+ goto free_telemetry_data;
+
+ sof_mailbox_read(sdev, slot_offset + sizeof(*telemetry_data), block, sizeof(*block));
+ if (block->soc != XTENSA_SOC_INTEL_ADSP) {
+ dev_err(sdev->dev, "%s invalid SOC %d\n", invalid_slot_msg, block->soc);
+ goto free_block;
+ }
+
+ if (telemetry_data->hdr.id[0] != COREDUMP_HDR_ID0 ||
+ telemetry_data->hdr.id[1] != COREDUMP_HDR_ID1 ||
+ telemetry_data->arch_hdr.id != COREDUMP_ARCH_HDR_ID) {
+ dev_err(sdev->dev, "%s invalid coredump header %c%c, arch hdr %c\n",
+ invalid_slot_msg, telemetry_data->hdr.id[0],
+ telemetry_data->hdr.id[1],
+ telemetry_data->arch_hdr.id);
+ goto free_block;
+ }
+
+ switch (block->toolchain) {
+ case XTENSA_TOOL_CHAIN_ZEPHYR:
+ dev_printk(level, sdev->dev, "FW is built with Zephyr toolchain\n");
+ break;
+ case XTENSA_TOOL_CHAIN_XCC:
+ dev_printk(level, sdev->dev, "FW is built with XCC toolchain\n");
+ break;
+ default:
+ dev_printk(level, sdev->dev, "Unknown toolchain is used\n");
+ break;
+ }
+
+ xoops = kzalloc(struct_size(xoops, ar, XTENSA_CORE_AR_REGS_COUNT), GFP_KERNEL);
+ if (!xoops)
+ goto free_block;
+
+ xoops->exccause = block->exccause;
+ xoops->excvaddr = block->excvaddr;
+ xoops->epc1 = block->pc;
+ xoops->ps = block->ps;
+ xoops->sar = block->sar;
+
+ xoops->plat_hdr.numaregs = XTENSA_CORE_AR_REGS_COUNT;
+ memcpy((void *)xoops->ar, block->ar, XTENSA_CORE_AR_REGS_COUNT * sizeof(u32));
+
+ sof_oops(sdev, level, xoops);
+ sof_stack(sdev, level, xoops, NULL, 0);
+
+ kfree(xoops);
+free_block:
+ kfree(block);
+free_telemetry_data:
+ kfree(telemetry_data);
+}