/* * SPDX-FileCopyrightText: Copyright (c) 2012-2024 NVIDIA CORPORATION & AFFILIATES * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef _NVLOG_DEFS_H_ #define _NVLOG_DEFS_H_ #include "nvtypes.h" /******************* Common Debug & Trace Defines ***************************\ * * * Module: NVLOG_DEFS.H * * * \****************************************************************************/ #define NVLOG_MAX_DBG_MODULES 256 /********************************/ /********* Structures *********/ /********************************/ // Forward declaration, so it can be used in the function type definition. /** * @brief Struct representing a buffer in NvLog * * All logging (Print, Regtrace, etc) use these buffers. */ typedef struct _NVLOG_BUFFER NVLOG_BUFFER; /** * @brief Type of the 'push' function for NvLog buffers * * Function called whenever pushing something to an NvLog buffer */ typedef NvBool (*NVLOG_BUFFER_PUSHFUNC) (NVLOG_BUFFER *, NvU8 *, NvU32); /** * @brief Fields specific to ring buffers */ typedef struct _NVLOG_RING_BUFFER_EXTRA_FIELDS { /** How many times the ring buffer has overflown */ NvU32 overflow; } NVLOG_RING_BUFFER_EXTRA_FIELDS; /** * @brief Struct representing a buffer in NvLog * * All logging (Print, Regtrace, etc) use these buffers. */ struct _NVLOG_BUFFER { /** Function to call when writing to this buffer */ union { NVLOG_BUFFER_PUSHFUNC fn; // Pad this union to prevent struct size from varying between 32/64 bit platforms NvP64 padding; } push; /** Size of the buffer data section */ NvU32 size; /** Buffer tag, for easier identification in a dump */ NvU32 tag; /** Flags of the buffer, following NVLOG_BUFFER_FLAGS_* DRF's */ NvU32 flags; /** Position of the next available byte in the buffer */ NvU32 pos; /** Number of threads currently writing to this buffer */ volatile NvS32 threadCount; /** Specific buffer types will define their fields here */ union { NVLOG_RING_BUFFER_EXTRA_FIELDS ring; } extra; /** Buffer data. */ NvU8 data[1]; }; #define NVLOG_MAX_BUFFERS_v11 16 #define NVLOG_MAX_BUFFERS_v12 256 #define NVLOG_MAX_BUFFERS_v13 3840 #define NVLOG_MAX_BUFFERS NVLOG_MAX_BUFFERS_v13 #define NVLOG_LOGGER_VERSION 13 // v1.3 // Due to this file's peculiar location, NvPort may or may not be includable typedef struct PORT_SPINLOCK PORT_SPINLOCK; typedef struct PORT_MUTEX PORT_MUTEX; typedef struct PORT_RWLOCK PORT_RWLOCK; #if PORT_IS_KERNEL_BUILD #include "nvport/nvport.h" #endif /** * @brief Information about the entire NvLog system */ typedef struct _NVLOG_LOGGER { /** NvLog logger version */ NvU32 version; /** Logging buffers */ NVLOG_BUFFER * pBuffers[NVLOG_MAX_BUFFERS]; /** Index of the first unallocated buffer */ NvU32 nextFree; /** Total number of free buffer slots */ NvU32 totalFree; /** Lock for some buffer oprations */ PORT_SPINLOCK* mainLock; /** Lock for creating/deleting pBuffers and accessing them from RmCtrls */ PORT_MUTEX* buffersLock; /** Lock for registering/deregistering flush callbacks */ PORT_RWLOCK *flushCbsLock; } NVLOG_LOGGER; extern NVLOG_LOGGER NvLogLogger; /** * NvLog uses two locks: * - NVLOG_LOGGER::mainLock is used to protect some accesses to pBuffers, or * an individual pBuffers entry depending on locking flags. * - NVLOG_LOGGER::buffersLock is used to protect creating/deleting pBuffers and accessing them * from certain RmCtrl handlers. * * Historically in most contexts obtaining RMAPI lock would suffice, and mainLock would optionally * be used for certain buffers. Ioctl NV_ESC_RM_LOCKLESS_DIAGNOSTIC cannot touch RMAPI lock and needs * to access NvLog. The latter operation might race if called at an inopportune time: e.g. if the * ioctl is called during RM init when KGSP creates/deletes GSP NvLog buffers. Using buffersLock is * thus necessary to resolve the potential race. * * This leads to an unfortunate sequence where mainLock and buffersLock are nested. The latter lock * cannot be removed as it is used in IRQ paths. * * This should be refactored to use a single RWLock that does conditional acquire in possible IRQ * paths. */ // // Buffer flags // // Logging to this buffer is disabled #define NVLOG_BUFFER_FLAGS_DISABLED 0:0 #define NVLOG_BUFFER_FLAGS_DISABLED_NO 0 #define NVLOG_BUFFER_FLAGS_DISABLED_YES 1 #define NVLOG_BUFFER_FLAGS_TYPE 2:1 #define NVLOG_BUFFER_FLAGS_TYPE_RING 0 #define NVLOG_BUFFER_FLAGS_TYPE_NOWRAP 1 #define NVLOG_BUFFER_FLAGS_TYPE_SYSTEMLOG 2 // Expand buffer when full #define NVLOG_BUFFER_FLAGS_EXPANDABLE 3:3 #define NVLOG_BUFFER_FLAGS_EXPANDABLE_NO 0 #define NVLOG_BUFFER_FLAGS_EXPANDABLE_YES 1 // Allocate buffer in non paged memory #define NVLOG_BUFFER_FLAGS_NONPAGED 4:4 #define NVLOG_BUFFER_FLAGS_NONPAGED_NO 0 #define NVLOG_BUFFER_FLAGS_NONPAGED_YES 1 // // Type of buffer locking to use // NONE - No locking performed, for buffers that are inherently single threaded // STATE - Lock only during state change, do memory copying unlocked // Don't use with tiny buffers that overflow every write or two. // FULL - Keep everything locked for the full duration of the write // #define NVLOG_BUFFER_FLAGS_LOCKING 6:5 #define NVLOG_BUFFER_FLAGS_LOCKING_NONE 0 #define NVLOG_BUFFER_FLAGS_LOCKING_STATE 1 #define NVLOG_BUFFER_FLAGS_LOCKING_FULL 2 // Store this buffer in OCA minidumps #define NVLOG_BUFFER_FLAGS_OCA 7:7 #define NVLOG_BUFFER_FLAGS_OCA_NO 0 #define NVLOG_BUFFER_FLAGS_OCA_YES 1 // Buffer format (not included in registry key) #define NVLOG_BUFFER_FLAGS_FORMAT 10:8 #define NVLOG_BUFFER_FLAGS_FORMAT_PRINTF 0 #define NVLOG_BUFFER_FLAGS_FORMAT_LIBOS_LOG 1 #define NVLOG_BUFFER_FLAGS_FORMAT_MEMTRACK 2 // Never deallocate this buffer until RM is unloaded #define NVLOG_BUFFER_FLAGS_PRESERVE 11:11 #define NVLOG_BUFFER_FLAGS_PRESERVE_NO 0 #define NVLOG_BUFFER_FLAGS_PRESERVE_YES 1 // Buffer GPU index #define NVLOG_BUFFER_FLAGS_GPU_INSTANCE 31:24 typedef NvU32 NVLOG_BUFFER_HANDLE; // // Utility macros // #define NVLOG_IS_RING_BUFFER(pBuffer) \ FLD_TEST_DRF(LOG_BUFFER, _FLAGS, _TYPE, _RING, pBuffer->flags) #define NVLOG_IS_NOWRAP_BUFFER(pBuffer) \ FLD_TEST_DRF(LOG_BUFFER, _FLAGS, _TYPE, _NOWRAP, pBuffer->flags) #define NVLOG_PRINT_BUFFER_SIZE(pBuffer) ((pBuffer)->size) #define NVLOG_BUFFER_SIZE(pBuffer) \ (NV_OFFSETOF(NVLOG_BUFFER, data) + NVLOG_PRINT_BUFFER_SIZE(pBuffer)) /********************************/ /********* Filtering **********/ /********************************/ // TODO - Remove all this once tools are updated #define NVLOG_FILTER_INVALID (~0) #define NVLOG_FILTER_VALUE_SIMPLE_NO 0x0 #define NVLOG_FILTER_VALUE_SIMPLE_YES 0x1 #define NVLOG_FILTER_VALUE_EXPLICIT_NO 0x2 #define NVLOG_FILTER_VALUE_EXPLICIT_YES 0x3 #define NVLOG_FILTER_PRINT_LEVEL_REGTRACE 1:0 #define NVLOG_FILTER_PRINT_LEVEL_INFO 3:2 #define NVLOG_FILTER_PRINT_LEVEL_NOTICE 5:4 #define NVLOG_FILTER_PRINT_LEVEL_WARNINGS 7:6 #define NVLOG_FILTER_PRINT_LEVEL_ERRORS 9:8 #define NVLOG_FILTER_PRINT_LEVEL_HW_ERROR 11:10 #define NVLOG_FILTER_PRINT_LEVEL_FATAL 13:12 #define NVLOG_FILTER_PRINT_BUFFER 18:14 #define NVLOG_FILTER_REGTRACE_BUFFER 22:19 #define NVLOG_FILTER_REGTRACE_LOG_READ 25:23 #define NVLOG_FILTER_REGTRACE_LOG_WRITE 27:26 #define NVLOG_FILTER_REGTRACE_BREAK_READ 29:28 #define NVLOG_FILTER_REGTRACE_BREAK_WRITE 31:30 #define NVLOG_FILTER_VALUE_IS_NO(val) ((val & 0x1) == 0) #define NVLOG_FILTER_VALUE_IS_YES(val) (val & 0x1) #define NVLOG_FILTER_PRINT_GET_VALUE(level, num) ((num >> (level*2)) & 0x3) /** * @brief Type representing a value of a given 16bit range. */ typedef struct _NVLOG_RANGE_16 { NvU16 low; NvU16 high; NvU32 value; } NVLOG_RANGE_16; /** * @brief Type representing a value of a given 32bit range. */ typedef struct _NVLOG_RANGE_32 { NvU32 low; NvU32 high; NvU32 value; } NVLOG_RANGE_32; // // Maximum number of files that have a filter assigned to them. // #define NVLOG_MAX_FILES 1 // // Maximum number of line rules (both single line and range) allowed per file // #define NVLOG_FILELINE_FILTER_MAX_RANGES 1 /** * @brief Internal type for NVLOG_FILELINE_FILTER. * * Contains filtering info for a single file. */ typedef struct _NVLOG_FILELINE_FILTER_FILEHASH { /** ID of the file (24bit MD5) */ NvU32 fileId; /** Number of elements in the array 'ranges' */ NvU32 numElems; /** Value to use if the given value isn't found in the range array */ NvU32 defaultValue; /** Array of ranges representing lines in the file */ NVLOG_RANGE_16 ranges[NVLOG_FILELINE_FILTER_MAX_RANGES]; } NVLOG_FILELINE_FILTER_FILEHASH; /** * @brief Filter that contains rules that depend on the file and line number. */ typedef struct _NVLOG_FILELINE_FILTER { /** Number of elements in the fileHash array */ NvU32 numFiles; /** Value to use if a given file isn't found */ NvU32 defaultValue; /** Array of file entries, ordered as a hash table */ NVLOG_FILELINE_FILTER_FILEHASH fileHash[NVLOG_MAX_FILES]; } NVLOG_FILELINE_FILTER; /********************************/ /********* Print Logger *********/ /********************************/ #define NVLOG_PRINT_LOGGER_VERSION 11 // v1.1 // Max buffers cannot be over 32. #define NVLOG_PRINT_MAX_BUFFERS 8 #define NVLOG_PRINT_BUFFER_PRIMARY 1 #define NVLOG_PRINT_BUFFER_SECONDARY 2 #define NVLOG_PRINT_BUFFER_SYSTEMLOG 3 #define NVLOG_PRINT_DESC1_FILEID 23:0 #define NVLOG_PRINT_DESC1_GPUID 28:24 // 2^5 = 32 possible #define NVLOG_PRINT_DESC1_MAGIC 31:29 #define NVLOG_PRINT_DESC1_MAGIC_VALUE 5 #define NVLOG_PRINT_DESC2_LINEID 15:0 #define NVLOG_PRINT_DESC2_GROUPID 17:16 #define NVLOG_PRINT_DESC2_GROUPID_RM 0 #define NVLOG_PRINT_DESC2_GROUPID_PMU 1 #define NVLOG_PRINT_DESC2_OPT_DATA_COUNT 24:18 // number of dwords #define NVLOG_PRINT_DESC2_OPT_DATA_COUNT_MAX 0x7F #define NVLOG_PRINT_DESC2_RESERVED 28:25 #define NVLOG_PRINT_DESC2_MAGIC 31:29 #define NVLOG_PRINT_DESC2_MAGIC_VALUE 6 #define NVLOG_UNKNOWN_GPU_INSTANCE 0x1f #define NVLOG_PRINT_MODULE_FILTER_VALUE 1:0 #define NVLOG_PRINT_MODULE_FILTER_BUFFER 6:2 #define NVLOG_PRINT_MODULE_FILTER_ENABLED 7:7 // // Regkey fields - These are copied directly from nvRmReg.h // A copy is necessary as these might be needed on systems that don't // have nvRmReg.h, such as DVS builds for NvWatch // #ifndef NV_REG_STR_RM_NVLOG #define NV_REG_STR_RM_NVLOG "RMNvLog" #define NV_REG_STR_RM_NVLOG_BUFFER_FLAGS 7:0 #define NV_REG_STR_RM_NVLOG_BUFFER_SIZE 23:8 #define NV_REG_STR_RM_NVLOG_BUFFER_SIZE_DEFAULT ((NVOS_IS_WINDOWS||NVOS_IS_MACINTOSH)?8:250) #define NV_REG_STR_RM_NVLOG_BUFFER_SIZE_DISABLE 0 #define NV_REG_STR_RM_NVLOG_RUNTIME_LEVEL 28:25 #define NV_REG_STR_RM_NVLOG_TIMESTAMP 30:29 #define NV_REG_STR_RM_NVLOG_TIMESTAMP_NONE 0 #define NV_REG_STR_RM_NVLOG_TIMESTAMP_32 1 #define NV_REG_STR_RM_NVLOG_TIMESTAMP_64 2 #define NV_REG_STR_RM_NVLOG_TIMESTAMP_32_DIFF 3 #define NV_REG_STR_RM_NVLOG_INITED 31:31 #define NV_REG_STR_RM_NVLOG_INITED_NO 0 #define NV_REG_STR_RM_NVLOG_INITED_YES 1 #endif // NV_REG_STR_RM_NVLOG // // Arg types: // 0: Special meaning. End of argument list. // 1: d, u, x, X, i, o - Integer type // 2: lld, llu, llx, llX, lli, llo - Long long integer type // 3: s - string type (size is 0) // 4: p - pointer type // 5: c - char type // 6: f, g, e, F, G, E - floating point type // 7-14: Unused at the moment, default value is 0 // 15: Special meaning. Error value - unsupported type. // #define NVLOG_PRINT_MAX_ARG_TYPES 0x10 #define NVLOG_PRINT_ARG_TYPE_ARGLIST_END 0x0 #define NVLOG_PRINT_ARG_TYPE_INT 0x1 #define NVLOG_PRINT_ARG_TYPE_LONGLONG 0x2 #define NVLOG_PRINT_ARG_TYPE_STRING 0x3 #define NVLOG_PRINT_ARG_TYPE_POINTER 0x4 #define NVLOG_PRINT_ARG_TYPE_CHAR 0x5 #define NVLOG_PRINT_ARG_TYPE_FLOAT 0x6 #define NVLOG_PRINT_ARG_TYPE_ERROR 0xf /** * @brief Signature of the database required to decode the print logs * * The sig1-sig3 values are generated randomly at compile time. */ typedef struct _NVLOG_DB_SIGNATURE { NvU32 timestamp; NvU32 sig1; NvU32 sig2; NvU32 sig3; } NVLOG_DB_SIGNATURE; /** * @brief Filter that contains all rules used to filter DBG_PRINTF calls */ typedef struct _NVLOG_PRINT_FILTER { /** Same file:line filter is shared with the Regtrace system */ NVLOG_FILELINE_FILTER *pFileLineFilter; /** Filter based on debug levels. Uses NVLOG_FILTER_PRINT_LEVEL_* DRF's */ NvU32 runtimePrintLevelFilter; /** Filter based on debug modules. Uses NVLOG_PRINT_MODULE_FILTER_* DRF's */ NvU8 runtimePrintModuleFilter[NVLOG_MAX_DBG_MODULES]; } NVLOG_PRINT_FILTER; /** * @brief Enum representing all possible argument types to DBG_PRINTF */ typedef enum _NVLOG_ARGTYPE { NVLOG_ARGTYPE_NONE, NVLOG_ARGTYPE_INT, NVLOG_ARGTYPE_LONG_LONG_INT, NVLOG_ARGTYPE_STRING, NVLOG_ARGTYPE_POINTER, NVLOG_ARGTYPE_FLOAT, NVLOG_ARGTYPE__COUNT } NVLOG_ARGTYPE; // Default flags for NvLog registry, used for single-buffer option or the read fails #ifndef NVLOG_DEFAULT_FLAGS #define NVLOG_DEFAULT_FLAGS \ ( \ DRF_NUM(_REG_STR_RM, _NVLOG, _BUFFER_FLAGS, \ ( \ DRF_DEF(LOG, _BUFFER_FLAGS, _DISABLED, _NO) | \ DRF_DEF(LOG, _BUFFER_FLAGS, _TYPE, _RING) | \ DRF_DEF(LOG, _BUFFER_FLAGS, _EXPANDABLE, _NO) | \ DRF_DEF(LOG, _BUFFER_FLAGS, _NONPAGED, _YES) | \ DRF_DEF(LOG, _BUFFER_FLAGS, _LOCKING, _STATE) | \ DRF_DEF(LOG, _BUFFER_FLAGS, _OCA, _YES) \ )) | \ DRF_DEF(_REG_STR_RM, _NVLOG, _BUFFER_SIZE, _DEFAULT) | \ DRF_NUM(_REG_STR_RM, _NVLOG, _RUNTIME_LEVEL, 0) | \ DRF_DEF(_REG_STR_RM, _NVLOG, _TIMESTAMP, _64) | \ DRF_DEF(_REG_STR_RM, _NVLOG, _INITED, _YES) \ ) #endif // NVLOG_DEFAULT_FLAGS /** * @brief General info about the NvLog Print system */ typedef struct _NVLOG_PRINT_LOGGER { /** NvLog print logger version */ NvU32 version; /** Runtime argument sizes (16 different arglist values) */ NvU8 runtimeSizes[NVLOG_PRINT_MAX_ARG_TYPES]; /** Database signature for decoding */ NVLOG_DB_SIGNATURE signature; /** Filter buffer for print statements */ NVLOG_PRINT_FILTER filter; /** Flags for all NvLog print buffers */ NvU32 flags; /** Buffer indices for all nvlog buffers. buffers[1] is default. */ NvU32 buffers[NVLOG_PRINT_MAX_BUFFERS]; /** Initialized flag, set to true after nvlogPrintInit has executed */ NvBool initialized; /** Paused flag, set to true after nvlogPrintInit has executed */ NvBool paused; } NVLOG_PRINT_LOGGER; extern NVLOG_PRINT_LOGGER NvLogPrintLogger; #define NVLOG_PRINT_BUFFER_TAG(_i) NvU32_BUILD('t','r','p','0' + (_i)) /********************************/ /********** Regtrace **********/ /********************************/ #define NVLOG_REGTRACE_LOGGER_VERSION 10 // v1.0 #define NVLOG_REGTRACE_MAX_BUFFERS 4 #define NVLOG_REGTRACE_READ 0 #define NVLOG_REGTRACE_WRITE 1 #define NVLOG_REGTRACE_DESC1_FILEID NVLOG_PRINT_DESC1_FILEID #define NVLOG_REGTRACE_DESC1_GPUID NVLOG_PRINT_DESC1_GPUID #define NVLOG_REGTRACE_DESC1_MAGIC NVLOG_PRINT_DESC1_MAGIC #define NVLOG_REGTRACE_DESC1_MAGIC_VALUE (NVLOG_PRINT_DESC1_MAGIC_VALUE-1) #define NVLOG_REGTRACE_DESC2_LINEID 15:0 #define NVLOG_REGTRACE_DESC2_READWRITE 16:16 #define NVLOG_REGTRACE_DESC2_READWRITE_READ NVLOG_REGTRACE_READ #define NVLOG_REGTRACE_DESC2_READWRITE_WRITE NVLOG_REGTRACE_WRITE #define NVLOG_REGTRACE_DESC2_REGSIZE 18:17 #define NVLOG_REGTRACE_DESC2_REGSIZE_8 0 #define NVLOG_REGTRACE_DESC2_REGSIZE_16 1 #define NVLOG_REGTRACE_DESC2_REGSIZE_32 2 #define NVLOG_REGTRACE_DESC2_REGSIZE_64 3 #define NVLOG_REGTRACE_DESC2_THREADID 28:19 #define NVLOG_REGTRACE_DESC2_MAGIC 31:29 #define NVLOG_REGTRACE_DESC2_MAGIC_VALUE 3 /** * @brief Single entry in an NvLog Regtrace buffer. */ typedef struct _NVLOG_REGTRACE_RECORD { /** Uses NVLOG_REGTRACE_DESC1_* DRF's */ NvU32 desc1; /** Uses NVLOG_REGTRACE_DESC1_* DRF's */ NvU32 desc2; /** Address of the register being accessed */ NvU32 address; /** Value that was read/written */ NvU32 value; } NVLOG_REGTRACE_RECORD; #define NVLOG_REGTRACE_FILTER_MAX_RANGES 256 // Regtrace shares the file:line filter with print /** * @brief Filter that contains all rules used to filter register access logging */ typedef struct _NVLOG_REGTRACE_FILTER { /** Number of elements in the 'ranges' array */ NvU32 numRanges; /** File:line based filter. Shared with NvLog print system */ NVLOG_FILELINE_FILTER *pFileLineFilter; /** Range array for filtering based on register addresses */ NVLOG_RANGE_32 ranges[NVLOG_REGTRACE_FILTER_MAX_RANGES]; } NVLOG_REGTRACE_FILTER; /** * @brief General info about the NvLog Regtrace system */ typedef struct _NVLOG_REGTRACE_LOGGER { /** NvLog regtrace logger version */ NvU32 version; /** Filter buffer for regtrace statements */ NVLOG_REGTRACE_FILTER filter; /** Buffer indices for all NvLog buffers. First element is default buffer */ NvU32 buffers[NVLOG_REGTRACE_MAX_BUFFERS]; } NVLOG_REGTRACE_LOGGER; #endif // _NVLOG_DEFS_H_