1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 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 25 #include "kernel/gpu/video/kernel_video_engine.h" 26 #include "kernel/gpu/mem_mgr/mem_desc.h" 27 #include "kernel/gpu/bus/kern_bus.h" 28 #include "kernel/os/os.h" 29 #include "nvrm_registry.h" 30 31 NV_STATUS kvidengConstruct_IMPL 32 ( 33 KernelVideoEngine *pKernelVideoEngine, 34 OBJGPU *pGpu, 35 ENGDESCRIPTOR physEngDesc 36 ) 37 { 38 pKernelVideoEngine->physEngDesc = physEngDesc; 39 return NV_OK; 40 } 41 42 NV_STATUS kvidengInitLogging_IMPL 43 ( 44 OBJGPU *pGpu, 45 KernelVideoEngine *pKernelVideoEngine 46 ) 47 { 48 NV_STATUS status; 49 NvU32 data = NV_REG_STR_RM_VIDEO_EVENT_TRACE_DISABLED; 50 NvBool alwaysLogging; 51 52 if (!gpuIsVideoTraceLogSupported(pGpu)) 53 return NV_OK; 54 55 NV_ASSERT_OR_RETURN(pKernelVideoEngine != NULL, NV_ERR_INVALID_STATE); 56 57 status = osReadRegistryDword(pGpu, NV_REG_STR_RM_VIDEO_EVENT_TRACE, &data); 58 if (status != NV_OK) 59 { 60 // When GLOBAL_FEATURE_GR2069_VIDEO_EVENT is enabled and the registry is not set, 61 // default eventbuffer size to 32K and staging buffer to 4K. 62 data = DRF_NUM(_REG_STR, _RM_VIDEO_EVENT_TRACE, _STAGING_BUFFER_SIZE_IN_4k, 1) | 63 DRF_NUM(_REG_STR, _RM_VIDEO_EVENT_TRACE, _EVENT_BUFFER_SIZE_IN_4k, 0x8); 64 } 65 66 alwaysLogging = DRF_VAL(_REG_STR, _RM_VIDEO_EVENT_TRACE, _ALWAYS_LOG, (data)) == 67 NV_REG_STR_RM_VIDEO_EVENT_TRACE_ALWAYS_LOG_ENABLED; 68 69 if (data != NV_REG_STR_RM_VIDEO_EVENT_TRACE_DISABLED) 70 { 71 NvU32 eventBufferSize; 72 VIDEO_TRACE_RING_BUFFER *pTraceBuf; 73 NvU64 seed; 74 NvBool bIsFbBroken = NV_FALSE; 75 NV_ADDRESS_SPACE videoBufferAddressSpace = ADDR_FBMEM; 76 77 eventBufferSize = DRF_VAL(_REG_STR, _RM_VIDEO_EVENT_TRACE, _EVENT_BUFFER_SIZE_IN_4k, (data)) * 0x1000; 78 79 bIsFbBroken = pGpu->getProperty(pGpu, PDB_PROP_GPU_BROKEN_FB) || 80 pGpu->getProperty(pGpu, PDB_PROP_GPU_IS_ALL_INST_IN_SYSMEM); 81 82 if (bIsFbBroken) 83 videoBufferAddressSpace = ADDR_SYSMEM; 84 85 // Allocate the staging buffer 86 NV_ASSERT_OK_OR_GOTO( 87 status, 88 memdescCreate(&pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc, 89 pGpu, 90 eventBufferSize, 91 0, 92 NV_TRUE, 93 videoBufferAddressSpace, 94 NV_MEMORY_UNCACHED, 95 MEMDESC_FLAGS_NONE), 96 exit); 97 98 NV_ASSERT_OK_OR_GOTO( 99 status, 100 memdescAlloc(pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc), 101 exit); 102 103 pTraceBuf = (VIDEO_TRACE_RING_BUFFER *)kbusMapRmAperture_HAL(pGpu, pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc); 104 105 NV_ASSERT_OR_ELSE(pTraceBuf != NULL, 106 status = NV_ERR_INSUFFICIENT_RESOURCES; 107 goto exit;); 108 109 // clear trace buffer 110 portMemSet(pTraceBuf, 0, eventBufferSize); 111 112 pTraceBuf->bufferSize = eventBufferSize - sizeof(VIDEO_TRACE_RING_BUFFER); 113 pTraceBuf->readPtr = 0; 114 pTraceBuf->writePtr = 0; 115 pTraceBuf->flags = alwaysLogging ? VIDEO_TRACE_FLAG__LOGGING_ENABLED : 0; 116 117 pKernelVideoEngine->videoTraceInfo.pTraceBufferEngine = pTraceBuf; 118 119 // Allocate allocate scratch pad for variable data 120 pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData = portMemAllocNonPaged(RM_VIDEO_TRACE_MAX_VARIABLE_DATA_SIZE); 121 122 if (pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData == NULL) 123 { 124 status = NV_ERR_NO_MEMORY; 125 goto exit; 126 } 127 portMemSet(pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData, 0x00, RM_VIDEO_TRACE_MAX_VARIABLE_DATA_SIZE); 128 129 /*! 130 * Random number generator used for generate noisy timestamp 131 */ 132 osGetCurrentTick(&seed); 133 pKernelVideoEngine->videoTraceInfo.pVideoLogPrng = portCryptoPseudoRandomGeneratorCreate(seed); 134 } 135 136 exit: 137 if (status != NV_OK) 138 { 139 kvidengFreeLogging(pGpu, pKernelVideoEngine); 140 141 if (status == NV_WARN_NOTHING_TO_DO) 142 status = NV_OK; 143 } 144 else 145 { 146 pKernelVideoEngine->bVideoTraceEnabled = NV_TRUE; 147 } 148 149 return status; 150 } 151 152 void kvidengFreeLogging_IMPL 153 ( 154 OBJGPU *pGpu, 155 KernelVideoEngine *pKernelVideoEngine 156 ) 157 { 158 if (pKernelVideoEngine->videoTraceInfo.pTraceBufferEngine != NULL) 159 { 160 kbusUnmapRmAperture_HAL(pGpu, pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc, 161 &(pKernelVideoEngine->videoTraceInfo.pTraceBufferEngine), 162 NV_TRUE); 163 pKernelVideoEngine->videoTraceInfo.pTraceBufferEngine = NULL; 164 } 165 166 if (pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc != NULL) 167 { 168 memdescFree(pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc); 169 memdescDestroy(pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc); 170 pKernelVideoEngine->videoTraceInfo.pTraceBufferEngineMemDesc = NULL; 171 } 172 173 portMemFree(pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData); 174 pKernelVideoEngine->videoTraceInfo.pTraceBufferVariableData = NULL; 175 176 /*! 177 * Free random number generator used for generate noisy timestamp 178 */ 179 portCryptoPseudoRandomGeneratorDestroy(pKernelVideoEngine->videoTraceInfo.pVideoLogPrng); 180 pKernelVideoEngine->videoTraceInfo.pVideoLogPrng = NULL; 181 182 pKernelVideoEngine->bVideoTraceEnabled = NV_FALSE; 183 } 184