diff --git a/drivers/platform/tegra/dce/dce-debug-logging.c b/drivers/platform/tegra/dce/dce-debug-logging.c index 7ca09027..824a5c88 100644 --- a/drivers/platform/tegra/dce/dce-debug-logging.c +++ b/drivers/platform/tegra/dce/dce-debug-logging.c @@ -12,6 +12,7 @@ #include #include #include +#include static int dbg_dce_log_help_fops_show(struct seq_file *s, void *data) { @@ -43,52 +44,51 @@ int dbg_dce_log_help_fops_open(struct inode *inode, struct file *file) 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; + uint64_t bytes_written = 0U; + struct tegra_dce *d = s->private; + char *base_addr = (char *)(d->dce_log_buff.cpu_base); + char *buff_start_addr = NULL; + uint32_t log_buf_size = d->dce_log_buff.size; + uint32_t circ_buf_size = 0U; + struct dce_log_buffer_header *header_info = NULL; + uint32_t cur_buf_idx = 0U; - 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; + header_info = (struct dce_log_buffer_header *)base_addr; + bytes_written = header_info->total_bytes_written; + buff_start_addr = (char *)(header_info->buff); + circ_buf_size = header_info->circ_buf_size; /** If complete buffer size is zero then buffer is invalid */ - if (log_buf_size == 0) { + if ((log_buf_size == 0) || (circ_buf_size == 0U)) { 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); + cur_buf_idx = (bytes_written % circ_buf_size); + + if (bytes_written == 0U) { + dce_os_err(d, "No logs available!\n"); goto out; } - /** Write buffer content to file in binary format */ - seq_write(s, base_addr, bytes_written); + + if (header_info->is_encoded_log) { + /** Write buffer content to file in binary format */ + seq_write(s, buff_start_addr, bytes_written); + } else { + /** If circular buffer is not yet wrapped around */ + if (bytes_written <= circ_buf_size) { + seq_printf(s, "%.*s", cur_buf_idx, buff_start_addr); + goto out; + } + + /** If circular buffer region has been overwritten */ + /** Print logs stored in circular buffer region */ + seq_printf(s, "%.*s", log_buf_size - cur_buf_idx, buff_start_addr + cur_buf_idx); + seq_printf(s, "%.*s", cur_buf_idx, buff_start_addr); + } + out: - if (msg) - dce_admin_channel_client_buffer_put(d, msg); - return ret; + return 0; } int dbg_dce_log_fops_open(struct inode *inode, struct file *file) diff --git a/drivers/platform/tegra/dce/include/interface/dce-log-header.h b/drivers/platform/tegra/dce/include/interface/dce-log-header.h new file mode 100644 index 00000000..341e7316 --- /dev/null +++ b/drivers/platform/tegra/dce/include/interface/dce-log-header.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT + * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + */ + +#ifndef DCE_LOG_HEADER_H +#define DCE_LOG_HEADER_H + +/** + * Log buffer header information structure + * + * This structure contains metadata about the circular log buffer including + * version information, buffer size, and synchronization flags for DCE and + * consumer communication. + */ +struct dce_log_buffer_header { + uint32_t version; /** Header version for compatibility checking */ + uint32_t header_size; /** Size of this header structure */ + uint32_t flag; /** Synchronization flag for producer-consumer */ + uint32_t circ_buf_size; /** Size of circular buffer region */ + uint32_t is_encoded_log; /** Indicates if logs are encoded or not */ + uint32_t reserved_32; /** Reserved 32-bit field */ + uint64_t reserved_64; /** Reserved 64-bit field */ + uint64_t total_bytes_written; /** Total bytes written by DCE */ + uint8_t buff[]; /** Starting point of circular region of buffer */ +}; + +/** Log buffer synchronization flag, indicates if DCE is writing actively */ +#define DCE_LOG_BUFFER_FLAG_DCE_ACTIVE 0x00000001U + +/** Current version of the log buffer header */ +#define DCE_LOG_BUFFER_HEADER_VERSION 0x00000001U + +/** Size of the log buffer header structure */ +#define DCE_LOG_BUFFER_HEADER_SIZE sizeof(dce_log_buffer_header_t) + +/** Default DCE log level for printing to log buffer */ +#define DCE_LOG_DEFAULT_LOG_LEVEL ((uint32_t)(0xFFFFFFFFU)) + +#endif