1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2019-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef LOGDECODE_H_
25 #define LOGDECODE_H_
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 #ifdef NVRM
32 
33 #        define LIBOS_LOG_DECODE_ENABLE 1
34 
35 #        define LIBOS_LOG_TO_NVLOG 1
36 
37 #    define LIBOS_LOG_MAX_LOGS      5   // Max logs per GPU
38 
39 #elif defined(LIBOS_LOG_OFFLINE_DECODER)
40 #    include "nvlog_decoder.h"
41 
42 #    define LIBOS_LOG_DECODE_ENABLE 1
43 #    define LIBOS_LOG_TO_NVLOG      0
44 
45 #    define LIBOS_LOG_MAX_LOGS    160   // Max logs for all GPUs for offline decoder
46 
47 #else
48 #    error "Need to define either NVRM or LIBOS_LOG_OFFLINE_DECODER."
49 #endif // NVRM
50 
51 #define LIBOS_LOG_ENABLE          (LIBOS_LOG_TO_NVLOG || LIBOS_LOG_DECODE_ENABLE)
52 
53 #if LIBOS_LOG_DECODE_ENABLE
54 #    include "../include/libos_log.h"
55 #    include "libdwarf.h"
56 #endif
57 
58 // Forward declarations.
59 struct LIBOS_LOG_DECODE_LOG;
60 typedef struct LIBOS_LOG_DECODE_LOG LIBOS_LOG_DECODE_LOG;
61 
62 #define LIBOS_LOG_LINE_BUFFER_SIZE 128
63 #define LIBOS_LOG_MAX_ARGS         20
64 
65 #if LIBOS_LOG_DECODE_ENABLE
66 
67 #    include "nvctassert.h"
68 
69 typedef struct
70 {
71     NV_DECLARE_ALIGNED(LIBOS_LOG_DECODE_LOG *log, 8);
72     NV_DECLARE_ALIGNED(LIBOS_LOG_DECODE_LOG *logSymbolResolver, 8);
73     NV_DECLARE_ALIGNED(libosLogMetadata *meta, 8);
74     NV_DECLARE_ALIGNED(NvU64 timeStamp, 8);
75     NvU64 args[LIBOS_LOG_MAX_ARGS];
76 } LIBOS_LOG_DECODE_RECORD;
77 
78 // Size of LIBOS_LOG_DECODE_RECORD without args, in number of NvU64 entries.
79 #    define LIBOS_LOG_DECODE_RECORD_BASE 4
80 
81 // Ensure that the size matches up (no padding in the struct)
82 ct_assert((LIBOS_LOG_DECODE_RECORD_BASE * sizeof(NvU64)) == (sizeof(LIBOS_LOG_DECODE_RECORD) - sizeof(((LIBOS_LOG_DECODE_RECORD*)NULL)->args)));
83 
84 #endif // LIBOS_LOG_DECODE_ENABLE
85 
86 #define TASK_NAME_MAX_LENGTH   (8)
87 #define SOURCE_NAME_MAX_LENGTH (4)
88 
89 #define ELF_SECTION_NAME_MAX   (32) // In bytes
90 
91 // NvLog buffer
92 typedef struct
93 {
94     NvU32 gpuArch;
95     NvU32 gpuImpl;
96     NvU32 rsvd1;
97     NvU32 rsvd2;
98     char taskPrefix[TASK_NAME_MAX_LENGTH]; // Prefix string printed before each line.
99     NvU8 data[0];
100 } LIBOS_LOG_NVLOG_BUFFER;
101 
102 #define LIBOS_LOG_NVLOG_BUFFER_SIZE(dataSize) (NV_OFFSETOF(LIBOS_LOG_NVLOG_BUFFER, data) + (dataSize))
103 
104 struct LIBOS_LOG_DECODE_LOG
105 {
106     volatile NvU64 *physicLogBuffer;
107     NvU64 logBufferSize;             // Includes put pointer located in first 8 bytes.
108     NvU64 previousPut;               // Keeps track of records already printed.
109     NvU64 putCopy;                   // End pointer for this batch.
110     NvU64 putIter;                   // Iterator for this batch.
111     NvU32 gpuInstance;               // GPU that this log is associated with.
112     char taskPrefix[TASK_NAME_MAX_LENGTH];     // Prefix string printed before each line.
113     char elfSectionName[ELF_SECTION_NAME_MAX]; // Task section name in container logging ELF serving as ID.
114 
115 #if LIBOS_LOG_TO_NVLOG
116     NvU32 hNvLogNoWrap;  // No wrap buffer captures first records.
117     NvU32 hNvLogWrap;    // Wrap buffer captures last records.
118     NvBool bNvLogNoWrap; // NV_TRUE if no wrap buffer not full.
119 
120     NvBool bDidPush;     // NV_TRUE if this buffer was ever pushed to
121     NvU64 preservedNoWrapPos; // Position in preserved nvlog buffer
122 #endif
123 
124 #if LIBOS_LOG_DECODE_ENABLE
125     LibosElf64Header *elf;
126     LibosElfImage elfImage;
127     LibosDebugResolver resolver;
128     LIBOS_LOG_DECODE_RECORD record;
129 #endif
130 };
131 
132 typedef struct
133 {
134     char sourceName[SOURCE_NAME_MAX_LENGTH]; // GSP, PMU etc
135 
136     NvU64 numLogBuffers;
137     LIBOS_LOG_DECODE_LOG log[LIBOS_LOG_MAX_LOGS];
138 
139 #if LIBOS_LOG_DECODE_ENABLE
140     NvBool bIsDecodable;     // True if a logging ELF is provided, False on NULL
141     NvU64 *scratchBuffer;    // Sorted by timestamp.
142     NvU64 scratchBufferSize; // Sum of logBufferSize.
143     char *curLineBufPtr;     // Current position in lineBuffer.
144     // Decodes into lineBuffer, then prints as a string.
145     char lineBuffer[LIBOS_LOG_LINE_BUFFER_SIZE];
146     NvBool bSynchronousBuffer;
147     NvBool bPtrSymbolResolve;
148     NvU8 lineLogLevel;
149 
150     // Fall back to SHDR when a PDHR with %s argument is not found.
151     NvBool bDecodeStrShdr;
152 #endif // LIBOS_LOG_DECODE_ENABLE
153 
154 #if defined(LIBOS_LOG_OFFLINE_DECODER)
155     LogPrinter *pLogPrinter;
156 #endif
157 
158 } LIBOS_LOG_DECODE;
159 
160 #if defined(LIBOS_LOG_OFFLINE_DECODER)
161 void libosLogCreate(LIBOS_LOG_DECODE *logDecode, LogPrinter *pLogPrinter);
162 void libosLogCreateEx(LIBOS_LOG_DECODE *logDecode, const char *pSourceName, LogPrinter *pLogPrinter);
163 #else
164 void libosLogCreate(LIBOS_LOG_DECODE *logDecode);
165 void libosLogCreateEx(LIBOS_LOG_DECODE *logDecode, const char *pSourceName);
166 #endif
167 
168 void libosLogAddLogEx(LIBOS_LOG_DECODE *logDecode, void *buffer, NvU64 bufferSize, NvU32 gpuInstance, NvU32 gpuArch, NvU32 gpuImpl, const char *name, const char *elfSectionName);
169 void libosLogAddLog(LIBOS_LOG_DECODE *logDecode, void *buffer, NvU64 bufferSize, NvU32 gpuInstance, const char *name, const char *elfSectionName);
170 
171 #if LIBOS_LOG_DECODE_ENABLE
172 void libosLogInit(LIBOS_LOG_DECODE *logDecode, LibosElf64Header *elf, NvU64 elfSize);
173 void libosLogInitEx(
174     LIBOS_LOG_DECODE *logDecode, LibosElf64Header *elf, NvBool bSynchronousBuffer,
175     NvBool bPtrSymbolResolve, NvBool bDecodeStrFmt, NvU64 elfSize);
176 #else
177 void libosLogInit(LIBOS_LOG_DECODE *logDecode, void *elf, NvU64 elfSize);
178 void libosLogInitEx(
179     LIBOS_LOG_DECODE *logDecode, void *elf, NvBool bSynchronousBuffer, NvBool bPtrSymbolResolve,
180     NvBool bDecodeStrFmt, NvU64 elfSize);
181 #endif // LIBOS_LOG_DECODE_ENABLE
182 
183 NvBool libosLogSymbolicateAddress(LIBOS_LOG_DECODE *logDecode, char *decodedLine, NvLength decodedLineSize, NvUPtr addr);
184 
185 void libosLogDestroy(LIBOS_LOG_DECODE *logDecode);
186 
187 void libosExtractLogs(LIBOS_LOG_DECODE *logDecode, NvBool bSyncNvLog);
188 
189 void libosPreserveLogs(LIBOS_LOG_DECODE *pLogDecode);
190 
191 #ifdef __cplusplus
192 }
193 #endif
194 
195 #endif // LOGDECODE_H_
196