diff --git a/include/sound/sof/ipc4/header.h b/include/sound/sof/ipc4/header.h index 4106d3b4cfe890..4c5a539e767a8e 100644 --- a/include/sound/sof/ipc4/header.h +++ b/include/sound/sof/ipc4/header.h @@ -585,6 +585,7 @@ struct sof_ipc4_notify_resource_data { #define SOF_IPC4_DEBUG_SLOT_DEBUG_LOG 0x474f4c00 /* byte 0: core ID */ #define SOF_IPC4_DEBUG_SLOT_GDB_STUB 0x42444700 #define SOF_IPC4_DEBUG_SLOT_TELEMETRY 0x4c455400 +#define SOF_IPC4_DEBUG_SLOT_DEBUG_STREAM 0x53523134 #define SOF_IPC4_DEBUG_SLOT_BROKEN 0x44414544 /** diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index 18dea3b4ade4fc..e51590a99c3f57 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -11,7 +11,7 @@ snd-sof-y += ipc3.o ipc3-loader.o ipc3-topology.o ipc3-control.o ipc3-pcm.o\ endif ifneq ($(CONFIG_SND_SOC_SOF_IPC4),) snd-sof-y += ipc4.o ipc4-loader.o ipc4-topology.o ipc4-control.o ipc4-pcm.o\ - ipc4-mtrace.o ipc4-telemetry.o + ipc4-mtrace.o ipc4-debug-slot-debugfs.o endif # SOF client support diff --git a/sound/soc/sof/ipc4-debug-slot-debugfs.c b/sound/soc/sof/ipc4-debug-slot-debugfs.c new file mode 100644 index 00000000000000..12a5a968c2b659 --- /dev/null +++ b/sound/soc/sof/ipc4-debug-slot-debugfs.c @@ -0,0 +1,89 @@ +// 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) 2024-2025 Intel Corporation. +// + +#include +#include +#include +#include +#include +#include "sof-priv.h" +#include "ops.h" +#include "ipc4-priv.h" + +struct debug_slot_fs_ud { + struct snd_sof_dfsentry dfse; + u32 slot_type; + size_t data_offset; +}; + +static ssize_t sof_debug_slot_debugfs_entry_read(struct file *file, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct debug_slot_fs_ud *ud = file->private_data; + struct snd_sof_dfsentry *dfse = &ud->dfse; + struct snd_sof_dev *sdev = dfse->sdev; + size_t doffset = ud->data_offset; + u32 type = ud->slot_type; + loff_t pos = *ppos; + size_t size_ret; + u32 offset; + u8 *buf; + + if (pos < 0) + return -EINVAL; + if (pos + doffset >= SOF_IPC4_DEBUG_SLOT_SIZE || !count) + return 0; + if (count > SOF_IPC4_DEBUG_SLOT_SIZE - pos - doffset) + count = SOF_IPC4_DEBUG_SLOT_SIZE - pos - doffset; + + offset = sof_ipc4_find_debug_slot_offset_by_type(sdev, type); + if (!offset) + return -EFAULT; + + buf = kzalloc(SOF_IPC4_DEBUG_SLOT_SIZE - doffset, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + sof_mailbox_read(sdev, offset + doffset, buf, SOF_IPC4_DEBUG_SLOT_SIZE - doffset); + size_ret = copy_to_user(buffer, buf + pos, count); + kfree(buf); + if (size_ret) + return -EFAULT; + + *ppos = pos + count; + + return count; +} + +static const struct file_operations sof_debug_stream_fops = { + .open = simple_open, + .read = sof_debug_slot_debugfs_entry_read, + .llseek = default_llseek, +}; + +void sof_ipc4_create_debug_slot_ro_debugfs_node(struct snd_sof_dev *sdev, u32 slot_type, + size_t data_offset, const char *name) +{ + struct debug_slot_fs_ud *ud; + + ud = devm_kzalloc(sdev->dev, sizeof(*ud), GFP_KERNEL); + if (!ud) + return; + + ud->dfse.type = SOF_DFSENTRY_TYPE_IOMEM; + ud->dfse.size = SOF_IPC4_DEBUG_SLOT_SIZE; + ud->dfse.access_type = SOF_DEBUGFS_ACCESS_ALWAYS; + ud->dfse.sdev = sdev; + + ud->slot_type = slot_type; + ud->data_offset = data_offset; + + list_add(&ud->dfse.list, &sdev->dfsentry_list); + + debugfs_create_file(name, 0444, sdev->debugfs_root, ud, &sof_debug_stream_fops); +} diff --git a/sound/soc/sof/ipc4-priv.h b/sound/soc/sof/ipc4-priv.h index a8cdf9bc750b4d..470117fe6e6d2f 100644 --- a/sound/soc/sof/ipc4-priv.h +++ b/sound/soc/sof/ipc4-priv.h @@ -129,4 +129,6 @@ void sof_ipc4_mic_privacy_state_change(struct snd_sof_dev *sdev, bool state); enum sof_ipc4_pipeline_state; const char *sof_ipc4_pipeline_state_str(enum sof_ipc4_pipeline_state state); +void sof_ipc4_create_debug_slot_ro_debugfs_node(struct snd_sof_dev *sdev, u32 slot_type, + size_t data_offset, const char *name); #endif diff --git a/sound/soc/sof/ipc4-telemetry.c b/sound/soc/sof/ipc4-telemetry.c deleted file mode 100644 index ddc3bc494ffefe..00000000000000 --- a/sound/soc/sof/ipc4-telemetry.c +++ /dev/null @@ -1,95 +0,0 @@ -// 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) 2018-2023 Intel Corporation -// - -#include -#include -#include -#include -#include -#include "sof-priv.h" -#include "ops.h" -#include "ipc4-telemetry.h" -#include "ipc4-priv.h" - -static void __iomem *sof_ipc4_query_exception_address(struct snd_sof_dev *sdev) -{ - u32 type = SOF_IPC4_DEBUG_SLOT_TELEMETRY; - size_t telemetry_slot_offset; - u32 offset; - - telemetry_slot_offset = sof_ipc4_find_debug_slot_offset_by_type(sdev, type); - if (!telemetry_slot_offset) - return NULL; - - /* skip the first separator magic number */ - offset = telemetry_slot_offset + sizeof(u32); - - return sdev->bar[sdev->mailbox_bar] + offset; -} - -static ssize_t sof_telemetry_entry_read(struct file *file, char __user *buffer, - size_t count, loff_t *ppos) -{ - struct snd_sof_dfsentry *dfse = file->private_data; - struct snd_sof_dev *sdev = dfse->sdev; - void __iomem *io_addr; - loff_t pos = *ppos; - size_t size_ret; - u8 *buf; - - if (pos < 0) - return -EINVAL; - /* skip the first separator magic number */ - if (pos >= SOF_IPC4_DEBUG_SLOT_SIZE - 4 || !count) - return 0; - if (count > SOF_IPC4_DEBUG_SLOT_SIZE - 4 - pos) - count = SOF_IPC4_DEBUG_SLOT_SIZE - 4 - pos; - - io_addr = sof_ipc4_query_exception_address(sdev); - if (!io_addr) - return -EFAULT; - - buf = kzalloc(SOF_IPC4_DEBUG_SLOT_SIZE - 4, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - memcpy_fromio(buf, io_addr, SOF_IPC4_DEBUG_SLOT_SIZE - 4); - size_ret = copy_to_user(buffer, buf + pos, count); - if (size_ret) { - kfree(buf); - return -EFAULT; - } - - *ppos = pos + count; - kfree(buf); - - return count; -} - -static const struct file_operations sof_telemetry_fops = { - .open = simple_open, - .read = sof_telemetry_entry_read, -}; - -void sof_ipc4_create_exception_debugfs_node(struct snd_sof_dev *sdev) -{ - struct snd_sof_dfsentry *dfse; - - dfse = devm_kzalloc(sdev->dev, sizeof(*dfse), GFP_KERNEL); - if (!dfse) - return; - - dfse->type = SOF_DFSENTRY_TYPE_IOMEM; - dfse->size = SOF_IPC4_DEBUG_SLOT_SIZE - 4; - dfse->access_type = SOF_DEBUGFS_ACCESS_ALWAYS; - dfse->sdev = sdev; - - list_add(&dfse->list, &sdev->dfsentry_list); - - debugfs_create_file("exception", 0444, sdev->debugfs_root, dfse, &sof_telemetry_fops); -} diff --git a/sound/soc/sof/ipc4-telemetry.h b/sound/soc/sof/ipc4-telemetry.h index 9298f8acc648b2..3d5914e1a18aa7 100644 --- a/sound/soc/sof/ipc4-telemetry.h +++ b/sound/soc/sof/ipc4-telemetry.h @@ -69,5 +69,4 @@ struct sof_ipc4_telemetry_slot_data { u32 arch_data[]; } __packed; -void sof_ipc4_create_exception_debugfs_node(struct snd_sof_dev *sdev); #endif diff --git a/sound/soc/sof/ipc4.c b/sound/soc/sof/ipc4.c index 157f7503b84469..e5149572325cea 100644 --- a/sound/soc/sof/ipc4.c +++ b/sound/soc/sof/ipc4.c @@ -15,7 +15,6 @@ #include "sof-audio.h" #include "ipc4-fw-reg.h" #include "ipc4-priv.h" -#include "ipc4-telemetry.h" #include "ops.h" static const struct sof_ipc4_fw_status { @@ -621,7 +620,12 @@ static int ipc4_fw_ready(struct snd_sof_dev *sdev, struct sof_ipc4_msg *ipc4_msg return 0; } - sof_ipc4_create_exception_debugfs_node(sdev); + /* sizeof(u32)is for skiping the first separator magic number */ + sof_ipc4_create_debug_slot_ro_debugfs_node(sdev, SOF_IPC4_DEBUG_SLOT_TELEMETRY, + sizeof(u32), "exception"); + + sof_ipc4_create_debug_slot_ro_debugfs_node(sdev, SOF_IPC4_DEBUG_SLOT_DEBUG_STREAM, + 0, "debug_stream"); return sof_ipc4_init_msg_memory(sdev); }