1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2020-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 #define NVOC_KERNEL_GRAPHICS_H_PRIVATE_ACCESS_ALLOWED
25
26
27 #include "rmconfig.h"
28
29 #include "kernel/gpu/gr/kernel_graphics_manager.h"
30 #include "kernel/gpu/gr/kernel_graphics.h"
31 #include "kernel/gpu/mig_mgr/kernel_mig_manager.h"
32 #include "kernel/gpu/device/device.h"
33 #include "kernel/gpu/subdevice/subdevice.h"
34 #include "kernel/rmapi/rmapi_utils.h"
35 #include "kernel/core/locks.h"
36 #include "kernel/gpu/mem_sys/kern_mem_sys.h"
37 #include "kernel/mem_mgr/gpu_vaspace.h"
38 #include "virtualization/hypervisor/hypervisor.h"
39 #include "nvRmReg.h"
40 #include "kernel/gpu/mem_mgr/mem_mgr.h"
41 #include "kernel/gpu/mem_mgr/heap.h"
42 #include "kernel/gpu/intr/engine_idx.h"
43 #include "gpu/mem_mgr/virt_mem_allocator.h"
44 #include "gpu/mmu/kern_gmmu.h"
45 #include "platform/sli/sli.h"
46 #include "rmapi/rs_utils.h"
47 #include "rmapi/client.h"
48
49 #include "vgpu/vgpu_events.h"
50 #include "vgpu/rpc.h"
51
52 #include "class/clb0c0.h"
53 #include "class/clb1c0.h"
54 #include "class/clc0c0.h"
55 #include "class/clc1c0.h"
56 #include "class/clc3c0.h"
57 #include "class/clc5c0.h"
58 #include "class/clc6c0.h"
59 #include "class/clc7c0.h"
60 #include "class/clcbc0.h"
61
62 #include "class/cl0080.h"
63 #include "class/cl2080.h"
64 #include "class/cla06f.h"
65 #include "class/cla06fsubch.h"
66 #include "class/cl90f1.h" // FERMI_VASPACE_A
67 #include "class/cl003e.h" // NV01_MEMORY_SYSTEM
68 #include "class/cl50a0.h" // NV50_MEMORY_VIRTUAL
69 #include "class/cl0040.h" // NV01_MEMORY_LOCAL_USER
70 #include "class/clc36f.h" // VOLTA_CHANNEL_GPFIFO_A
71 #include "class/clc46f.h" // TURING_CHANNEL_GPFIFO_A
72 #include "class/clc56f.h" // AMPERE_CHANNEL_GPFIFO_A
73 #include "class/clc86f.h" // HOPPER_CHANNEL_GPFIFO_A
74 #include "class/clc637.h"
75 #include "class/clc638.h"
76
77 //
78 // We use NV2080_CTRL_INTERNAL_GR_MAX_GPC to statically allocate certain
79 // GPC related array in ctrl call header file. We will need to adjust
80 // NV2080_CTRL_INTERNAL_GR_MAX_GPC if some day KGRMGR_MAX_GPC gets changed
81 //
82 ct_assert(NV2080_CTRL_INTERNAL_GR_MAX_GPC == KGRMGR_MAX_GPC);
83
84 //
85 // Ensure the external and internal ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT
86 // will always in sync
87 //
88 ct_assert(NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT ==
89 NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT);
90
91 typedef struct KGRAPHICS_PRIVATE_DATA
92 {
93 NvBool bInitialized;
94 KGRAPHICS_STATIC_INFO staticInfo;
95 } KGRAPHICS_PRIVATE_DATA;
96 static NV_STATUS _kgraphicsMapGlobalCtxBuffer(OBJGPU *pGpu, KernelGraphics *pKernelGraphics, NvU32 gfid, OBJVASPACE *,
97 KernelGraphicsContext *, GR_GLOBALCTX_BUFFER, NvBool bIsReadOnly);
98 static NV_STATUS _kgraphicsPostSchedulingEnableHandler(OBJGPU *, void *);
99
100 static void
_kgraphicsInitRegistryOverrides(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)101 _kgraphicsInitRegistryOverrides(OBJGPU *pGpu, KernelGraphics *pKernelGraphics)
102 {
103 {
104 NvU32 data;
105
106 if (osReadRegistryDword(pGpu, NV_REG_STR_RM_FORCE_GR_SCRUBBER_CHANNEL, &data) == NV_OK)
107 {
108 if (data == NV_REG_STR_RM_FORCE_GR_SCRUBBER_CHANNEL_DISABLE)
109 {
110 kgraphicsSetBug4208224WAREnabled(pGpu, pKernelGraphics, NV_FALSE);
111 }
112 else if (data == NV_REG_STR_RM_FORCE_GR_SCRUBBER_CHANNEL_ENABLE)
113 {
114 kgraphicsSetBug4208224WAREnabled(pGpu, pKernelGraphics, NV_TRUE);
115 }
116 }
117 }
118 return;
119 }
120
121 NV_STATUS
kgraphicsConstructEngine_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,ENGDESCRIPTOR engDesc)122 kgraphicsConstructEngine_IMPL
123 (
124 OBJGPU *pGpu,
125 KernelGraphics *pKernelGraphics,
126 ENGDESCRIPTOR engDesc
127 )
128 {
129 KGRAPHICS_PRIVATE_DATA *pPrivate;
130 NvU32 idx;
131 GR_GLOBALCTX_BUFFER buf;
132 GR_CTX_BUFFER localBuf;
133
134 pKernelGraphics->instance = ENGDESC_FIELD(engDesc, _INST);
135
136 pPrivate = portMemAllocNonPaged(sizeof(*pPrivate));
137 if (pPrivate == NULL)
138 return NV_ERR_NO_MEMORY;
139 portMemSet(pPrivate, 0, sizeof(*pPrivate));
140 pKernelGraphics->pPrivate = pPrivate;
141
142 // All local ctx buffers default to uncached FB preferred
143 FOR_EACH_IN_ENUM(GR_CTX_BUFFER, localBuf)
144 {
145 pKernelGraphics->ctxAttr[localBuf].pAllocList = ADDRLIST_FBMEM_PREFERRED;
146 pKernelGraphics->ctxAttr[localBuf].cpuAttr = NV_MEMORY_UNCACHED;
147 }
148 FOR_EACH_IN_ENUM_END;
149
150 // Process instloc overrides
151 {
152 struct
153 {
154 GR_CTX_BUFFER buf;
155 NvU32 override;
156 } instlocOverrides[] =
157 {
158 { GR_CTX_BUFFER_MAIN, DRF_VAL(_REG_STR_RM, _INST_LOC, _GRCTX, pGpu->instLocOverrides) },
159 { GR_CTX_BUFFER_PATCH, DRF_VAL(_REG_STR_RM, _INST_LOC_2, _CTX_PATCH, pGpu->instLocOverrides2) },
160 { GR_CTX_BUFFER_ZCULL, DRF_VAL(_REG_STR_RM, _INST_LOC_2, _ZCULLCTX, pGpu->instLocOverrides2) },
161 { GR_CTX_BUFFER_PM, DRF_VAL(_REG_STR_RM, _INST_LOC_2, _PMCTX, pGpu->instLocOverrides2) },
162 { GR_CTX_BUFFER_PREEMPT, DRF_VAL(_REG_STR_RM, _INST_LOC_3, _PREEMPT_BUFFER, pGpu->instLocOverrides3) },
163 { GR_CTX_BUFFER_BETA_CB, DRF_VAL(_REG_STR_RM, _INST_LOC_3, _GFXP_BETACB_BUFFER, pGpu->instLocOverrides3) },
164 { GR_CTX_BUFFER_PAGEPOOL, DRF_VAL(_REG_STR_RM, _INST_LOC_3, _GFXP_PAGEPOOL_BUFFER, pGpu->instLocOverrides3) },
165 { GR_CTX_BUFFER_SPILL, DRF_VAL(_REG_STR_RM, _INST_LOC_3, _GFXP_SPILL_BUFFER, pGpu->instLocOverrides3) },
166 { GR_CTX_BUFFER_RTV_CB, DRF_VAL(_REG_STR_RM, _INST_LOC_3, _GFXP_RTVCB_BUFFER, pGpu->instLocOverrides3) },
167 { GR_CTX_BUFFER_SETUP, DRF_VAL(_REG_STR_RM, _INST_LOC_4, _GFXP_SETUP_BUFFER, pGpu->instLocOverrides4) }
168 };
169
170 for (idx = 0; idx < NV_ARRAY_ELEMENTS(instlocOverrides); ++idx)
171 {
172 memdescOverrideInstLocList(instlocOverrides[idx].override,
173 NV_ENUM_TO_STRING(GR_CTX_BUFFER, instlocOverrides[idx].buf),
174 &pKernelGraphics->ctxAttr[instlocOverrides[idx].buf].pAllocList,
175 &pKernelGraphics->ctxAttr[instlocOverrides[idx].buf].cpuAttr);
176 }
177 }
178
179 // Most global ctx buffers default to uncached FB preferred
180 FOR_EACH_IN_ENUM(GR_GLOBALCTX_BUFFER, buf)
181 {
182 pKernelGraphics->globalCtxBuffersInfo.globalCtxAttr[buf].pAllocList = ADDRLIST_FBMEM_PREFERRED;
183 pKernelGraphics->globalCtxBuffersInfo.globalCtxAttr[buf].cpuAttr = NV_MEMORY_UNCACHED;
184 }
185 FOR_EACH_IN_ENUM_END;
186
187 // FECS event buffer defaults to cached SYSMEM
188 pKernelGraphics->globalCtxBuffersInfo.globalCtxAttr[GR_GLOBALCTX_BUFFER_FECS_EVENT].pAllocList = ADDRLIST_SYSMEM_ONLY;
189 pKernelGraphics->globalCtxBuffersInfo.globalCtxAttr[GR_GLOBALCTX_BUFFER_FECS_EVENT].cpuAttr = NV_MEMORY_CACHED;
190
191 // Process instloc overrides
192 {
193 struct
194 {
195 GR_GLOBALCTX_BUFFER buf;
196 NvU32 override;
197 } instlocOverrides[] =
198 {
199 { GR_GLOBALCTX_BUFFER_FECS_EVENT, DRF_VAL(_REG_STR_RM, _INST_LOC_4, _FECS_EVENT_BUF, pGpu->instLocOverrides4) },
200 { GR_GLOBALCTX_BUFFER_ATTRIBUTE_CB, DRF_VAL(_REG_STR_RM, _INST_LOC_2, _ATTR_CB, pGpu->instLocOverrides2) },
201 { GR_GLOBALCTX_BUFFER_BUNDLE_CB, DRF_VAL(_REG_STR_RM, _INST_LOC_2, _BUNDLE_CB, pGpu->instLocOverrides2) },
202 { GR_GLOBALCTX_BUFFER_PAGEPOOL, DRF_VAL(_REG_STR_RM, _INST_LOC_2, _PAGEPOOL, pGpu->instLocOverrides2) },
203 { GR_GLOBALCTX_BUFFER_PRIV_ACCESS_MAP, DRF_VAL(_REG_STR_RM, _INST_LOC_3, _PRIV_ACCESS_MAP, pGpu->instLocOverrides3) },
204 { GR_GLOBALCTX_BUFFER_UNRESTRICTED_PRIV_ACCESS_MAP, DRF_VAL(_REG_STR_RM, _INST_LOC_3, _PRIV_ACCESS_MAP, pGpu->instLocOverrides3) },
205 { GR_GLOBAL_BUFFER_GLOBAL_PRIV_ACCESS_MAP, DRF_VAL(_REG_STR_RM, _INST_LOC_3, _PRIV_ACCESS_MAP, pGpu->instLocOverrides3) },
206 { GR_GLOBALCTX_BUFFER_RTV_CB, DRF_VAL(_REG_STR_RM, _INST_LOC_3, _RTVCB_BUFFER, pGpu->instLocOverrides3) }
207 };
208
209 for (idx = 0; idx < NV_ARRAY_ELEMENTS(instlocOverrides); ++idx)
210 {
211 memdescOverrideInstLocList(instlocOverrides[idx].override,
212 NV_ENUM_TO_STRING(GR_GLOBALCTX_BUFFER, instlocOverrides[idx].buf),
213 &pKernelGraphics->globalCtxBuffersInfo.globalCtxAttr[instlocOverrides[idx].buf].pAllocList,
214 &pKernelGraphics->globalCtxBuffersInfo.globalCtxAttr[instlocOverrides[idx].buf].cpuAttr);
215 }
216 }
217
218 // Copy final global buffer attributes for local versions
219 FOR_EACH_IN_ENUM(GR_GLOBALCTX_BUFFER, buf)
220 {
221 // Host RM cannot allocate system memory on behalf of the VF RM, so force FB.
222 pKernelGraphics->globalCtxBuffersInfo.vfGlobalCtxAttr[buf].pAllocList = ADDRLIST_FBMEM_ONLY;
223 pKernelGraphics->globalCtxBuffersInfo.vfGlobalCtxAttr[buf].cpuAttr = NV_MEMORY_UNCACHED;
224
225 // Local context allocation
226 pKernelGraphics->globalCtxBuffersInfo.localCtxAttr[buf] = pKernelGraphics->globalCtxBuffersInfo.globalCtxAttr[buf];
227 }
228 FOR_EACH_IN_ENUM_END;
229
230 //
231 // Default context buffers to non size aligned. The attribute buffer is
232 // required to be mapped with an offset naturally aligned to the size.
233 //
234 for (idx = 0; idx < GR_GLOBALCTX_BUFFER_COUNT; idx++)
235 pKernelGraphics->globalCtxBuffersInfo.bSizeAligned[idx] = NV_FALSE;
236 pKernelGraphics->globalCtxBuffersInfo.bSizeAligned[GR_GLOBALCTX_BUFFER_ATTRIBUTE_CB] = NV_TRUE;
237
238 NV_ASSERT_OK_OR_RETURN(fecsCtxswLoggingInit(pGpu, pKernelGraphics, &pKernelGraphics->pFecsTraceInfo));
239
240 _kgraphicsInitRegistryOverrides(pGpu, pKernelGraphics);
241 return NV_OK;
242 }
243
244 void
kgraphicsDestruct_IMPL(KernelGraphics * pKernelGraphics)245 kgraphicsDestruct_IMPL
246 (
247 KernelGraphics *pKernelGraphics
248 )
249 {
250 OBJGPU *pGpu = ENG_GET_GPU(pKernelGraphics);
251
252 fecsCtxswLoggingTeardown(pGpu, pKernelGraphics);
253 pKernelGraphics->pFecsTraceInfo = NULL;
254 kgraphicsInvalidateStaticInfo(pGpu, pKernelGraphics);
255
256 portMemFree(pKernelGraphics->pPrivate);
257 pKernelGraphics->pPrivate = NULL;
258 }
259
260 NV_STATUS
kgraphicsStateInitLocked_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)261 kgraphicsStateInitLocked_IMPL
262 (
263 OBJGPU *pGpu,
264 KernelGraphics *pKernelGraphics
265 )
266 {
267 NvU32 nGlobalCtx = 1;
268 NvU32 numClasses;
269
270 NV_ASSERT_OK_OR_RETURN(gpuGetClassList(pGpu, &numClasses, NULL, ENG_GR(pKernelGraphics->instance)));
271
272 //
273 // Number of supported class can be zero when Graphics engine is disabled, but we still
274 // need those classes in ClassDB for KernelGraphics engine operation, thus here we are adding
275 // the ENG_GR(X) supported classes back to ClassDB
276 //
277 if (numClasses == 0)
278 {
279 PGPU_ENGINE_ORDER pEngineOrder = &pGpu->engineOrder;
280 const CLASSDESCRIPTOR *pClassDesc = &pEngineOrder->pClassDescriptors[0];
281 NvU32 i;
282 NvU32 classNum;
283
284 for (i = 0; i < pEngineOrder->numClassDescriptors; i++)
285 {
286 classNum = pClassDesc[i].externalClassId;
287 if (classNum == (NvU32)~0)
288 continue;
289
290 if (ENG_GR(pKernelGraphics->instance) == pClassDesc[i].engDesc)
291 {
292 NV_PRINTF(LEVEL_INFO, "Adding class ID 0x%x to ClassDB\n", classNum);
293 NV_ASSERT_OK_OR_RETURN(
294 gpuAddClassToClassDBByEngTagClassId(pGpu, ENG_GR(pKernelGraphics->instance), classNum));
295 }
296 }
297 }
298
299 //
300 // Allocate guest context db array
301 //
302 if (gpuIsSriovEnabled(pGpu))
303 {
304 nGlobalCtx = VMMU_MAX_GFID;
305 }
306
307 pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers = portMemAllocNonPaged(sizeof(*pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers) * nGlobalCtx);
308 if (pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers == NULL)
309 {
310 return NV_ERR_NO_MEMORY;
311 }
312 portMemSet(pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers, 0,
313 sizeof(*pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers) * nGlobalCtx);
314
315 if (pKernelGraphics->instance == 0)
316 {
317 //
318 // GSP_CLIENT creates the golden context channel GR post load. However,
319 // if PMA scrubber is enabled, a scrubber channel must be constructed
320 // first as a part of Fifo post load. Hence, add the golden channel
321 // creation as a fifo post-scheduling-enablement callback.
322 //
323 NV_ASSERT_OK_OR_RETURN(
324 kfifoAddSchedulingHandler(pGpu, GPU_GET_KERNEL_FIFO(pGpu),
325 _kgraphicsPostSchedulingEnableHandler,
326 (void *)((NvUPtr)(pKernelGraphics->instance)),
327 NULL, NULL));
328 }
329
330 pKernelGraphics->bug4208224Info.hClient = NV01_NULL_OBJECT;
331 pKernelGraphics->bug4208224Info.hDeviceId = NV01_NULL_OBJECT;
332 pKernelGraphics->bug4208224Info.hSubdeviceId = NV01_NULL_OBJECT;
333 pKernelGraphics->bug4208224Info.bConstructed = NV_FALSE;
334 return NV_OK;
335 }
336
337 NV_STATUS
kgraphicsStateUnload_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU32 flags)338 kgraphicsStateUnload_IMPL
339 (
340 OBJGPU *pGpu,
341 KernelGraphics *pKernelGraphics,
342 NvU32 flags
343
344 )
345 {
346 if (pKernelGraphics->instance != 0)
347 return NV_OK;
348
349 kfifoRemoveSchedulingHandler(pGpu, GPU_GET_KERNEL_FIFO(pGpu),
350 _kgraphicsPostSchedulingEnableHandler,
351 (void *)((NvUPtr)(pKernelGraphics->instance)),
352 NULL, NULL);
353
354 return NV_OK;
355 }
356
357 NV_STATUS
kgraphicsStateLoad_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU32 flags)358 kgraphicsStateLoad_IMPL
359 (
360 OBJGPU *pGpu,
361 KernelGraphics *pKernelGraphics,
362 NvU32 flags
363 )
364 {
365 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
366
367 if (fecsGetCtxswLogConsumerCount(pGpu, pKernelGraphicsManager) > 0)
368 {
369 fecsBufferMap(pGpu, pKernelGraphics);
370 fecsBufferReset(pGpu, pKernelGraphics);
371 }
372
373 return NV_OK;
374 }
375
376 NV_STATUS
kgraphicsStatePreUnload_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU32 flags)377 kgraphicsStatePreUnload_IMPL
378 (
379 OBJGPU *pGpu,
380 KernelGraphics *pKernelGraphics,
381 NvU32 flags
382 )
383 {
384 if (pKernelGraphics->bug4208224Info.bConstructed)
385 {
386 RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
387 NV2080_CTRL_INTERNAL_KGR_INIT_BUG4208224_WAR_PARAMS params = {0};
388
389 params.bTeardown = NV_TRUE;
390 NV_ASSERT_OK(pRmApi->Control(pRmApi,
391 pKernelGraphics->bug4208224Info.hClient,
392 pKernelGraphics->bug4208224Info.hSubdeviceId,
393 NV2080_CTRL_CMD_INTERNAL_KGR_INIT_BUG4208224_WAR,
394 ¶ms,
395 sizeof(params)));
396 NV_ASSERT_OK(pRmApi->Free(pRmApi, pKernelGraphics->bug4208224Info.hClient, pKernelGraphics->bug4208224Info.hClient));
397 pKernelGraphics->bug4208224Info.bConstructed = NV_FALSE;
398 }
399
400 fecsBufferUnmap(pGpu, pKernelGraphics);
401
402 // Release global buffers used as part of the gr context, when not in S/R
403 if (!(flags & GPU_STATE_FLAGS_PRESERVING))
404 kgraphicsFreeGlobalCtxBuffers(pGpu, pKernelGraphics, GPU_GFID_PF);
405
406 return NV_OK;
407 }
408
409 void
kgraphicsStateDestroy_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)410 kgraphicsStateDestroy_IMPL
411 (
412 OBJGPU *pGpu,
413 KernelGraphics *pKernelGraphics
414 )
415 {
416 fecsBufferTeardown(pGpu, pKernelGraphics);
417
418 portMemFree(pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers);
419 pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers = NULL;
420 }
421
kgraphicsIsPresent_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)422 NvBool kgraphicsIsPresent_IMPL
423 (
424 OBJGPU *pGpu,
425 KernelGraphics *pKernelGraphics
426 )
427 {
428 KernelFifo *pKernelFifo = GPU_GET_KERNEL_FIFO(pGpu);
429 NvU32 unused;
430
431 if (IsDFPGA(pGpu))
432 return NV_FALSE;
433
434 if (IS_MODS_AMODEL(pGpu))
435 return NV_TRUE;
436
437 return kfifoEngineInfoXlate_HAL(pGpu, pKernelFifo,
438 ENGINE_INFO_TYPE_RM_ENGINE_TYPE, (NvU32)RM_ENGINE_TYPE_GR(pKernelGraphics->instance),
439 ENGINE_INFO_TYPE_INVALID, &unused) == NV_OK;
440 }
441
442 NV_STATUS
kgraphicsStatePostLoad_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU32 flags)443 kgraphicsStatePostLoad_IMPL
444 (
445 OBJGPU *pGpu,
446 KernelGraphics *pKernelGraphics,
447 NvU32 flags
448 )
449 {
450 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
451 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR, kgraphicsLoadStaticInfo(pGpu, pKernelGraphics, KMIGMGR_SWIZZID_INVALID));
452 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
453
454 if ((!IS_VIRTUAL(pGpu)) &&
455 (pKernelGraphicsStaticInfo != NULL) &&
456 (pKernelGraphicsStaticInfo->pContextBuffersInfo != NULL) &&
457 (kgraphicsGetGlobalCtxBuffers(pGpu, pKernelGraphics, GPU_GFID_PF)->memDesc[GR_GLOBALCTX_BUFFER_FECS_EVENT] == NULL))
458 {
459 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
460 kgraphicsAllocGlobalCtxBuffers_HAL(pGpu, pKernelGraphics, GPU_GFID_PF));
461 }
462
463 return NV_OK;
464 }
465
466 /*!
467 * @brief Create a golden image channel after Fifo post load
468 * Instead of lazily waiting until first client request, we proactively create a
469 * golden channel here.
470 */
471 static NV_STATUS
_kgraphicsPostSchedulingEnableHandler(OBJGPU * pGpu,void * pGrIndex)472 _kgraphicsPostSchedulingEnableHandler
473 (
474 OBJGPU *pGpu,
475 void *pGrIndex
476 )
477 {
478 MemoryManager *pMemoryManager = GPU_GET_MEMORY_MANAGER(pGpu);
479 KernelGraphics *pKernelGraphics = GPU_GET_KERNEL_GRAPHICS(pGpu, ((NvU32)(NvUPtr)pGrIndex));
480 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
481
482 // Nothing to do for non-GSPCLIENT
483 if (!IS_GSP_CLIENT(pGpu) && !kgraphicsIsBug4208224WARNeeded_HAL(pGpu, pKernelGraphics))
484 return NV_OK;
485
486 // Defer golden context channel creation to GPU instance configuration
487 if (IS_MIG_ENABLED(pGpu))
488 return NV_OK;
489
490 // Skip for MIG engines with 0 GPCs
491 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
492 if (pKernelGraphicsStaticInfo->floorsweepingMasks.gpcMask == 0x0)
493 return NV_OK;
494
495 if (memmgrIsPmaInitialized(pMemoryManager))
496 {
497 Heap *pHeap = GPU_GET_HEAP(pGpu);
498 NvU32 pmaConfig = PMA_QUERY_SCRUB_ENABLED | PMA_QUERY_SCRUB_VALID;
499
500 NV_ASSERT_OK_OR_RETURN(pmaQueryConfigs(&pHeap->pmaObject, &pmaConfig));
501
502 //
503 // Scrubber is also constructed from the same Fifo post scheduling
504 // enable callback queue. This check enforces the dependency that
505 // scrubber must be initialized first
506 //
507 if ((pmaConfig & PMA_QUERY_SCRUB_ENABLED) &&
508 !(pmaConfig & PMA_QUERY_SCRUB_VALID))
509 {
510 return NV_WARN_MORE_PROCESSING_REQUIRED;
511 }
512 }
513
514 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR, kgraphicsCreateGoldenImageChannel(pGpu, pKernelGraphics));
515 if (kgraphicsIsBug4208224WARNeeded_HAL(pGpu, pKernelGraphics))
516 {
517 return kgraphicsInitializeBug4208224WAR_HAL(pGpu, pKernelGraphics);
518 }
519
520 return NV_OK;
521 }
522
523 void
kgraphicsInvalidateStaticInfo_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)524 kgraphicsInvalidateStaticInfo_IMPL
525 (
526 OBJGPU *pGpu,
527 KernelGraphics *pKernelGraphics
528 )
529 {
530 portMemFree(pKernelGraphics->pPrivate->staticInfo.pGrInfo);
531 pKernelGraphics->pPrivate->staticInfo.pGrInfo = NULL;
532
533 portMemFree(pKernelGraphics->pPrivate->staticInfo.pPpcMasks);
534 pKernelGraphics->pPrivate->staticInfo.pPpcMasks = NULL;
535
536 portMemFree(pKernelGraphics->pPrivate->staticInfo.pZcullInfo);
537 pKernelGraphics->pPrivate->staticInfo.pZcullInfo = NULL;
538
539 portMemFree(pKernelGraphics->pPrivate->staticInfo.pRopInfo);
540 pKernelGraphics->pPrivate->staticInfo.pRopInfo = NULL;
541
542 portMemFree(pKernelGraphics->pPrivate->staticInfo.pContextBuffersInfo);
543 pKernelGraphics->pPrivate->staticInfo.pContextBuffersInfo = NULL;
544
545 portMemFree(pKernelGraphics->pPrivate->staticInfo.pSmIssueRateModifier);
546 pKernelGraphics->pPrivate->staticInfo.pSmIssueRateModifier = NULL;
547
548 portMemFree(pKernelGraphics->pPrivate->staticInfo.pFecsTraceDefines);
549 pKernelGraphics->pPrivate->staticInfo.pFecsTraceDefines = NULL;
550
551 portMemSet(&pKernelGraphics->pPrivate->staticInfo, 0, sizeof(pKernelGraphics->pPrivate->staticInfo));
552 pKernelGraphics->pPrivate->bInitialized = NV_FALSE;
553 }
554
555 const KGRAPHICS_STATIC_INFO *
kgraphicsGetStaticInfo_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)556 kgraphicsGetStaticInfo_IMPL
557 (
558 OBJGPU *pGpu,
559 KernelGraphics *pKernelGraphics
560 )
561 {
562 KGRAPHICS_PRIVATE_DATA *pPrivate = pKernelGraphics->pPrivate;
563 return ((pPrivate != NULL) && pPrivate->bInitialized) ? &pPrivate->staticInfo : NULL;
564 }
565
566 static NV_STATUS
_kgraphicsInternalClientAlloc(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU32 swizzId,NvHandle * phClient,NvHandle * phDevice,NvHandle * phSubdevice)567 _kgraphicsInternalClientAlloc
568 (
569 OBJGPU *pGpu,
570 KernelGraphics *pKernelGraphics,
571 NvU32 swizzId,
572 NvHandle *phClient,
573 NvHandle *phDevice,
574 NvHandle *phSubdevice
575 )
576 {
577 RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL); //FIXME = GPU_GET_PHYSICAL_RMAPI(pGpu);
578 NvU32 grIdx = pKernelGraphics->instance;
579
580 NV_ASSERT_OR_RETURN(phClient != NULL, NV_ERR_INVALID_ARGUMENT);
581 NV_ASSERT_OR_RETURN(phDevice != NULL, NV_ERR_INVALID_ARGUMENT);
582 NV_ASSERT_OR_RETURN(phSubdevice != NULL, NV_ERR_INVALID_ARGUMENT);
583
584 if (IS_MIG_IN_USE(pGpu))
585 {
586 NvHandle hSubscription;
587
588 // Delay initialization to GPU instance configuration
589 if (swizzId == KMIGMGR_SWIZZID_INVALID)
590 return NV_ERR_NOT_READY;
591
592 // With MIG enabled, we need to use a client subscribed to the correct GPU instance.
593 NV_ASSERT_OK_OR_RETURN(
594 rmapiutilAllocClientAndDeviceHandles(pRmApi, pGpu, phClient, phDevice, phSubdevice));
595
596 {
597 NVC637_ALLOCATION_PARAMETERS params;
598 NV_ASSERT_OK(
599 serverutilGenResourceHandle(*phClient, &hSubscription));
600 portMemSet(¶ms, 0, sizeof(params));
601 params.swizzId = swizzId;
602 NV_ASSERT_OK(
603 pRmApi->AllocWithHandle(pRmApi, *phClient, *phSubdevice, hSubscription, AMPERE_SMC_PARTITION_REF, ¶ms, sizeof(params)));
604 }
605
606 }
607 else if (grIdx != 0)
608 {
609 // Static data is only defined for GR0 in legacy mode
610 return NV_ERR_NOT_READY;
611 }
612 else
613 {
614 NV_ASSERT_OK_OR_RETURN(
615 rmapiutilAllocClientAndDeviceHandles(pRmApi, pGpu, phClient, phDevice, phSubdevice));
616 }
617
618 return NV_OK;
619 }
620
621 /*!
622 * @brief Initialize static data that isn't collected right away
623 */
624 NV_STATUS
kgraphicsInitializeDeferredStaticData_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvHandle hClient,NvHandle hSubdevice)625 kgraphicsInitializeDeferredStaticData_IMPL
626 (
627 OBJGPU *pGpu,
628 KernelGraphics *pKernelGraphics,
629 NvHandle hClient,
630 NvHandle hSubdevice
631 )
632 {
633 NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS *pParams;
634 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
635 KGRAPHICS_PRIVATE_DATA *pPrivate = pKernelGraphics->pPrivate;
636 RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
637 NvU32 grIdx = pKernelGraphics->instance;
638 NV_STATUS status = NV_OK;
639 NvBool bInternalClientAllocated = NV_FALSE;
640 NvU32 gfid;
641 NvBool bCallingContextPlugin;
642
643 NV_ASSERT_OK_OR_RETURN(vgpuGetCallingContextGfid(pGpu, &gfid));
644 NV_ASSERT_OK_OR_RETURN(vgpuIsCallingContextPlugin(pGpu, &bCallingContextPlugin));
645
646 if (bCallingContextPlugin)
647 {
648 gfid = GPU_GFID_PF;
649 }
650
651 //
652 // Most of GR is stub'd so context related things are not needed in AMODEL.
653 // But this function can be called in some MODS test, so return OK directly
654 // to avoid failing the test.
655 //
656 if (IS_MODS_AMODEL(pGpu))
657 return NV_OK;
658
659 // Not ready
660 if (!pPrivate->bInitialized)
661 return NV_OK;
662
663 // Already done
664 if (pPrivate->staticInfo.pContextBuffersInfo != NULL)
665 return NV_OK;
666
667 // In progress
668 if (pKernelGraphics->bCollectingDeferredStaticData)
669 return NV_OK;
670
671 if (hClient == NV01_NULL_OBJECT)
672 {
673 NvHandle hDevice = NV01_NULL_OBJECT;
674 NvU32 swizzId = KMIGMGR_SWIZZID_INVALID;
675
676 if (IS_MIG_IN_USE(pGpu))
677 {
678 MIG_INSTANCE_REF ref;
679
680 NV_ASSERT_OK_OR_RETURN(
681 kmigmgrGetMIGReferenceFromEngineType(pGpu, pKernelMIGManager,
682 RM_ENGINE_TYPE_GR(pKernelGraphics->instance), &ref));
683
684 swizzId = ref.pKernelMIGGpuInstance->swizzId;
685 }
686
687 status = _kgraphicsInternalClientAlloc(pGpu, pKernelGraphics, swizzId, &hClient, &hDevice, &hSubdevice);
688 if (status == NV_ERR_NOT_READY)
689 {
690 return NV_OK;
691 }
692 NV_ASSERT_OR_RETURN(status == NV_OK, status);
693 NV_ASSERT_OR_RETURN(hClient != NV01_NULL_OBJECT, NV_ERR_INVALID_STATE);
694 bInternalClientAllocated = NV_TRUE;
695 }
696
697 // Prevent recursion when deferred static data collection is ON
698 pKernelGraphics->bCollectingDeferredStaticData = NV_TRUE;
699
700 if (IS_MIG_IN_USE(pGpu))
701 {
702 MIG_INSTANCE_REF ref;
703 RM_ENGINE_TYPE localRmEngineType;
704 Subdevice *pSubdevice;
705 RsClient *pClient;
706
707 NV_CHECK_OK_OR_GOTO(
708 status,
709 LEVEL_ERROR,
710 serverGetClientUnderLock(&g_resServ, hClient, &pClient),
711 cleanup);
712
713 NV_CHECK_OK_OR_GOTO(
714 status,
715 LEVEL_ERROR,
716 subdeviceGetByHandle(pClient, hSubdevice, &pSubdevice),
717 cleanup);
718
719 // Physical RM will fill with local indices, so localize the index
720 NV_CHECK_OK_OR_GOTO(
721 status,
722 LEVEL_ERROR,
723 kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager,
724 GPU_RES_GET_DEVICE(pSubdevice),
725 &ref),
726 cleanup);
727 NV_CHECK_OK_OR_GOTO(
728 status,
729 LEVEL_ERROR,
730 kmigmgrGetGlobalToLocalEngineType(pGpu, pKernelMIGManager, ref,
731 RM_ENGINE_TYPE_GR(grIdx),
732 &localRmEngineType),
733 cleanup);
734 grIdx = RM_ENGINE_TYPE_GR_IDX(localRmEngineType);
735 }
736
737 pParams = portMemAllocNonPaged(sizeof(*pParams));
738 if (pParams == NULL)
739 {
740 return NV_ERR_NO_MEMORY;
741 }
742 portMemSet(pParams, 0, sizeof(*pParams));
743 NV_CHECK_OK_OR_GOTO(
744 status,
745 LEVEL_ERROR,
746 pRmApi->Control(pRmApi,
747 hClient,
748 hSubdevice,
749 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO,
750 pParams,
751 sizeof(*pParams)),
752 cleanup_context_buffers_info);
753
754 pPrivate->staticInfo.pContextBuffersInfo =
755 portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pContextBuffersInfo));
756
757 if (pPrivate->staticInfo.pContextBuffersInfo == NULL)
758 {
759 status = NV_ERR_NO_MEMORY;
760 goto cleanup_context_buffers_info;
761 }
762
763 portMemCopy(pPrivate->staticInfo.pContextBuffersInfo,
764 sizeof(*pPrivate->staticInfo.pContextBuffersInfo),
765 &pParams->engineContextBuffersInfo[grIdx],
766 sizeof(pParams->engineContextBuffersInfo[grIdx]));
767
768 cleanup_context_buffers_info:
769 portMemFree(pParams);
770
771 //
772 // We are not cleaning pContextBuffersInfo here since it's used after this
773 // function so has to be cleaned after used.
774 //
775
776 cleanup:
777 if (bInternalClientAllocated)
778 {
779 pRmApi->Free(pRmApi, hClient, hClient);
780 }
781
782 pKernelGraphics->bCollectingDeferredStaticData = NV_FALSE;
783
784 if (status == NV_OK)
785 {
786 //
787 // Allocate Ctx Buffers that are global to all channels if they have yet
788 // to be allocated. We delay them until now to save memory when runs
789 // are done without using graphics contexts!
790 //
791 if (!pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers[gfid].bAllocated &&
792 (!gpuIsClientRmAllocatedCtxBufferEnabled(pGpu) ||
793 (gpuIsSriovEnabled(pGpu) && IS_GFID_PF(gfid))))
794 {
795 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
796 kgraphicsAllocGrGlobalCtxBuffers_HAL(pGpu, pKernelGraphics, gfid, NULL));
797 }
798 }
799
800 return status;
801 }
802
803 NV_STATUS
kgraphicsLoadStaticInfo_VF(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU32 swizzId)804 kgraphicsLoadStaticInfo_VF
805 (
806 OBJGPU *pGpu,
807 KernelGraphics *pKernelGraphics,
808 NvU32 swizzId
809 )
810 {
811 KGRAPHICS_PRIVATE_DATA *pPrivate = pKernelGraphics->pPrivate;
812 VGPU_STATIC_INFO *pVSI = GPU_GET_STATIC_INFO(pGpu);
813 NvU32 grIdx = pKernelGraphics->instance;
814 NVOS_STATUS status = NV_OK;
815
816 NV_ASSERT_OR_RETURN(pVSI != NULL, NV_ERR_INVALID_STATE);
817 NV_ASSERT_OR_RETURN(pPrivate != NULL, NV_ERR_INVALID_STATE);
818
819 if (pPrivate->bInitialized)
820 return status;
821
822 if (IS_MIG_IN_USE(pGpu))
823 {
824 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
825
826 //
827 // Delay initialization to GPU instance configuration, unless MODS is using
828 // legacy VGPU mode, in which case the guest never receives a
829 // configuration call
830 //
831 if ((swizzId == KMIGMGR_SWIZZID_INVALID) && !kmigmgrUseLegacyVgpuPolicy(pGpu, pKernelMIGManager))
832 return status;
833
834 pPrivate->staticInfo.pGrInfo = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pGrInfo));
835 if (pPrivate->staticInfo.pGrInfo == NULL)
836 {
837 status = NV_ERR_NO_MEMORY;
838 goto cleanup;
839 }
840
841 portMemCopy(pPrivate->staticInfo.pGrInfo->infoList,
842 NV0080_CTRL_GR_INFO_MAX_SIZE * sizeof(*pPrivate->staticInfo.pGrInfo->infoList),
843 pVSI->grInfoParams.engineInfo[grIdx].infoList,
844 NV0080_CTRL_GR_INFO_MAX_SIZE * sizeof(*pVSI->grInfoParams.engineInfo[grIdx].infoList));
845
846 portMemCopy(&pPrivate->staticInfo.globalSmOrder, sizeof(pPrivate->staticInfo.globalSmOrder),
847 &pVSI->globalSmOrder.globalSmOrder[grIdx], sizeof(pVSI->globalSmOrder.globalSmOrder[grIdx]));
848
849 // grCaps are the same for all GR and can be copied from VGPU static info
850 portMemCopy(pPrivate->staticInfo.grCaps.capsTbl, sizeof(pPrivate->staticInfo.grCaps.capsTbl),
851 pVSI->grCapsBits, sizeof(pVSI->grCapsBits));
852
853 // Initialize PDB properties synchronized with physical RM
854 pPrivate->staticInfo.pdbTable.bPerSubCtxheaderSupported = pVSI->bPerSubCtxheaderSupported;
855 kgraphicsSetPerSubcontextContextHeaderSupported(pGpu, pKernelGraphics, pPrivate->staticInfo.pdbTable.bPerSubCtxheaderSupported);
856
857 pPrivate->staticInfo.pSmIssueRateModifier =
858 portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pSmIssueRateModifier));
859 if (pPrivate->staticInfo.pSmIssueRateModifier == NULL)
860 {
861 status = NV_ERR_NO_MEMORY;
862 goto cleanup;
863 }
864
865 portMemCopy(pPrivate->staticInfo.pSmIssueRateModifier, sizeof(*pPrivate->staticInfo.pSmIssueRateModifier),
866 &pVSI->smIssueRateModifier.smIssueRateModifier[grIdx], sizeof(pVSI->smIssueRateModifier.smIssueRateModifier[grIdx]));
867
868 pPrivate->staticInfo.pPpcMasks = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pPpcMasks));
869 if (pPrivate->staticInfo.pPpcMasks == NULL)
870 {
871 status = NV_ERR_NO_MEMORY;
872 goto cleanup;
873 }
874
875 portMemCopy(pPrivate->staticInfo.pPpcMasks, sizeof(*pPrivate->staticInfo.pPpcMasks),
876 &pVSI->ppcMaskParams.enginePpcMasks[grIdx], sizeof(pVSI->ppcMaskParams.enginePpcMasks[grIdx]));
877
878 portMemCopy(&pPrivate->staticInfo.floorsweepingMasks, sizeof(pPrivate->staticInfo.floorsweepingMasks),
879 &pVSI->floorsweepMaskParams.floorsweepingMasks[grIdx], sizeof(pVSI->floorsweepMaskParams.floorsweepingMasks[grIdx]));
880
881 pPrivate->staticInfo.pContextBuffersInfo =
882 portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pContextBuffersInfo));
883
884 if (pPrivate->staticInfo.pContextBuffersInfo == NULL)
885 {
886 status = NV_ERR_NO_MEMORY;
887 goto cleanup;
888 }
889
890 portMemCopy(pPrivate->staticInfo.pContextBuffersInfo,
891 sizeof(*pPrivate->staticInfo.pContextBuffersInfo),
892 &pVSI->ctxBuffInfo.engineContextBuffersInfo[grIdx],
893 sizeof(pVSI->ctxBuffInfo.engineContextBuffersInfo[grIdx]));
894
895 pPrivate->staticInfo.fecsRecordSize.fecsRecordSize = pVSI->fecsRecordSize.fecsRecordSize[grIdx].fecsRecordSize;
896
897 pPrivate->staticInfo.pFecsTraceDefines =
898 portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pFecsTraceDefines));
899
900 if (pPrivate->staticInfo.pFecsTraceDefines == NULL)
901 {
902 status = NV_ERR_NO_MEMORY;
903 goto cleanup;
904 }
905
906 portMemCopy(pPrivate->staticInfo.pFecsTraceDefines,
907 sizeof(*pPrivate->staticInfo.pFecsTraceDefines),
908 &pVSI->fecsTraceDefines.fecsTraceDefines[grIdx],
909 sizeof(pVSI->fecsTraceDefines.fecsTraceDefines[grIdx]));
910
911 portMemCopy(&pPrivate->staticInfo.pdbTable, sizeof(pPrivate->staticInfo.pdbTable),
912 &pVSI->pdbTableParams.pdbTable[grIdx], sizeof(pVSI->pdbTableParams.pdbTable[grIdx]));
913 }
914 else if (grIdx == 0)
915 {
916 portMemCopy(pPrivate->staticInfo.grCaps.capsTbl, sizeof(pPrivate->staticInfo.grCaps.capsTbl),
917 pVSI->grCapsBits, sizeof(pVSI->grCapsBits));
918
919 pPrivate->staticInfo.pGrInfo = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pGrInfo));
920 if (pPrivate->staticInfo.pGrInfo == NULL)
921 {
922 status = NV_ERR_NO_MEMORY;
923 goto cleanup;
924 }
925
926 portMemCopy(pPrivate->staticInfo.pGrInfo->infoList,
927 NV0080_CTRL_GR_INFO_MAX_SIZE * sizeof(*pPrivate->staticInfo.pGrInfo->infoList),
928 pVSI->grInfoParams.engineInfo[grIdx].infoList,
929 NV0080_CTRL_GR_INFO_MAX_SIZE * sizeof(*pVSI->grInfoParams.engineInfo[grIdx].infoList));
930
931 // Initialize PDB properties synchronized with physical RM
932 pPrivate->staticInfo.pdbTable.bPerSubCtxheaderSupported = pVSI->bPerSubCtxheaderSupported;
933 kgraphicsSetPerSubcontextContextHeaderSupported(pGpu, pKernelGraphics, pPrivate->staticInfo.pdbTable.bPerSubCtxheaderSupported);
934
935 portMemCopy(&pPrivate->staticInfo.globalSmOrder, sizeof(pPrivate->staticInfo.globalSmOrder),
936 &pVSI->globalSmOrder.globalSmOrder[grIdx], sizeof(pVSI->globalSmOrder.globalSmOrder[grIdx]));
937
938 pPrivate->staticInfo.pSmIssueRateModifier =
939 portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pSmIssueRateModifier));
940 if (pPrivate->staticInfo.pSmIssueRateModifier == NULL)
941 {
942 status = NV_ERR_NO_MEMORY;
943 goto cleanup;
944 }
945
946 portMemCopy(pPrivate->staticInfo.pSmIssueRateModifier, sizeof(*pPrivate->staticInfo.pSmIssueRateModifier),
947 &pVSI->smIssueRateModifier.smIssueRateModifier[grIdx], sizeof(pVSI->smIssueRateModifier.smIssueRateModifier[grIdx]));
948
949 pPrivate->staticInfo.pPpcMasks = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pPpcMasks));
950 if (pPrivate->staticInfo.pPpcMasks == NULL)
951 {
952 status = NV_ERR_NO_MEMORY;
953 goto cleanup;
954 }
955
956 portMemCopy(pPrivate->staticInfo.pPpcMasks, sizeof(*pPrivate->staticInfo.pPpcMasks),
957 &pVSI->ppcMaskParams.enginePpcMasks[grIdx], sizeof(pVSI->ppcMaskParams.enginePpcMasks[grIdx]));
958
959 pPrivate->staticInfo.pContextBuffersInfo =
960 portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pContextBuffersInfo));
961
962 if (pPrivate->staticInfo.pContextBuffersInfo == NULL)
963 {
964 status = NV_ERR_NO_MEMORY;
965 goto cleanup;
966 }
967
968 portMemCopy(pPrivate->staticInfo.pContextBuffersInfo,
969 sizeof(*pPrivate->staticInfo.pContextBuffersInfo),
970 &pVSI->ctxBuffInfo.engineContextBuffersInfo[grIdx],
971 sizeof(pVSI->ctxBuffInfo.engineContextBuffersInfo[grIdx]));
972
973 portMemCopy(&pPrivate->staticInfo.floorsweepingMasks, sizeof(pPrivate->staticInfo.floorsweepingMasks),
974 &pVSI->floorsweepMaskParams.floorsweepingMasks[grIdx], sizeof(pVSI->floorsweepMaskParams.floorsweepingMasks[grIdx]));
975
976 pPrivate->staticInfo.pRopInfo = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pRopInfo));
977 if (pPrivate->staticInfo.pRopInfo == NULL)
978 {
979 status = NV_ERR_NO_MEMORY;
980 goto cleanup;
981 }
982
983 portMemCopy(pPrivate->staticInfo.pRopInfo, sizeof(*pPrivate->staticInfo.pRopInfo),
984 &pVSI->ropInfoParams.engineRopInfo[grIdx], sizeof(pVSI->ropInfoParams.engineRopInfo[grIdx]));
985
986 pPrivate->staticInfo.pZcullInfo = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pZcullInfo));
987 if (pPrivate->staticInfo.pZcullInfo == NULL)
988 {
989 status = NV_ERR_NO_MEMORY;
990 goto cleanup;
991 }
992
993 portMemCopy(pPrivate->staticInfo.pZcullInfo, sizeof(*pPrivate->staticInfo.pZcullInfo),
994 &pVSI->zcullInfoParams.engineZcullInfo[grIdx], sizeof(pVSI->zcullInfoParams.engineZcullInfo[grIdx]));
995
996 pPrivate->staticInfo.fecsRecordSize.fecsRecordSize = pVSI->fecsRecordSize.fecsRecordSize[grIdx].fecsRecordSize;
997
998 pPrivate->staticInfo.pFecsTraceDefines =
999 portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pFecsTraceDefines));
1000 if (pPrivate->staticInfo.pFecsTraceDefines == NULL)
1001 {
1002 status = NV_ERR_NO_MEMORY;
1003 goto cleanup;
1004 }
1005
1006 portMemCopy(pPrivate->staticInfo.pFecsTraceDefines,
1007 sizeof(*pPrivate->staticInfo.pFecsTraceDefines),
1008 &pVSI->fecsTraceDefines.fecsTraceDefines[grIdx],
1009 sizeof(pVSI->fecsTraceDefines.fecsTraceDefines[grIdx]));
1010
1011 portMemCopy(&pPrivate->staticInfo.pdbTable, sizeof(pPrivate->staticInfo.pdbTable),
1012 &pVSI->pdbTableParams.pdbTable[grIdx], sizeof(pVSI->pdbTableParams.pdbTable[grIdx]));
1013 }
1014 else
1015 {
1016 // if MIG disabled, only GR0 static data needs to be published
1017 return status;
1018 }
1019
1020 if (status == NV_OK)
1021 {
1022 // Publish static configuration
1023 pPrivate->bInitialized = NV_TRUE;
1024 }
1025
1026 if (!IS_MIG_IN_USE(pGpu) && (grIdx == 0))
1027 {
1028 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
1029
1030 // Cache legacy GR mask info (i.e. GR0 with MIG disabled) to pKernelGraphicsManager->legacyFsMaskState
1031 kgrmgrSetLegacyKgraphicsStaticInfo(pGpu, pKernelGraphicsManager, pKernelGraphics);
1032 }
1033
1034 cleanup :
1035
1036 if (status != NV_OK)
1037 {
1038 portMemFree(pPrivate->staticInfo.pGrInfo);
1039 pPrivate->staticInfo.pGrInfo = NULL;
1040
1041 portMemFree(pPrivate->staticInfo.pPpcMasks);
1042 pPrivate->staticInfo.pPpcMasks = NULL;
1043
1044 portMemFree(pPrivate->staticInfo.pZcullInfo);
1045 pPrivate->staticInfo.pZcullInfo = NULL;
1046
1047 portMemFree(pPrivate->staticInfo.pRopInfo);
1048 pPrivate->staticInfo.pRopInfo = NULL;
1049
1050 portMemFree(pPrivate->staticInfo.pContextBuffersInfo);
1051 pPrivate->staticInfo.pContextBuffersInfo = NULL;
1052
1053 portMemFree(pPrivate->staticInfo.pSmIssueRateModifier);
1054 pPrivate->staticInfo.pSmIssueRateModifier = NULL;
1055
1056 portMemFree(pPrivate->staticInfo.pFecsTraceDefines);
1057 pPrivate->staticInfo.pFecsTraceDefines = NULL;
1058 }
1059
1060 return status;
1061 }
1062
1063 NV_STATUS
kgraphicsLoadStaticInfo_KERNEL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU32 swizzId)1064 kgraphicsLoadStaticInfo_KERNEL
1065 (
1066 OBJGPU *pGpu,
1067 KernelGraphics *pKernelGraphics,
1068 NvU32 swizzId
1069 )
1070 {
1071 KGRAPHICS_PRIVATE_DATA *pPrivate = pKernelGraphics->pPrivate;
1072 NvHandle hClient = NV01_NULL_OBJECT;
1073 NvHandle hDevice;
1074 NvHandle hSubdevice;
1075 RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
1076 NvU32 grIdx = pKernelGraphics->instance;
1077 NV_STATUS status = NV_OK;
1078 NvBool bBcState = gpumgrGetBcEnabledStatus(pGpu);
1079 union
1080 {
1081 NV2080_CTRL_INTERNAL_STATIC_GR_GET_CAPS_PARAMS caps;
1082 NV2080_CTRL_INTERNAL_STATIC_GR_GET_INFO_PARAMS info;
1083 NV2080_CTRL_INTERNAL_STATIC_GR_GET_GLOBAL_SM_ORDER_PARAMS globalSmOrder;
1084 NV2080_CTRL_INTERNAL_STATIC_GR_GET_FLOORSWEEPING_MASKS_PARAMS floorsweepingMasks;
1085 NV2080_CTRL_INTERNAL_STATIC_GR_GET_PPC_MASKS_PARAMS ppcMasks;
1086 NV2080_CTRL_INTERNAL_STATIC_GR_GET_ZCULL_INFO_PARAMS zcullInfo;
1087 NV2080_CTRL_INTERNAL_STATIC_GR_GET_ROP_INFO_PARAMS ropInfo;
1088 NV2080_CTRL_INTERNAL_STATIC_GR_GET_SM_ISSUE_RATE_MODIFIER_PARAMS smIssueRateModifier;
1089 NV2080_CTRL_INTERNAL_STATIC_GR_GET_FECS_RECORD_SIZE_PARAMS fecsRecordSize;
1090 NV2080_CTRL_INTERNAL_STATIC_GR_GET_FECS_TRACE_DEFINES_PARAMS fecsTraceDefines;
1091 NV2080_CTRL_INTERNAL_STATIC_GR_GET_PDB_PROPERTIES_PARAMS pdbProperties;
1092 } *pParams = NULL;
1093
1094 NV_ASSERT_OR_RETURN(pPrivate != NULL, NV_ERR_INVALID_STATE);
1095
1096 if (pPrivate->bInitialized)
1097 return NV_OK;
1098
1099 status = _kgraphicsInternalClientAlloc(pGpu, pKernelGraphics, swizzId, &hClient, &hDevice, &hSubdevice);
1100
1101 if (status == NV_ERR_NOT_READY)
1102 {
1103 return NV_OK;
1104 }
1105 NV_ASSERT_OR_RETURN(status == NV_OK, status);
1106 NV_ASSERT_OR_RETURN(hClient != NV01_NULL_OBJECT, NV_ERR_INVALID_STATE);
1107
1108 pParams = portMemAllocNonPaged(sizeof(*pParams));
1109 if (pParams == NULL)
1110 {
1111 status = NV_ERR_NO_MEMORY;
1112 goto cleanup;
1113 }
1114
1115 if (IS_MIG_IN_USE(pGpu))
1116 {
1117 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
1118 MIG_INSTANCE_REF ref;
1119 RM_ENGINE_TYPE localRmEngineType;
1120 RsClient *pClient;
1121 Device *pDevice;
1122
1123 NV_CHECK_OK_OR_GOTO(
1124 status,
1125 LEVEL_ERROR,
1126 serverGetClientUnderLock(&g_resServ, hClient, &pClient),
1127 cleanup);
1128
1129 NV_CHECK_OK_OR_GOTO(
1130 status,
1131 LEVEL_ERROR,
1132 deviceGetByHandle(pClient, hDevice, &pDevice),
1133 cleanup);
1134
1135 // Physical RM will fill with local indices, so localize the index
1136 NV_CHECK_OK_OR_GOTO(
1137 status,
1138 LEVEL_ERROR,
1139 kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager, pDevice, &ref),
1140 cleanup);
1141 NV_CHECK_OK_OR_GOTO(
1142 status,
1143 LEVEL_ERROR,
1144 kmigmgrGetGlobalToLocalEngineType(pGpu, pKernelMIGManager, ref,
1145 RM_ENGINE_TYPE_GR(grIdx),
1146 &localRmEngineType),
1147 cleanup);
1148 grIdx = RM_ENGINE_TYPE_GR_IDX(localRmEngineType);
1149 }
1150
1151 // GR Caps
1152 portMemSet(pParams, 0, sizeof(*pParams));
1153 NV_CHECK_OK_OR_GOTO(
1154 status,
1155 LEVEL_ERROR,
1156 pRmApi->Control(pRmApi,
1157 hClient,
1158 hSubdevice,
1159 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_CAPS,
1160 pParams,
1161 sizeof(pParams->caps)),
1162 cleanup);
1163
1164 portMemCopy(&pPrivate->staticInfo.grCaps, sizeof(pPrivate->staticInfo.grCaps),
1165 &pParams->caps.engineCaps[grIdx], sizeof(pParams->caps.engineCaps[grIdx]));
1166
1167 // GR Info
1168 portMemSet(pParams, 0, sizeof(*pParams));
1169 status = pRmApi->Control(pRmApi,
1170 hClient,
1171 hSubdevice,
1172 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_INFO,
1173 pParams,
1174 sizeof(pParams->info));
1175
1176 if (status == NV_OK)
1177 {
1178 pPrivate->staticInfo.pGrInfo = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pGrInfo));
1179 if (pPrivate->staticInfo.pGrInfo == NULL)
1180 {
1181 status = NV_ERR_NO_MEMORY;
1182 goto cleanup;
1183 }
1184
1185 portMemCopy(pPrivate->staticInfo.pGrInfo->infoList,
1186 NV0080_CTRL_GR_INFO_MAX_SIZE * sizeof(*pPrivate->staticInfo.pGrInfo->infoList),
1187 pParams->info.engineInfo[grIdx].infoList,
1188 NV0080_CTRL_GR_INFO_MAX_SIZE * sizeof(*pParams->info.engineInfo[grIdx].infoList));
1189
1190 }
1191
1192 // Floorsweeping masks
1193 portMemSet(pParams, 0, sizeof(*pParams));
1194 NV_CHECK_OK_OR_GOTO(
1195 status,
1196 LEVEL_ERROR,
1197 pRmApi->Control(pRmApi,
1198 hClient,
1199 hSubdevice,
1200 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_FLOORSWEEPING_MASKS,
1201 pParams,
1202 sizeof(pParams->floorsweepingMasks)),
1203 cleanup);
1204
1205 portMemCopy(&pPrivate->staticInfo.floorsweepingMasks, sizeof(pPrivate->staticInfo.floorsweepingMasks),
1206 &pParams->floorsweepingMasks.floorsweepingMasks[grIdx], sizeof(pParams->floorsweepingMasks.floorsweepingMasks[grIdx]));
1207
1208 //
1209 // Most of GR is stub'd in AMODEL. However, some tests still need the CAPS/INFO data,
1210 // so we still need to generate CAPS/INFO data for AMODEL
1211 //
1212 if (IS_MODS_AMODEL(pGpu))
1213 {
1214 pPrivate->bInitialized = NV_TRUE;
1215 if (!IS_MIG_IN_USE(pGpu) && (grIdx == 0))
1216 {
1217 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
1218
1219 // Cache legacy GR mask info (i.e. GR0 with MIG disabled) to pKernelGraphicsManager->legacyFsMaskState
1220 kgrmgrSetLegacyKgraphicsStaticInfo(pGpu, pKernelGraphicsManager, pKernelGraphics);
1221 }
1222 status = NV_OK;
1223 goto cleanup;
1224 }
1225
1226 // GR Global SM Order
1227 portMemSet(pParams, 0, sizeof(*pParams));
1228 NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
1229 pRmApi->Control(pRmApi,
1230 hClient,
1231 hSubdevice,
1232 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_GLOBAL_SM_ORDER,
1233 pParams,
1234 sizeof(pParams->globalSmOrder)),
1235 cleanup);
1236
1237 portMemCopy(&pPrivate->staticInfo.globalSmOrder, sizeof(pPrivate->staticInfo.globalSmOrder),
1238 &pParams->globalSmOrder.globalSmOrder[grIdx], sizeof(pParams->globalSmOrder.globalSmOrder[grIdx]));
1239
1240 // PPC Mask
1241 portMemSet(pParams, 0, sizeof(*pParams));
1242 status = pRmApi->Control(pRmApi,
1243 hClient,
1244 hSubdevice,
1245 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_PPC_MASKS,
1246 pParams,
1247 sizeof(pParams->ppcMasks));
1248
1249 if (status == NV_OK)
1250 {
1251 pPrivate->staticInfo.pPpcMasks = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pPpcMasks));
1252 if (pPrivate->staticInfo.pPpcMasks == NULL)
1253 {
1254 status = NV_ERR_NO_MEMORY;
1255 goto cleanup;
1256 }
1257
1258 portMemCopy(pPrivate->staticInfo.pPpcMasks, sizeof(*pPrivate->staticInfo.pPpcMasks),
1259 &pParams->ppcMasks.enginePpcMasks[grIdx], sizeof(pParams->ppcMasks.enginePpcMasks[grIdx]));
1260 }
1261 else if (status == NV_ERR_NOT_SUPPORTED)
1262 {
1263 //
1264 // Some chips don't support this call, so just keep the pPpcMasks
1265 // pointer as NULL, but don't return error
1266 //
1267 status = NV_OK;
1268 }
1269
1270 portMemSet(pParams, 0, sizeof(*pParams));
1271 status = pRmApi->Control(pRmApi,
1272 hClient,
1273 hSubdevice,
1274 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_ZCULL_INFO,
1275 pParams,
1276 sizeof(pParams->zcullInfo));
1277
1278 if (status == NV_OK)
1279 {
1280 pPrivate->staticInfo.pZcullInfo = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pZcullInfo));
1281 if (pPrivate->staticInfo.pZcullInfo == NULL)
1282 {
1283 status = NV_ERR_NO_MEMORY;
1284 goto cleanup;
1285 }
1286
1287 portMemCopy(pPrivate->staticInfo.pZcullInfo, sizeof(*pPrivate->staticInfo.pZcullInfo),
1288 &pParams->zcullInfo.engineZcullInfo[grIdx], sizeof(pParams->zcullInfo.engineZcullInfo[grIdx]));
1289 }
1290 else if (status == NV_ERR_NOT_SUPPORTED)
1291 {
1292 // It's expected to get this error when MIG is enabled, thus don't return error
1293 if (IS_MIG_ENABLED(pGpu))
1294 {
1295 status = NV_OK;
1296 }
1297 }
1298
1299 // ROP Info
1300 portMemSet(pParams, 0, sizeof(*pParams));
1301 status = pRmApi->Control(pRmApi,
1302 hClient,
1303 hSubdevice,
1304 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_ROP_INFO,
1305 pParams,
1306 sizeof(pParams->ropInfo));
1307
1308 if (status == NV_OK)
1309 {
1310 pPrivate->staticInfo.pRopInfo = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pRopInfo));
1311 if (pPrivate->staticInfo.pRopInfo == NULL)
1312 {
1313 status = NV_ERR_NO_MEMORY;
1314 goto cleanup;
1315 }
1316
1317 portMemCopy(pPrivate->staticInfo.pRopInfo, sizeof(*pPrivate->staticInfo.pRopInfo),
1318 &pParams->ropInfo.engineRopInfo[grIdx], sizeof(pParams->ropInfo.engineRopInfo[grIdx]));
1319 }
1320 else if (status == NV_ERR_NOT_SUPPORTED)
1321 {
1322 // It's expected to get this error when MIG is enabled, thus don't return error
1323 if (IS_MIG_ENABLED(pGpu))
1324 {
1325 status = NV_OK;
1326 }
1327 }
1328
1329 // SM Issue Rate Modifier
1330 portMemSet(pParams, 0, sizeof(*pParams));
1331 status = pRmApi->Control(pRmApi,
1332 hClient,
1333 hSubdevice,
1334 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_SM_ISSUE_RATE_MODIFIER,
1335 pParams,
1336 sizeof(pParams->smIssueRateModifier));
1337
1338 if (status == NV_OK)
1339 {
1340 pPrivate->staticInfo.pSmIssueRateModifier = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pSmIssueRateModifier));
1341 if (pPrivate->staticInfo.pSmIssueRateModifier == NULL)
1342 {
1343 status = NV_ERR_NO_MEMORY;
1344 goto cleanup;
1345 }
1346
1347 portMemCopy(pPrivate->staticInfo.pSmIssueRateModifier, sizeof(*pPrivate->staticInfo.pSmIssueRateModifier),
1348 &pParams->smIssueRateModifier.smIssueRateModifier[grIdx], sizeof(pParams->smIssueRateModifier.smIssueRateModifier[grIdx]));
1349 }
1350 else if (status == NV_ERR_NOT_SUPPORTED)
1351 {
1352 status = NV_OK;
1353 }
1354
1355 // FECS Record Size
1356 portMemSet(pParams, 0, sizeof(*pParams));
1357 NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
1358 pRmApi->Control(pRmApi,
1359 hClient,
1360 hSubdevice,
1361 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_FECS_RECORD_SIZE,
1362 pParams,
1363 sizeof(pParams->fecsRecordSize)),
1364 cleanup);
1365
1366 pPrivate->staticInfo.fecsRecordSize.fecsRecordSize = pParams->fecsRecordSize.fecsRecordSize[grIdx].fecsRecordSize;
1367
1368 // FECS Trace Defines
1369 portMemSet(pParams, 0, sizeof(*pParams));
1370 status = pRmApi->Control(pRmApi,
1371 hClient,
1372 hSubdevice,
1373 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_FECS_TRACE_DEFINES,
1374 pParams,
1375 sizeof(pParams->fecsTraceDefines));
1376 if (status == NV_OK)
1377 {
1378 pPrivate->staticInfo.pFecsTraceDefines = portMemAllocNonPaged(sizeof(*pPrivate->staticInfo.pFecsTraceDefines));
1379 if (pPrivate->staticInfo.pFecsTraceDefines == NULL)
1380 {
1381 status = NV_ERR_NO_MEMORY;
1382 goto cleanup;
1383 }
1384 portMemCopy(pPrivate->staticInfo.pFecsTraceDefines, sizeof(*pPrivate->staticInfo.pFecsTraceDefines),
1385 &pParams->fecsTraceDefines.fecsTraceDefines[grIdx], sizeof(pParams->fecsTraceDefines.fecsTraceDefines[grIdx]));
1386 }
1387 else if (status == NV_ERR_NOT_SUPPORTED)
1388 {
1389 status = NV_OK;
1390 }
1391
1392 // PDB Properties
1393 portMemSet(pParams, 0, sizeof(*pParams));
1394 NV_CHECK_OK_OR_GOTO(
1395 status,
1396 LEVEL_ERROR,
1397 pRmApi->Control(pRmApi,
1398 hClient,
1399 hSubdevice,
1400 NV2080_CTRL_CMD_INTERNAL_STATIC_KGR_GET_PDB_PROPERTIES,
1401 pParams,
1402 sizeof(pParams->pdbProperties)),
1403 cleanup);
1404
1405 portMemCopy(&pPrivate->staticInfo.pdbTable, sizeof(pPrivate->staticInfo.pdbTable),
1406 &pParams->pdbProperties.pdbTable[grIdx], sizeof(pParams->pdbProperties.pdbTable[grIdx]));
1407 kgraphicsSetPerSubcontextContextHeaderSupported(pGpu, pKernelGraphics, pPrivate->staticInfo.pdbTable.bPerSubCtxheaderSupported);
1408
1409 // Publish static configuration
1410 pPrivate->bInitialized = NV_TRUE;
1411
1412 // The deferred data is ready after MIG is enabled, so no need to defer the initialization
1413 if (IS_MIG_IN_USE(pGpu) ||
1414 !kgraphicsShouldDeferContextInit(pGpu, pKernelGraphics))
1415 {
1416 NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
1417 kgraphicsInitializeDeferredStaticData(pGpu, pKernelGraphics, hClient, hSubdevice), cleanup);
1418 }
1419
1420 if (!IS_MIG_IN_USE(pGpu) && (grIdx == 0))
1421 {
1422 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
1423
1424 // Cache legacy GR mask info (i.e. GR0 with MIG disabled) to pKernelGraphicsManager->legacyFsMaskState
1425 kgrmgrSetLegacyKgraphicsStaticInfo(pGpu, pKernelGraphicsManager, pKernelGraphics);
1426 }
1427
1428 cleanup:
1429 if (status != NV_OK)
1430 {
1431 // Redact static configuration
1432 pPrivate->bInitialized = NV_FALSE;
1433
1434 portMemFree(pPrivate->staticInfo.pGrInfo);
1435 pPrivate->staticInfo.pGrInfo = NULL;
1436
1437 portMemFree(pPrivate->staticInfo.pPpcMasks);
1438 pPrivate->staticInfo.pPpcMasks = NULL;
1439
1440 portMemFree(pPrivate->staticInfo.pZcullInfo);
1441 pPrivate->staticInfo.pZcullInfo = NULL;
1442
1443 portMemFree(pPrivate->staticInfo.pRopInfo);
1444 pPrivate->staticInfo.pRopInfo = NULL;
1445
1446 portMemFree(pPrivate->staticInfo.pContextBuffersInfo);
1447 pPrivate->staticInfo.pContextBuffersInfo = NULL;
1448
1449 portMemFree(pPrivate->staticInfo.pSmIssueRateModifier);
1450 pPrivate->staticInfo.pSmIssueRateModifier = NULL;
1451
1452 portMemFree(pPrivate->staticInfo.pFecsTraceDefines);
1453 pPrivate->staticInfo.pFecsTraceDefines = NULL;
1454 }
1455
1456 // If we had to subscribe specifically, free the hclient we allocated
1457 if (hClient != NV01_NULL_OBJECT)
1458 pRmApi->Free(pRmApi, hClient, hClient);
1459
1460 if (gpumgrGetBcEnabledStatus(pGpu) != bBcState)
1461 {
1462 // Corrupted broadcast state!
1463 NV_ASSERT(gpumgrGetBcEnabledStatus(pGpu) != bBcState);
1464 gpumgrSetBcEnabledStatus(pGpu, bBcState);
1465 }
1466
1467 portMemFree(pParams);
1468
1469 return status;
1470 }
1471
1472 /*! Return if GFX is supported for the given kernel graphics engine */
1473 NvBool
kgraphicsIsGFXSupported_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)1474 kgraphicsIsGFXSupported_IMPL
1475 (
1476 OBJGPU *pGpu,
1477 KernelGraphics *pKernelGraphics
1478 )
1479 {
1480 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
1481 NvU32 gfxCapabilites;
1482
1483 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_FALSE);
1484 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pGrInfo != NULL, NV_FALSE);
1485
1486 gfxCapabilites = pKernelGraphicsStaticInfo->pGrInfo->infoList[NV2080_CTRL_GR_INFO_INDEX_GFX_CAPABILITIES].data;
1487
1488 return (FLD_TEST_DRF(2080_CTRL_GR, _INFO_GFX_CAPABILITIES, _2D, _TRUE, gfxCapabilites) &&
1489 FLD_TEST_DRF(2080_CTRL_GR, _INFO_GFX_CAPABILITIES, _3D, _TRUE, gfxCapabilites) &&
1490 FLD_TEST_DRF(2080_CTRL_GR, _INFO_GFX_CAPABILITIES, _I2M, _TRUE, gfxCapabilites));
1491 }
1492
1493 /*! Retrieve ctxbufpool parameters for given local ctx buffer */
1494 const CTX_BUF_INFO *
kgraphicsGetCtxBufferInfo_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,GR_CTX_BUFFER buf)1495 kgraphicsGetCtxBufferInfo_IMPL
1496 (
1497 OBJGPU *pGpu,
1498 KernelGraphics *pKernelGraphics,
1499 GR_CTX_BUFFER buf
1500 )
1501 {
1502 NV_ASSERT_OR_RETURN(NV_ENUM_IS(GR_CTX_BUFFER, buf), NULL);
1503 return &pKernelGraphics->maxCtxBufSize[buf];
1504 }
1505
1506 /*! Set ctxbufpool parameters for given local ctx buffer */
1507 void
kgraphicsSetCtxBufferInfo_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,GR_CTX_BUFFER buf,NvU64 size,NvU64 align,RM_ATTR_PAGE_SIZE attr,NvBool bContiguous)1508 kgraphicsSetCtxBufferInfo_IMPL
1509 (
1510 OBJGPU *pGpu,
1511 KernelGraphics *pKernelGraphics,
1512 GR_CTX_BUFFER buf,
1513 NvU64 size,
1514 NvU64 align,
1515 RM_ATTR_PAGE_SIZE attr,
1516 NvBool bContiguous
1517 )
1518 {
1519 CTX_BUF_INFO *pInfo;
1520 NV_ASSERT_OR_RETURN_VOID(NV_ENUM_IS(GR_CTX_BUFFER, buf));
1521
1522 pInfo = &pKernelGraphics->maxCtxBufSize[buf];
1523 pInfo->size = size;
1524 pInfo->align = align;
1525 pInfo->attr = attr;
1526 pInfo->bContig = bContiguous;
1527 }
1528
1529 /*! Clear ctxbufpool parameters for all local ctx buffers */
1530 void
kgraphicsClearCtxBufferInfo_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)1531 kgraphicsClearCtxBufferInfo_IMPL
1532 (
1533 OBJGPU *pGpu,
1534 KernelGraphics *pKernelGraphics
1535 )
1536 {
1537 portMemSet(pKernelGraphics->maxCtxBufSize, 0, sizeof(pKernelGraphics->maxCtxBufSize));
1538 }
1539
1540 /*! Initialize ctxbufpool for this engine */
1541 NV_STATUS
kgraphicsInitCtxBufPool_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,Heap * pHeap)1542 kgraphicsInitCtxBufPool_IMPL
1543 (
1544 OBJGPU *pGpu,
1545 KernelGraphics *pKernelGraphics,
1546 Heap *pHeap
1547 )
1548 {
1549 return ctxBufPoolInit(pGpu, pHeap, &pKernelGraphics->pCtxBufPool);
1550 }
1551
1552 /*! Retrieve ctxbufpool for this engine */
1553 CTX_BUF_POOL_INFO *
kgraphicsGetCtxBufPool_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)1554 kgraphicsGetCtxBufPool_IMPL
1555 (
1556 OBJGPU *pGpu,
1557 KernelGraphics *pKernelGraphics
1558 )
1559 {
1560 return pKernelGraphics->pCtxBufPool;
1561 }
1562
1563 /*! destroy ctxbufpool for this engine */
1564 void
kgraphicsDestroyCtxBufPool_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)1565 kgraphicsDestroyCtxBufPool_IMPL
1566 (
1567 OBJGPU *pGpu,
1568 KernelGraphics *pKernelGraphics
1569 )
1570 {
1571 if (pKernelGraphics->pCtxBufPool == NULL)
1572 return;
1573
1574 ctxBufPoolRelease(pKernelGraphics->pCtxBufPool);
1575 ctxBufPoolDestroy(&pKernelGraphics->pCtxBufPool);
1576 pKernelGraphics->pCtxBufPool = NULL;
1577 }
1578
1579 /*! Get the global ctx buffers for the given GFID */
1580 GR_GLOBALCTX_BUFFERS *
kgraphicsGetGlobalCtxBuffers_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU32 gfid)1581 kgraphicsGetGlobalCtxBuffers_IMPL
1582 (
1583 OBJGPU *pGpu,
1584 KernelGraphics *pKernelGraphics,
1585 NvU32 gfid
1586 )
1587 {
1588 if (pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers == NULL)
1589 return NULL;
1590 return &pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers[gfid];
1591 }
1592
1593 /*! Should this global ctx buffer be mapped as size aligned? */
1594 NvBool
kgraphicsIsGlobalCtxBufferSizeAligned_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,GR_GLOBALCTX_BUFFER buf)1595 kgraphicsIsGlobalCtxBufferSizeAligned_IMPL
1596 (
1597 OBJGPU *pGpu,
1598 KernelGraphics *pKernelGraphics,
1599 GR_GLOBALCTX_BUFFER buf
1600 )
1601 {
1602 NV_ASSERT_OR_RETURN(NV_ENUM_IS(GR_GLOBALCTX_BUFFER, buf), NV_FALSE);
1603 return pKernelGraphics->globalCtxBuffersInfo.bSizeAligned[buf];
1604 }
1605
1606 /*! Get ctx buf attr for global priv access map */
1607 const GR_BUFFER_ATTR *
kgraphicsGetGlobalPrivAccessMapAttr_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)1608 kgraphicsGetGlobalPrivAccessMapAttr_IMPL
1609 (
1610 OBJGPU *pGpu,
1611 KernelGraphics *pKernelGraphics
1612 )
1613 {
1614 return &pKernelGraphics->globalCtxBuffersInfo.globalCtxAttr[GR_GLOBAL_BUFFER_GLOBAL_PRIV_ACCESS_MAP];
1615 }
1616
1617 /*
1618 * @brief Get Main context buffer size
1619 *
1620 * @param[in] pGpu
1621 * @param[in] pKernelGraphics
1622 * @param[in] bIncludeSubctxHdrs If subctx headers should be included in size calculation
1623 * @param[out] pSize Main Context buffer size
1624 */
1625 NV_STATUS
kgraphicsGetMainCtxBufferSize_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvBool bIncludeSubctxHdrs,NvU32 * pSize)1626 kgraphicsGetMainCtxBufferSize_IMPL
1627 (
1628 OBJGPU *pGpu,
1629 KernelGraphics *pKernelGraphics,
1630 NvBool bIncludeSubctxHdrs,
1631 NvU32 *pSize
1632 )
1633 {
1634 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
1635 NvU32 size;
1636
1637 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
1638 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pGrInfo != NULL, NV_ERR_INVALID_STATE);
1639 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pContextBuffersInfo != NULL, NV_ERR_INVALID_STATE);
1640
1641 size = pKernelGraphicsStaticInfo->pContextBuffersInfo->engine[NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS].size;
1642
1643 // Allocate space for per VEID headers in the golden context buffer.
1644 if (bIncludeSubctxHdrs &&
1645 kgraphicsIsPerSubcontextContextHeaderSupported(pGpu, pKernelGraphics))
1646 {
1647 // TODO size this down to max per-engine subcontexts
1648 NvU32 maxSubctx = pKernelGraphicsStaticInfo->pGrInfo->infoList[NV2080_CTRL_GR_INFO_INDEX_MAX_SUBCONTEXT_COUNT].data;
1649
1650 // The header needs to start at a 4 KB aligned address
1651 size = RM_ALIGN_UP(size, RM_PAGE_SIZE);
1652
1653 // The header is only 256 bytes; but needs to be 4KB aligned.
1654 size += (RM_PAGE_SIZE * maxSubctx);
1655 }
1656
1657 *pSize = size;
1658 return NV_OK;
1659 }
1660
1661 NV_STATUS
kgraphicsAllocKgraphicsBuffers_KERNEL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,KernelGraphicsContext * pKernelGraphicsContext,KernelChannel * pKernelChannel)1662 kgraphicsAllocKgraphicsBuffers_KERNEL
1663 (
1664 OBJGPU *pGpu,
1665 KernelGraphics *pKernelGraphics,
1666 KernelGraphicsContext *pKernelGraphicsContext,
1667 KernelChannel *pKernelChannel
1668 )
1669 {
1670 NvU32 gfid;
1671 OBJGVASPACE *pGVAS;
1672
1673 NV_ASSERT_OR_RETURN(pKernelChannel != NULL, NV_ERR_INVALID_CHANNEL);
1674 pGVAS = dynamicCast(pKernelChannel->pVAS, OBJGVASPACE);
1675 gfid = kchannelGetGfid(pKernelChannel);
1676
1677 // Deferred static info is necessary at this point for FECS buffer allocation. Skip for guest RM
1678 if (!IS_VIRTUAL(pGpu))
1679 {
1680 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
1681 kgraphicsInitializeDeferredStaticData(pGpu, pKernelGraphics, NV01_NULL_OBJECT, NV01_NULL_OBJECT));
1682 }
1683
1684 //
1685 // Allocate global context buffers for this gfid, if they haven't been
1686 // already
1687 //
1688 if (kgraphicsGetGlobalCtxBuffers(pGpu, pKernelGraphics, gfid)->memDesc[GR_GLOBALCTX_BUFFER_FECS_EVENT] == NULL)
1689 {
1690 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
1691 kgraphicsAllocGlobalCtxBuffers_HAL(pGpu, pKernelGraphics, gfid));
1692 }
1693
1694 if (kgraphicsIsCtxswLoggingSupported(pGpu, pKernelGraphics) &&
1695 (kgraphicsGetGlobalCtxBuffers(pGpu, pKernelGraphics, gfid)->memDesc[GR_GLOBALCTX_BUFFER_FECS_EVENT] != NULL))
1696 {
1697 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
1698
1699 if (!gvaspaceIsExternallyOwned(pGVAS) && !IS_VIRTUAL_WITHOUT_SRIOV(pGpu))
1700 {
1701 //
1702 // We map CTXSW buffer on each object allocation including compute object
1703 // Other global context buffers are not mapped during compute object alloc with subcontexts since
1704 // those are GR-only buffers and not needed for compute-only contexts
1705 //
1706 _kgraphicsMapGlobalCtxBuffer(pGpu, pKernelGraphics, gfid, pKernelChannel->pVAS, pKernelGraphicsContext,
1707 GR_GLOBALCTX_BUFFER_FECS_EVENT, NV_FALSE);
1708 }
1709
1710 if (!fecsBufferIsMapped(pGpu, pKernelGraphics))
1711 {
1712 fecsBufferMap(pGpu, pKernelGraphics);
1713 }
1714
1715 if (fecsGetCtxswLogConsumerCount(pGpu, pKernelGraphicsManager) > 0)
1716 fecsBufferReset(pGpu, pKernelGraphics);
1717 }
1718
1719 return NV_OK;
1720 }
1721
1722 static NV_STATUS
_kgraphicsMapGlobalCtxBuffer(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU32 gfid,OBJVASPACE * pVAS,KernelGraphicsContext * pKernelGraphicsContext,GR_GLOBALCTX_BUFFER buffId,NvBool bIsReadOnly)1723 _kgraphicsMapGlobalCtxBuffer
1724 (
1725 OBJGPU *pGpu,
1726 KernelGraphics *pKernelGraphics,
1727 NvU32 gfid,
1728 OBJVASPACE *pVAS,
1729 KernelGraphicsContext *pKernelGraphicsContext,
1730 GR_GLOBALCTX_BUFFER buffId,
1731 NvBool bIsReadOnly
1732 )
1733 {
1734 KernelGraphicsContextUnicast *pKernelGraphicsContextUnicast;
1735 NV_STATUS status = NV_OK;
1736 NvU64 vaddr = 0;
1737 MEMORY_DESCRIPTOR *pMemDesc;
1738 NvBool bSizeAligned;
1739
1740 NV_ASSERT_OK_OR_RETURN(
1741 kgrctxGetUnicast(pGpu, pKernelGraphicsContext, &pKernelGraphicsContextUnicast));
1742
1743 bSizeAligned = pKernelGraphics->globalCtxBuffersInfo.bSizeAligned[buffId];
1744 pMemDesc = pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers[gfid].memDesc[buffId];
1745
1746 if (pMemDesc == NULL)
1747 {
1748 NvU32 buffSize;
1749 NvU32 fifoEngineId;
1750 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
1751
1752 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
1753 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
1754 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pContextBuffersInfo != NULL, NV_ERR_INVALID_STATE);
1755
1756 NV_ASSERT_OK_OR_RETURN(kgrctxGlobalCtxBufferToFifoEngineId(buffId, &fifoEngineId));
1757 buffSize = pKernelGraphicsStaticInfo->pContextBuffersInfo->engine[fifoEngineId].size;
1758 if (buffSize == 0)
1759 {
1760 NV_PRINTF(LEVEL_INFO,
1761 "Could not map %s Buffer as buffer is not supported\n",
1762 NV_ENUM_TO_STRING(GR_GLOBALCTX_BUFFER, buffId));
1763 return NV_OK;
1764 }
1765 else
1766 {
1767 NV_PRINTF(LEVEL_ERROR,
1768 "Could not map %s Buffer, no memory allocated for it!\n",
1769 NV_ENUM_TO_STRING(GR_GLOBALCTX_BUFFER, buffId));
1770 return NV_ERR_INVALID_ARGUMENT;
1771 }
1772 }
1773
1774 // Unconditionally call map for refcounting
1775 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
1776 kgraphicsMapCtxBuffer(pGpu, pKernelGraphics, pMemDesc, pVAS,
1777 &pKernelGraphicsContextUnicast->globalCtxBufferVaList[buffId],
1778 bSizeAligned,
1779 bIsReadOnly));
1780
1781 NV_ASSERT_OK(vaListFindVa(&pKernelGraphicsContextUnicast->globalCtxBufferVaList[buffId], pVAS, &vaddr));
1782
1783 NV_PRINTF(LEVEL_INFO,
1784 "GPU:%d %s Buffer PA @ 0x%llx VA @ 0x%llx of Size 0x%llx\n",
1785 pGpu->gpuInstance, NV_ENUM_TO_STRING(GR_GLOBALCTX_BUFFER, buffId),
1786 memdescGetPhysAddr(memdescGetMemDescFromGpu(pMemDesc, pGpu), AT_GPU, 0),
1787 vaddr, pMemDesc->Size);
1788
1789 return status;
1790 }
1791
1792 /*!
1793 * @brief Map a GR ctx buffer
1794 */
1795 NV_STATUS
kgraphicsMapCtxBuffer_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,MEMORY_DESCRIPTOR * pMemDesc,OBJVASPACE * pVAS,VA_LIST * pVaList,NvBool bAlignSize,NvBool bIsReadOnly)1796 kgraphicsMapCtxBuffer_IMPL
1797 (
1798 OBJGPU *pGpu,
1799 KernelGraphics *pKernelGraphics,
1800 MEMORY_DESCRIPTOR *pMemDesc,
1801 OBJVASPACE *pVAS,
1802 VA_LIST *pVaList,
1803 NvBool bAlignSize,
1804 NvBool bIsReadOnly
1805 )
1806 {
1807 NV_STATUS status = NV_OK;
1808 NvU64 vaddr = 0;
1809 OBJGVASPACE *pGVAS;
1810
1811 NV_ASSERT(!gpumgrGetBcEnabledStatus(pGpu));
1812
1813 NV_PRINTF(LEVEL_INFO, "gpu:%d isBC=%d\n", pGpu->gpuInstance,
1814 gpumgrGetBcEnabledStatus(pGpu));
1815
1816 pGVAS = dynamicCast(pVAS, OBJGVASPACE);
1817 NV_ASSERT_OR_RETURN(!gvaspaceIsExternallyOwned(pGVAS), NV_ERR_INVALID_OPERATION);
1818
1819 status = vaListFindVa(pVaList, pVAS, &vaddr);
1820 if (status == NV_ERR_OBJECT_NOT_FOUND)
1821 {
1822 // create a new subcontext mapping
1823 NvU32 allocFlags = bAlignSize ? DMA_ALLOC_VASPACE_SIZE_ALIGNED : DMA_ALLOC_VASPACE_NONE;
1824 NvU32 updateFlags = bIsReadOnly ? (DMA_UPDATE_VASPACE_FLAGS_READ_ONLY |
1825 DMA_UPDATE_VASPACE_FLAGS_SHADER_READ_ONLY) : DMA_UPDATE_VASPACE_FLAGS_NONE;
1826
1827 if (pGVAS->flags & VASPACE_FLAGS_RESTRICTED_RM_INTERNAL_VALIMITS)
1828 {
1829 allocFlags |= DMA_ALLOC_VASPACE_USE_RM_INTERNAL_VALIMITS;
1830 }
1831
1832 if (kgraphicsIsPerSubcontextContextHeaderSupported(pGpu, pKernelGraphics))
1833 {
1834 status = dmaMapBuffer_HAL(pGpu, GPU_GET_DMA(pGpu), pVAS, pMemDesc, &vaddr,
1835 allocFlags, updateFlags);
1836 }
1837 else
1838 {
1839 //
1840 // Per subcontext headers not enabled.
1841 // If subcontext is not supported, create a new mapping.
1842 // If subcontext is supported, create an identity mapping to the existing one.
1843 //
1844
1845 if (vaListMapCount(pVaList) == 0)
1846 {
1847 status = dmaMapBuffer_HAL(pGpu, GPU_GET_DMA(pGpu), pVAS,
1848 pMemDesc,
1849 &vaddr,
1850 allocFlags,
1851 updateFlags);
1852 }
1853 else
1854 {
1855 OBJVASPACE *pVas;
1856 NvU32 mapFlags = 0x0;
1857 NvU64 vaddrCached;
1858
1859 FOR_EACH_IN_VADDR_LIST(pVaList, pVas, vaddr)
1860 {
1861 // Find the first virtual address in any VAS
1862 break;
1863 }
1864 FOR_EACH_IN_VADDR_LIST_END(pVaList, pVas, vaddr);
1865
1866 if (bIsReadOnly)
1867 {
1868 mapFlags = FLD_SET_DRF(OS46, _FLAGS, _ACCESS, _READ_ONLY, mapFlags);
1869 mapFlags = FLD_SET_DRF(OS46, _FLAGS, _SHADER_ACCESS, _READ_ONLY, mapFlags);
1870 }
1871 mapFlags = FLD_SET_DRF(OS46, _FLAGS, _DMA_UNICAST_REUSE_ALLOC, _FALSE, mapFlags);
1872 mapFlags = FLD_SET_DRF(OS46, _FLAGS, _DMA_OFFSET_FIXED, _TRUE, mapFlags);
1873
1874 NV_ASSERT(!bAlignSize); // TODO: Add support for size align
1875 vaddrCached = vaddr;
1876 NV_ASSERT_OK_OR_ELSE(status,
1877 dmaAllocMapping_HAL(pGpu, GPU_GET_DMA(pGpu), pVAS, pMemDesc,
1878 &vaddr,
1879 mapFlags,
1880 NULL,
1881 KMIGMGR_SWIZZID_INVALID),
1882 /* do nothing on error, but make sure we overwrite status */;);
1883 NV_ASSERT(vaddr == vaddrCached);
1884 }
1885 }
1886
1887 NV_PRINTF(LEVEL_INFO, "New ctx buffer mapping at VA 0x%llx\n", vaddr);
1888 }
1889
1890 if (status == NV_OK)
1891 NV_ASSERT_OK_OR_RETURN(vaListAddVa(pVaList, pVAS, vaddr));
1892
1893 return status;
1894 }
1895
1896 /*!
1897 * @brief Unmap a GR ctx buffer
1898 */
1899 void
kgraphicsUnmapCtxBuffer_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,OBJVASPACE * pVAS,VA_LIST * pVaList)1900 kgraphicsUnmapCtxBuffer_IMPL
1901 (
1902 OBJGPU *pGpu,
1903 KernelGraphics *pKernelGraphics,
1904 OBJVASPACE *pVAS,
1905 VA_LIST *pVaList
1906 )
1907 {
1908 NV_STATUS status = NV_OK;
1909 NvU64 vaddr = 0;
1910
1911 NV_ASSERT(!gpumgrGetBcEnabledStatus(pGpu));
1912
1913 NV_PRINTF(LEVEL_INFO, "gpu:%d isBC=%d\n", pGpu->gpuInstance,
1914 gpumgrGetBcEnabledStatus(pGpu));
1915
1916 status = vaListFindVa(pVaList, pVAS, &vaddr);
1917 if (status == NV_OK)
1918 {
1919 NV_ASSERT_OK(vaListRemoveVa(pVaList, pVAS));
1920
1921 status = vaListFindVa(pVaList, pVAS, &vaddr);
1922
1923 NV_ASSERT((NV_OK == status) || (NV_ERR_OBJECT_NOT_FOUND == status));
1924 if (NV_ERR_OBJECT_NOT_FOUND == status)
1925 {
1926 if (vaListGetManaged(pVaList))
1927 {
1928 dmaUnmapBuffer_HAL(pGpu, GPU_GET_DMA(pGpu), pVAS, vaddr);
1929 }
1930
1931 NV_PRINTF(LEVEL_INFO, "Freed ctx buffer mapping at VA 0x%llx\n",
1932 vaddr);
1933 }
1934 }
1935 }
1936
1937 /*!
1938 * @brief Get the Class number for a given gr object type
1939 *
1940 * @param[in] pGpu
1941 * @param[in] pKernelGraphics
1942 * @param[in] wantObjectType GR object type to lookup
1943 * @param[out] pClass class number
1944 */
1945 NV_STATUS
kgraphicsGetClassByType_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU32 wantObjectType,NvU32 * pClass)1946 kgraphicsGetClassByType_IMPL
1947 (
1948 OBJGPU *pGpu,
1949 KernelGraphics *pKernelGraphics,
1950 NvU32 wantObjectType,
1951 NvU32 *pClass
1952 )
1953 {
1954 NV_STATUS status = NV_OK;
1955 NvU32 objectType;
1956 NvU32 i;
1957 NvU32 numClasses;
1958 NvU32 *pClassesSupported;
1959
1960 *pClass = 0;
1961
1962 if (wantObjectType >= GR_OBJECT_TYPE_INVALID)
1963 {
1964 NV_PRINTF(LEVEL_ERROR, "bad requested object type : %d\n",
1965 wantObjectType);
1966 return NV_ERR_INVALID_ARGUMENT;
1967 }
1968
1969 // find out how many classes of type ENG_GR(0) we have
1970 NV_ASSERT_OK_OR_RETURN(
1971 gpuGetClassList(pGpu, &numClasses, NULL, ENG_GR(pKernelGraphics->instance)));
1972
1973 pClassesSupported = portMemAllocNonPaged(sizeof(NvU32) * numClasses);
1974 NV_CHECK_OR_RETURN(LEVEL_ERROR, pClassesSupported != NULL, NV_ERR_NO_MEMORY);
1975
1976 status = gpuGetClassList(pGpu, &numClasses, pClassesSupported, ENG_GR(pKernelGraphics->instance));
1977
1978 if (status == NV_OK)
1979 {
1980 for (i = 0; i < numClasses; i++)
1981 {
1982 kgrmgrGetGrObjectType(pClassesSupported[i], &objectType);
1983
1984 NV_PRINTF(LEVEL_INFO, "classNum=0x%08x, type=%d\n",
1985 pClassesSupported[i], objectType);
1986
1987 if (objectType == wantObjectType)
1988 *pClass = pClassesSupported[i];
1989 }
1990 }
1991
1992 portMemFree(pClassesSupported);
1993
1994 return (*pClass != 0) ? NV_OK : NV_ERR_INVALID_CLASS;
1995 }
1996
1997 /*!
1998 * @brief retrieve the ctx attributes for the given buffer
1999 */
2000 const GR_BUFFER_ATTR *
kgraphicsGetContextBufferAttr_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,GR_CTX_BUFFER buf)2001 kgraphicsGetContextBufferAttr_IMPL
2002 (
2003 OBJGPU *pGpu,
2004 KernelGraphics *pKernelGraphics,
2005 GR_CTX_BUFFER buf
2006 )
2007 {
2008 NV_ASSERT_OR_RETURN(NV_ENUM_IS(GR_CTX_BUFFER, buf), NULL);
2009 return &pKernelGraphics->ctxAttr[buf];
2010 }
2011
2012 /*!
2013 * @brief Creates a VEID0 channel for Golden Image creation
2014 *
2015 * @return NV_OK if channel and golden image created successfully
2016 */
2017 NV_STATUS
kgraphicsCreateGoldenImageChannel_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)2018 kgraphicsCreateGoldenImageChannel_IMPL
2019 (
2020 OBJGPU *pGpu,
2021 KernelGraphics *pKernelGraphics
2022 )
2023 {
2024 NV_STATUS status = NV_OK;
2025 NvHandle hClientId = NV01_NULL_OBJECT;
2026 NvHandle hDeviceId;
2027 NvHandle hSubdeviceId;
2028 NvHandle hVASpace = 0xbaba0042;
2029 NvHandle hPBVirtMemId = 0xbaba0043;
2030 NvHandle hPBPhysMemId = 0xbaba0044;
2031 NvHandle hChannelId = 0xbaba0045;
2032 NvHandle hObj3D = 0xbaba0046;
2033 NvHandle hUserdId = 0xbaba0049;
2034 NvU32 gpFifoEntries = 32; // power-of-2 random choice
2035 NvU64 gpFifoSize = NVA06F_GP_ENTRY__SIZE * gpFifoEntries;
2036 NvU64 chSize = gpFifoSize;
2037 RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
2038 RsClient *pClientId;
2039 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
2040 NvBool bNeedMIGWar;
2041 NvBool bBcStatus;
2042 NvBool bClientUserd = IsVOLTAorBetter(pGpu);
2043 NvBool bAcquireLock = NV_FALSE;
2044 NvU32 sliLoopReentrancy;
2045 NV_VASPACE_ALLOCATION_PARAMETERS vaParams;
2046 NV_MEMORY_ALLOCATION_PARAMS memAllocParams;
2047 NV_CHANNEL_ALLOC_PARAMS channelGPFIFOAllocParams;
2048 NvU32 classNum;
2049 MIG_INSTANCE_REF ref;
2050 NvU32 objectType;
2051 NvU32 primarySliSubDeviceInstance;
2052
2053 // XXX This should be removed when broadcast SLI support is deprecated
2054 if (!gpumgrIsParentGPU(pGpu))
2055 {
2056 return NV_OK;
2057 }
2058
2059 bBcStatus = gpumgrGetBcEnabledStatus(pGpu);
2060
2061 // FIXME these allocations corrupt BC state
2062 NV_ASSERT_OK_OR_RETURN(
2063 rmapiutilAllocClientAndDeviceHandles(pRmApi, pGpu, &hClientId, &hDeviceId, &hSubdeviceId));
2064 // rmapiutilAllocClientAndDeviceHandles allocates a subdevice object for this subDeviceInstance
2065 primarySliSubDeviceInstance = gpumgrGetSubDeviceInstanceFromGpu(pGpu);
2066
2067 NV_ASSERT_OK_OR_RETURN(serverGetClientUnderLock(&g_resServ, hClientId, &pClientId));
2068
2069 gpumgrSetBcEnabledStatus(pGpu, NV_TRUE);
2070
2071 // As we have forced here SLI broadcast mode, temporarily reset the reentrancy count
2072 sliLoopReentrancy = gpumgrSLILoopReentrancyPop(pGpu);
2073
2074 bNeedMIGWar = IS_MIG_IN_USE(pGpu);
2075
2076 // Allocate subdevices for secondary GPUs
2077 SLI_LOOP_START(SLI_LOOP_FLAGS_BC_ONLY)
2078 {
2079 NvHandle hSecondary;
2080 NV2080_ALLOC_PARAMETERS nv2080AllocParams;
2081 NvU32 thisSubDeviceInstance = gpumgrGetSubDeviceInstanceFromGpu(pGpu);
2082
2083 // Skip if already allocated by rmapiutilAllocClientAndDeviceHandles()
2084 if (thisSubDeviceInstance == primarySliSubDeviceInstance)
2085 SLI_LOOP_CONTINUE;
2086
2087 // Allocate a subDevice
2088 NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
2089 clientGenResourceHandle(pClientId, &hSecondary),
2090 cleanup);
2091
2092 portMemSet(&nv2080AllocParams, 0, sizeof(nv2080AllocParams));
2093 nv2080AllocParams.subDeviceId = thisSubDeviceInstance;
2094
2095 NV_CHECK_OK(status, LEVEL_SILENT,
2096 pRmApi->AllocWithHandle(pRmApi,
2097 hClientId,
2098 hDeviceId,
2099 hSecondary,
2100 NV20_SUBDEVICE_0,
2101 &nv2080AllocParams,
2102 sizeof(nv2080AllocParams)));
2103 }
2104 SLI_LOOP_END;
2105
2106 if (bNeedMIGWar)
2107 {
2108 NvHandle hPartitionRef = 0xbaba0048;
2109 NvHandle hExecPartitionRef = 0xbaba004a;
2110 NVC637_ALLOCATION_PARAMETERS nvC637AllocParams = {0};
2111
2112 // Get swizzId for this GR
2113 NV_ASSERT_OK_OR_GOTO(status,
2114 kmigmgrGetMIGReferenceFromEngineType(pGpu, pKernelMIGManager,
2115 RM_ENGINE_TYPE_GR(pKernelGraphics->instance), &ref),
2116 cleanup);
2117
2118 portMemSet(&nvC637AllocParams, 0, sizeof(NVC637_ALLOCATION_PARAMETERS));
2119 nvC637AllocParams.swizzId = ref.pKernelMIGGpuInstance->swizzId;
2120
2121 // allocate partition reference
2122 NV_ASSERT_OK_OR_GOTO(status,
2123 pRmApi->AllocWithHandle(pRmApi,
2124 hClientId,
2125 hSubdeviceId,
2126 hPartitionRef,
2127 AMPERE_SMC_PARTITION_REF,
2128 &nvC637AllocParams,
2129 sizeof(nvC637AllocParams)),
2130 cleanup);
2131
2132 if (ref.pMIGComputeInstance != NULL)
2133 {
2134 NVC638_ALLOCATION_PARAMETERS nvC638AllocParams = {0};
2135 nvC638AllocParams.execPartitionId = ref.pMIGComputeInstance->id;
2136 NV_ASSERT_OK_OR_GOTO(status,
2137 pRmApi->AllocWithHandle(pRmApi,
2138 hClientId,
2139 hPartitionRef,
2140 hExecPartitionRef,
2141 AMPERE_SMC_EXEC_PARTITION_REF,
2142 &nvC638AllocParams,
2143 sizeof(nvC638AllocParams)),
2144 cleanup);
2145 }
2146 }
2147
2148 //
2149 // VidHeapControl and vaspace creation calls should happen outside GPU locks
2150 // UVM/CUDA may be holding the GPU locks here and the allocation may subsequently fail
2151 // So explicitly release GPU locks before RmVidHeapControl
2152 // See Bug 1735851-#24
2153 //
2154 rmGpuLocksRelease(GPUS_LOCK_FLAGS_NONE, NULL);
2155 bAcquireLock = NV_TRUE;
2156 pRmApi = rmapiGetInterface(RMAPI_API_LOCK_INTERNAL);
2157
2158 // Create a new VAspace for channel
2159 portMemSet(&vaParams, 0, sizeof(NV_VASPACE_ALLOCATION_PARAMETERS));
2160 NV_ASSERT_OK_OR_GOTO(status,
2161 pRmApi->AllocWithHandle(pRmApi, hClientId, hDeviceId, hVASpace, FERMI_VASPACE_A, &vaParams, sizeof(vaParams)),
2162 cleanup);
2163
2164 // Allocate gpfifo entries
2165 portMemSet(&memAllocParams, 0, sizeof(NV_MEMORY_ALLOCATION_PARAMS));
2166 memAllocParams.owner = HEAP_OWNER_RM_CLIENT_GENERIC;
2167 memAllocParams.type = NVOS32_TYPE_IMAGE;
2168 memAllocParams.size = chSize;
2169 memAllocParams.attr = DRF_DEF(OS32, _ATTR, _LOCATION, _PCI);
2170 memAllocParams.hVASpace = 0; // Physical allocations don't expect vaSpace handles
2171
2172 //
2173 // When APM feature is enabled all RM internal sysmem allocations must
2174 // be in unprotected memory
2175 // When Hopper CC is enabled all RM internal sysmem allocations that
2176 // are required to be accessed from GPU should be in unprotected memory
2177 // Other sysmem allocations that are not required to be accessed from GPU
2178 // must be in protected memory
2179 //
2180 memAllocParams.attr2 |= DRF_DEF(OS32, _ATTR2, _MEMORY_PROTECTION, _UNPROTECTED);
2181
2182 NV_ASSERT_OK_OR_GOTO(status,
2183 pRmApi->AllocWithHandle(pRmApi, hClientId, hDeviceId, hPBPhysMemId, NV01_MEMORY_SYSTEM, &memAllocParams, sizeof(memAllocParams)),
2184 cleanup);
2185
2186 portMemSet(&memAllocParams, 0, sizeof(NV_MEMORY_ALLOCATION_PARAMS));
2187 memAllocParams.owner = HEAP_OWNER_RM_CLIENT_GENERIC;
2188 memAllocParams.type = NVOS32_TYPE_IMAGE;
2189 memAllocParams.size = chSize;
2190 memAllocParams.attr = DRF_DEF(OS32, _ATTR, _LOCATION, _PCI);
2191 memAllocParams.flags = NVOS32_ALLOC_FLAGS_VIRTUAL;
2192 memAllocParams.hVASpace = hVASpace; // Virtual allocation expect vaSpace handles
2193 // 0 handle = allocations on gpu default vaSpace
2194
2195 NV_ASSERT_OK_OR_GOTO(status,
2196 pRmApi->AllocWithHandle(pRmApi, hClientId, hDeviceId, hPBVirtMemId, NV50_MEMORY_VIRTUAL, &memAllocParams, sizeof(memAllocParams)),
2197 cleanup);
2198
2199 // Allocate Userd
2200 if (bClientUserd)
2201 {
2202 NvU32 userdMemClass = NV01_MEMORY_LOCAL_USER;
2203 NvU32 ctrlSize;
2204
2205 if (gpuIsClassSupported(pGpu, VOLTA_CHANNEL_GPFIFO_A))
2206 {
2207 ctrlSize = sizeof(Nvc36fControl);
2208 }
2209 else if (gpuIsClassSupported(pGpu, TURING_CHANNEL_GPFIFO_A))
2210 {
2211 ctrlSize = sizeof(Nvc46fControl);
2212 }
2213 else if (gpuIsClassSupported(pGpu, AMPERE_CHANNEL_GPFIFO_A))
2214 {
2215 ctrlSize = sizeof(Nvc56fControl);
2216 }
2217 else if (gpuIsClassSupported(pGpu, HOPPER_CHANNEL_GPFIFO_A))
2218 {
2219 ctrlSize = sizeof(Nvc86fControl);
2220 }
2221 else
2222 {
2223 status = NV_ERR_NOT_SUPPORTED;
2224 goto cleanup;
2225 }
2226
2227 portMemSet(&memAllocParams, 0, sizeof(NV_MEMORY_ALLOCATION_PARAMS));
2228 memAllocParams.owner = HEAP_OWNER_RM_CLIENT_GENERIC;
2229 memAllocParams.size = ctrlSize;
2230 memAllocParams.type = NVOS32_TYPE_IMAGE;
2231
2232 // Apply registry overrides to USERD.
2233 switch (DRF_VAL(_REG_STR_RM, _INST_LOC, _USERD, pGpu->instLocOverrides))
2234 {
2235 case NV_REG_STR_RM_INST_LOC_USERD_NCOH:
2236 case NV_REG_STR_RM_INST_LOC_USERD_COH:
2237 userdMemClass = NV01_MEMORY_SYSTEM;
2238 memAllocParams.attr = DRF_DEF(OS32, _ATTR, _LOCATION, _PCI);
2239 break;
2240
2241 case NV_REG_STR_RM_INST_LOC_USERD_VID:
2242 case NV_REG_STR_RM_INST_LOC_USERD_DEFAULT:
2243 memAllocParams.attr = DRF_DEF(OS32, _ATTR, _LOCATION, _VIDMEM);
2244 break;
2245 }
2246
2247 //
2248 // When APM is enabled all RM internal allocations must to go to
2249 // unprotected memory irrespective of vidmem or sysmem
2250 // When Hopper CC is enabled all RM internal sysmem allocations that
2251 // are required to be accessed from GPU should be in unprotected memory
2252 // and all vidmem allocations must go to protected memory
2253 //
2254 if (gpuIsApmFeatureEnabled(pGpu) ||
2255 FLD_TEST_DRF(OS32, _ATTR, _LOCATION, _PCI, memAllocParams.attr))
2256 {
2257 memAllocParams.attr2 |= DRF_DEF(OS32, _ATTR2, _MEMORY_PROTECTION,
2258 _UNPROTECTED);
2259 }
2260
2261 NV_ASSERT_OK_OR_GOTO(status,
2262 pRmApi->AllocWithHandle(pRmApi, hClientId, hDeviceId, hUserdId,
2263 userdMemClass, &memAllocParams, sizeof(memAllocParams)),
2264 cleanup);
2265 }
2266
2267 // Get fifo channel class Id
2268 classNum = kfifoGetChannelClassId(pGpu, GPU_GET_KERNEL_FIFO(pGpu));
2269 NV_ASSERT_OR_GOTO(classNum != 0, cleanup);
2270
2271 // Allocate a bare channel
2272 portMemSet(&channelGPFIFOAllocParams, 0, sizeof(NV_CHANNEL_ALLOC_PARAMS));
2273 channelGPFIFOAllocParams.hVASpace = hVASpace;
2274 channelGPFIFOAllocParams.hObjectBuffer = hPBVirtMemId;
2275 channelGPFIFOAllocParams.gpFifoEntries = gpFifoEntries;
2276 //
2277 // Set the gpFifoOffset to zero intentionally since we only need this channel
2278 // to be created, but will not submit any work to it. So it's fine not to
2279 // provide a valid offset here.
2280 //
2281 channelGPFIFOAllocParams.gpFifoOffset = 0;
2282 if (bClientUserd)
2283 {
2284 channelGPFIFOAllocParams.hUserdMemory[0] = hUserdId;
2285 }
2286
2287 if (bNeedMIGWar)
2288 {
2289 RM_ENGINE_TYPE localRmEngineType;
2290 Device *pDevice;
2291
2292 NV_ASSERT_OK_OR_GOTO(status,
2293 deviceGetByHandle(pClientId, hDeviceId, &pDevice),
2294 cleanup);
2295
2296 NV_ASSERT_OK_OR_GOTO(status,
2297 kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager, pDevice, &ref),
2298 cleanup);
2299
2300 NV_ASSERT_OK_OR_GOTO(status,
2301 kmigmgrGetGlobalToLocalEngineType(pGpu, pKernelMIGManager, ref, RM_ENGINE_TYPE_GR(pKernelGraphics->instance), &localRmEngineType),
2302 cleanup);
2303
2304 channelGPFIFOAllocParams.engineType = gpuGetNv2080EngineType(localRmEngineType);
2305 }
2306 else
2307 {
2308 channelGPFIFOAllocParams.engineType = gpuGetNv2080EngineType(RM_ENGINE_TYPE_GR0);
2309 }
2310
2311 NV_ASSERT_OK_OR_GOTO(status,
2312 pRmApi->AllocWithHandle(pRmApi, hClientId, hDeviceId, hChannelId,
2313 classNum, &channelGPFIFOAllocParams, sizeof(channelGPFIFOAllocParams)),
2314 cleanup);
2315
2316 //
2317 // When using split VAS, we need to reserve enough pagepool memory to
2318 // sustain large context buffer mappings. For GSPCLIENT where the golden
2319 // context buffer channel is initialized on boot, the pagepool does not have
2320 // enough reserved memory to accommodate these buffers, so we need to
2321 // reserve extra here.
2322 //
2323 if (IS_GSP_CLIENT(pGpu))
2324 {
2325 KernelChannel *pKernelChannel;
2326 NvU64 reserveSize;
2327 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
2328 NvU32 i;
2329
2330 NV_ASSERT_OK(CliGetKernelChannel(pClientId, hChannelId, &pKernelChannel));
2331
2332 NV_ASSERT_OR_ELSE(pKernelGraphicsStaticInfo != NULL,
2333 status = NV_ERR_INVALID_STATE;
2334 goto cleanup;);
2335 NV_ASSERT_OR_ELSE(pKernelGraphicsStaticInfo->pContextBuffersInfo != NULL,
2336 status = NV_ERR_INVALID_STATE;
2337 goto cleanup;);
2338
2339 reserveSize = 0;
2340 for (i = 0; i < NV_ARRAY_ELEMENTS(pKernelGraphicsStaticInfo->pContextBuffersInfo->engine); ++i)
2341 {
2342 if (pKernelGraphicsStaticInfo->pContextBuffersInfo->engine[i].size != NV_U32_MAX)
2343 reserveSize += pKernelGraphicsStaticInfo->pContextBuffersInfo->engine[i].size;
2344 }
2345
2346 NV_ASSERT_OK(
2347 vaspaceReserveMempool(pKernelChannel->pVAS, pGpu,
2348 GPU_RES_GET_DEVICE(pKernelChannel),
2349 reserveSize, RM_PAGE_SIZE,
2350 VASPACE_RESERVE_FLAGS_NONE));
2351 }
2352
2353 // Reaquire the GPU locks
2354 NV_ASSERT_OK_OR_GOTO(status,
2355 rmGpuLocksAcquire(GPUS_LOCK_FLAGS_NONE, RM_LOCK_MODULES_GR),
2356 cleanup);
2357 bAcquireLock = NV_FALSE;
2358 pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
2359
2360 if (!bNeedMIGWar)
2361 {
2362 objectType = GR_OBJECT_TYPE_3D;
2363 }
2364 else
2365 {
2366 objectType = GR_OBJECT_TYPE_COMPUTE;
2367
2368 }
2369
2370 // Get KernelGraphicsObject class Id
2371 NV_ASSERT_OK_OR_GOTO(status,
2372 kgraphicsGetClassByType(pGpu, pKernelGraphics, objectType, &classNum),
2373 cleanup);
2374 NV_ASSERT_OR_GOTO(classNum != 0, cleanup);
2375
2376 // Allocate a GR object on the channel
2377 NV_ASSERT_OK_OR_GOTO(status,
2378 pRmApi->AllocWithHandle(pRmApi, hClientId, hChannelId, hObj3D, classNum, NULL, 0),
2379 cleanup);
2380
2381 cleanup:
2382
2383 if (bAcquireLock)
2384 {
2385 NV_ASSERT_OK_OR_CAPTURE_FIRST_ERROR(status,
2386 rmGpuLocksAcquire(GPUS_LOCK_FLAGS_NONE, RM_LOCK_MODULES_GR));
2387 }
2388
2389 // Free all handles
2390 NV_ASSERT_OK_OR_CAPTURE_FIRST_ERROR(status,
2391 pRmApi->Free(pRmApi, hClientId, hClientId));
2392
2393 // Restore the reentrancy count
2394 gpumgrSLILoopReentrancyPush(pGpu, sliLoopReentrancy);
2395
2396 gpumgrSetBcEnabledStatus(pGpu, bBcStatus);
2397
2398 return status;
2399 }
2400
2401 /*!
2402 * @brief Free context buffers shared by all/most graphics contexts
2403 */
kgraphicsFreeGlobalCtxBuffers_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU32 gfid)2404 void kgraphicsFreeGlobalCtxBuffers_IMPL
2405 (
2406 OBJGPU *pGpu,
2407 KernelGraphics *pKernelGraphics,
2408 NvU32 gfid
2409 )
2410 {
2411 KernelMemorySystem *pKernelMemorySystem = GPU_GET_KERNEL_MEMORY_SYSTEM(pGpu);
2412 GR_GLOBALCTX_BUFFERS *pCtxBuffers;
2413 GR_GLOBALCTX_BUFFER buff;
2414 NvBool bEvict = NV_FALSE;
2415
2416 NV_ASSERT(!gpumgrGetBcEnabledStatus(pGpu));
2417
2418 if (pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers == NULL)
2419 return;
2420
2421 pCtxBuffers = &pKernelGraphics->globalCtxBuffersInfo.pGlobalCtxBuffers[gfid];
2422
2423 if (!pCtxBuffers->bAllocated)
2424 return;
2425
2426 FOR_EACH_IN_ENUM(GR_GLOBALCTX_BUFFER, buff)
2427 {
2428 if (pCtxBuffers->memDesc[buff] != NULL)
2429 {
2430 bEvict = NV_TRUE;
2431
2432 memdescFree(pCtxBuffers->memDesc[buff]);
2433 memdescDestroy(pCtxBuffers->memDesc[buff]);
2434 pCtxBuffers->memDesc[buff] = NULL;
2435 pCtxBuffers->bInitialized[buff] = NV_FALSE;
2436 }
2437 }
2438 FOR_EACH_IN_ENUM_END;
2439
2440 pCtxBuffers->bAllocated = NV_FALSE;
2441
2442 // make sure all L2 cache lines using CB buffers are clear after we free them
2443 if (bEvict)
2444 NV_ASSERT_OK(kmemsysCacheOp_HAL(pGpu, pKernelMemorySystem, NULL, FB_CACHE_VIDEO_MEMORY, FB_CACHE_EVICT));
2445 }
2446
2447 NV_STATUS
kgraphicsGetCaps_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,NvU8 * pGrCaps)2448 kgraphicsGetCaps_IMPL
2449 (
2450 OBJGPU *pGpu,
2451 KernelGraphics *pKernelGraphics,
2452 NvU8 *pGrCaps
2453 )
2454 {
2455 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
2456
2457 NV_ASSERT_OR_RETURN(pGrCaps != NULL, NV_ERR_INVALID_ARGUMENT);
2458 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
2459
2460 portMemCopy(pGrCaps,
2461 NV0080_CTRL_GR_CAPS_TBL_SIZE * sizeof(*pGrCaps),
2462 pKernelGraphicsStaticInfo->grCaps.capsTbl,
2463 NV0080_CTRL_GR_CAPS_TBL_SIZE * sizeof(*pGrCaps));
2464
2465 return NV_OK;
2466 }
2467
2468 /*!
2469 * @brief Return whether unrestricted register access bufffer is supported or not.
2470 */
2471 NvBool
kgraphicsIsUnrestrictedAccessMapSupported_PF(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)2472 kgraphicsIsUnrestrictedAccessMapSupported_PF
2473 (
2474 OBJGPU *pGpu,
2475 KernelGraphics *pKernelGraphics
2476 )
2477 {
2478 return !hypervisorIsVgxHyper();
2479 }
2480
2481 /*!
2482 * @brief Provides an opportunity to register some IntrService during intrStateInit.
2483 */
2484 void
kgraphicsRegisterIntrService_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,IntrServiceRecord pRecords[MC_ENGINE_IDX_MAX])2485 kgraphicsRegisterIntrService_IMPL
2486 (
2487 OBJGPU *pGpu,
2488 KernelGraphics *pKernelGraphics,
2489 IntrServiceRecord pRecords[MC_ENGINE_IDX_MAX]
2490 )
2491 {
2492 NvU32 engineIdx = MC_ENGINE_IDX_GRn_FECS_LOG(pKernelGraphics->instance);
2493
2494 NV_ASSERT(pRecords[engineIdx].pInterruptService == NULL);
2495 pRecords[engineIdx].pInterruptService = staticCast(pKernelGraphics, IntrService);
2496
2497 engineIdx = MC_ENGINE_IDX_GRn(pKernelGraphics->instance);
2498
2499 NV_ASSERT(pRecords[engineIdx].pNotificationService == NULL);
2500 pRecords[engineIdx].bFifoWaiveNotify = NV_FALSE;
2501 pRecords[engineIdx].pNotificationService = staticCast(pKernelGraphics, IntrService);
2502 }
2503
2504 /*!
2505 * @brief Services the nonstall interrupt.
2506 */
2507 NvU32
kgraphicsServiceNotificationInterrupt_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics,IntrServiceServiceNotificationInterruptArguments * pParams)2508 kgraphicsServiceNotificationInterrupt_IMPL
2509 (
2510 OBJGPU *pGpu,
2511 KernelGraphics *pKernelGraphics,
2512 IntrServiceServiceNotificationInterruptArguments *pParams
2513 )
2514 {
2515 NvU32 grIdx = pKernelGraphics->instance;
2516
2517 NV_ASSERT_OR_RETURN(pParams != NULL, 0);
2518 NV_ASSERT_OR_RETURN(pParams->engineIdx == MC_ENGINE_IDX_GRn(grIdx), 0);
2519
2520 MODS_ARCH_REPORT(NV_ARCH_EVENT_NONSTALL_GR, "%s", "processing GR nonstall interrupt\n");
2521
2522 kgraphicsNonstallIntrCheckAndClear_HAL(pGpu, pKernelGraphics, pParams->pThreadState);
2523 engineNonStallIntrNotify(pGpu, RM_ENGINE_TYPE_GR(pKernelGraphics->instance));
2524 return NV_OK;
2525 }
2526
2527 /*!
2528 * KernelGraphics RM Device Controls
2529 */
2530
2531 /*!
2532 * deviceCtrlCmdKGrGetCaps_IMPL
2533 *
2534 * Lock Requirements:
2535 * Assert that API lock held on entry
2536 *
2537 * TODO: remove once all uses have been migrated to V2
2538 */
2539 NV_STATUS
deviceCtrlCmdKGrGetCaps_IMPL(Device * pDevice,NV0080_CTRL_GR_GET_CAPS_PARAMS * pParams)2540 deviceCtrlCmdKGrGetCaps_IMPL
2541 (
2542 Device *pDevice,
2543 NV0080_CTRL_GR_GET_CAPS_PARAMS *pParams
2544 )
2545 {
2546 OBJGPU *pGpu = GPU_RES_GET_GPU(pDevice);
2547 NvU8 *pGrCaps = NvP64_VALUE(pParams->capsTbl);
2548 NvBool bCapsPopulated = NV_FALSE;
2549
2550 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
2551
2552 if (IsDFPGA(pGpu))
2553 {
2554 return NV_ERR_NOT_SUPPORTED;
2555 }
2556
2557 NV_CHECK_OR_RETURN(LEVEL_ERROR, pGrCaps != NULL, NV_ERR_INVALID_ARGUMENT);
2558 NV_CHECK_OR_RETURN(LEVEL_ERROR, pParams->capsTblSize == NV0080_CTRL_GR_CAPS_TBL_SIZE, NV_ERR_INVALID_ARGUMENT);
2559
2560 SLI_LOOP_START(SLI_LOOP_FLAGS_BC_ONLY)
2561 {
2562 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
2563 KernelGraphics *pKernelGraphics;
2564 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo;
2565 NV_STATUS status;
2566
2567 portMemSet(&grRouteInfo, 0, sizeof(grRouteInfo));
2568 kgrmgrCtrlSetEngineID(0, &grRouteInfo);
2569 NV_CHECK_OK_OR_ELSE(status, LEVEL_ERROR,
2570 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &grRouteInfo, &pKernelGraphics),
2571 SLI_LOOP_RETURN(status););
2572
2573 if (!bCapsPopulated)
2574 {
2575 NV_CHECK_OK_OR_ELSE(status, LEVEL_ERROR,
2576 kgraphicsGetCaps(pGpu, pKernelGraphics, pGrCaps),
2577 SLI_LOOP_RETURN(status););
2578
2579 bCapsPopulated = NV_TRUE;
2580 }
2581 }
2582 SLI_LOOP_END
2583
2584 return NV_OK;
2585 }
2586
2587 /*!
2588 * deviceCtrlCmdKGrGetCapsV2_IMPL
2589 *
2590 * Lock Requirements:
2591 * Assert that API lock held on entry
2592 */
2593 NV_STATUS
deviceCtrlCmdKGrGetCapsV2_IMPL(Device * pDevice,NV0080_CTRL_GR_GET_CAPS_V2_PARAMS * pParams)2594 deviceCtrlCmdKGrGetCapsV2_IMPL
2595 (
2596 Device *pDevice,
2597 NV0080_CTRL_GR_GET_CAPS_V2_PARAMS *pParams
2598 )
2599 {
2600 OBJGPU *pGpu = GPU_RES_GET_GPU(pDevice);
2601
2602 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
2603
2604 if (IsDFPGA(pGpu))
2605 {
2606 return NV_ERR_NOT_SUPPORTED;
2607 }
2608
2609 SLI_LOOP_START(SLI_LOOP_FLAGS_BC_ONLY)
2610 {
2611 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
2612 KernelGraphics *pKernelGraphics;
2613 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo = pParams->grRouteInfo;
2614 NV_STATUS status;
2615
2616 kgrmgrCtrlSetEngineID(0, &grRouteInfo);
2617 NV_CHECK_OK_OR_ELSE(status, LEVEL_ERROR,
2618 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &grRouteInfo, &pKernelGraphics),
2619 SLI_LOOP_RETURN(status););
2620
2621 if (!pParams->bCapsPopulated)
2622 {
2623 NV_CHECK_OK_OR_ELSE(status, LEVEL_ERROR,
2624 kgraphicsGetCaps(pGpu, pKernelGraphics, pParams->capsTbl),
2625 SLI_LOOP_RETURN(status););
2626
2627 pParams->bCapsPopulated = NV_TRUE;
2628 }
2629 }
2630 SLI_LOOP_END
2631
2632 return NV_OK;
2633 }
2634
2635 static NV_STATUS
_kgraphicsCtrlCmdGrGetInfoV2(OBJGPU * pGpu,Device * pDevice,NV2080_CTRL_GR_GET_INFO_V2_PARAMS * pParams)2636 _kgraphicsCtrlCmdGrGetInfoV2
2637 (
2638 OBJGPU *pGpu,
2639 Device *pDevice,
2640 NV2080_CTRL_GR_GET_INFO_V2_PARAMS *pParams
2641 )
2642 {
2643 NV_STATUS status = NV_OK;
2644 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
2645 NvU32 grInfoListSize = pParams->grInfoListSize;
2646 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
2647 NV2080_CTRL_INTERNAL_STATIC_GR_INFO *pGrInfo;
2648 NvU32 i;
2649
2650 if (pKernelGraphicsManager == NULL)
2651 {
2652 return NV_ERR_NOT_SUPPORTED;
2653 }
2654
2655 if ((0 == grInfoListSize) ||
2656 (grInfoListSize > NV2080_CTRL_GR_INFO_MAX_SIZE))
2657 {
2658 NV_PRINTF(LEVEL_ERROR, "Invalid grInfoList size: 0x%x\n", grInfoListSize);
2659 return NV_ERR_INVALID_ARGUMENT;
2660 }
2661
2662 if (kmigmgrIsDeviceUsingDeviceProfiling(pGpu, pKernelMIGManager, pDevice))
2663 {
2664 NV_ASSERT_OR_RETURN(kgrmgrGetLegacyKGraphicsStaticInfo(pGpu, pKernelGraphicsManager)->bInitialized, NV_ERR_INVALID_STATE);
2665 NV_ASSERT_OR_RETURN(kgrmgrGetLegacyKGraphicsStaticInfo(pGpu, pKernelGraphicsManager)->pGrInfo != NULL, NV_ERR_NOT_SUPPORTED);
2666
2667 pGrInfo = kgrmgrGetLegacyKGraphicsStaticInfo(pGpu, pKernelGraphicsManager)->pGrInfo;
2668 }
2669 else
2670 {
2671 KernelGraphics *pKernelGraphics;
2672 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
2673
2674 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
2675 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &pParams->grRouteInfo, &pKernelGraphics));
2676
2677 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
2678 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
2679 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pGrInfo != NULL, NV_ERR_NOT_SUPPORTED);
2680
2681 pGrInfo = pKernelGraphicsStaticInfo->pGrInfo;
2682 }
2683
2684 for (i = 0; i < grInfoListSize; i++)
2685 {
2686 NV_CHECK_OR_RETURN(LEVEL_ERROR, pParams->grInfoList[i].index < NV2080_CTRL_GR_INFO_MAX_SIZE, NV_ERR_INVALID_ARGUMENT);
2687 pParams->grInfoList[i].data = pGrInfo->infoList[pParams->grInfoList[i].index].data;
2688 }
2689
2690 return status;
2691 }
2692
2693 /*!
2694 * deviceCtrlCmdKGrGetInfo
2695 *
2696 * Lock Requirements:
2697 * Assert that API lock and GPUs lock held on entry
2698 *
2699 * TODO: remove once all uses have been migrated to V2
2700 */
2701 NV_STATUS
deviceCtrlCmdKGrGetInfo_IMPL(Device * pDevice,NV0080_CTRL_GR_GET_INFO_PARAMS * pParams)2702 deviceCtrlCmdKGrGetInfo_IMPL
2703 (
2704 Device *pDevice,
2705 NV0080_CTRL_GR_GET_INFO_PARAMS *pParams
2706 )
2707 {
2708 OBJGPU *pGpu = GPU_RES_GET_GPU(pDevice);
2709 NV0080_CTRL_GR_GET_INFO_V2_PARAMS grInfoParamsV2;
2710 NV0080_CTRL_GR_INFO *pGrInfos = NvP64_VALUE(pParams->grInfoList);
2711 NvU32 grInfoListSize = NV_MIN(pParams->grInfoListSize,
2712 NV0080_CTRL_GR_INFO_MAX_SIZE);
2713
2714 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
2715
2716 NV_CHECK_OR_RETURN(LEVEL_ERROR, pGrInfos != NULL, NV_ERR_INVALID_ARGUMENT);
2717
2718 portMemSet(&grInfoParamsV2, 0, sizeof(grInfoParamsV2));
2719 portMemCopy(grInfoParamsV2.grInfoList, grInfoListSize * sizeof(*pGrInfos),
2720 pGrInfos, grInfoListSize * sizeof(*pGrInfos));
2721 grInfoParamsV2.grInfoListSize = grInfoListSize;
2722
2723 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
2724 _kgraphicsCtrlCmdGrGetInfoV2(pGpu, pDevice, &grInfoParamsV2));
2725
2726 portMemCopy(pGrInfos, grInfoListSize * sizeof(*pGrInfos),
2727 grInfoParamsV2.grInfoList, grInfoListSize * sizeof(*pGrInfos));
2728 return NV_OK;
2729 }
2730
2731 /*!
2732 * deviceCtrlCmdKGrGetInfoV2
2733 *
2734 * Lock Requirements:
2735 * Assert that API lock and GPUs lock held on entry
2736 */
2737 NV_STATUS
deviceCtrlCmdKGrGetInfoV2_IMPL(Device * pDevice,NV0080_CTRL_GR_GET_INFO_V2_PARAMS * pParams)2738 deviceCtrlCmdKGrGetInfoV2_IMPL
2739 (
2740 Device *pDevice,
2741 NV0080_CTRL_GR_GET_INFO_V2_PARAMS *pParams
2742 )
2743 {
2744 OBJGPU *pGpu = GPU_RES_GET_GPU(pDevice);
2745
2746 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
2747
2748 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
2749 _kgraphicsCtrlCmdGrGetInfoV2(pGpu, pDevice, pParams));
2750
2751 return NV_OK;
2752 }
2753
2754 NV_STATUS
kgraphicsDiscoverMaxLocalCtxBufferSize_IMPL(OBJGPU * pGpu,KernelGraphics * pKernelGraphics)2755 kgraphicsDiscoverMaxLocalCtxBufferSize_IMPL
2756 (
2757 OBJGPU *pGpu,
2758 KernelGraphics *pKernelGraphics
2759 )
2760 {
2761 NvU32 bufId = 0;
2762 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
2763
2764 if (IS_MODS_AMODEL(pGpu))
2765 return NV_OK;
2766
2767 NV_ASSERT_OK_OR_RETURN(
2768 kgraphicsInitializeDeferredStaticData(pGpu, pKernelGraphics, NV01_NULL_OBJECT, NV01_NULL_OBJECT));
2769
2770 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pContextBuffersInfo != NULL, NV_ERR_INVALID_STATE);
2771
2772 FOR_EACH_IN_ENUM(GR_CTX_BUFFER, bufId)
2773 {
2774 if (bufId == GR_CTX_BUFFER_MAIN)
2775 {
2776 NvU32 size;
2777
2778 NV_ASSERT_OK_OR_RETURN(kgraphicsGetMainCtxBufferSize(pGpu, pKernelGraphics, NV_TRUE, &size));
2779 kgraphicsSetCtxBufferInfo(pGpu, pKernelGraphics, bufId,
2780 size,
2781 RM_PAGE_SIZE,
2782 RM_ATTR_PAGE_SIZE_4KB,
2783 kgraphicsShouldForceMainCtxContiguity_HAL(pGpu, pKernelGraphics));
2784 }
2785 else
2786 {
2787 NvU32 fifoEngineId;
2788
2789 NV_ASSERT_OK_OR_RETURN(
2790 kgrctxCtxBufferToFifoEngineId(bufId, &fifoEngineId));
2791
2792 kgraphicsSetCtxBufferInfo(pGpu, pKernelGraphics, bufId,
2793 pKernelGraphicsStaticInfo->pContextBuffersInfo->engine[fifoEngineId].size,
2794 RM_PAGE_SIZE,
2795 RM_ATTR_PAGE_SIZE_4KB,
2796 ((bufId == GR_CTX_BUFFER_PATCH) || (bufId == GR_CTX_BUFFER_PM)));
2797 }
2798 }
2799 FOR_EACH_IN_ENUM_END;
2800 return NV_OK;
2801 }
2802
2803 /*!
2804 * KernelGraphics RM SubDevice Controls
2805 */
2806
2807 /*!
2808 * subdeviceCtrlCmdKGrGetCapsV2
2809 *
2810 * Lock Requirements:
2811 * Assert that API lock held on entry
2812 */
2813 NV_STATUS
subdeviceCtrlCmdKGrGetCapsV2_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_CAPS_V2_PARAMS * pParams)2814 subdeviceCtrlCmdKGrGetCapsV2_IMPL
2815 (
2816 Subdevice *pSubdevice,
2817 NV2080_CTRL_GR_GET_CAPS_V2_PARAMS *pParams
2818 )
2819 {
2820 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2821 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
2822 KernelGraphics *pKernelGraphics;
2823 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo = pParams->grRouteInfo;
2824 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
2825
2826 kgrmgrCtrlSetEngineID(0, &grRouteInfo);
2827 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
2828 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &grRouteInfo, &pKernelGraphics));
2829
2830 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
2831
2832 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
2833 if (pKernelGraphicsStaticInfo == NULL)
2834 {
2835 return NV_ERR_INVALID_STATE;
2836 }
2837
2838 if (!pParams->bCapsPopulated)
2839 {
2840 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
2841 kgraphicsGetCaps(pGpu, pKernelGraphics, pParams->capsTbl));
2842
2843 pParams->bCapsPopulated = NV_TRUE;
2844 }
2845
2846 return NV_OK;
2847 }
2848
2849 /*!
2850 * subdeviceCtrlCmdKGrGetInfo
2851 *
2852 * Lock Requirements:
2853 * Assert that API lock and GPUs lock held on entry
2854 *
2855 * TODO: remove once all uses have been migrated to V2
2856 */
2857 NV_STATUS
subdeviceCtrlCmdKGrGetInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_INFO_PARAMS * pParams)2858 subdeviceCtrlCmdKGrGetInfo_IMPL
2859 (
2860 Subdevice *pSubdevice,
2861 NV2080_CTRL_GR_GET_INFO_PARAMS *pParams
2862 )
2863 {
2864 NV2080_CTRL_GR_GET_INFO_V2_PARAMS grInfoParamsV2;
2865 NV2080_CTRL_GR_INFO *pGrInfos = NvP64_VALUE(pParams->grInfoList);
2866 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo = pParams->grRouteInfo;
2867 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2868 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
2869 NvU32 grInfoListSize = NV_MIN(pParams->grInfoListSize,
2870 NV2080_CTRL_GR_INFO_MAX_SIZE);
2871
2872 //
2873 // Adding the null check as engine GRMGR is missing for DFPGA.
2874 //
2875 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
2876 NV_CHECK_OR_RETURN(LEVEL_ERROR, pKernelGraphicsManager != NULL, NV_ERR_NOT_SUPPORTED);
2877
2878 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
2879
2880 NV_CHECK_OR_RETURN(LEVEL_ERROR, pGrInfos != NULL, NV_ERR_INVALID_ARGUMENT);
2881
2882 portMemSet(&grInfoParamsV2, 0, sizeof(grInfoParamsV2));
2883 grInfoParamsV2.grInfoListSize = grInfoListSize;
2884 portMemCopy(grInfoParamsV2.grInfoList, grInfoListSize * sizeof(*pGrInfos),
2885 pGrInfos, grInfoListSize * sizeof(*pGrInfos));
2886 grInfoParamsV2.grRouteInfo = grRouteInfo;
2887
2888 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
2889 _kgraphicsCtrlCmdGrGetInfoV2(pGpu, pDevice, &grInfoParamsV2));
2890
2891 portMemCopy(pGrInfos, grInfoListSize * sizeof(*pGrInfos),
2892 grInfoParamsV2.grInfoList, grInfoListSize * sizeof(*pGrInfos));
2893 return NV_OK;
2894 }
2895
2896 /*!
2897 * subdeviceCtrlCmdKGrGetInfoV2
2898 *
2899 * Lock Requirements:
2900 * Assert that API lock and GPUs lock held on entry
2901 */
2902 NV_STATUS
subdeviceCtrlCmdKGrGetInfoV2_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_INFO_V2_PARAMS * pParams)2903 subdeviceCtrlCmdKGrGetInfoV2_IMPL
2904 (
2905 Subdevice *pSubdevice,
2906 NV2080_CTRL_GR_GET_INFO_V2_PARAMS *pParams
2907 )
2908 {
2909 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2910 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
2911
2912 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
2913
2914 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
2915 _kgraphicsCtrlCmdGrGetInfoV2(pGpu, pDevice, pParams));
2916
2917 return NV_OK;
2918 }
2919
2920 /*!
2921 * subdeviceCtrlCmdKGrGetSmToGpcTpcMappings
2922 *
2923 * Lock Requirements:
2924 * Assert that API lock and GPUs lock held on entry
2925 */
2926 NV_STATUS
subdeviceCtrlCmdKGrGetSmToGpcTpcMappings_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_SM_TO_GPC_TPC_MAPPINGS_PARAMS * pParams)2927 subdeviceCtrlCmdKGrGetSmToGpcTpcMappings_IMPL
2928 (
2929 Subdevice *pSubdevice,
2930 NV2080_CTRL_GR_GET_SM_TO_GPC_TPC_MAPPINGS_PARAMS *pParams
2931 )
2932 {
2933 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2934 KernelGraphics *pKernelGraphics;
2935 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
2936 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
2937 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
2938 const KGRAPHICS_STATIC_INFO *pStaticInfo;
2939 NvU32 i;
2940
2941 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
2942
2943 if (kmigmgrIsDeviceUsingDeviceProfiling(pGpu, pKernelMIGManager, pDevice))
2944 {
2945 return NV_ERR_NOT_SUPPORTED;
2946 }
2947 else
2948 {
2949 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
2950 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &pParams->grRouteInfo, &pKernelGraphics));
2951 }
2952
2953 // Verify static info is available
2954 pStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
2955 NV_ASSERT_OR_RETURN(pStaticInfo != NULL, NV_ERR_INVALID_STATE);
2956
2957 // Verify limits are within bounds
2958 NV_ASSERT_OR_RETURN(pStaticInfo->globalSmOrder.numSm <= NV2080_CTRL_GR_GET_SM_TO_GPC_TPC_MAPPINGS_MAX_SM_COUNT,
2959 NV_ERR_INVALID_LIMIT);
2960
2961 // Populate output data
2962 pParams->smCount = pStaticInfo->globalSmOrder.numSm;
2963 for (i = 0; i < pStaticInfo->globalSmOrder.numSm; ++i)
2964 {
2965 pParams->smId[i].gpcId = pStaticInfo->globalSmOrder.globalSmId[i].gpcId;
2966 pParams->smId[i].tpcId = pStaticInfo->globalSmOrder.globalSmId[i].localTpcId;
2967 }
2968
2969 return NV_OK;
2970 }
2971
2972 NV_STATUS
subdeviceCtrlCmdKGrGetGlobalSmOrder_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_GLOBAL_SM_ORDER_PARAMS * pParams)2973 subdeviceCtrlCmdKGrGetGlobalSmOrder_IMPL
2974 (
2975 Subdevice *pSubdevice,
2976 NV2080_CTRL_GR_GET_GLOBAL_SM_ORDER_PARAMS *pParams
2977 )
2978 {
2979 NV_STATUS status = NV_OK;
2980 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
2981 KernelGraphics *pKernelGraphics;
2982 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
2983 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
2984 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
2985 const KGRAPHICS_STATIC_INFO *pStaticInfo;
2986 NvU32 i;
2987
2988 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
2989
2990 if (kmigmgrIsDeviceUsingDeviceProfiling(pGpu, pKernelMIGManager, pDevice))
2991 {
2992 return NV_ERR_NOT_SUPPORTED;
2993 }
2994 else
2995 {
2996 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
2997 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &pParams->grRouteInfo, &pKernelGraphics));
2998 }
2999
3000 // Verify static info is available
3001 pStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3002 NV_ASSERT_OR_RETURN(pStaticInfo != NULL, NV_ERR_INVALID_STATE);
3003
3004 // Verify limits are within bounds
3005 NV_ASSERT_OR_RETURN(pStaticInfo->globalSmOrder.numSm <= NV2080_CTRL_CMD_GR_GET_GLOBAL_SM_ORDER_MAX_SM_COUNT,
3006 NV_ERR_INVALID_LIMIT);
3007
3008 // Populate output data
3009 pParams->numSm = pStaticInfo->globalSmOrder.numSm;
3010 pParams->numTpc = pStaticInfo->globalSmOrder.numTpc;
3011 for (i = 0; i < pStaticInfo->globalSmOrder.numSm; ++i)
3012 {
3013 pParams->globalSmId[i].gpcId = pStaticInfo->globalSmOrder.globalSmId[i].gpcId;
3014 pParams->globalSmId[i].localTpcId = pStaticInfo->globalSmOrder.globalSmId[i].localTpcId;
3015 pParams->globalSmId[i].localSmId = pStaticInfo->globalSmOrder.globalSmId[i].localSmId;
3016 pParams->globalSmId[i].globalTpcId = pStaticInfo->globalSmOrder.globalSmId[i].globalTpcId;
3017 pParams->globalSmId[i].virtualGpcId = pStaticInfo->globalSmOrder.globalSmId[i].virtualGpcId;
3018 pParams->globalSmId[i].migratableTpcId = pStaticInfo->globalSmOrder.globalSmId[i].migratableTpcId;
3019 }
3020
3021 return status;
3022 }
3023
3024 /*!
3025 * subdeviceCtrlCmdKGrGetSmIssueRateModifier
3026 *
3027 * Lock Requirements:
3028 * Assert that API lock and GPUs lock held on entry
3029 */
3030 NV_STATUS
subdeviceCtrlCmdKGrGetSmIssueRateModifier_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_SM_ISSUE_RATE_MODIFIER_PARAMS * pParams)3031 subdeviceCtrlCmdKGrGetSmIssueRateModifier_IMPL
3032 (
3033 Subdevice *pSubdevice,
3034 NV2080_CTRL_GR_GET_SM_ISSUE_RATE_MODIFIER_PARAMS *pParams
3035 )
3036 {
3037 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3038 KernelGraphics *pKernelGraphics;
3039 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3040 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3041 const KGRAPHICS_STATIC_INFO *pStaticInfo;
3042 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
3043
3044 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
3045
3046 if (kmigmgrIsDeviceUsingDeviceProfiling(pGpu, pKernelMIGManager, pDevice))
3047 {
3048 NvU32 grIdx;
3049 for (grIdx = 0; grIdx < GPU_MAX_GRS; grIdx++)
3050 {
3051 pKernelGraphics = GPU_GET_KERNEL_GRAPHICS(pGpu, grIdx);
3052 if (pKernelGraphics != NULL)
3053 break;
3054 }
3055 if (pKernelGraphics == NULL)
3056 return NV_ERR_INVALID_STATE;
3057 }
3058 else
3059 {
3060 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3061 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &pParams->grRouteInfo, &pKernelGraphics));
3062 }
3063
3064 // Verify static info is available
3065 pStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3066 NV_ASSERT_OR_RETURN(pStaticInfo != NULL, NV_ERR_INVALID_STATE);
3067 NV_ASSERT_OR_RETURN(pStaticInfo->pSmIssueRateModifier != NULL, NV_ERR_NOT_SUPPORTED);
3068
3069 pParams->imla0 = pStaticInfo->pSmIssueRateModifier->imla0;
3070 pParams->fmla16 = pStaticInfo->pSmIssueRateModifier->fmla16;
3071 pParams->dp = pStaticInfo->pSmIssueRateModifier->dp;
3072 pParams->fmla32 = pStaticInfo->pSmIssueRateModifier->fmla32;
3073 pParams->ffma = pStaticInfo->pSmIssueRateModifier->ffma;
3074 pParams->imla1 = pStaticInfo->pSmIssueRateModifier->imla1;
3075 pParams->imla2 = pStaticInfo->pSmIssueRateModifier->imla2;
3076 pParams->imla3 = pStaticInfo->pSmIssueRateModifier->imla3;
3077 pParams->imla4 = pStaticInfo->pSmIssueRateModifier->imla4;
3078
3079 return NV_OK;
3080 }
3081
3082 /*!
3083 * subdeviceCtrlCmdKGrGetGpcMask
3084 *
3085 * Lock Requirements:
3086 * Assert that API lock and GPUs lock held on entry
3087 */
3088 NV_STATUS
subdeviceCtrlCmdKGrGetGpcMask_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_GPC_MASK_PARAMS * pParams)3089 subdeviceCtrlCmdKGrGetGpcMask_IMPL
3090 (
3091 Subdevice *pSubdevice,
3092 NV2080_CTRL_GR_GET_GPC_MASK_PARAMS *pParams
3093 )
3094 {
3095 NV_STATUS status = NV_OK;
3096 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3097 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3098 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3099 KernelGraphics *pKernelGraphics;
3100 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
3101 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
3102
3103 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
3104
3105 if (!IS_MIG_IN_USE(pGpu) ||
3106 kmigmgrIsDeviceUsingDeviceProfiling(pGpu, pKernelMIGManager, pDevice))
3107 {
3108 pParams->gpcMask = kgrmgrGetLegacyGpcMask(pGpu, pKernelGraphicsManager);
3109 }
3110 else
3111 {
3112 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3113 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &pParams->grRouteInfo, &pKernelGraphics));
3114
3115 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3116 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
3117
3118 pParams->gpcMask = pKernelGraphicsStaticInfo->floorsweepingMasks.gpcMask;
3119 }
3120
3121 return status;
3122 }
3123
3124 /*!
3125 * subdeviceCtrlCmdKGrGetTpcMask
3126 *
3127 * Note:
3128 * pParams->gpcId is physical GPC id for non-MIG case, but logical GPC id for
3129 * MIG case.
3130 *
3131 * Lock Requirements:
3132 * Assert that API lock and GPUs lock held on entry
3133 */
3134 NV_STATUS
subdeviceCtrlCmdKGrGetTpcMask_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_TPC_MASK_PARAMS * pParams)3135 subdeviceCtrlCmdKGrGetTpcMask_IMPL
3136 (
3137 Subdevice *pSubdevice,
3138 NV2080_CTRL_GR_GET_TPC_MASK_PARAMS *pParams
3139 )
3140 {
3141 NV_STATUS status = NV_OK;
3142 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3143 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3144 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3145 KernelGraphics *pKernelGraphics;
3146 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
3147 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
3148 NvU32 gpcCount;
3149
3150 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
3151
3152 if (!IS_MIG_IN_USE(pGpu) ||
3153 kmigmgrIsDeviceUsingDeviceProfiling(pGpu, pKernelMIGManager, pDevice))
3154 {
3155 pParams->tpcMask = kgrmgrGetLegacyTpcMask(pGpu, pKernelGraphicsManager, pParams->gpcId);
3156 }
3157 else
3158 {
3159 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3160 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &pParams->grRouteInfo, &pKernelGraphics));
3161
3162 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3163 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
3164
3165 gpcCount = nvPopCount32(pKernelGraphicsStaticInfo->floorsweepingMasks.gpcMask);
3166 if (pParams->gpcId >= gpcCount)
3167 {
3168 NV_PRINTF(LEVEL_ERROR, "Incorrect GPC-Idx provided = %d\n", pParams->gpcId);
3169 return NV_ERR_INVALID_ARGUMENT;
3170 }
3171
3172 pParams->tpcMask = pKernelGraphicsStaticInfo->floorsweepingMasks.tpcMask[pParams->gpcId];
3173 }
3174
3175 return status;
3176 }
3177
3178 NV_STATUS
subdeviceCtrlCmdKGrGetNumTpcsForGpc_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_NUM_TPCS_FOR_GPC_PARAMS * pParams)3179 subdeviceCtrlCmdKGrGetNumTpcsForGpc_IMPL
3180 (
3181 Subdevice *pSubdevice,
3182 NV2080_CTRL_GR_GET_NUM_TPCS_FOR_GPC_PARAMS *pParams
3183 )
3184 {
3185 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3186 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3187 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3188 KernelGraphics *pKernelGraphics;
3189 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
3190 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo;
3191 NvU32 gpcCount;
3192
3193 portMemSet(&grRouteInfo, 0, sizeof(grRouteInfo));
3194 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3195 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &grRouteInfo, &pKernelGraphics));
3196
3197 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3198 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
3199
3200 gpcCount = nvPopCount32(pKernelGraphicsStaticInfo->floorsweepingMasks.gpcMask);
3201 if (pParams->gpcId >= gpcCount)
3202 {
3203 NV_PRINTF(LEVEL_ERROR, "Incorrect GPC-Idx provided = %d\n", pParams->gpcId);
3204 return NV_ERR_INVALID_ARGUMENT;
3205 }
3206
3207 pParams->numTpcs = pKernelGraphicsStaticInfo->floorsweepingMasks.tpcCount[pParams->gpcId];
3208
3209 return NV_OK;
3210 }
3211
3212 /*!
3213 * subdeviceCtrlCmdKGrGetPpcMask
3214 *
3215 * Lock Requirements:
3216 * Assert that API lock and GPUs lock held on entry
3217 */
3218 NV_STATUS
subdeviceCtrlCmdKGrGetPpcMask_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_PPC_MASK_PARAMS * pParams)3219 subdeviceCtrlCmdKGrGetPpcMask_IMPL
3220 (
3221 Subdevice *pSubdevice,
3222 NV2080_CTRL_GR_GET_PPC_MASK_PARAMS *pParams
3223 )
3224 {
3225 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3226 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3227 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3228 KernelGraphics *pKernelGraphics;
3229 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
3230 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
3231
3232 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
3233
3234 if (kmigmgrIsDeviceUsingDeviceProfiling(pGpu, pKernelMIGManager, pDevice))
3235 {
3236 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR, kgrmgrGetLegacyPpcMask(pGpu, pKernelGraphicsManager, pParams->gpcId, &pParams->ppcMask));
3237 }
3238 else
3239 {
3240 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3241 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &pParams->grRouteInfo, &pKernelGraphics));
3242
3243 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3244 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
3245 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pPpcMasks != NULL, NV_ERR_NOT_SUPPORTED);
3246 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pGrInfo != NULL, NV_ERR_NOT_SUPPORTED);
3247
3248 if (pParams->gpcId >=
3249 pKernelGraphicsStaticInfo->pGrInfo->infoList[NV2080_CTRL_GR_INFO_INDEX_LITTER_NUM_GPCS].data)
3250 {
3251 NV_PRINTF(LEVEL_ERROR, "Incorrect GPC-Idx provided = %d\n", pParams->gpcId);
3252 return NV_ERR_INVALID_ARGUMENT;
3253 }
3254
3255 pParams->ppcMask = pKernelGraphicsStaticInfo->pPpcMasks->mask[pParams->gpcId];
3256 }
3257
3258 return NV_OK;
3259 }
3260
3261 //
3262 // subdeviceCtrlCmdKGrFecsBindEvtbufForUid
3263 //
3264 // Lock Requirements:
3265 // Assert that API lock and GPUs lock held on entry
3266 //
3267 NV_STATUS
subdeviceCtrlCmdKGrFecsBindEvtbufForUid_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_FECS_BIND_EVTBUF_FOR_UID_PARAMS * pParams)3268 subdeviceCtrlCmdKGrFecsBindEvtbufForUid_IMPL
3269 (
3270 Subdevice *pSubdevice,
3271 NV2080_CTRL_GR_FECS_BIND_EVTBUF_FOR_UID_PARAMS *pParams
3272 )
3273 {
3274 NV_STATUS status;
3275 RmClient *pClient;
3276 RsResourceRef *pEventBufferRef = NULL;
3277 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3278 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
3279 NvBool bMIGInUse = IS_MIG_IN_USE(pGpu);
3280
3281 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
3282
3283 NV_ASSERT_OK_OR_RETURN(
3284 serverutilGetResourceRefWithType(hClient, pParams->hEventBuffer, classId(EventBuffer), &pEventBufferRef));
3285
3286 pClient = serverutilGetClientUnderLock(hClient);
3287 NV_ASSERT_OR_RETURN(pClient != NULL, NV_ERR_INVALID_CLIENT);
3288
3289 if (bMIGInUse)
3290 return NV_ERR_NOT_SUPPORTED;
3291
3292 status = fecsAddBindpoint(pGpu,
3293 pClient,
3294 pEventBufferRef,
3295 pSubdevice,
3296 pParams->bAllUsers,
3297 pParams->levelOfDetail,
3298 pParams->eventFilter,
3299 1,
3300 NULL);
3301
3302 return status;
3303 }
3304
3305 //
3306 // subdeviceCtrlCmdKGrFecsBindEvtbufForUidV2
3307 //
3308 // Lock Requirements:
3309 // Assert that API lock and GPUs lock held on entry
3310 //
3311 NV_STATUS
subdeviceCtrlCmdKGrFecsBindEvtbufForUidV2_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_FECS_BIND_EVTBUF_FOR_UID_V2_PARAMS * pParams)3312 subdeviceCtrlCmdKGrFecsBindEvtbufForUidV2_IMPL
3313 (
3314 Subdevice *pSubdevice,
3315 NV2080_CTRL_GR_FECS_BIND_EVTBUF_FOR_UID_V2_PARAMS *pParams
3316 )
3317 {
3318 NV_STATUS status;
3319 RmClient *pClient;
3320 RsResourceRef *pEventBufferRef = NULL;
3321 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3322 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
3323 pParams->reasonCode = NV2080_CTRL_GR_FECS_BIND_REASON_CODE_NONE;
3324
3325 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
3326
3327 NV_ASSERT_OK_OR_RETURN(
3328 serverutilGetResourceRefWithType(hClient, pParams->hEventBuffer, classId(EventBuffer), &pEventBufferRef));
3329
3330 pClient = serverutilGetClientUnderLock(hClient);
3331 NV_ASSERT_OR_RETURN(pClient != NULL, NV_ERR_INVALID_CLIENT);
3332
3333 status = fecsAddBindpoint(pGpu,
3334 pClient,
3335 pEventBufferRef,
3336 pSubdevice,
3337 pParams->bAllUsers,
3338 pParams->levelOfDetail,
3339 pParams->eventFilter,
3340 2,
3341 &pParams->reasonCode);
3342 return status;
3343 }
3344
3345 /*!
3346 * subdeviceCtrlCmdKGrGetPhysGpcMask
3347 *
3348 * Lock Requirements:
3349 * Assert that API lock and GPUs lock held on entry
3350 */
3351 NV_STATUS
subdeviceCtrlCmdKGrGetPhysGpcMask_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_PHYS_GPC_MASK_PARAMS * pParams)3352 subdeviceCtrlCmdKGrGetPhysGpcMask_IMPL
3353 (
3354 Subdevice *pSubdevice,
3355 NV2080_CTRL_GR_GET_PHYS_GPC_MASK_PARAMS *pParams
3356 )
3357 {
3358 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3359 KernelGraphics *pKernelGraphics;
3360 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
3361 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3362 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
3363 NvU32 grIdx = 0;
3364
3365 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
3366
3367 if (!IS_MIG_ENABLED(pGpu))
3368 {
3369 grIdx = 0;
3370 }
3371 //
3372 // if MIG is enabled we follow below policies:
3373 // For device level monitoring with no subscription - Return GPC mask for
3374 // requested syspipe
3375 // For valid subscription - Return physical GPC mask after validating that
3376 // a physical syspipe exist in given GPU instance
3377 //
3378 else if (kmigmgrIsDeviceUsingDeviceProfiling(pGpu, pKernelMIGManager, pDevice))
3379 {
3380 NV_ASSERT_OR_RETURN(pParams->physSyspipeId < GPU_MAX_GRS, NV_ERR_INVALID_ARGUMENT);
3381 grIdx = pParams->physSyspipeId;
3382 }
3383 else
3384 {
3385 MIG_INSTANCE_REF ref;
3386 RM_ENGINE_TYPE localRmEngineType;
3387
3388 //
3389 // Get the relevant subscription and see if provided physicalId is
3390 // valid in defined GPU instance
3391 //
3392 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3393 kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager,
3394 pDevice, &ref));
3395
3396 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3397 kmigmgrGetGlobalToLocalEngineType(pGpu, pKernelMIGManager, ref,
3398 RM_ENGINE_TYPE_GR(pParams->physSyspipeId),
3399 &localRmEngineType));
3400 // Not failing above means physSyspipeId is valid in GPU instance
3401 grIdx = pParams->physSyspipeId;
3402 }
3403
3404 pKernelGraphics = GPU_GET_KERNEL_GRAPHICS(pGpu, grIdx);
3405 NV_ASSERT_OR_RETURN(pKernelGraphics != NULL, NV_ERR_INVALID_STATE);
3406 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3407 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
3408
3409 pParams->gpcMask = pKernelGraphicsStaticInfo->floorsweepingMasks.physGpcMask;
3410
3411 return NV_OK;
3412 }
3413
3414 /*!
3415 * subdeviceCtrlCmdKGrGetZcullMask_IMPL
3416 *
3417 * Lock Requirements:
3418 * Assert that API lock and GPUs lock held on entry
3419 */
3420 NV_STATUS
subdeviceCtrlCmdKGrGetZcullMask_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_ZCULL_MASK_PARAMS * pParams)3421 subdeviceCtrlCmdKGrGetZcullMask_IMPL
3422 (
3423 Subdevice *pSubdevice,
3424 NV2080_CTRL_GR_GET_ZCULL_MASK_PARAMS *pParams
3425 )
3426 {
3427 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3428 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3429 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3430 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo;
3431 KernelGraphics *pKernelGraphics;
3432 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
3433 KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
3434
3435 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
3436
3437 if (kmigmgrIsDeviceUsingDeviceProfiling(pGpu, pKernelMIGManager, pDevice))
3438 {
3439 pParams->zcullMask = kgrmgrGetLegacyZcullMask(pGpu, pKernelGraphicsManager, pParams->gpcId);
3440 }
3441 else
3442 {
3443 portMemSet(&grRouteInfo, 0, sizeof(grRouteInfo));
3444 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3445 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &grRouteInfo, &pKernelGraphics));
3446
3447 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3448 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
3449
3450 if (pParams->gpcId >=
3451 pKernelGraphicsStaticInfo->pGrInfo->infoList[NV2080_CTRL_GR_INFO_INDEX_LITTER_NUM_GPCS].data)
3452 {
3453 NV_PRINTF(LEVEL_ERROR, "Incorrect GPC-Idx provided = %d\n", pParams->gpcId);
3454 return NV_ERR_INVALID_ARGUMENT;
3455 }
3456
3457 if (pKernelGraphicsStaticInfo->floorsweepingMasks.zcullMask[pParams->gpcId] == NV_U32_MAX)
3458 {
3459 return NV_ERR_NOT_SUPPORTED;
3460 }
3461 else
3462 {
3463 pParams->zcullMask = pKernelGraphicsStaticInfo->floorsweepingMasks.zcullMask[pParams->gpcId];
3464 }
3465 }
3466
3467 return NV_OK;
3468 }
3469
3470 /*!
3471 * subdeviceCtrlCmdKGrGetZcullInfo
3472 *
3473 * Lock Requirements:
3474 * Assert that API lock held on entry
3475 */
3476 NV_STATUS
subdeviceCtrlCmdKGrGetZcullInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_ZCULL_INFO_PARAMS * pParams)3477 subdeviceCtrlCmdKGrGetZcullInfo_IMPL
3478 (
3479 Subdevice *pSubdevice,
3480 NV2080_CTRL_GR_GET_ZCULL_INFO_PARAMS *pParams
3481 )
3482 {
3483 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3484 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3485 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3486 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo;
3487 KernelGraphics *pKernelGraphics;
3488 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
3489
3490 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
3491
3492 if (pKernelGraphicsManager == NULL)
3493 {
3494 return NV_ERR_NOT_SUPPORTED;
3495 }
3496
3497 portMemSet(&grRouteInfo, 0, sizeof(grRouteInfo));
3498 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3499 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &grRouteInfo, &pKernelGraphics));
3500
3501 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3502 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
3503 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pZcullInfo != NULL, NV_ERR_NOT_SUPPORTED);
3504
3505 portMemCopy(pParams,
3506 sizeof(*pParams),
3507 pKernelGraphicsStaticInfo->pZcullInfo,
3508 sizeof(*pKernelGraphicsStaticInfo->pZcullInfo));
3509
3510 return NV_OK;
3511 }
3512
3513 NV_STATUS
subdeviceCtrlCmdKGrCtxswPmMode_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_CTXSW_PM_MODE_PARAMS * pParams)3514 subdeviceCtrlCmdKGrCtxswPmMode_IMPL
3515 (
3516 Subdevice *pSubdevice,
3517 NV2080_CTRL_GR_CTXSW_PM_MODE_PARAMS *pParams
3518 )
3519 {
3520 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3521 NV_STATUS status = NV_OK;
3522
3523 if (IS_GSP_CLIENT(pGpu))
3524 {
3525 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo = pParams->grRouteInfo;
3526 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3527 KernelGraphics *pKernelGraphics;
3528 KernelChannel *pKernelChannel;
3529 KernelGraphicsContext *pKernelGraphicsContext;
3530 RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
3531
3532 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
3533
3534 if (pParams->pmMode != NV2080_CTRL_CTXSW_PM_MODE_NO_CTXSW)
3535 {
3536 kgrmgrCtrlSetChannelHandle(pParams->hChannel, &grRouteInfo);
3537 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3538 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager,
3539 GPU_RES_GET_DEVICE(pSubdevice),
3540 &grRouteInfo,
3541 &pKernelGraphics));
3542
3543 // Retrieve channel from either bare channel or TSG handle
3544 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3545 kchannelGetFromDualHandleRestricted(RES_GET_CLIENT(pSubdevice),
3546 pParams->hChannel, &pKernelChannel));
3547
3548 NV_ASSERT_OK_OR_RETURN(
3549 kgrctxFromKernelChannel(pKernelChannel, &pKernelGraphicsContext));
3550
3551 // Setup / promote the PM ctx buffer if required
3552 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3553 kgrctxSetupDeferredPmBuffer(pGpu, pKernelGraphicsContext, pKernelGraphics, pKernelChannel));
3554 }
3555
3556 status = pRmApi->Control(pRmApi,
3557 RES_GET_CLIENT_HANDLE(pSubdevice),
3558 RES_GET_HANDLE(pSubdevice),
3559 NV2080_CTRL_CMD_GR_CTXSW_PM_MODE,
3560 pParams,
3561 sizeof(*pParams));
3562 }
3563
3564 return status;
3565 }
3566
3567 /*!
3568 * @brief Gets information about ROPs.
3569 *
3570 * Lock Requirements:
3571 * Assert that API and Gpus lock held on entry
3572 *
3573 * @return NV_OK if success. Error otherwise.
3574 */
3575 NV_STATUS
subdeviceCtrlCmdKGrGetROPInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_ROP_INFO_PARAMS * pRopInfoParams)3576 subdeviceCtrlCmdKGrGetROPInfo_IMPL
3577 (
3578 Subdevice *pSubdevice,
3579 NV2080_CTRL_GR_GET_ROP_INFO_PARAMS *pRopInfoParams
3580 )
3581 {
3582 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3583 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3584 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3585 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo;
3586 KernelGraphics *pKernelGraphics;
3587 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
3588
3589 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner());
3590
3591 portMemSet(&grRouteInfo, 0, sizeof(grRouteInfo));
3592 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3593 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &grRouteInfo, &pKernelGraphics));
3594
3595 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3596 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
3597 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pRopInfo != NULL, NV_ERR_NOT_SUPPORTED);
3598
3599 portMemCopy(pRopInfoParams,
3600 sizeof(*pRopInfoParams),
3601 pKernelGraphicsStaticInfo->pRopInfo,
3602 sizeof(*pKernelGraphicsStaticInfo->pRopInfo));
3603
3604 return NV_OK;
3605 }
3606
3607 /*!
3608 * @brief Gets the current attribute buffer size.
3609 *
3610 * Lock Requirements:
3611 * Assert that API lock held on entry
3612 *
3613 * @return NV_OK if success. Error otherwise.
3614 */
3615 NV_STATUS
subdeviceCtrlCmdKGrGetAttributeBufferSize_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_ATTRIBUTE_BUFFER_SIZE_PARAMS * pAttribBufferSizeParams)3616 subdeviceCtrlCmdKGrGetAttributeBufferSize_IMPL
3617 (
3618 Subdevice *pSubdevice,
3619 NV2080_CTRL_GR_GET_ATTRIBUTE_BUFFER_SIZE_PARAMS *pAttribBufferSizeParams
3620 )
3621 {
3622 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3623 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3624 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo;
3625 KernelGraphics *pKernelGraphics;
3626 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
3627 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3628 NvU32 engineId;
3629
3630 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
3631
3632 portMemSet(&grRouteInfo, 0, sizeof(grRouteInfo));
3633 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3634 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &grRouteInfo, &pKernelGraphics));
3635
3636 // Verify static info is available
3637 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3638 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
3639
3640 if (pKernelGraphicsStaticInfo->pContextBuffersInfo == NULL)
3641 {
3642 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3643 kgraphicsInitializeDeferredStaticData(pGpu, pKernelGraphics, NV01_NULL_OBJECT, NV01_NULL_OBJECT));
3644
3645 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pContextBuffersInfo != NULL, NV_ERR_INVALID_STATE);
3646 }
3647
3648 engineId = NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_GRAPHICS_ATTRIBUTE_CB;
3649 pAttribBufferSizeParams->attribBufferSize = pKernelGraphicsStaticInfo->pContextBuffersInfo->engine[engineId].size;
3650
3651 return NV_OK;
3652 }
3653
3654 /*!
3655 * subdeviceCtrlCmdKGrGetEngineContextProperties
3656 *
3657 * Lock Requirements:
3658 * Assert that API lock and GPUs lock held on entry
3659 */
3660 NV_STATUS
subdeviceCtrlCmdKGrGetEngineContextProperties_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_ENGINE_CONTEXT_PROPERTIES_PARAMS * pParams)3661 subdeviceCtrlCmdKGrGetEngineContextProperties_IMPL
3662 (
3663 Subdevice *pSubdevice,
3664 NV2080_CTRL_GR_GET_ENGINE_CONTEXT_PROPERTIES_PARAMS *pParams
3665 )
3666 {
3667 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3668 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3669 KernelGraphics *pKernelGraphics;
3670 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
3671 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3672 NvU32 size = 0;
3673 NvU32 alignment = RM_PAGE_SIZE;
3674 NvU32 engineId;
3675
3676 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
3677
3678 engineId = DRF_VAL(0080_CTRL_FIFO, _GET_ENGINE_CONTEXT_PROPERTIES, _ENGINE_ID, pParams->engineId);
3679
3680 if (engineId >= NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_COUNT)
3681 {
3682 return NV_ERR_INVALID_ARGUMENT;
3683 }
3684
3685 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3686 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice,
3687 &pParams->grRouteInfo, &pKernelGraphics));
3688
3689 // Verify static info is available
3690 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
3691 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
3692
3693 if (pKernelGraphicsStaticInfo->pContextBuffersInfo == NULL)
3694 {
3695 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3696 kgraphicsInitializeDeferredStaticData(pGpu, pKernelGraphics, NV01_NULL_OBJECT, NV01_NULL_OBJECT));
3697
3698 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo->pContextBuffersInfo != NULL, NV_ERR_INVALID_STATE);
3699 }
3700
3701 size = pKernelGraphicsStaticInfo->pContextBuffersInfo->engine[engineId].size;
3702 alignment = pKernelGraphicsStaticInfo->pContextBuffersInfo->engine[engineId].alignment;
3703
3704 if (size == NV_U32_MAX)
3705 {
3706 return NV_ERR_NOT_SUPPORTED;
3707 }
3708
3709 if (pParams->bInfoPopulated)
3710 {
3711 size = NV_MAX(size, pParams->size);
3712 alignment = NV_MAX(alignment, pParams->alignment);
3713 }
3714
3715 pParams->size = size;
3716 pParams->alignment = alignment;
3717 pParams->bInfoPopulated = NV_TRUE;
3718
3719 return NV_OK;
3720 }
3721
3722 /*!
3723 * @brief Gets the Graphics Context buffer size and alignment
3724 *
3725 * Lock Requirements:
3726 * Assert that API and Gpus lock held on entry
3727 */
3728 NV_STATUS
subdeviceCtrlCmdKGrGetCtxBufferSize_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_CTX_BUFFER_SIZE_PARAMS * pParams)3729 subdeviceCtrlCmdKGrGetCtxBufferSize_IMPL
3730 (
3731 Subdevice *pSubdevice,
3732 NV2080_CTRL_GR_GET_CTX_BUFFER_SIZE_PARAMS *pParams
3733 )
3734 {
3735 NV_STATUS status = NV_OK;
3736 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3737 KernelGraphics *pKernelGraphics;
3738 RsClient *pClient = RES_GET_CLIENT(pSubdevice);
3739 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
3740 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3741 NV2080_CTRL_GR_CTX_BUFFER_INFO *pCtxBufferInfo;
3742 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo;
3743 KernelChannel *pKernelChannel;
3744 KernelGraphicsContext *pKernelGraphicsContext;
3745 NvU32 bufferCount;
3746 NvU64 totalBufferSize;
3747 NvU64 prevAlignment;
3748 NvU32 i;
3749
3750 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
3751
3752 //
3753 // vGPU:
3754 //
3755 // Since vGPU does all real hardware management in the
3756 // host, if we are in guest OS (where IS_VIRTUAL(pGpu) is true),
3757 // do an RPC to the host to fetch the total GR Context Buffer Size.
3758 //
3759 if (IS_VIRTUAL_WITHOUT_SRIOV(pGpu) ||
3760 (IS_VIRTUAL_WITH_SRIOV(pGpu) && gpuIsWarBug200577889SriovHeavyEnabled(pGpu)))
3761 {
3762 CALL_CONTEXT *pCallContext = resservGetTlsCallContext();
3763 RmCtrlParams *pRmCtrlParams = pCallContext->pControlParams;
3764
3765 NV_RM_RPC_CONTROL(pGpu,
3766 pRmCtrlParams->hClient,
3767 pRmCtrlParams->hObject,
3768 pRmCtrlParams->cmd,
3769 pRmCtrlParams->pParams,
3770 pRmCtrlParams->paramsSize,
3771 status);
3772 return status;
3773 }
3774
3775 portMemSet(&grRouteInfo, 0, sizeof(grRouteInfo));
3776 kgrmgrCtrlSetChannelHandle(pParams->hChannel, &grRouteInfo);
3777 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3778 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice,
3779 &grRouteInfo, &pKernelGraphics));
3780
3781 // Get channel from provided handle and owner client
3782 NV_CHECK_OK_OR_RETURN(LEVEL_INFO,
3783 CliGetKernelChannel(pClient, pParams->hChannel, &pKernelChannel));
3784
3785 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3786 kgrctxFromKernelChannel(pKernelChannel, &pKernelGraphicsContext));
3787
3788 // Get the total buffer count
3789 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3790 kgrctxGetBufferCount(pGpu, pKernelGraphicsContext, pKernelGraphics, &bufferCount));
3791
3792 pCtxBufferInfo = portMemAllocNonPaged(bufferCount * sizeof(NV2080_CTRL_GR_CTX_BUFFER_INFO));
3793 NV_CHECK_OR_ELSE(LEVEL_ERROR,
3794 pCtxBufferInfo != NULL,
3795 status = NV_ERR_NO_MEMORY;
3796 goto done;);
3797 portMemSet(pCtxBufferInfo, 0, bufferCount * sizeof(NV2080_CTRL_GR_CTX_BUFFER_INFO));
3798
3799 NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
3800 kgrctxGetCtxBufferInfo(pGpu,
3801 pKernelGraphicsContext,
3802 pKernelGraphics,
3803 kchannelGetGfid(pKernelChannel),
3804 bufferCount,
3805 &bufferCount,
3806 pCtxBufferInfo),
3807 done);
3808
3809 //
3810 // Calculate total size by walking thru all buffers & alignments. Adjust the total size
3811 // by adding the respective alignment so that the mapping VA can be adjusted.
3812 //
3813 totalBufferSize = 0;
3814 prevAlignment = 0x0;
3815 for (i = 0; i < bufferCount; i++)
3816 {
3817 if (prevAlignment != pCtxBufferInfo[i].alignment)
3818 {
3819 totalBufferSize += pCtxBufferInfo[i].alignment;
3820 prevAlignment = pCtxBufferInfo[i].alignment;
3821 }
3822
3823 totalBufferSize += (pCtxBufferInfo[i].alignment != 0x0) ?
3824 NV_ALIGN_UP(pCtxBufferInfo[i].size, pCtxBufferInfo[i].alignment) : pCtxBufferInfo[i].size;
3825 }
3826
3827 pParams->totalBufferSize = totalBufferSize;
3828
3829 done:
3830 portMemFree(pCtxBufferInfo);
3831 return status;
3832 }
3833
3834 /*!
3835 * @brief Gets the Graphics Context buffer info like opaque buffer pointer
3836 * size, alignment, aperture, allocation contiguity etc.
3837 *
3838 * Lock Requirements:
3839 * Assert that API and Gpus lock held on entry
3840 */
3841 NV_STATUS
subdeviceCtrlCmdKGrGetCtxBufferInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_CTX_BUFFER_INFO_PARAMS * pParams)3842 subdeviceCtrlCmdKGrGetCtxBufferInfo_IMPL
3843 (
3844 Subdevice *pSubdevice,
3845 NV2080_CTRL_GR_GET_CTX_BUFFER_INFO_PARAMS *pParams
3846 )
3847 {
3848 NV_STATUS status = NV_OK;
3849 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3850 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3851 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo;
3852 RsClient *pUserClient;
3853 KernelGraphics *pKernelGraphics;
3854 KernelChannel *pKernelChannel;
3855 KernelGraphicsContext *pKernelGraphicsContext;
3856
3857 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
3858
3859 //
3860 // vGPU:
3861 //
3862 // Since vGPU does all real hardware management in the
3863 // host, if we are in guest OS (where IS_VIRTUAL(pGpu) is true),
3864 // do an RPC to the host to get Graphics context buffers information.
3865 //
3866 if (IS_VIRTUAL_WITHOUT_SRIOV(pGpu) ||
3867 (IS_VIRTUAL_WITH_SRIOV(pGpu) && gpuIsWarBug200577889SriovHeavyEnabled(pGpu)))
3868 {
3869 CALL_CONTEXT *pCallContext = resservGetTlsCallContext();
3870 RmCtrlParams *pRmCtrlParams = pCallContext->pControlParams;
3871
3872 NV_RM_RPC_CONTROL(pGpu,
3873 pRmCtrlParams->hClient,
3874 pRmCtrlParams->hObject,
3875 pRmCtrlParams->cmd,
3876 pRmCtrlParams->pParams,
3877 pRmCtrlParams->paramsSize,
3878 status);
3879 return status;
3880 }
3881
3882 NV_CHECK_OK_OR_RETURN(LEVEL_INFO,
3883 serverGetClientUnderLock(&g_resServ, pParams->hUserClient, &pUserClient));
3884
3885 // Get channel from provided handle and owner client
3886 NV_CHECK_OK_OR_RETURN(LEVEL_INFO,
3887 CliGetKernelChannel(pUserClient, pParams->hChannel, &pKernelChannel));
3888
3889 portMemSet(&grRouteInfo, 0, sizeof(grRouteInfo));
3890 kgrmgrCtrlSetChannelHandle(pParams->hChannel, &grRouteInfo);
3891 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3892 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager,
3893 GPU_RES_GET_DEVICE(pKernelChannel),
3894 &grRouteInfo, &pKernelGraphics));
3895
3896 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3897 kgrctxFromKernelChannel(pKernelChannel, &pKernelGraphicsContext));
3898
3899 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3900 kgrctxGetCtxBufferInfo(pGpu,
3901 pKernelGraphicsContext,
3902 pKernelGraphics,
3903 kchannelGetGfid(pKernelChannel),
3904 NV_ARRAY_ELEMENTS(pParams->ctxBufferInfo),
3905 &pParams->bufferCount,
3906 pParams->ctxBufferInfo));
3907
3908 return status;
3909 }
3910
3911 /*!
3912 * subdeviceCtrlCmdKGrInternalGetCtxBufferPtes
3913 *
3914 * Lock Requirements:
3915 * Assert that API lock and GPUs lock held on entry
3916 */
3917 NV_STATUS
subdeviceCtrlCmdKGrGetCtxBufferPtes_IMPL(Subdevice * pSubdevice,NV2080_CTRL_KGR_GET_CTX_BUFFER_PTES_PARAMS * pParams)3918 subdeviceCtrlCmdKGrGetCtxBufferPtes_IMPL
3919 (
3920 Subdevice *pSubdevice,
3921 NV2080_CTRL_KGR_GET_CTX_BUFFER_PTES_PARAMS *pParams
3922 )
3923 {
3924 NV_STATUS status = NV_OK;
3925 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
3926 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
3927 NV2080_CTRL_GR_ROUTE_INFO grRouteInfo;
3928 RsClient *pUserClient;
3929 KernelGraphics *pKernelGraphics;
3930 KernelChannel *pKernelChannel;
3931 KernelGraphicsContext *pKernelGraphicsContext;
3932
3933 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
3934
3935 //
3936 // Currently, ROUTE_TO_VGPU_HOST instructs resource server to call the RPC
3937 // on all vGPU configurations including SRIOV Standard which is not required.
3938 // Hence, manually dispatching the RPC for required vGPU configs.
3939 //
3940 // vGPU:
3941 //
3942 // Since vGPU does all real hardware management in the
3943 // host, if we are in guest OS (where IS_VIRTUAL(pGpu) is true),
3944 // do an RPC to the host to get Graphics context buffers PTEs information.
3945 //
3946 if (IS_VIRTUAL_WITHOUT_SRIOV(pGpu) ||
3947 (IS_VIRTUAL_WITH_SRIOV(pGpu) && gpuIsWarBug200577889SriovHeavyEnabled(pGpu)))
3948 {
3949 CALL_CONTEXT *pCallContext = resservGetTlsCallContext();
3950 RmCtrlParams *pRmCtrlParams = pCallContext->pControlParams;
3951 NvHandle hClient = RES_GET_CLIENT_HANDLE(pSubdevice);
3952 NvHandle hObject = RES_GET_HANDLE(pSubdevice);
3953
3954 NV_RM_RPC_CONTROL(pGpu,
3955 hClient,
3956 hObject,
3957 pRmCtrlParams->cmd,
3958 pRmCtrlParams->pParams,
3959 pRmCtrlParams->paramsSize,
3960 status);
3961 return status;
3962 }
3963
3964 NV_CHECK_OK_OR_RETURN(LEVEL_INFO,
3965 serverGetClientUnderLock(&g_resServ, pParams->hUserClient, &pUserClient));
3966
3967 // Get channel from provided handle and owner client
3968 NV_CHECK_OK_OR_RETURN(LEVEL_INFO,
3969 CliGetKernelChannel(pUserClient, pParams->hChannel, &pKernelChannel));
3970
3971 portMemSet(&grRouteInfo, 0, sizeof(grRouteInfo));
3972 kgrmgrCtrlSetChannelHandle(pParams->hChannel, &grRouteInfo);
3973 NV_CHECK_OK_OR_RETURN(LEVEL_INFO,
3974 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager,
3975 GPU_RES_GET_DEVICE(pKernelChannel),
3976 &grRouteInfo, &pKernelGraphics));
3977
3978 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3979 kgrctxFromKernelChannel(pKernelChannel, &pKernelGraphicsContext));
3980
3981 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
3982 kgrctxGetCtxBufferPtes(pGpu,
3983 pKernelGraphicsContext,
3984 pKernelGraphics,
3985 kchannelGetGfid(pKernelChannel),
3986 pParams->bufferType,
3987 pParams->firstPage,
3988 pParams->physAddrs,
3989 NV_ARRAY_ELEMENTS(pParams->physAddrs),
3990 &pParams->numPages,
3991 &pParams->bNoMorePages));
3992
3993 return status;
3994 }
3995
3996 /*!
3997 * subdeviceCtrlCmdKGrGetGfxGpcAndTpcInfo
3998 *
3999 * Lock Requirements:
4000 * Assert that API lock and GPUs lock held on entry
4001 */
4002 NV_STATUS
subdeviceCtrlCmdKGrGetGfxGpcAndTpcInfo_IMPL(Subdevice * pSubdevice,NV2080_CTRL_GR_GET_GFX_GPC_AND_TPC_INFO_PARAMS * pParams)4003 subdeviceCtrlCmdKGrGetGfxGpcAndTpcInfo_IMPL
4004 (
4005 Subdevice *pSubdevice,
4006 NV2080_CTRL_GR_GET_GFX_GPC_AND_TPC_INFO_PARAMS *pParams
4007 )
4008 {
4009 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
4010 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
4011 KernelGraphics *pKernelGraphics;
4012 const KGRAPHICS_STATIC_INFO *pKernelGraphicsStaticInfo;
4013 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
4014
4015 LOCK_ASSERT_AND_RETURN(rmapiLockIsOwner() && rmGpuLockIsOwner());
4016
4017 NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
4018 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice,
4019 &pParams->grRouteInfo, &pKernelGraphics));
4020
4021 // Verify static info is available
4022 pKernelGraphicsStaticInfo = kgraphicsGetStaticInfo(pGpu, pKernelGraphics);
4023 NV_ASSERT_OR_RETURN(pKernelGraphicsStaticInfo != NULL, NV_ERR_INVALID_STATE);
4024
4025 pParams->physGfxGpcMask = pKernelGraphicsStaticInfo->floorsweepingMasks.physGfxGpcMask;
4026 pParams->numGfxTpc = pKernelGraphicsStaticInfo->floorsweepingMasks.numGfxTpc;
4027
4028 return NV_OK;
4029 }
4030
4031 #define KGR_DO_WITH_GR(pGpu, pKernelGraphics, body) do \
4032 { \
4033 (body); \
4034 } while (0);
4035
4036 NV_STATUS
subdeviceCtrlCmdGrInternalSetFecsTraceHwEnable_IMPL(Subdevice * pSubdevice,NV2080_CTRL_INTERNAL_GR_SET_FECS_TRACE_HW_ENABLE_PARAMS * pParams)4037 subdeviceCtrlCmdGrInternalSetFecsTraceHwEnable_IMPL
4038 (
4039 Subdevice *pSubdevice,
4040 NV2080_CTRL_INTERNAL_GR_SET_FECS_TRACE_HW_ENABLE_PARAMS *pParams
4041 )
4042 {
4043 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
4044 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
4045 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
4046 NV_STATUS status = NV_OK;
4047 KernelGraphics *pKernelGraphics;
4048
4049 LOCK_ASSERT_AND_RETURN(rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
4050
4051 NV_CHECK_OK_OR_RETURN(
4052 LEVEL_ERROR,
4053 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice,
4054 &pParams->grRouteInfo, &pKernelGraphics));
4055
4056 KGR_DO_WITH_GR(pGpu, pKernelGraphics,
4057 kgraphicsSetFecsTraceHwEnable_HAL(pGpu, pKernelGraphics, pParams->bEnable));
4058 pKernelGraphics->bCtxswLoggingEnabled = pParams->bEnable;
4059
4060 return status;
4061 }
4062
4063 NV_STATUS
subdeviceCtrlCmdGrInternalGetFecsTraceHwEnable_IMPL(Subdevice * pSubdevice,NV2080_CTRL_INTERNAL_GR_GET_FECS_TRACE_HW_ENABLE_PARAMS * pParams)4064 subdeviceCtrlCmdGrInternalGetFecsTraceHwEnable_IMPL
4065 (
4066 Subdevice *pSubdevice,
4067 NV2080_CTRL_INTERNAL_GR_GET_FECS_TRACE_HW_ENABLE_PARAMS *pParams
4068 )
4069 {
4070 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
4071 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
4072 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
4073 NV_STATUS status = NV_OK;
4074 KernelGraphics *pKernelGraphics;
4075
4076 LOCK_ASSERT_AND_RETURN(rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
4077
4078 NV_CHECK_OK_OR_RETURN(
4079 LEVEL_ERROR,
4080 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &pParams->grRouteInfo,
4081 &pKernelGraphics));
4082
4083 KGR_DO_WITH_GR(pGpu, pKernelGraphics,
4084 pParams->bEnable = kgraphicsIsCtxswLoggingEnabled(pGpu, pKernelGraphics));
4085
4086 return status;
4087 }
4088
4089 NV_STATUS
subdeviceCtrlCmdGrInternalSetFecsTraceRdOffset_IMPL(Subdevice * pSubdevice,NV2080_CTRL_INTERNAL_GR_SET_FECS_TRACE_RD_OFFSET_PARAMS * pParams)4090 subdeviceCtrlCmdGrInternalSetFecsTraceRdOffset_IMPL
4091 (
4092 Subdevice *pSubdevice,
4093 NV2080_CTRL_INTERNAL_GR_SET_FECS_TRACE_RD_OFFSET_PARAMS *pParams
4094 )
4095 {
4096 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
4097 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
4098 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
4099 NV_STATUS status = NV_OK;
4100 KernelGraphics *pKernelGraphics;
4101
4102 LOCK_ASSERT_AND_RETURN(rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
4103
4104 NV_CHECK_OK_OR_RETURN(
4105 LEVEL_ERROR,
4106 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &pParams->grRouteInfo,
4107 &pKernelGraphics));
4108
4109 KGR_DO_WITH_GR(pGpu, pKernelGraphics,
4110 kgraphicsSetFecsTraceRdOffset_HAL(pGpu, pKernelGraphics, pParams->offset));
4111
4112 return status;
4113 }
4114
4115 NV_STATUS
subdeviceCtrlCmdGrInternalGetFecsTraceRdOffset_IMPL(Subdevice * pSubdevice,NV2080_CTRL_INTERNAL_GR_GET_FECS_TRACE_RD_OFFSET_PARAMS * pParams)4116 subdeviceCtrlCmdGrInternalGetFecsTraceRdOffset_IMPL
4117 (
4118 Subdevice *pSubdevice,
4119 NV2080_CTRL_INTERNAL_GR_GET_FECS_TRACE_RD_OFFSET_PARAMS *pParams
4120 )
4121 {
4122 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
4123 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
4124 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
4125 NV_STATUS status = NV_OK;
4126 KernelGraphics *pKernelGraphics;
4127
4128 LOCK_ASSERT_AND_RETURN(rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
4129
4130 NV_CHECK_OK_OR_RETURN(
4131 LEVEL_ERROR,
4132 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &pParams->grRouteInfo,
4133 &pKernelGraphics));
4134
4135 KGR_DO_WITH_GR(pGpu, pKernelGraphics,
4136 pParams->offset = kgraphicsGetFecsTraceRdOffset_HAL(pGpu, pKernelGraphics));
4137
4138 return status;
4139 }
4140
4141 NV_STATUS
subdeviceCtrlCmdGrInternalSetFecsTraceWrOffset_IMPL(Subdevice * pSubdevice,NV2080_CTRL_INTERNAL_GR_SET_FECS_TRACE_WR_OFFSET_PARAMS * pParams)4142 subdeviceCtrlCmdGrInternalSetFecsTraceWrOffset_IMPL
4143 (
4144 Subdevice *pSubdevice,
4145 NV2080_CTRL_INTERNAL_GR_SET_FECS_TRACE_WR_OFFSET_PARAMS *pParams
4146 )
4147 {
4148 OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
4149 KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
4150 Device *pDevice = GPU_RES_GET_DEVICE(pSubdevice);
4151 NV_STATUS status = NV_OK;
4152 KernelGraphics *pKernelGraphics;
4153
4154 LOCK_ASSERT_AND_RETURN(rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
4155
4156 NV_CHECK_OK_OR_RETURN(
4157 LEVEL_ERROR,
4158 kgrmgrCtrlRouteKGRWithDevice(pGpu, pKernelGraphicsManager, pDevice, &pParams->grRouteInfo,
4159 &pKernelGraphics));
4160
4161 KGR_DO_WITH_GR(pGpu, pKernelGraphics,
4162 kgraphicsSetFecsTraceWrOffset_HAL(pGpu, pKernelGraphics, pParams->offset));
4163
4164 return status;
4165 }
4166