mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 22:51:35 +00:00
ASoC: SOF: Intel: add telemetry retrieval support on Intel platforms
Telemetry data is decoded based on intel xtensa design and printed in kernel log by sof debug framework. Signed-off-by: Rander Wang <rander.wang@intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://lore.kernel.org/r/20230919092416.4137-7-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
80b567f899
commit
c8b54a2f7a
@ -7,7 +7,8 @@ snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \
|
||||
hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \
|
||||
hda-dai.o hda-dai-ops.o hda-bus.o \
|
||||
skl.o hda-loader-skl.o \
|
||||
apl.o cnl.o tgl.o icl.o mtl.o lnl.o hda-common-ops.o
|
||||
apl.o cnl.o tgl.o icl.o mtl.o lnl.o hda-common-ops.o \
|
||||
telemetry.o
|
||||
|
||||
snd-sof-intel-hda-mlink-objs := hda-mlink.o
|
||||
|
||||
|
95
sound/soc/sof/intel/telemetry.c
Normal file
95
sound/soc/sof/intel/telemetry.c
Normal file
@ -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);
|
||||
}
|
35
sound/soc/sof/intel/telemetry.h
Normal file
35
sound/soc/sof/intel/telemetry.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* 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 in debug windows
|
||||
*/
|
||||
|
||||
#ifndef _SOF_INTEL_TELEMETRY_H
|
||||
#define _SOF_INTEL_TELEMETRY_H
|
||||
|
||||
#include "../ipc4-telemetry.h"
|
||||
|
||||
struct xtensa_arch_block {
|
||||
u8 soc; /* should be equal to XTENSA_SOC_INTEL_ADSP */
|
||||
u16 version;
|
||||
u8 toolchain; /* ZEPHYR or XCC */
|
||||
|
||||
u32 pc;
|
||||
u32 exccause;
|
||||
u32 excvaddr;
|
||||
u32 sar;
|
||||
u32 ps;
|
||||
u32 scompare1;
|
||||
u32 ar[XTENSA_CORE_AR_REGS_COUNT];
|
||||
u32 lbeg;
|
||||
u32 lend;
|
||||
u32 lcount;
|
||||
} __packed;
|
||||
|
||||
void sof_ipc4_intel_dump_telemetry_state(struct snd_sof_dev *sdev, u32 flags);
|
||||
|
||||
#endif /* _SOF_INTEL_TELEMETRY_H */
|
Loading…
Reference in New Issue
Block a user