Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/sound/sof/ipc4/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,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

/**
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/sof/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ snd-sof-$(CONFIG_SND_SOC_SOF_COMPRESS) += ipc3-compress.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
snd-sof-$(CONFIG_SND_SOC_SOF_COMPRESS) += ipc4-compress.o
endif

Expand Down
113 changes: 113 additions & 0 deletions sound/soc/sof/ipc4-debug-slot-debugfs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// 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 <linux/debugfs.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <sound/sof/debug.h>
#include <sound/sof/ipc4/header.h>
#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 exposed_size;
size_t size_ret;
u32 offset;
u8 *buf;

if (doffset >= SOF_IPC4_DEBUG_SLOT_SIZE)
return -EINVAL;

exposed_size = SOF_IPC4_DEBUG_SLOT_SIZE - doffset;

if (pos < 0)
return -EINVAL;
if (pos >= exposed_size || !count)
return 0;
if (count > exposed_size - pos)
count = exposed_size - pos;

offset = sof_ipc4_find_debug_slot_offset_by_type(sdev, type);
if (!offset)
return -EFAULT;

buf = kzalloc(exposed_size, GFP_KERNEL);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be better to just allocate this on open() and then free it on close(). This way we simplify and optimize the flow.

if (!buf)
return -ENOMEM;

sof_mailbox_read(sdev, offset + doffset, buf, exposed_size);
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;
size_t exposed_size;

if (data_offset >= SOF_IPC4_DEBUG_SLOT_SIZE)
return;

exposed_size = SOF_IPC4_DEBUG_SLOT_SIZE - data_offset;

/*
* Reject partial descriptor 15 if this interface must not cross the
* end of page 0 into the next slot.
*/
if (slot_type == SOF_IPC4_DEBUG_SLOT_DEBUG_STREAM &&
sof_ipc4_find_debug_slot_offset_by_type(sdev, slot_type) ==
sdev->debug_box.offset + SOF_IPC4_DEBUG_PAGE0_SLOT_OFFSET)
return;
Comment thread
jsarha marked this conversation as resolved.

if (data_offset >= SOF_IPC4_DEBUG_SLOT_SIZE)
return;

ud = devm_kzalloc(sdev->dev, sizeof(*ud), GFP_KERNEL);
if (!ud)
return;

ud->dfse.type = SOF_DFSENTRY_TYPE_IOMEM;
ud->dfse.size = exposed_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);
}
2 changes: 2 additions & 0 deletions sound/soc/sof/ipc4-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,6 @@ static inline void sof_ipc4_compr_drain_done(struct snd_sof_dev *sdev,
void *ipc_message) { }
#endif

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
95 changes: 0 additions & 95 deletions sound/soc/sof/ipc4-telemetry.c

This file was deleted.

1 change: 0 additions & 1 deletion sound/soc/sof/ipc4-telemetry.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 8 additions & 3 deletions sound/soc/sof/ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "ipc4-fw-reg.h"
#include "ipc4-priv.h"
#include "ipc4-topology.h"
#include "ipc4-telemetry.h"
#include "ops.h"

static const struct sof_ipc4_fw_status {
Expand Down Expand Up @@ -720,7 +719,8 @@ size_t sof_ipc4_find_debug_slot_offset_by_type(struct snd_sof_dev *sdev,
slot_desc_type_offset += SOF_IPC4_DEBUG_DESCRIPTOR_SIZE;
}

dev_dbg(sdev->dev, "Slot type %#x is not available in debug window\n", slot_type);
dev_dbg_ratelimited(sdev->dev, "Slot type %#x is not available in debug window\n",
slot_type);
return 0;
}
EXPORT_SYMBOL(sof_ipc4_find_debug_slot_offset_by_type);
Expand All @@ -741,7 +741,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 skipping 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");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to say "probes_stream" instead here ?


return sof_ipc4_init_msg_memory(sdev);
}
Expand Down
Loading