DCE-KMD: Add header support and use bytes written

Parse header info stored at beginning of buffer to retrieve log buffer
info and use bytes written to print the data depending on if encoding is
enabled or not.

JIRA TDS-17441

Change-Id: I99119be05ddda5c5354ba39497a0e471305863e1
Signed-off-by: Jaiyash Agrawal <jaiyasha@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3436761
Reviewed-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3448848
This commit is contained in:
Jaiyash Agrawal
2025-08-20 19:16:49 +00:00
committed by mobile promotions
parent 1c3b3fa89b
commit b6fa67fca1
2 changed files with 75 additions and 36 deletions

View File

@@ -12,6 +12,7 @@
#include <dce-os-log.h>
#include <dce-logging.h>
#include <dce.h>
#include <interface/dce-log-header.h>
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)

View File

@@ -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