1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 1993-2024 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 /***************************** HW State Routines ***************************\
25 *                                                                           *
26 *         System Object Function Definitions.                               *
27 *                                                                           *
28 \***************************************************************************/
29 
30 #include "core/core.h"
31 #include "core/system.h"
32 #include "gpu/gpu.h"
33 #include "gpu_mgr/gpu_mgr.h"
34 #include "core/locks.h"
35 #include "os/os.h"
36 #include "nvrm_registry.h"
37 #include "core/thread_state.h"
38 #include "diagnostics/tracer.h"
39 #include "rmosxfac.h"
40 #include "tls/tls.h"
41 #include "rmapi/rmapi.h"
42 #include "rmapi/client.h"
43 #include "core/hal_mgr.h"
44 #include "nvoc/rtti.h"
45 
46 #include "platform/chipset/chipset.h"
47 #include "platform/cpu.h"
48 #include "platform/platform.h"
49 #include "diagnostics/gpu_acct.h"
50 #include "platform/platform_request_handler.h"
51 #include "gpu/external_device/gsync.h"
52 #include "virtualization/kernel_vgpu_mgr.h"
53 #include "mem_mgr/virt_mem_mgr.h"
54 #include "diagnostics/journal.h"
55 #include "virtualization/hypervisor/hypervisor.h"
56 #include "power/gpu_boost_mgr.h"
57 #include "compute/fabric.h"
58 #include "gpu_mgr/gpu_db.h"
59 #include "core/bin_data.h"
60 
61 // local static functions
62 static NV_STATUS    _sysCreateOs(OBJSYS *);
63 static NV_STATUS    _sysCreateChildObjects(OBJSYS *);
64 static void         _sysDeleteChildObjects(OBJSYS *);
65 static void         _sysNvSwitchDetection(OBJSYS *pSys);
66 static void         _sysInitStaticConfig(OBJSYS *pSys);;
67 
68 // Global pointer to instance of OBJSYS
69 OBJSYS *g_pSys = NULL;
70 
71 typedef struct
72 {
73     NvLength               childOffset;
74     const NVOC_CLASS_INFO *pClassInfo;
75     NvBool                 bDynamicConstruct;
76 } sysChildObject;
77 
78 static sysChildObject sysChildObjects[] =
79 {
80     { NV_OFFSETOF(OBJSYS, pHalMgr),         classInfo(OBJHALMGR),       NV_TRUE },
81     { NV_OFFSETOF(OBJSYS, pPfm),            classInfo(OBJPFM),          NV_TRUE },
82     { NV_OFFSETOF(OBJSYS, pHypervisor),     classInfo(OBJHYPERVISOR),   NV_TRUE },
83     { NV_OFFSETOF(OBJSYS, pOS),             classInfo(OBJOS),           NV_FALSE }, //  OS: Wrapper macros must be enabled to use :CONSTRUCT.
84     { NV_OFFSETOF(OBJSYS, pCl),             classInfo(OBJCL),           NV_TRUE },
85     { NV_OFFSETOF(OBJSYS, pGpuMgr),         classInfo(OBJGPUMGR),       NV_TRUE },
86     { NV_OFFSETOF(OBJSYS, pGsyncMgr),       classInfo(OBJGSYNCMGR),     NV_TRUE },
87     { NV_OFFSETOF(OBJSYS, pGpuAcct),        classInfo(GpuAccounting),   NV_TRUE },
88     { NV_OFFSETOF(OBJSYS, pPlatformRequestHandler), classInfo(PlatformRequestHandler),  NV_TRUE },
89     { NV_OFFSETOF(OBJSYS, pRcDB),           classInfo(OBJRCDB),         NV_TRUE },
90     { NV_OFFSETOF(OBJSYS, pVmm),            classInfo(OBJVMM),          NV_TRUE },
91     { NV_OFFSETOF(OBJSYS, pKernelVgpuMgr),  classInfo(KernelVgpuMgr),   NV_TRUE },
92     { NV_OFFSETOF(OBJSYS, pGpuBoostMgr),    classInfo(OBJGPUBOOSTMGR),  NV_TRUE },
93     { NV_OFFSETOF(OBJSYS, pFabric),         classInfo(Fabric),          NV_TRUE },
94     { NV_OFFSETOF(OBJSYS, pGpuDb),          classInfo(GpuDb),           NV_TRUE },
95 };
96 
97 static void
_sysDestroyMemExportCache(OBJSYS * pSys)98 _sysDestroyMemExportCache(OBJSYS *pSys)
99 {
100     if (pSys->pSysMemExportModuleLock != NULL)
101     {
102         portSyncRwLockDestroy(pSys->pSysMemExportModuleLock);
103         pSys->pSysMemExportModuleLock = NULL;
104     }
105 
106     NV_ASSERT(multimapCountItems(&pSys->sysMemExportCache) == 0);
107 
108     multimapDestroy(&pSys->sysMemExportCache);
109 }
110 
111 static NV_STATUS
_sysInitMemExportCache(OBJSYS * pSys)112 _sysInitMemExportCache(OBJSYS *pSys)
113 {
114     multimapInit(&pSys->sysMemExportCache, portMemAllocatorGetGlobalNonPaged());
115 
116     pSys->pSysMemExportModuleLock =
117                     portSyncRwLockCreate(portMemAllocatorGetGlobalNonPaged());
118     if (pSys->pSysMemExportModuleLock == NULL)
119     {
120         _sysDestroyMemExportCache(pSys);
121         return NV_ERR_NO_MEMORY;
122     }
123 
124     return NV_OK;
125 }
126 
127 static void
_sysDestroyMemExportClient(OBJSYS * pSys)128 _sysDestroyMemExportClient(OBJSYS *pSys)
129 {
130     RM_API *pRmApi;
131 
132     if (pSys->hSysMemExportClient == 0)
133         return;
134 
135     // Acquire lock to keep rmapiGetInterface() happy.
136     NV_ASSERT(rmapiLockAcquire(API_LOCK_FLAGS_NONE,
137                                RM_LOCK_MODULES_DESTROY) == NV_OK);
138 
139     pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
140 
141     NV_ASSERT(pRmApi->Free(pRmApi, pSys->hSysMemExportClient,
142                            pSys->hSysMemExportClient) == NV_OK);
143 
144     rmapiLockRelease();
145 
146     pSys->hSysMemExportClient = 0;
147 }
148 
149 static NV_STATUS
_sysInitMemExportClient(OBJSYS * pSys)150 _sysInitMemExportClient(OBJSYS *pSys)
151 {
152     RM_API *pRmApi;
153     NV_STATUS status;
154 
155     // Acquire lock to keep rmapiGetInterface() happy.
156     status = rmapiLockAcquire(API_LOCK_FLAGS_NONE, RM_LOCK_MODULES_INIT);
157     if (status != NV_OK)
158         return status;
159 
160     pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
161 
162     status = pRmApi->AllocWithHandle(pRmApi, NV01_NULL_OBJECT,
163                                      NV01_NULL_OBJECT, NV01_NULL_OBJECT,
164                                      NV01_ROOT, &pSys->hSysMemExportClient,
165                                      sizeof(pSys->hSysMemExportClient));
166 
167     rmapiLockRelease();
168 
169     return status;
170 }
171 
172 NV_STATUS
sysConstruct_IMPL(OBJSYS * pSys)173 sysConstruct_IMPL(OBJSYS *pSys)
174 {
175     NV_STATUS          status;
176     OBJOS             *pOS;
177     NvU32              sec = 0;
178     NvU32              uSec = 0;
179 
180     g_pSys = pSys;
181 
182     RMTRACE_INIT();
183     RMTRACE_INIT_NEW();
184 
185     _sysInitStaticConfig(pSys);
186 
187     status = _sysCreateChildObjects(pSys);
188     if (status != NV_OK)
189     {
190         goto failed;
191     }
192 
193     // Use the monotonic system clock for a unique value
194     pOS = SYS_GET_OS(pSys);
195     osGetCurrentTime(&sec, &uSec);
196     pSys->rmInstanceId = (NvU64)sec * 1000000 + (NvU64)uSec;
197 
198     {
199         // Using Hypervisor native interface to detect
200         OBJHYPERVISOR *pHypervisor = SYS_GET_HYPERVISOR(pSys);
201         if (pHypervisor)
202             hypervisorDetection(pHypervisor, pOS);
203     }
204 
205     if (!pOS->osRmInitRm(pOS))
206     {
207         status = NV_ERR_GENERIC;
208         goto failed;
209     }
210 
211     _sysNvSwitchDetection(pSys);
212 
213     // init cpu state
214     RmInitCpuInfo();
215 
216     // allocate locks, semaphores, whatever
217     status = rmLocksAlloc(pSys);
218     if (status != NV_OK)
219         goto failed;
220 
221     status = threadStateGlobalAlloc();
222     if (status != NV_OK)
223         goto failed;
224 
225     status = rmapiInitialize();
226     if (status != NV_OK)
227         goto failed;
228 
229     status = _sysInitMemExportCache(pSys);
230     if (status != NV_OK)
231         goto failed;
232 
233     status = _sysInitMemExportClient(pSys);
234     if (status != NV_OK)
235         goto failed;
236 
237     bindataInitialize();
238 
239     return NV_OK;
240 
241 failed:
242 
243     _sysDestroyMemExportCache(pSys);
244 
245     _sysDeleteChildObjects(pSys);
246 
247     g_pSys = NULL;
248 
249     threadStateGlobalFree();
250 
251     rmapiShutdown();
252     rmLocksFree(pSys);
253 
254     return status;
255 }
256 
257 void
sysDestruct_IMPL(OBJSYS * pSys)258 sysDestruct_IMPL(OBJSYS *pSys)
259 {
260 
261     pSys->setProperty(pSys, PDB_PROP_SYS_DESTRUCTING, NV_TRUE);
262 
263     _sysDestroyMemExportCache(pSys);
264     _sysDestroyMemExportClient(pSys);
265 
266     //
267     // Any of these operations might fail but go ahead and
268     // attempt to free remaining resources before complaining.
269     //
270     listDestroy(&g_clientListBehindGpusLock);
271     listDestroy(&g_userInfoList);
272     multimapDestroy(&g_osInfoList);
273 
274     rmapiShutdown();
275     osSyncWithRmDestroy();
276     threadStateGlobalFree();
277     rmLocksFree(pSys);
278 
279     //
280     // Free child objects
281     //
282     _sysDeleteChildObjects(pSys);
283 
284     g_pSys = NULL;
285 
286     RMTRACE_DESTROY();
287     RMTRACE_DESTROY_NEW();
288 
289     bindataDestroy();
290 }
291 
292 //
293 // Create static system object offspring.
294 //
295 static NV_STATUS
_sysCreateChildObjects(OBJSYS * pSys)296 _sysCreateChildObjects(OBJSYS *pSys)
297 {
298     NV_STATUS status = NV_OK;
299     NvU32 i, n;
300 
301     n = NV_ARRAY_ELEMENTS(sysChildObjects);
302 
303     for (i = 0; i < n; i++)
304     {
305         if (sysChildObjects[i].bDynamicConstruct)
306         {
307             NvLength offset = sysChildObjects[i].childOffset;
308             Dynamic **ppChild = reinterpretCast(reinterpretCast(pSys, NvU8*) + offset, Dynamic**);
309             Dynamic *pNewObj;
310             status = objCreateDynamic(&pNewObj, pSys, sysChildObjects[i].pClassInfo);
311 
312             if (status == NV_OK)
313             {
314                 *ppChild = pNewObj;
315             }
316         }
317         else
318         {
319             //
320             // More cases should NOT be added to this list. OBJOS needs to be
321             // cleaned up to use the bDynamicConstruct path then this hack can
322             // be removed.
323             //
324             switch (sysChildObjects[i].pClassInfo->classId)
325             {
326                 case classId(OBJOS):
327                     status = _sysCreateOs(pSys);
328                     break;
329                 default:
330                     NV_ASSERT(0);
331                     status = NV_ERR_INVALID_ARGUMENT;
332                     break;
333             }
334         }
335 
336         // RMCONFIG:  Bail on errors unless the feature/object/engine/class
337         //            is simply unsupported
338         if (status == NV_ERR_NOT_SUPPORTED)
339             status = NV_OK;
340         if (status != NV_OK) break;
341     }
342 
343     return status;
344 }
345 
346 static void
_sysDeleteChildObjects(OBJSYS * pSys)347 _sysDeleteChildObjects(OBJSYS *pSys)
348 {
349     int i;
350 
351     osRmCapUnregister(&pSys->pOsRmCaps);
352 
353     for (i = NV_ARRAY_ELEMENTS(sysChildObjects) - 1; i >= 0; i--)
354     {
355         NvLength offset = sysChildObjects[i].childOffset;
356         Dynamic **ppChild = reinterpretCast(reinterpretCast(pSys, NvU8*) + offset, Dynamic**);
357         objDelete(*ppChild);
358         *ppChild = NULL;
359     }
360 }
361 
362 static void
_sysRegistryOverrideResourceServer(OBJSYS * pSys,OBJGPU * pGpu)363 _sysRegistryOverrideResourceServer
364 (
365     OBJSYS *pSys,
366     OBJGPU *pGpu
367 )
368 {
369     NvU32 data32;
370 
371     // Set read-only API lock override
372     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_READONLY_API_LOCK,
373                             &data32) == NV_OK)
374     {
375         NvU32 apiMask = 0;
376 
377         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _ALLOC_RESOURCE, _ENABLE, data32))
378             apiMask |= NVBIT(RS_API_ALLOC_RESOURCE);
379 
380         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _FREE_RESOURCE, _ENABLE, data32))
381             apiMask |= NVBIT(RS_API_FREE_RESOURCE);
382 
383         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _MAP, _ENABLE, data32))
384             apiMask |= NVBIT(RS_API_MAP);
385 
386         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _UNMAP, _ENABLE, data32))
387             apiMask |= NVBIT(RS_API_UNMAP);
388 
389         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _INTER_MAP, _ENABLE, data32))
390             apiMask |= NVBIT(RS_API_INTER_MAP);
391 
392         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _INTER_UNMAP, _ENABLE, data32))
393             apiMask |= NVBIT(RS_API_INTER_UNMAP);
394 
395         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _CTRL, _ENABLE, data32))
396             apiMask |= NVBIT(RS_API_CTRL);
397 
398         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _COPY, _ENABLE, data32))
399             apiMask |= NVBIT(RS_API_COPY);
400 
401         if (FLD_TEST_DRF(_REG_STR_RM, _READONLY_API_LOCK, _SHARE, _ENABLE, data32))
402             apiMask |= NVBIT(RS_API_SHARE);
403 
404         pSys->apiLockMask = apiMask;
405     }
406     else
407     {
408         pSys->apiLockMask = NVBIT(RS_API_CTRL);
409     }
410 
411     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_READONLY_API_LOCK_MODULE,
412                             &data32) == NV_OK)
413     {
414         pSys->apiLockModuleMask = data32;
415     }
416     else
417     {
418         pSys->apiLockModuleMask = RM_LOCK_MODULE_GRP(RM_LOCK_MODULES_CLIENT);
419     }
420 
421     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_CLIENT_HANDLE_LOOKUP,
422                             &data32) == NV_OK)
423     {
424         pSys->setProperty(pSys, PDB_PROP_SYS_CLIENT_HANDLE_LOOKUP, !!data32);
425     }
426 
427     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_LOCK_TIME_COLLECT,
428                             &data32) == NV_OK)
429     {
430         pSys->setProperty(pSys, PDB_PROP_SYS_RM_LOCK_TIME_COLLECT, !!data32);
431     }
432 
433     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_CLIENT_LIST_DEFERRED_FREE,
434                             &data32) == NV_OK)
435     {
436         pSys->bUseDeferredClientListFree = !!data32;
437     }
438 
439     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_CLIENT_LIST_DEFERRED_FREE_LIMIT,
440                             &data32) == NV_OK)
441     {
442         pSys->clientListDeferredFreeLimit = data32;
443     }
444 }
445 
446 static void
_sysRegistryOverrideExternalFabricMgmt(OBJSYS * pSys,OBJGPU * pGpu)447 _sysRegistryOverrideExternalFabricMgmt
448 (
449     OBJSYS *pSys,
450     OBJGPU *pGpu
451 )
452 {
453     NvU32 data32;
454 
455     // Set external fabric management property
456     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_EXTERNAL_FABRIC_MGMT,
457                             &data32) == NV_OK)
458     {
459         if (FLD_TEST_DRF(_REG_STR_RM, _EXTERNAL_FABRIC_MGMT, _MODE, _ENABLE, data32))
460         {
461             NV_PRINTF(LEVEL_INFO,
462                       "Enabling external fabric management.\n");
463 
464             pSys->setProperty(pSys, PDB_PROP_SYS_FABRIC_IS_EXTERNALLY_MANAGED, NV_TRUE);
465         }
466 
467         if (FLD_TEST_DRF(_REG_STR_RM, _EXTERNAL_FABRIC_MGMT, _MODE, _DISABLE, data32))
468         {
469             NV_PRINTF(LEVEL_INFO,
470                       "Disabling external fabric management.\n");
471 
472             pSys->setProperty(pSys, PDB_PROP_SYS_FABRIC_IS_EXTERNALLY_MANAGED, NV_FALSE);
473         }
474     }
475 }
476 
477 void
sysEnableExternalFabricMgmt_IMPL(OBJSYS * pSys)478 sysEnableExternalFabricMgmt_IMPL
479 (
480     OBJSYS *pSys
481 )
482 {
483     pSys->setProperty(pSys, PDB_PROP_SYS_FABRIC_IS_EXTERNALLY_MANAGED, NV_TRUE);
484 
485     NV_PRINTF(LEVEL_INFO,
486               "Enabling external fabric management for Proxy NvSwitch systems.\n");
487 }
488 
489 void
sysForceInitFabricManagerState_IMPL(OBJSYS * pSys)490 sysForceInitFabricManagerState_IMPL
491 (
492     OBJSYS *pSys
493 )
494 {
495     //
496     // We should only allow force init if there is not way to run fabric
497     // manager. For example, HGX-2 virtualization use-case.
498     //
499     if (pSys->getProperty(pSys, PDB_PROP_SYS_NVSWITCH_IS_PRESENT) ||
500         pSys->getProperty(pSys, PDB_PROP_SYS_FABRIC_MANAGER_IS_REGISTERED))
501     {
502         NV_ASSERT(0);
503         return;
504     }
505 
506     pSys->setProperty(pSys, PDB_PROP_SYS_FABRIC_MANAGER_IS_INITIALIZED, NV_TRUE);
507 
508     NV_PRINTF(LEVEL_INFO,
509               "Forcing fabric manager's state as initialized to unblock clients.\n");
510 }
511 
512 static void
_sysNvSwitchDetection(OBJSYS * pSys)513 _sysNvSwitchDetection
514 (
515     OBJSYS *pSys
516 )
517 {
518 
519     if (osIsNvswitchPresent())
520     {
521         pSys->setProperty(pSys, PDB_PROP_SYS_NVSWITCH_IS_PRESENT, NV_TRUE);
522 
523         NV_PRINTF(LEVEL_INFO, "NvSwitch is found in the system\n");
524 
525         sysEnableExternalFabricMgmt(pSys);
526     }
527 }
528 
529 /*!
530  * @brief Initialize static system configuration data.
531  *
532  * @param[in]   pSys    SYSTEM object pointer
533  */
534 static void
_sysInitStaticConfig(OBJSYS * pSys)535 _sysInitStaticConfig(OBJSYS *pSys)
536 {
537     portMemSet(&pSys->staticConfig, 0, sizeof(pSys->staticConfig));
538     osInitSystemStaticConfig(&pSys->staticConfig);
539 }
540 
541 NV_STATUS
coreInitializeRm(void)542 coreInitializeRm(void)
543 {
544     NV_STATUS  status;
545     OBJSYS    *pSys = NULL;
546 
547     //
548     // Initialize libraries used by RM
549     //
550 
551     // Portable runtime init
552     status = portInitialize();
553     if (status != NV_OK)
554         return status;
555 
556     // Required before any NvLog (NV_PRINTF) calls
557     NVLOG_INIT(NULL);
558 
559     // Required before any NV_PRINTF() calls
560     if (!DBG_INIT())
561     {
562         status = NV_ERR_GENERIC;
563         return status;
564     }
565 
566     //
567     // Initialize OBJSYS which spawns all the RM internal modules
568     //
569     status = objCreate(&pSys, NVOC_NULL_OBJECT, OBJSYS);
570 
571     nvAssertInit();
572 
573     return status;
574  }
575 
576 void
coreShutdownRm(void)577 coreShutdownRm(void)
578 {
579     OBJSYS *pSys = SYS_GET_INSTANCE();
580 
581     //
582     // Destruct OBJSYS which frees all the RM internal modules
583     //
584     objDelete(pSys);
585 
586     //
587     // Deinitialize libraries used by RM
588     //
589     nvAssertDestroy();
590 
591     DBG_DESTROY();
592 
593     NVLOG_DESTROY();
594 
595     portShutdown();
596 }
597 
598 // Obsolete RM init function -- code should migrate to new interfaces
599 NvS32
RmInitRm(void)600 RmInitRm(void)
601 {
602     return (coreInitializeRm() == NV_OK);
603 }
604 
605 // Obsolete RM destroy function -- code should migrate to new interfaces
606 NvS32
RmDestroyRm(void)607 RmDestroyRm(void)
608 {
609     coreShutdownRm();
610     return NV_TRUE;
611 }
612 
613 static NV_STATUS
_sysCreateOs(OBJSYS * pSys)614 _sysCreateOs(OBJSYS *pSys)
615 {
616     OBJOS      *pOS;
617     NV_STATUS   status;
618 
619     // RMCONFIG: only if OS is enabled :-)
620     RMCFG_MODULE_ENABLED_OR_BAIL(OS);
621 
622     status = objCreate(&pOS, pSys, OBJOS);
623     if (status != NV_OK)
624     {
625         return status;
626     }
627 
628     status = constructObjOS(pOS);
629     if (status != NV_OK)
630     {
631         objDelete(pOS);
632         return status;
633     }
634 
635     status = osRmCapRegisterSys(&pSys->pOsRmCaps);
636     if (status != NV_OK)
637     {
638         //
639         // Device objects needed for some access rights failed
640         // This is not system-critical since access rights are currently disabled,
641         // so continue booting, just log error.
642         //
643         // RS-TODO make this fail once RM Capabilities are enabled (Bug 2549938)
644         //
645         NV_PRINTF(LEVEL_ERROR, "RM Access Sys Cap creation failed: 0x%x\n", status);
646     }
647 
648     pSys->pOS = pOS;
649 
650     return NV_OK;
651 }
652 
653 NV_STATUS
sysCaptureState_IMPL(OBJSYS * pSys)654 sysCaptureState_IMPL(OBJSYS *pSys)
655 {
656     return NV_OK;
657 }
658 
659 OBJOS*
sysGetOs_IMPL(OBJSYS * pSys)660 sysGetOs_IMPL(OBJSYS *pSys)
661 {
662     if (pSys->pOS)
663         return pSys->pOS;
664 
665     //
666     // A special case for any early 'get-object' calls for the OS
667     // object before there is an OS object. Some RC code called on
668     // DBG_BREAKPOINT assumes an OS object exists, and can cause a crash.
669     //
670     PORT_BREAKPOINT_ALWAYS();
671 
672     return NULL;
673 }
674 
675 void
sysInitRegistryOverrides_IMPL(OBJSYS * pSys)676 sysInitRegistryOverrides_IMPL
677 (
678     OBJSYS         *pSys
679 )
680 {
681     OBJGPU         *pGpu      = NULL;
682     NvU32           data32    = 0;
683 
684     if (pSys->getProperty(pSys,
685                 PDB_PROP_SYS_REGISTRY_OVERRIDES_INITIALIZED))
686     {
687         // The registry overrides, if any, have already been applied.
688         return;
689     }
690 
691     // Get some GPU - as of now we need some gpu to read registry.
692     pGpu = gpumgrGetSomeGpu();
693     if (pGpu == NULL)
694     {
695         // Too early call ! we can not read the registry.
696         return;
697     }
698 
699     if ((osReadRegistryDword(pGpu,
700             NV_REG_STR_RM_ENABLE_EVENT_TRACER, &data32) == NV_OK) && data32 )
701     {
702         RMTRACE_ENABLE(data32);
703     }
704 
705     if (osReadRegistryDword(pGpu,
706             NV_REG_STR_RM_CLIENT_DATA_VALIDATION, &data32) == NV_OK)
707     {
708         if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _KERNEL_BUFFERS, _ENABLED, data32))
709         {
710             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_KERNEL_BUFFERS, NV_TRUE);
711         }
712         else if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _KERNEL_BUFFERS, _DISABLED, data32))
713         {
714             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_KERNEL_BUFFERS, NV_FALSE);
715         }
716 
717         if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _HANDLE, _ENABLED, data32))
718         {
719             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE, NV_TRUE);
720         }
721         else  if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _HANDLE, _DISABLED, data32))
722         {
723             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE, NV_FALSE);
724         }
725 
726         if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _STRICT_CLIENT, _ENABLED, data32))
727         {
728             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE_STRICT, NV_TRUE);
729         }
730         else if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _STRICT_CLIENT, _DISABLED, data32))
731         {
732             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE_STRICT, NV_FALSE);
733         }
734 
735         if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _ALL, _ENABLED, data32))
736         {
737             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE, NV_TRUE);
738             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_KERNEL_BUFFERS, NV_TRUE);
739             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE_STRICT, NV_TRUE);
740         }
741         else  if (FLD_TEST_DRF(_REG_STR_RM, _CLIENT_DATA_VALIDATION, _ALL, _DISABLED, data32))
742         {
743             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE, NV_FALSE);
744             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_KERNEL_BUFFERS, NV_FALSE);
745             pSys->setProperty(pSys, PDB_PROP_SYS_VALIDATE_CLIENT_HANDLE_STRICT, NV_FALSE);
746         }
747     }
748 
749     pSys->setProperty(pSys, PDB_PROP_SYS_REGISTRY_OVERRIDES_INITIALIZED, NV_TRUE);
750 
751     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_STREAM_MEMOPS,
752                             &data32) == NV_OK)
753     {
754         if (FLD_TEST_DRF(_REG_STR_RM, _STREAM_MEMOPS, _ENABLE, _YES, data32))
755         {
756             pSys->setProperty(pSys, PDB_PROP_SYS_ENABLE_STREAM_MEMOPS, NV_TRUE);
757         }
758     }
759 
760     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_PRIORITY_BOOST,
761                             &data32) == NV_OK)
762     {
763         if (data32 == NV_REG_STR_RM_PRIORITY_BOOST_DISABLE)
764             pSys->setProperty(pSys, PDB_PROP_SYS_PRIORITY_BOOST, NV_FALSE);
765         else
766             pSys->setProperty(pSys, PDB_PROP_SYS_PRIORITY_BOOST, NV_TRUE);
767     }
768 
769     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_PRIORITY_THROTTLE_DELAY,
770                             &data32) == NV_OK)
771     {
772         pSys->setProperty(pSys, PDB_PROP_SYS_PRIORITY_THROTTLE_DELAY_US, data32);
773     }
774 
775     _sysRegistryOverrideExternalFabricMgmt(pSys, pGpu);
776     _sysRegistryOverrideResourceServer(pSys, pGpu);
777 
778     if (osBugCheckOnTimeoutEnabled())
779     {
780         pSys->setProperty(pSys, PDB_PROP_SYS_BUGCHECK_ON_TIMEOUT, NV_TRUE);
781     }
782 
783     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_ENABLE_ROUTE_TO_PHYSICAL_LOCK_BYPASS,
784                             &data32) == NV_OK)
785     {
786         pSys->setProperty(pSys, PDB_PROP_SYS_ROUTE_TO_PHYSICAL_LOCK_BYPASS, !!data32);
787     }
788 
789     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_GPU_LOCK_MIDPATH, &data32) == NV_OK)
790     {
791         pSys->setProperty(pSys, PDB_PROP_SYS_GPU_LOCK_MIDPATH_ENABLED, !!data32);
792     }
793 
794     gpumgrSetGpuNvlinkBwModeFromRegistry(pGpu);
795 }
796 
797 void
sysApplyLockingPolicy_IMPL(OBJSYS * pSys)798 sysApplyLockingPolicy_IMPL(OBJSYS *pSys)
799 {
800     g_resServ.bRouteToPhysicalLockBypass = pSys->getProperty(pSys, PDB_PROP_SYS_ROUTE_TO_PHYSICAL_LOCK_BYPASS);
801     g_resServ.roTopLockApiMask = pSys->apiLockMask;
802 }
803 
804 NV_STATUS
sysSyncExternalFabricMgmtWAR_IMPL(OBJSYS * pSys,OBJGPU * pGpu)805 sysSyncExternalFabricMgmtWAR_IMPL
806 (
807     OBJSYS  *pSys,
808     OBJGPU  *pGpu
809 )
810 {
811     NV0000_CTRL_CMD_SYSTEM_SYNC_EXTERNAL_FABRIC_MGMT_PARAMS params;
812     RM_API    *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
813     NV_STATUS  status = NV_OK;
814 
815     params.bExternalFabricMgmt = pSys->getProperty(pSys,
816                                      PDB_PROP_SYS_FABRIC_IS_EXTERNALLY_MANAGED);
817 
818     status = pRmApi->Control(pRmApi, pGpu->hInternalClient, pGpu->hInternalClient,
819                              NV0000_CTRL_CMD_SYSTEM_SYNC_EXTERNAL_FABRIC_MGMT,
820                              &params, sizeof(params));
821 
822     return status;
823 }
824