mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
Encoded data in the buffer is copied to the user buffer in binary format Jira TDS-17299 Change-Id: I329c9cd2fc1b91fe8700c4ef3c8d444fee6d4151 Signed-off-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3409070 Reviewed-by: Mahesh Kumar <mahkumar@nvidia.com> GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> (cherry picked from commit f865e4b21dbf5a50d47ef244929b625ff0d9aa78) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3433716
138 lines
3.6 KiB
C
138 lines
3.6 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
*/
|
|
|
|
#include <linux/errno.h>
|
|
#include <linux/debugfs.h>
|
|
#include <linux/uaccess.h>
|
|
|
|
#include <dce-os-utils.h>
|
|
#include <dce-debug-logging.h>
|
|
#include <dce-os-log.h>
|
|
#include <dce-logging.h>
|
|
#include <dce.h>
|
|
|
|
static int dbg_dce_log_help_fops_show(struct seq_file *s, void *data)
|
|
{
|
|
/**
|
|
* Writing:
|
|
* '0' to /sys/kernel/debug/tegra_dce/dce_logs/logs
|
|
* - Clear the circular buffer region data.
|
|
*
|
|
* Reading:
|
|
* cat /sys/kernel/debug/tegra_dce/dce_logs/logs
|
|
* - Prints the data stored in the buffer.
|
|
* - Current size of buffer is 512KB and on overflow starts overwriting the circular
|
|
* portion of the buffer in FIFO manner
|
|
*/
|
|
seq_printf(s, " DCE logs capture\n"
|
|
"---------------------------------------------------------------\n"
|
|
" echo '0' > dce_logs/logs: Clear circular region of buffer\n"
|
|
"---------------------------------------------------------------\n"
|
|
" cat dce_logs/logs: Print buffer data\n"
|
|
"---------------------------------------------------------------\n");
|
|
return 0;
|
|
}
|
|
|
|
int dbg_dce_log_help_fops_open(struct inode *inode, struct file *file)
|
|
{
|
|
return single_open(file, dbg_dce_log_help_fops_show,
|
|
inode->i_private);
|
|
}
|
|
|
|
static int dbg_dce_log_fops_show(struct seq_file *s, void *data)
|
|
{
|
|
int ret = 0;
|
|
uint32_t offset;
|
|
uint64_t bytes_written;
|
|
struct tegra_dce *d = s->private;
|
|
char *base_addr = (char *)d->dce_log_buff.cpu_base;
|
|
uint32_t log_buf_size = d->dce_log_buff.size;
|
|
struct dce_ipc_message *msg = NULL;
|
|
struct dce_admin_ipc_resp *resp_msg;
|
|
|
|
msg = dce_admin_channel_client_buffer_get(d, DCE_ADMIN_CH_CL_DBG_BUFF,
|
|
0 /* reserved flags */);
|
|
|
|
if (!msg) {
|
|
ret = -1;
|
|
dce_os_err(d, "IPC msg allocation failed");
|
|
goto out;
|
|
}
|
|
|
|
/** Retrieve logging info */
|
|
ret = dce_admin_get_log_info(d, msg);
|
|
if (ret) {
|
|
dce_os_err(d, "Failed to retrieve logging info, ret = 0x%x", ret);
|
|
goto out;
|
|
}
|
|
|
|
resp_msg = (struct dce_admin_ipc_resp *) (msg->rx.data);
|
|
|
|
bytes_written = resp_msg->args.log.get_log_info.bytes_written;
|
|
offset = resp_msg->args.log.get_log_info.offset;
|
|
|
|
/** If complete buffer size is zero then buffer is invalid */
|
|
if (log_buf_size == 0) {
|
|
dce_os_err(d, "%s", "Invalid log buffer\n");
|
|
goto out;
|
|
}
|
|
|
|
if (bytes_written == 0U || (log_buf_size <= offset)) {
|
|
dce_os_err(d, "%.*s", offset, base_addr);
|
|
goto out;
|
|
}
|
|
/** Write buffer content to file in binary format */
|
|
seq_write(s, base_addr, bytes_written);
|
|
out:
|
|
if (msg)
|
|
dce_admin_channel_client_buffer_put(d, msg);
|
|
return ret;
|
|
}
|
|
|
|
int dbg_dce_log_fops_open(struct inode *inode, struct file *file)
|
|
{
|
|
size_t seq_buf_size = 100*PAGE_SIZE;
|
|
|
|
return single_open_size(file, &dbg_dce_log_fops_show, inode->i_private, seq_buf_size);
|
|
}
|
|
|
|
ssize_t dbg_dce_log_fops_write(struct file *file, const char __user *user_buf,
|
|
size_t count, loff_t *ppos)
|
|
{
|
|
int ret = 0;
|
|
char buf[32];
|
|
uint32_t buf_size;
|
|
uint32_t log_op;
|
|
struct dce_ipc_message *msg = NULL;
|
|
struct tegra_dce *d = ((struct seq_file *)file->private_data)->private;
|
|
|
|
buf_size = min(count, (sizeof(buf)-1));
|
|
|
|
msg = dce_admin_channel_client_buffer_get(d, DCE_ADMIN_CH_CL_DBG_BUFF,
|
|
0 /* reserved flags */);
|
|
if (!msg) {
|
|
dce_os_err(d, "IPC msg allocation failed");
|
|
goto out;
|
|
}
|
|
|
|
ret = kstrtou32_from_user(user_buf, buf_size, 10, &log_op);
|
|
if (ret) {
|
|
dce_os_err(d, "Invalid format!");
|
|
goto out;
|
|
}
|
|
|
|
if (log_op == 0U) {
|
|
dce_os_err(d, "Clearing circular region of log buffer");
|
|
ret = dce_log_clear_buffer(d, msg);
|
|
if (ret)
|
|
dce_os_err(d, "Failed to clear log buffer!");
|
|
}
|
|
|
|
out:
|
|
if (msg)
|
|
dce_admin_channel_client_buffer_put(d, msg);
|
|
return count;
|
|
}
|