11739a20eSAndy Ritger /*
2b5bf85a8SAndy Ritger  * SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
31739a20eSAndy Ritger  * SPDX-License-Identifier: MIT
41739a20eSAndy Ritger  *
51739a20eSAndy Ritger  * Permission is hereby granted, free of charge, to any person obtaining a
61739a20eSAndy Ritger  * copy of this software and associated documentation files (the "Software"),
71739a20eSAndy Ritger  * to deal in the Software without restriction, including without limitation
81739a20eSAndy Ritger  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
91739a20eSAndy Ritger  * and/or sell copies of the Software, and to permit persons to whom the
101739a20eSAndy Ritger  * Software is furnished to do so, subject to the following conditions:
111739a20eSAndy Ritger  *
121739a20eSAndy Ritger  * The above copyright notice and this permission notice shall be included in
131739a20eSAndy Ritger  * all copies or substantial portions of the Software.
141739a20eSAndy Ritger  *
151739a20eSAndy Ritger  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161739a20eSAndy Ritger  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171739a20eSAndy Ritger  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
181739a20eSAndy Ritger  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191739a20eSAndy Ritger  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201739a20eSAndy Ritger  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211739a20eSAndy Ritger  * DEALINGS IN THE SOFTWARE.
221739a20eSAndy Ritger  */
231739a20eSAndy Ritger 
241739a20eSAndy Ritger #include "core/core.h"
251739a20eSAndy Ritger #include "gpu/gpu.h"
2691676d66SBernhard Stoeckner #include "gpu/device/device.h"
271739a20eSAndy Ritger #include "mem_mgr/vaspace.h"
281739a20eSAndy Ritger #include "mem_mgr/io_vaspace.h"
291739a20eSAndy Ritger #include "mem_mgr/gpu_vaspace.h"
301739a20eSAndy Ritger #include "gpu/mmu/kern_gmmu.h"
311739a20eSAndy Ritger #include "gpu/bus/kern_bus.h"
321739a20eSAndy Ritger #include "kernel/gpu/mem_mgr/mem_mgr.h"
331739a20eSAndy Ritger #include "kernel/gpu/mem_sys/kern_mem_sys.h"
34758b4ee8SAndy Ritger #include "kernel/gpu/nvbitmask.h"
351739a20eSAndy Ritger #include "platform/chipset/chipset.h"
361739a20eSAndy Ritger #include "rmapi/client.h"
3791676d66SBernhard Stoeckner #include "platform/sli/sli.h"
38758b4ee8SAndy Ritger #include "nvdevid.h"
391739a20eSAndy Ritger 
401739a20eSAndy Ritger #include "gpu/gsp/gsp_static_config.h"
411739a20eSAndy Ritger #include "vgpu/rpc.h"
421739a20eSAndy Ritger 
431739a20eSAndy Ritger #include "nvRmReg.h"
441739a20eSAndy Ritger 
451739a20eSAndy Ritger static NV_STATUS kbusInitRegistryOverrides(OBJGPU *pGpu, KernelBus *pKernelBus);
461739a20eSAndy Ritger 
471739a20eSAndy Ritger NV_STATUS
kbusConstructEngine_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus,ENGDESCRIPTOR engDesc)481739a20eSAndy Ritger kbusConstructEngine_IMPL(OBJGPU *pGpu, KernelBus *pKernelBus, ENGDESCRIPTOR engDesc)
491739a20eSAndy Ritger {
501739a20eSAndy Ritger     NV_STATUS  status;
511739a20eSAndy Ritger 
521739a20eSAndy Ritger     if (IsAMPEREorBetter(pGpu) && pGpu->getProperty(pGpu, PDB_PROP_GPU_IS_ALL_INST_IN_SYSMEM))
531739a20eSAndy Ritger     {
541739a20eSAndy Ritger         pKernelBus->bBar1PhysicalModeEnabled = NV_TRUE;
551739a20eSAndy Ritger     }
561739a20eSAndy Ritger 
571739a20eSAndy Ritger     if (IS_VIRTUAL_WITH_SRIOV(pGpu))
581739a20eSAndy Ritger     {
591739a20eSAndy Ritger         pKernelBus->bUsePhysicalBar2InitPagetable = NV_TRUE;
601739a20eSAndy Ritger     }
611739a20eSAndy Ritger 
621739a20eSAndy Ritger     // allocate HAL private info block
631739a20eSAndy Ritger     status = kbusConstructHal_HAL(pGpu, pKernelBus);
641739a20eSAndy Ritger     if (status != NV_OK)
651739a20eSAndy Ritger         return status;
661739a20eSAndy Ritger 
671739a20eSAndy Ritger     kbusInitRegistryOverrides(pGpu, pKernelBus);
681739a20eSAndy Ritger 
691739a20eSAndy Ritger     kbusInitPciBars_HAL(pKernelBus);
701739a20eSAndy Ritger 
711739a20eSAndy Ritger     // Special handle for VGPU.  WAR for bug 3458057, bug 3458029
721739a20eSAndy Ritger     if (IS_VIRTUAL(pGpu))
731739a20eSAndy Ritger     {
741739a20eSAndy Ritger         NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
751739a20eSAndy Ritger             kbusInitBarsSize_HAL(pGpu, pKernelBus));
761739a20eSAndy Ritger     }
771739a20eSAndy Ritger 
781739a20eSAndy Ritger     NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
791739a20eSAndy Ritger             kbusInitBarsBaseInfo_HAL(pKernelBus));
801739a20eSAndy Ritger 
811739a20eSAndy Ritger     NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
821739a20eSAndy Ritger             kbusSetBarsApertureSize_HAL(pGpu, pKernelBus, GPU_GFID_PF));
831739a20eSAndy Ritger 
841739a20eSAndy Ritger     return NV_OK;
851739a20eSAndy Ritger }
861739a20eSAndy Ritger 
871739a20eSAndy Ritger /*!
881739a20eSAndy Ritger  * @brief Initialize all registry overrides for this object
891739a20eSAndy Ritger  *
901739a20eSAndy Ritger  * @param[in]      pGpu
911739a20eSAndy Ritger  * @param[in,out]  pKernelBus
921739a20eSAndy Ritger  */
931739a20eSAndy Ritger static NV_STATUS
kbusInitRegistryOverrides(OBJGPU * pGpu,KernelBus * pKernelBus)941739a20eSAndy Ritger kbusInitRegistryOverrides(OBJGPU *pGpu, KernelBus *pKernelBus)
951739a20eSAndy Ritger {
961739a20eSAndy Ritger     NvU32 data32;
971739a20eSAndy Ritger 
981739a20eSAndy Ritger     switch (DRF_VAL(_REG_STR_RM, _INST_LOC, _BAR_PTE, pGpu->instLocOverrides))
991739a20eSAndy Ritger     {
1001739a20eSAndy Ritger         default:
1011739a20eSAndy Ritger         case NV_REG_STR_RM_INST_LOC_BAR_PTE_DEFAULT:
1021739a20eSAndy Ritger             // Do not override on default..
1031739a20eSAndy Ritger             break;
1041739a20eSAndy Ritger         case NV_REG_STR_RM_INST_LOC_BAR_PTE_VID:
1051739a20eSAndy Ritger             pKernelBus->PTEBAR2Aperture = ADDR_FBMEM;
1061739a20eSAndy Ritger             pKernelBus->PTEBAR2Attr = NV_MEMORY_WRITECOMBINED;
1071739a20eSAndy Ritger             break;
1081739a20eSAndy Ritger 
1091739a20eSAndy Ritger         case NV_REG_STR_RM_INST_LOC_BAR_PTE_COH:
1101739a20eSAndy Ritger             if (gpuIsBarPteInSysmemSupported(pGpu) || !gpuIsRegUsesGlobalSurfaceOverridesEnabled(pGpu))
1111739a20eSAndy Ritger             {
1121739a20eSAndy Ritger                 pKernelBus->PTEBAR2Aperture = ADDR_SYSMEM;
1131739a20eSAndy Ritger                 pKernelBus->PTEBAR2Attr = NV_MEMORY_CACHED;
1141739a20eSAndy Ritger             }
1151739a20eSAndy Ritger             else
1161739a20eSAndy Ritger             {
1171739a20eSAndy Ritger                 //
1181739a20eSAndy Ritger                 // BAR PTEs in sysmem is not supported on all hardware.
1191739a20eSAndy Ritger                 // HW bug 415430. Once fixed, this property will be set on supported GPUs.
1201739a20eSAndy Ritger                 // On unsupported GPUs where the GlobalSurfaceOverrides regkey is used, show a warning and don't override.
1211739a20eSAndy Ritger                 //
1221739a20eSAndy Ritger                 NV_PRINTF(LEVEL_WARNING,
1231739a20eSAndy Ritger                           "BAR PTEs not supported in sysmem. Ignoring global override request.\n");
1241739a20eSAndy Ritger             }
1251739a20eSAndy Ritger             break;
1261739a20eSAndy Ritger 
1271739a20eSAndy Ritger         case NV_REG_STR_RM_INST_LOC_BAR_PTE_NCOH:
1281739a20eSAndy Ritger             if (gpuIsBarPteInSysmemSupported(pGpu) || !gpuIsRegUsesGlobalSurfaceOverridesEnabled(pGpu))
1291739a20eSAndy Ritger             {
1301739a20eSAndy Ritger                 pKernelBus->PTEBAR2Aperture = ADDR_SYSMEM;
1311739a20eSAndy Ritger                 pKernelBus->PTEBAR2Attr = NV_MEMORY_UNCACHED;
1321739a20eSAndy Ritger             }
1331739a20eSAndy Ritger             else
1341739a20eSAndy Ritger             {
1351739a20eSAndy Ritger                 // BAR PTEs in sysmem is not supported on current hardware. See above.
1361739a20eSAndy Ritger                 NV_PRINTF(LEVEL_WARNING,
1371739a20eSAndy Ritger                           "BAR PTEs not supported in sysmem. Ignoring global override request.\n");
1381739a20eSAndy Ritger             }
1391739a20eSAndy Ritger             break;
1401739a20eSAndy Ritger     }
1411739a20eSAndy Ritger 
1421739a20eSAndy Ritger     NV_PRINTF(LEVEL_INFO, "Using aperture %d for BAR2 PTEs\n",
1431739a20eSAndy Ritger               pKernelBus->PTEBAR2Aperture);
1441739a20eSAndy Ritger 
1451739a20eSAndy Ritger     switch (DRF_VAL(_REG_STR_RM, _INST_LOC, _BAR_PDE, pGpu->instLocOverrides))
1461739a20eSAndy Ritger     {
1471739a20eSAndy Ritger         default:
1481739a20eSAndy Ritger         case NV_REG_STR_RM_INST_LOC_BAR_PDE_DEFAULT:
1491739a20eSAndy Ritger             // Do not override on default.
1501739a20eSAndy Ritger             break;
1511739a20eSAndy Ritger         case NV_REG_STR_RM_INST_LOC_BAR_PDE_VID:
1521739a20eSAndy Ritger             pKernelBus->PDEBAR2Aperture = ADDR_FBMEM;
1531739a20eSAndy Ritger             pKernelBus->PDEBAR2Attr = NV_MEMORY_WRITECOMBINED;
1541739a20eSAndy Ritger             break;
1551739a20eSAndy Ritger 
1561739a20eSAndy Ritger         case NV_REG_STR_RM_INST_LOC_BAR_PDE_COH:
1571739a20eSAndy Ritger             if (gpuIsBarPteInSysmemSupported(pGpu) || !gpuIsRegUsesGlobalSurfaceOverridesEnabled(pGpu))
1581739a20eSAndy Ritger             {
1591739a20eSAndy Ritger                 pKernelBus->PDEBAR2Aperture = ADDR_SYSMEM;
1601739a20eSAndy Ritger                 pKernelBus->PDEBAR2Attr = NV_MEMORY_CACHED;
1611739a20eSAndy Ritger             }
1621739a20eSAndy Ritger             else
1631739a20eSAndy Ritger             {
1641739a20eSAndy Ritger                 // BAR PDEs in sysmem is not supported on all hardware. See above.
1651739a20eSAndy Ritger                 NV_PRINTF(LEVEL_WARNING,
1661739a20eSAndy Ritger                           "BAR PDEs not supported in sysmem. Ignoring global override request.\n");
1671739a20eSAndy Ritger             }
1681739a20eSAndy Ritger             break;
1691739a20eSAndy Ritger 
1701739a20eSAndy Ritger         case NV_REG_STR_RM_INST_LOC_BAR_PDE_NCOH:
1711739a20eSAndy Ritger             if (gpuIsBarPteInSysmemSupported(pGpu) || !gpuIsRegUsesGlobalSurfaceOverridesEnabled(pGpu))
1721739a20eSAndy Ritger             {
1731739a20eSAndy Ritger                 pKernelBus->PDEBAR2Aperture = ADDR_SYSMEM;
1741739a20eSAndy Ritger                 pKernelBus->PDEBAR2Attr = NV_MEMORY_UNCACHED;
1751739a20eSAndy Ritger             }
1761739a20eSAndy Ritger             else
1771739a20eSAndy Ritger             {
1781739a20eSAndy Ritger                 // BAR PDEs in sysmem is not supported on all hardware. See above.
1791739a20eSAndy Ritger                 NV_PRINTF(LEVEL_WARNING,
1801739a20eSAndy Ritger                           "BAR PDEs not supported in sysmem. Ignoring global override request.\n");
1811739a20eSAndy Ritger             }
1821739a20eSAndy Ritger             break;
1831739a20eSAndy Ritger     }
1841739a20eSAndy Ritger 
18591676d66SBernhard Stoeckner     if (RMCFG_FEATURE_PLATFORM_WINDOWS && !pGpu->getProperty(pGpu, PDB_PROP_GPU_IN_TCC_MODE))
1861739a20eSAndy Ritger     {
1871739a20eSAndy Ritger         //
1881739a20eSAndy Ritger         // Aligns to unlinked SLI: Volta and up
1891739a20eSAndy Ritger         // Next: Plan for all GPUs after validation
1901739a20eSAndy Ritger         //
1911739a20eSAndy Ritger         pKernelBus->bP2pMailboxClientAllocated =
1921739a20eSAndy Ritger             pKernelBus->bP2pMailboxClientAllocatedBug3466714VoltaAndUp;
1931739a20eSAndy Ritger     }
1941739a20eSAndy Ritger 
1951739a20eSAndy Ritger     if (osReadRegistryDword(pGpu, NV_REG_STR_P2P_MAILBOX_CLIENT_ALLOCATED, &data32) == NV_OK)
1961739a20eSAndy Ritger     {
1971739a20eSAndy Ritger         pKernelBus->bP2pMailboxClientAllocated = !!data32;
1981739a20eSAndy Ritger     }
1991739a20eSAndy Ritger 
200b5bf85a8SAndy Ritger     if (osReadRegistryDword(pGpu, NV_REG_STR_RESTORE_BAR1_SIZE_BUG_3249028_WAR, &data32) == NV_OK)
201b5bf85a8SAndy Ritger     {
202b5bf85a8SAndy Ritger         pKernelBus->setProperty(pKernelBus, PDB_PROP_KBUS_RESTORE_BAR1_SIZE_BUG_3249028_WAR, !!data32);
203b5bf85a8SAndy Ritger     }
204b5bf85a8SAndy Ritger 
20591676d66SBernhard Stoeckner     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_FORCE_BAR_ACCESS_ON_HCC, &data32) == NV_OK &&
20691676d66SBernhard Stoeckner         data32 == NV_REG_STR_RM_FORCE_BAR_ACCESS_ON_HCC_YES  && gpuIsCCDevToolsModeEnabled(pGpu))
20791676d66SBernhard Stoeckner     {
20891676d66SBernhard Stoeckner         pKernelBus->bForceBarAccessOnHcc = NV_TRUE;
20991676d66SBernhard Stoeckner     }
21091676d66SBernhard Stoeckner 
2111739a20eSAndy Ritger     return NV_OK;
2121739a20eSAndy Ritger }
2131739a20eSAndy Ritger 
2141739a20eSAndy Ritger /**
215b5bf85a8SAndy Ritger  * @brief  Gets the BAR1 VA range for a device
2161739a20eSAndy Ritger  *
2171739a20eSAndy Ritger  * @param[in] pGpu
2181739a20eSAndy Ritger  * @param[in] pKernelBus
219b5bf85a8SAndy Ritger  * @param[in] pDevice               Device pointer
2201739a20eSAndy Ritger  * @param[out] pBar1VARange         BAR1 VA range
2211739a20eSAndy Ritger  */
2221739a20eSAndy Ritger 
2231739a20eSAndy Ritger NV_STATUS
kbusGetBar1VARangeForDevice_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus,Device * pDevice,NV_RANGE * pBar1VARange)224b5bf85a8SAndy Ritger kbusGetBar1VARangeForDevice_IMPL(OBJGPU *pGpu, KernelBus *pKernelBus, Device *pDevice, NV_RANGE *pBar1VARange)
2251739a20eSAndy Ritger {
2261739a20eSAndy Ritger     KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
2271739a20eSAndy Ritger     OBJVASPACE       *pBar1VAS          = kbusGetBar1VASpace_HAL(pGpu, pKernelBus);
2281739a20eSAndy Ritger 
2291739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(pBar1VAS != NULL, NV_ERR_INVALID_STATE);
2301739a20eSAndy Ritger 
2311739a20eSAndy Ritger    *pBar1VARange = rangeMake(vaspaceGetVaStart(pBar1VAS), vaspaceGetVaLimit(pBar1VAS));
2321739a20eSAndy Ritger 
2331739a20eSAndy Ritger     if ((pKernelMIGManager != NULL) && kmigmgrIsMIGMemPartitioningEnabled(pGpu, pKernelMIGManager) &&
234b5bf85a8SAndy Ritger         !rmclientIsCapableByHandle(RES_GET_CLIENT_HANDLE(pDevice), NV_RM_CAP_SYS_SMC_MONITOR) &&
235b5bf85a8SAndy Ritger         !kmigmgrIsDeviceUsingDeviceProfiling(pGpu, pKernelMIGManager, pDevice))
2361739a20eSAndy Ritger     {
2371739a20eSAndy Ritger         MemoryManager *pMemoryManager = GPU_GET_MEMORY_MANAGER(pGpu);
2381739a20eSAndy Ritger         KernelMemorySystem *pKernelMemorySystem = GPU_GET_KERNEL_MEMORY_SYSTEM(pGpu);
2391739a20eSAndy Ritger         MIG_INSTANCE_REF ref;
2401739a20eSAndy Ritger 
2411739a20eSAndy Ritger        *pBar1VARange = memmgrGetMIGPartitionableBAR1Range(pGpu, pMemoryManager);
2421739a20eSAndy Ritger 
243b5bf85a8SAndy Ritger         NV_ASSERT_OK_OR_RETURN(kmigmgrGetInstanceRefFromDevice(pGpu, pKernelMIGManager,
244b5bf85a8SAndy Ritger                                    pDevice, &ref));
2451739a20eSAndy Ritger         NV_ASSERT_OK_OR_RETURN(kmemsysSwizzIdToMIGMemRange(pGpu, pKernelMemorySystem, ref.pKernelMIGGpuInstance->swizzId,
2461739a20eSAndy Ritger                                    *pBar1VARange, pBar1VARange));
2471739a20eSAndy Ritger     }
2481739a20eSAndy Ritger     return NV_OK;
2491739a20eSAndy Ritger }
2501739a20eSAndy Ritger 
2511739a20eSAndy Ritger RmPhysAddr
kbusSetupPeerBarAccess_IMPL(OBJGPU * pLocalGpu,OBJGPU * pRemoteGpu,RmPhysAddr base,NvU64 size,PMEMORY_DESCRIPTOR * ppMemDesc)2521739a20eSAndy Ritger kbusSetupPeerBarAccess_IMPL
2531739a20eSAndy Ritger (
2541739a20eSAndy Ritger     OBJGPU *pLocalGpu,
2551739a20eSAndy Ritger     OBJGPU *pRemoteGpu,
2561739a20eSAndy Ritger     RmPhysAddr base,
2571739a20eSAndy Ritger     NvU64 size,
2581739a20eSAndy Ritger     PMEMORY_DESCRIPTOR *ppMemDesc
2591739a20eSAndy Ritger )
2601739a20eSAndy Ritger {
2611739a20eSAndy Ritger     NV_STATUS          status;
2621739a20eSAndy Ritger     MEMORY_DESCRIPTOR *pMemDesc = *ppMemDesc;
2631739a20eSAndy Ritger     IOVAMAPPING       *pIovaMapping;
2641739a20eSAndy Ritger 
2651739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(((base & RM_PAGE_MASK) == 0), ~0ULL);
2661739a20eSAndy Ritger 
2671739a20eSAndy Ritger     if (pMemDesc == NULL)
2681739a20eSAndy Ritger     {
2691739a20eSAndy Ritger         status = memdescCreate(&pMemDesc, pLocalGpu, size, 0, NV_TRUE,
2701739a20eSAndy Ritger                                ADDR_SYSMEM, NV_MEMORY_UNCACHED,
2711739a20eSAndy Ritger                                MEMDESC_FLAGS_SKIP_RESOURCE_COMPUTE);
2721739a20eSAndy Ritger         NV_ASSERT_OR_RETURN(status == NV_OK, ~0ULL);
2731739a20eSAndy Ritger 
2741739a20eSAndy Ritger         memdescDescribe(pMemDesc, ADDR_SYSMEM, base, size);
2751739a20eSAndy Ritger     }
2761739a20eSAndy Ritger     else
2771739a20eSAndy Ritger     {
2781739a20eSAndy Ritger         NV_ASSERT_OR_RETURN(
2791739a20eSAndy Ritger             (memdescGetPhysAddr(pMemDesc, AT_GPU, 0) == base) &&
2801739a20eSAndy Ritger             (memdescGetSize(pMemDesc) == size), ~0ULL);
2811739a20eSAndy Ritger     }
2821739a20eSAndy Ritger 
2831739a20eSAndy Ritger     //
2841739a20eSAndy Ritger     // Even if IOMMU-remapping fails (which it shouldn't), try to continue
2851739a20eSAndy Ritger     // using the CPU physical address. In most cases, this is still sufficient.
2861739a20eSAndy Ritger     //
2871739a20eSAndy Ritger     status = memdescMapIommu(pMemDesc, pRemoteGpu->busInfo.iovaspaceId);
2881739a20eSAndy Ritger     NV_ASSERT(status == NV_OK);
2891739a20eSAndy Ritger 
2901739a20eSAndy Ritger     pIovaMapping = memdescGetIommuMap(pMemDesc, pRemoteGpu->busInfo.iovaspaceId);
2911739a20eSAndy Ritger 
2921739a20eSAndy Ritger     *ppMemDesc = pMemDesc;
2931739a20eSAndy Ritger 
2941739a20eSAndy Ritger     if (pIovaMapping == NULL)
2951739a20eSAndy Ritger     {
2961739a20eSAndy Ritger         NV_PRINTF(LEVEL_INFO,
2971739a20eSAndy Ritger                   "no IOVA mapping found for pre-existing P2P domain memdesc\n");
2981739a20eSAndy Ritger         return memdescGetPhysAddr(pMemDesc, AT_GPU, 0);
2991739a20eSAndy Ritger     }
3001739a20eSAndy Ritger 
3011739a20eSAndy Ritger     return pIovaMapping->iovaArray[0];
3021739a20eSAndy Ritger }
3031739a20eSAndy Ritger 
3041739a20eSAndy Ritger /*!
3051739a20eSAndy Ritger  *  @brief Get the bus flush aperture flag for the NV_ADDRESS_SPACE
3061739a20eSAndy Ritger  *         For use with the kbusFlush_HAL() api
3071739a20eSAndy Ritger  *
3081739a20eSAndy Ritger  *  @param[in]  addrSpace         NV_ADDRESS_SPACE
3091739a20eSAndy Ritger  *
3101739a20eSAndy Ritger  *  @returns bush flush aperture flag
3111739a20eSAndy Ritger  */
kbusGetFlushAperture_IMPL(KernelBus * pKernelBus,NV_ADDRESS_SPACE addrSpace)3121739a20eSAndy Ritger NvU32 kbusGetFlushAperture_IMPL(KernelBus *pKernelBus, NV_ADDRESS_SPACE addrSpace)
3131739a20eSAndy Ritger {
3141739a20eSAndy Ritger     return (addrSpace == ADDR_FBMEM) ? BUS_FLUSH_VIDEO_MEMORY : BUS_FLUSH_SYSTEM_MEMORY;
3151739a20eSAndy Ritger }
3161739a20eSAndy Ritger 
3171739a20eSAndy Ritger void
kbusDestruct_IMPL(KernelBus * pKernelBus)3181739a20eSAndy Ritger kbusDestruct_IMPL(KernelBus *pKernelBus)
3191739a20eSAndy Ritger {
3201739a20eSAndy Ritger     OBJGPU *pGpu = ENG_GET_GPU(pKernelBus);
3211739a20eSAndy Ritger 
32291676d66SBernhard Stoeckner     memdescFree(pKernelBus->bar1[GPU_GFID_PF].pInstBlkMemDesc);
32391676d66SBernhard Stoeckner     memdescDestroy(pKernelBus->bar1[GPU_GFID_PF].pInstBlkMemDesc);
32491676d66SBernhard Stoeckner     pKernelBus->bar1[GPU_GFID_PF].pInstBlkMemDesc = NULL;
32591676d66SBernhard Stoeckner     memdescFree(pKernelBus->bar2[GPU_GFID_PF].pInstBlkMemDesc);
32691676d66SBernhard Stoeckner     memdescDestroy(pKernelBus->bar2[GPU_GFID_PF].pInstBlkMemDesc);
32791676d66SBernhard Stoeckner     pKernelBus->bar2[GPU_GFID_PF].pInstBlkMemDesc = NULL;
32891676d66SBernhard Stoeckner 
3291739a20eSAndy Ritger     //
3301739a20eSAndy Ritger     // We need to clean-up the memory resources for BAR2 as late as possible,
3311739a20eSAndy Ritger     // and after all memory descriptors have been reclaimed.
3321739a20eSAndy Ritger     //
3331739a20eSAndy Ritger     kbusDestructVirtualBar2_HAL(pGpu, pKernelBus, NV_TRUE, GPU_GFID_PF);
3341739a20eSAndy Ritger 
33591676d66SBernhard Stoeckner     // Unmap BAR2 mapping that was retained for RPC
33691676d66SBernhard Stoeckner     if (IS_VGPU_GSP_PLUGIN_OFFLOAD_ENABLED(pGpu) &&
33791676d66SBernhard Stoeckner         IS_VIRTUAL_WITH_SRIOV(pGpu) &&
33891676d66SBernhard Stoeckner         pKernelBus->virtualBar2[GPU_GFID_PF].pCpuMapping != NULL)
33991676d66SBernhard Stoeckner     {
34091676d66SBernhard Stoeckner         // vgpuDestructObject should have been run
34191676d66SBernhard Stoeckner         OBJVGPU *pVGpu = GPU_GET_VGPU(pGpu);
34291676d66SBernhard Stoeckner         NV_ASSERT(pVGpu == NULL);
34391676d66SBernhard Stoeckner 
34491676d66SBernhard Stoeckner         osUnmapPciMemoryKernelOld(pGpu, pKernelBus->virtualBar2[GPU_GFID_PF].pCpuMapping);
34591676d66SBernhard Stoeckner     }
34691676d66SBernhard Stoeckner 
3471739a20eSAndy Ritger     return;
3481739a20eSAndy Ritger }
3491739a20eSAndy Ritger 
3501739a20eSAndy Ritger /*! Send sysmembar to all sub-devices */
3511739a20eSAndy Ritger NV_STATUS
kbusSendSysmembar_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus)3521739a20eSAndy Ritger kbusSendSysmembar_IMPL
3531739a20eSAndy Ritger (
3541739a20eSAndy Ritger     OBJGPU      *pGpu,
3551739a20eSAndy Ritger     KernelBus   *pKernelBus
3561739a20eSAndy Ritger )
3571739a20eSAndy Ritger {
3581739a20eSAndy Ritger     NV_STATUS   status  = NV_OK;
3591739a20eSAndy Ritger 
3601739a20eSAndy Ritger     // Nothing to be done in guest in the paravirtualization case.
3611739a20eSAndy Ritger     if (IS_VIRTUAL_WITHOUT_SRIOV(pGpu))
3621739a20eSAndy Ritger     {
3631739a20eSAndy Ritger         return NV_OK;
3641739a20eSAndy Ritger     }
3651739a20eSAndy Ritger 
3661739a20eSAndy Ritger     // Wait for the flush to flow through
3671739a20eSAndy Ritger     SLI_LOOP_START(SLI_LOOP_FLAGS_BC_ONLY | SLI_LOOP_FLAGS_IGNORE_REENTRANCY);
3681739a20eSAndy Ritger         pKernelBus = GPU_GET_KERNEL_BUS(pGpu);
3691739a20eSAndy Ritger         if (kbusSendSysmembarSingle_HAL(pGpu, pKernelBus) == NV_ERR_TIMEOUT)
3701739a20eSAndy Ritger         {
3711739a20eSAndy Ritger             status = NV_ERR_TIMEOUT;
3721739a20eSAndy Ritger         }
3731739a20eSAndy Ritger     SLI_LOOP_END;
3741739a20eSAndy Ritger     pKernelBus = GPU_GET_KERNEL_BUS(pGpu);
3751739a20eSAndy Ritger 
3761739a20eSAndy Ritger     return status;
3771739a20eSAndy Ritger }
3781739a20eSAndy Ritger 
3791739a20eSAndy Ritger /**
3801739a20eSAndy Ritger  * @brief Send sysmembar to a single sub-devices
3811739a20eSAndy Ritger  *        Trigger RPC to Physical RM.
3821739a20eSAndy Ritger  *
3831739a20eSAndy Ritger  * @param[in] pGpu
3841739a20eSAndy Ritger  * @param[in] pKernelBus
3851739a20eSAndy Ritger  */
3861739a20eSAndy Ritger NV_STATUS
kbusSendSysmembarSingle_KERNEL(OBJGPU * pGpu,KernelBus * pKernelBus)3871739a20eSAndy Ritger kbusSendSysmembarSingle_KERNEL
3881739a20eSAndy Ritger (
3891739a20eSAndy Ritger     OBJGPU    *pGpu,
3901739a20eSAndy Ritger     KernelBus *pKernelBus
3911739a20eSAndy Ritger )
3921739a20eSAndy Ritger {
3931739a20eSAndy Ritger     RM_API    *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
3941739a20eSAndy Ritger     NV_STATUS  status;
3951739a20eSAndy Ritger 
3961739a20eSAndy Ritger     status = pRmApi->Control(pRmApi, pGpu->hInternalClient, pGpu->hInternalSubdevice,
3971739a20eSAndy Ritger                                 NV2080_CTRL_CMD_INTERNAL_BUS_FLUSH_WITH_SYSMEMBAR,
3981739a20eSAndy Ritger                                 NULL, 0);
3991739a20eSAndy Ritger 
4001739a20eSAndy Ritger     return status;
4011739a20eSAndy Ritger }
4021739a20eSAndy Ritger 
4031739a20eSAndy Ritger /*!
4041739a20eSAndy Ritger  * @brief Commit BAR2
4051739a20eSAndy Ritger  *
4061739a20eSAndy Ritger  * @param[in] pGpu
4071739a20eSAndy Ritger  * @param[in] pKernelBus
4081739a20eSAndy Ritger  * @param[in] flags         GPU state flag (not used by Kernel RM)
4091739a20eSAndy Ritger  *
4101739a20eSAndy Ritger  * @returns NV_OK on success.
4111739a20eSAndy Ritger  */
4121739a20eSAndy Ritger NV_STATUS
kbusCommitBar2_KERNEL(OBJGPU * pGpu,KernelBus * pKernelBus,NvU32 flags)4131739a20eSAndy Ritger kbusCommitBar2_KERNEL
4141739a20eSAndy Ritger (
4151739a20eSAndy Ritger     OBJGPU    *pGpu,
4161739a20eSAndy Ritger     KernelBus *pKernelBus,
4171739a20eSAndy Ritger     NvU32      flags
4181739a20eSAndy Ritger )
4191739a20eSAndy Ritger {
420eb5c7665SAndy Ritger     if (!KBUS_BAR0_PRAMIN_DISABLED(pGpu) &&
421eb5c7665SAndy Ritger         !kbusIsBarAccessBlocked(pKernelBus) &&
422eb5c7665SAndy Ritger         !(flags & GPU_STATE_FLAGS_GC6_TRANSITION))
4234397463eSAndy Ritger     {
4241739a20eSAndy Ritger         // we will initialize bar2 to the default big page size of the system
4251739a20eSAndy Ritger         NV_ASSERT_OK_OR_RETURN(kbusInitVirtualBar2_HAL(pGpu, pKernelBus));
4261739a20eSAndy Ritger         NV_ASSERT_OK_OR_RETURN(kbusSetupCpuPointerForBusFlush_HAL(pGpu, pKernelBus));
4274397463eSAndy Ritger     }
4281739a20eSAndy Ritger     return NV_OK;
4291739a20eSAndy Ritger }
4301739a20eSAndy Ritger 
4311739a20eSAndy Ritger /*! Get pci bar size in BYTE */
4321739a20eSAndy Ritger NvU64
kbusGetPciBarSize_IMPL(KernelBus * pKernelBus,NvU32 index)4331739a20eSAndy Ritger kbusGetPciBarSize_IMPL(KernelBus *pKernelBus, NvU32 index)
4341739a20eSAndy Ritger {
4351739a20eSAndy Ritger     if (index >= pKernelBus->totalPciBars)
4361739a20eSAndy Ritger     {
4371739a20eSAndy Ritger         NV_PRINTF(LEVEL_ERROR, "bad index 0x%x\n", index);
4381739a20eSAndy Ritger         return 0;
4391739a20eSAndy Ritger     }
4401739a20eSAndy Ritger 
4411739a20eSAndy Ritger     return pKernelBus->pciBarSizes[index];
4421739a20eSAndy Ritger }
4431739a20eSAndy Ritger 
4441739a20eSAndy Ritger RmPhysAddr
kbusGetPciBarOffset_IMPL(KernelBus * pKernelBus,NvU32 index)4451739a20eSAndy Ritger kbusGetPciBarOffset_IMPL(KernelBus *pKernelBus, NvU32 index)
4461739a20eSAndy Ritger {
4471739a20eSAndy Ritger     RmPhysAddr offset = 0x0;
4481739a20eSAndy Ritger 
4491739a20eSAndy Ritger     if (index < pKernelBus->totalPciBars)
4501739a20eSAndy Ritger     {
4511739a20eSAndy Ritger         offset = pKernelBus->pciBars[index];
4521739a20eSAndy Ritger     }
4531739a20eSAndy Ritger     else
4541739a20eSAndy Ritger     {
4551739a20eSAndy Ritger         NV_PRINTF(LEVEL_ERROR, "bad index 0x%x\n", index);
4561739a20eSAndy Ritger     }
4571739a20eSAndy Ritger 
4581739a20eSAndy Ritger     return offset;
4591739a20eSAndy Ritger }
4601739a20eSAndy Ritger 
4611739a20eSAndy Ritger /**
4621739a20eSAndy Ritger  * @brief Determine bBar1Force64KBMapping base on regkey and bar1 size
4631739a20eSAndy Ritger  *   Determine if 64KB mappings need to be forced based on total BAR1 size.
4641739a20eSAndy Ritger  *   Default threshold is 256MB unless overridden by regkey
4651739a20eSAndy Ritger  *   Force 64KB for SKUs with BAR1 size <= 256MB
4661739a20eSAndy Ritger  *
4671739a20eSAndy Ritger  * @param[in] pKernelBus
4681739a20eSAndy Ritger  */
4691739a20eSAndy Ritger void
kbusDetermineBar1Force64KBMapping_IMPL(KernelBus * pKernelBus)4701739a20eSAndy Ritger kbusDetermineBar1Force64KBMapping_IMPL
4711739a20eSAndy Ritger (
4721739a20eSAndy Ritger     KernelBus *pKernelBus
4731739a20eSAndy Ritger )
4741739a20eSAndy Ritger {
4751739a20eSAndy Ritger     OBJGPU*   pGpu = ENG_GET_GPU(pKernelBus);
4761739a20eSAndy Ritger     NvU32     data;
4771739a20eSAndy Ritger 
4781739a20eSAndy Ritger     pKernelBus->bBar1Force64KBMapping = NV_TRUE;
4791739a20eSAndy Ritger 
4801739a20eSAndy Ritger     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_64KB_BAR1_MAPPINGS,
4811739a20eSAndy Ritger                             &data) == NV_OK)
4821739a20eSAndy Ritger     {
4831739a20eSAndy Ritger         if (data == NV_REG_STR_RM_64KB_BAR1_MAPPINGS_DISABLED)
4841739a20eSAndy Ritger         {
4851739a20eSAndy Ritger             pKernelBus->bBar1Force64KBMapping = NV_FALSE;
4861739a20eSAndy Ritger         }
4871739a20eSAndy Ritger     }
4881739a20eSAndy Ritger     else
4891739a20eSAndy Ritger     {
4901739a20eSAndy Ritger         NvU32   bar1SizeMB;
4911739a20eSAndy Ritger         bar1SizeMB = (NvU32)(kbusGetPciBarSize(pKernelBus, 1) >> 20);
4921739a20eSAndy Ritger 
4931739a20eSAndy Ritger         if (bar1SizeMB > 256)
4941739a20eSAndy Ritger         {
4951739a20eSAndy Ritger             pKernelBus->bBar1Force64KBMapping = NV_FALSE;
4961739a20eSAndy Ritger         }
4971739a20eSAndy Ritger     }
4981739a20eSAndy Ritger }
4991739a20eSAndy Ritger 
5001739a20eSAndy Ritger 
5011739a20eSAndy Ritger /**
5021739a20eSAndy Ritger  * @brief Determine bar1[gfid].apertureLength base on regkey and bar1 size
5031739a20eSAndy Ritger  *
5041739a20eSAndy Ritger  * @param[in] pKernelBus
5051739a20eSAndy Ritger  * @param[in] gfid
5061739a20eSAndy Ritger  */
5071739a20eSAndy Ritger void
kbusDetermineBar1ApertureLength_IMPL(KernelBus * pKernelBus,NvU32 gfid)5081739a20eSAndy Ritger kbusDetermineBar1ApertureLength_IMPL
5091739a20eSAndy Ritger (
5101739a20eSAndy Ritger     KernelBus *pKernelBus,
5111739a20eSAndy Ritger     NvU32      gfid
5121739a20eSAndy Ritger )
5131739a20eSAndy Ritger {
5141739a20eSAndy Ritger     OBJGPU   *pGpu = ENG_GET_GPU(pKernelBus);
5151739a20eSAndy Ritger     NvU32     data32;
5161739a20eSAndy Ritger 
5171739a20eSAndy Ritger     if (IS_GFID_VF(gfid))
5181739a20eSAndy Ritger     {
5191739a20eSAndy Ritger         pKernelBus->bar1[gfid].apertureLength = pGpu->sriovState.vfBarSize[1];
5201739a20eSAndy Ritger     }
5211739a20eSAndy Ritger     else
5221739a20eSAndy Ritger     {
5231739a20eSAndy Ritger         pKernelBus->bar1[gfid].apertureLength = kbusGetPciBarSize(pKernelBus, 1);
5241739a20eSAndy Ritger     }
5251739a20eSAndy Ritger 
5261739a20eSAndy Ritger     // We can shrink BAR1 using this reg key but cannot grow it.
5271739a20eSAndy Ritger     if (((NV_OK == osReadRegistryDword(pGpu,
5281739a20eSAndy Ritger                         NV_REG_STR_RM_BAR1_APERTURE_SIZE_MB, &data32))) &&
5291739a20eSAndy Ritger             data32 && (((NvU64)data32 << 20) < pKernelBus->bar1[gfid].apertureLength))
5301739a20eSAndy Ritger     {
5311739a20eSAndy Ritger         // Set BAR1 aperture length based on the override
5321739a20eSAndy Ritger         pKernelBus->bar1[gfid].apertureLength = (NvU64) data32 << 20;
5331739a20eSAndy Ritger     }
5341739a20eSAndy Ritger 
5351739a20eSAndy Ritger }
5361739a20eSAndy Ritger 
5371739a20eSAndy Ritger /*!
5381739a20eSAndy Ritger  * @brief Initialize pciBarSizes[], set pKernelBus->bPciBarSizesValid
5391739a20eSAndy Ritger  *        Trigger an internal RMAPI to get the data from Physical RM.
5401739a20eSAndy Ritger  *
5411739a20eSAndy Ritger  * @param[in] pGpu
5421739a20eSAndy Ritger  * @param[in] pKernelBus
5431739a20eSAndy Ritger  */
5441739a20eSAndy Ritger NV_STATUS
kbusInitBarsSize_KERNEL(OBJGPU * pGpu,KernelBus * pKernelBus)5451739a20eSAndy Ritger kbusInitBarsSize_KERNEL
5461739a20eSAndy Ritger (
5471739a20eSAndy Ritger     OBJGPU    *pGpu,
5481739a20eSAndy Ritger     KernelBus *pKernelBus
5491739a20eSAndy Ritger )
5501739a20eSAndy Ritger {
5511739a20eSAndy Ritger     RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
5521739a20eSAndy Ritger     NV2080_CTRL_BUS_GET_PCI_BAR_INFO_PARAMS params;
5531739a20eSAndy Ritger     NvU32 i;
5541739a20eSAndy Ritger 
5551739a20eSAndy Ritger     NV_ASSERT( ! pKernelBus->bPciBarSizesValid);
5561739a20eSAndy Ritger 
5571739a20eSAndy Ritger     NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
5581739a20eSAndy Ritger         pRmApi->Control(pRmApi, pGpu->hInternalClient, pGpu->hInternalSubdevice,
5591739a20eSAndy Ritger                         NV2080_CTRL_CMD_BUS_GET_PCI_BAR_INFO,
5601739a20eSAndy Ritger                         &params, sizeof(params)));
5611739a20eSAndy Ritger 
5621739a20eSAndy Ritger     for (i = 0; i< params.pciBarCount; i++)
5631739a20eSAndy Ritger     {
5641739a20eSAndy Ritger         pKernelBus->pciBarSizes[i] = params.pciBarInfo[i].barSizeBytes;
5651739a20eSAndy Ritger     }
5661739a20eSAndy Ritger 
5671739a20eSAndy Ritger     pKernelBus->bPciBarSizesValid = NV_TRUE;
5681739a20eSAndy Ritger 
5691739a20eSAndy Ritger     return NV_OK;
5701739a20eSAndy Ritger }
5711739a20eSAndy Ritger 
5721739a20eSAndy Ritger /*!
5731739a20eSAndy Ritger  * @brief Remove P2P mapping to a given peer GPU
5741739a20eSAndy Ritger  *
5751739a20eSAndy Ritger  * @param[in]   pGpu0         (Local)
5761739a20eSAndy Ritger  * @param[in]   pKernelBus0   (Local)
5771739a20eSAndy Ritger  * @param[in]   pGpu1         (Remote)
5781739a20eSAndy Ritger  * @param[in]   peerIdx
5791739a20eSAndy Ritger  *
5801739a20eSAndy Ritger  * return NV_OK on success
5811739a20eSAndy Ritger  */
5821739a20eSAndy Ritger void
kbusDestroyMailbox_IMPL(OBJGPU * pGpu0,KernelBus * pKernelBus0,OBJGPU * pGpu1,NvU32 peerIdx)5831739a20eSAndy Ritger kbusDestroyMailbox_IMPL
5841739a20eSAndy Ritger (
5851739a20eSAndy Ritger     OBJGPU      *pGpu0,
5861739a20eSAndy Ritger     KernelBus   *pKernelBus0,
5871739a20eSAndy Ritger     OBJGPU      *pGpu1,
5881739a20eSAndy Ritger     NvU32        peerIdx
5891739a20eSAndy Ritger )
5901739a20eSAndy Ritger {
5911739a20eSAndy Ritger     RM_API *pRmApi  = GPU_GET_PHYSICAL_RMAPI(pGpu0);
5921739a20eSAndy Ritger     NvBool  bNeedWarBug999673 = kbusNeedWarForBug999673_HAL(pGpu0, pKernelBus0, pGpu1) ||
5931739a20eSAndy Ritger                                 kbusNeedWarForBug999673_HAL(pGpu1, GPU_GET_KERNEL_BUS(pGpu1), pGpu0);
5941739a20eSAndy Ritger     NV2080_CTRL_INTERNAL_BUS_DESTROY_P2P_MAILBOX_PARAMS busParams   = {0};
5951739a20eSAndy Ritger     NV2080_CTRL_INTERNAL_HSHUB_PEER_CONN_CONFIG_PARAMS  hshubParams = {0};
5961739a20eSAndy Ritger     NV_STATUS status;
5971739a20eSAndy Ritger 
5981739a20eSAndy Ritger     kbusDestroyPeerAccess_HAL(pGpu0, pKernelBus0, peerIdx);
5991739a20eSAndy Ritger 
6001739a20eSAndy Ritger     busParams.peerIdx           = peerIdx;
6011739a20eSAndy Ritger     busParams.bNeedWarBug999673 = bNeedWarBug999673;
6021739a20eSAndy Ritger     status = pRmApi->Control(pRmApi, pGpu0->hInternalClient, pGpu0->hInternalSubdevice,
6031739a20eSAndy Ritger                              NV2080_CTRL_CMD_INTERNAL_BUS_DESTROY_P2P_MAILBOX,
6041739a20eSAndy Ritger                              &busParams, sizeof(busParams));
6051739a20eSAndy Ritger     NV_ASSERT(status == NV_OK);
6061739a20eSAndy Ritger 
6071739a20eSAndy Ritger     // Create a peer mask for each peer to program their respective peer_connection_cfg registers
6081739a20eSAndy Ritger     hshubParams.invalidatePeerMask = NVBIT32(peerIdx);
6091739a20eSAndy Ritger     // Program connection_cfg registers
6101739a20eSAndy Ritger     status = pRmApi->Control(pRmApi, pGpu0->hInternalClient, pGpu0->hInternalSubdevice,
6111739a20eSAndy Ritger                              NV2080_CTRL_CMD_INTERNAL_HSHUB_PEER_CONN_CONFIG,
6121739a20eSAndy Ritger                              &hshubParams, sizeof(hshubParams));
6131739a20eSAndy Ritger     NV_ASSERT(status == NV_OK);
6141739a20eSAndy Ritger }
6151739a20eSAndy Ritger 
6161739a20eSAndy Ritger NvU8 *
kbusCpuOffsetInBar2WindowGet_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus,MEMORY_DESCRIPTOR * pMemDesc)6171739a20eSAndy Ritger kbusCpuOffsetInBar2WindowGet_IMPL
6181739a20eSAndy Ritger (
6191739a20eSAndy Ritger     OBJGPU            *pGpu,
6201739a20eSAndy Ritger     KernelBus         *pKernelBus,
6211739a20eSAndy Ritger     MEMORY_DESCRIPTOR *pMemDesc
6221739a20eSAndy Ritger )
6231739a20eSAndy Ritger {
6241739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(NULL != pKernelBus->virtualBar2[GPU_GFID_PF].pCpuMapping, NULL);
6251739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(ADDR_FBMEM == pMemDesc->_addressSpace, NULL);
6261739a20eSAndy Ritger 
6271739a20eSAndy Ritger     return (NvU8 *)(pKernelBus->virtualBar2[GPU_GFID_PF].pCpuMapping +
6281739a20eSAndy Ritger                     memdescGetPhysAddr(pMemDesc, AT_GPU, 0));
6291739a20eSAndy Ritger }
6301739a20eSAndy Ritger 
6311739a20eSAndy Ritger /*!
6321739a20eSAndy Ritger  * Calculates the BAR2 VA limit (in Byte units) which usually means the
6331739a20eSAndy Ritger  * cpuVisible area limit in CPU-RM.  Can be safely called only after
6341739a20eSAndy Ritger  * kbusSetBarsApertureSize_HAL is executed.
6351739a20eSAndy Ritger  *
6361739a20eSAndy Ritger  * @param   pGpu
6371739a20eSAndy Ritger  * @param   pKernelBus
6381739a20eSAndy Ritger  *
6391739a20eSAndy Ritger  * @return VA limit of BAR2
6401739a20eSAndy Ritger  */
6411739a20eSAndy Ritger NvU64
kbusGetVaLimitForBar2_FWCLIENT(OBJGPU * pGpu,KernelBus * pKernelBus)64291676d66SBernhard Stoeckner kbusGetVaLimitForBar2_FWCLIENT
6431739a20eSAndy Ritger (
6441739a20eSAndy Ritger     OBJGPU    *pGpu,
6451739a20eSAndy Ritger     KernelBus *pKernelBus
6461739a20eSAndy Ritger )
6471739a20eSAndy Ritger {
6481739a20eSAndy Ritger     NvU64 limit = pKernelBus->bar2[GPU_GFID_PF].cpuVisibleLimit;
6491739a20eSAndy Ritger 
6501739a20eSAndy Ritger     NV_PRINTF(LEVEL_INFO, "va limit: 0x%llx\n", limit);
6511739a20eSAndy Ritger 
6521739a20eSAndy Ritger     //
6531739a20eSAndy Ritger     // pKernelBus->bar2.vaLimit is set by this function.
6541739a20eSAndy Ritger     // Assert to ensure that this value doesn't get changed.
6551739a20eSAndy Ritger     //
6561739a20eSAndy Ritger     NV_ASSERT(pKernelBus->bar2[GPU_GFID_PF].vaLimit == 0 || pKernelBus->bar2[GPU_GFID_PF].vaLimit == limit);
6571739a20eSAndy Ritger 
6581739a20eSAndy Ritger     return limit;
6591739a20eSAndy Ritger }
6601739a20eSAndy Ritger 
6611739a20eSAndy Ritger /*!
66291676d66SBernhard Stoeckner  * @brief Calculates the BAR2 VA limit (in Byte units)
66391676d66SBernhard Stoeckner  * Can be safely called only after kbusSetBarsApertureSize_HAL is executed.
66491676d66SBernhard Stoeckner  */
kbusGetVaLimitForBar2_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus)66591676d66SBernhard Stoeckner NvU64 kbusGetVaLimitForBar2_IMPL
66691676d66SBernhard Stoeckner (
66791676d66SBernhard Stoeckner     OBJGPU    *pGpu,
66891676d66SBernhard Stoeckner     KernelBus *pKernelBus
66991676d66SBernhard Stoeckner )
67091676d66SBernhard Stoeckner {
67191676d66SBernhard Stoeckner     NvU64 limit = 0;
67291676d66SBernhard Stoeckner     NvU32 gfid;
67391676d66SBernhard Stoeckner 
67491676d66SBernhard Stoeckner     NV_ASSERT_OR_RETURN(vgpuGetCallingContextGfid(pGpu, &gfid) == NV_OK, 0);
67591676d66SBernhard Stoeckner 
67691676d66SBernhard Stoeckner     //
67791676d66SBernhard Stoeckner     // Return zero from the guest in the paravirtualization case or
67891676d66SBernhard Stoeckner     // if guest is running in SRIOV heavy mode.
67991676d66SBernhard Stoeckner     //
68091676d66SBernhard Stoeckner     if (IS_VIRTUAL_WITHOUT_SRIOV(pGpu) ||
68191676d66SBernhard Stoeckner         (IS_VIRTUAL(pGpu) && gpuIsWarBug200577889SriovHeavyEnabled(pGpu)))
68291676d66SBernhard Stoeckner     {
68391676d66SBernhard Stoeckner         return 0;
68491676d66SBernhard Stoeckner     }
68591676d66SBernhard Stoeckner 
68691676d66SBernhard Stoeckner     kbusCalcCpuInvisibleBar2Range_HAL(pGpu, pKernelBus, gfid);
68791676d66SBernhard Stoeckner 
68891676d66SBernhard Stoeckner     //
68991676d66SBernhard Stoeckner     // we are just accounting here for possibility that
69091676d66SBernhard Stoeckner     // we are on pre_PASCAL and so we set the va limit
69191676d66SBernhard Stoeckner     // to account only for the cpuVisible Aperture
69291676d66SBernhard Stoeckner     //
69391676d66SBernhard Stoeckner     if (pKernelBus->bar2[gfid].cpuInvisibleLimit > pKernelBus->bar2[gfid].cpuInvisibleBase)
69491676d66SBernhard Stoeckner     {
69591676d66SBernhard Stoeckner         limit = pKernelBus->bar2[gfid].cpuInvisibleLimit;
69691676d66SBernhard Stoeckner     }
69791676d66SBernhard Stoeckner     else
69891676d66SBernhard Stoeckner     {
69991676d66SBernhard Stoeckner         limit = pKernelBus->bar2[gfid].cpuVisibleLimit;
70091676d66SBernhard Stoeckner     }
70191676d66SBernhard Stoeckner     NV_PRINTF(LEVEL_INFO, "va limit: 0x%llx\n", limit);
70291676d66SBernhard Stoeckner     //
70391676d66SBernhard Stoeckner     // pKernelBus->bar2.vaLimit is set by this function.
70491676d66SBernhard Stoeckner     // Assert to ensure that this value doesn't get changed.
70591676d66SBernhard Stoeckner     //
70691676d66SBernhard Stoeckner     NV_ASSERT(pKernelBus->bar2[gfid].vaLimit == 0 || pKernelBus->bar2[gfid].vaLimit == limit);
70791676d66SBernhard Stoeckner 
70891676d66SBernhard Stoeckner     return limit;
70991676d66SBernhard Stoeckner }
71091676d66SBernhard Stoeckner 
71191676d66SBernhard Stoeckner /*!
7121739a20eSAndy Ritger  * Patch CPU-RM's SW cache of BAR1 PDB to GSP-RM's BAR1 PDB so that CPU-RM can
7131739a20eSAndy Ritger  * do TLB invalidation to correct VA space.
7141739a20eSAndy Ritger  *
7151739a20eSAndy Ritger  * @param   pGpu
7161739a20eSAndy Ritger  * @param   pKernelBus
7171739a20eSAndy Ritger  *
7181739a20eSAndy Ritger  * @return NV_OK if PDB is updated successfully
7191739a20eSAndy Ritger  *         Or bubble up the error code returned by the callees
7201739a20eSAndy Ritger  */
7211739a20eSAndy Ritger NV_STATUS
kbusPatchBar1Pdb_GSPCLIENT(OBJGPU * pGpu,KernelBus * pKernelBus)7221739a20eSAndy Ritger kbusPatchBar1Pdb_GSPCLIENT
7231739a20eSAndy Ritger (
7241739a20eSAndy Ritger     OBJGPU      *pGpu,
7251739a20eSAndy Ritger     KernelBus   *pKernelBus
7261739a20eSAndy Ritger )
7271739a20eSAndy Ritger {
7281739a20eSAndy Ritger     NV_STATUS            status    = NV_OK;
7291739a20eSAndy Ritger     OBJGVASPACE         *pGVAS     = dynamicCast(pKernelBus->bar1[GPU_GFID_PF].pVAS, OBJGVASPACE);
7301739a20eSAndy Ritger     KernelGmmu          *pKernelGmmu = GPU_GET_KERNEL_GMMU(pGpu);
7311739a20eSAndy Ritger     MEMORY_DESCRIPTOR   *pMemDesc  = NULL;
7321739a20eSAndy Ritger     GVAS_GPU_STATE      *pGpuState = gvaspaceGetGpuState(pGVAS, pGpu);
7331739a20eSAndy Ritger     const MMU_FMT_LEVEL *pRootFmt  = pGpuState->pFmt->pRoot;
73491676d66SBernhard Stoeckner     NvU32                rootSize  = mmuFmtLevelSize(pRootFmt);
7351739a20eSAndy Ritger     MMU_WALK_USER_CTX    userCtx   = {0};
7361739a20eSAndy Ritger     GspStaticConfigInfo *pGSCI     = GPU_GET_GSP_STATIC_INFO(pGpu);
7371739a20eSAndy Ritger 
7381739a20eSAndy Ritger     NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
7391739a20eSAndy Ritger          memdescCreate(&pMemDesc, pGpu, rootSize, RM_PAGE_SIZE, NV_TRUE, ADDR_FBMEM,
7401739a20eSAndy Ritger                        kgmmuGetPTEAttr(pKernelGmmu), MEMDESC_FLAGS_NONE));
7411739a20eSAndy Ritger 
7421739a20eSAndy Ritger     memdescDescribe(pMemDesc, ADDR_FBMEM, pGSCI->bar1PdeBase, rootSize);
7431739a20eSAndy Ritger     memdescSetPageSize(pMemDesc, VAS_ADDRESS_TRANSLATION(pKernelBus->bar1[GPU_GFID_PF].pVAS), RM_PAGE_SIZE);
7441739a20eSAndy Ritger 
7451739a20eSAndy Ritger     gvaspaceWalkUserCtxAcquire(pGVAS, pGpu, NULL, &userCtx);
7461739a20eSAndy Ritger 
7471739a20eSAndy Ritger     //
7481739a20eSAndy Ritger     // Modify the CPU-RM's walker state with the new backing memory.
7491739a20eSAndy Ritger     // This is intended to replace CPU-RM's PDB by GSP-RM's PDB.
7501739a20eSAndy Ritger     //
7511739a20eSAndy Ritger     status = mmuWalkModifyLevelInstance(pGpuState->pWalk,
7521739a20eSAndy Ritger                                         pRootFmt,
7531739a20eSAndy Ritger                                         vaspaceGetVaStart(pKernelBus->bar1[GPU_GFID_PF].pVAS),
7541739a20eSAndy Ritger                                         (MMU_WALK_MEMDESC*)pMemDesc,
75591676d66SBernhard Stoeckner                                         rootSize,
7561739a20eSAndy Ritger                                         NV_TRUE,
7571739a20eSAndy Ritger                                         NV_TRUE,
7581739a20eSAndy Ritger                                         NV_FALSE);
7591739a20eSAndy Ritger     gvaspaceWalkUserCtxRelease(pGVAS, &userCtx);
7601739a20eSAndy Ritger     if (NV_OK != status)
7611739a20eSAndy Ritger     {
7621739a20eSAndy Ritger         NV_PRINTF(LEVEL_ERROR, "Failed to modify CPU-RM's BAR1 PDB to GSP-RM's BAR1 PDB.\n");
7631739a20eSAndy Ritger         return status;
7641739a20eSAndy Ritger     }
7651739a20eSAndy Ritger 
7661739a20eSAndy Ritger     gvaspaceInvalidateTlb(pGVAS, pGpu, PTE_DOWNGRADE);
7671739a20eSAndy Ritger 
7681739a20eSAndy Ritger     return status;
7691739a20eSAndy Ritger }
7701739a20eSAndy Ritger 
7711739a20eSAndy Ritger /*!
7721739a20eSAndy Ritger  * Patch CPU-RM's SW cache of BAR2 PDB to GSP-RM's BAR2 PDB so that CPU-RM can
7731739a20eSAndy Ritger  * do TLB invalidation to correct VA space.
7741739a20eSAndy Ritger  *
7751739a20eSAndy Ritger  * For the BAR2 support in RM-offload model, CPU-RM owns the VA range under
7761739a20eSAndy Ritger  * PDE3[0] and GSP-RM owns the VA range under PDE3[1]. GSP-RM and CPU-RM
7771739a20eSAndy Ritger  * establish their own BAR2 page tables respectively. After CPU-RM establishes
7781739a20eSAndy Ritger  * its own table, it passes its PDE3[0] value to GSP-RM, then GSP-RM will fill
7791739a20eSAndy Ritger  * this value to PDE3[0] of GSP-RM's table (only GSP-RM's BAR2 table will be
7801739a20eSAndy Ritger  * bound to HW) so that HW sees single BAR2 page table for both GSP-RM and
7811739a20eSAndy Ritger  * CPU-RM.
7821739a20eSAndy Ritger  *
7831739a20eSAndy Ritger  * @param   pGpu
7841739a20eSAndy Ritger  * @param   pKernelBus
7851739a20eSAndy Ritger  *
7861739a20eSAndy Ritger  * @return NV_OK if PDB is updated successfully
7871739a20eSAndy Ritger  *         Or bubble up the error code returned by the callees
7881739a20eSAndy Ritger  */
7891739a20eSAndy Ritger NV_STATUS
kbusPatchBar2Pdb_GSPCLIENT(OBJGPU * pGpu,KernelBus * pKernelBus)7901739a20eSAndy Ritger kbusPatchBar2Pdb_GSPCLIENT
7911739a20eSAndy Ritger (
7921739a20eSAndy Ritger     OBJGPU      *pGpu,
7931739a20eSAndy Ritger     KernelBus   *pKernelBus
7941739a20eSAndy Ritger )
7951739a20eSAndy Ritger {
7961739a20eSAndy Ritger     NV_STATUS            status   = NV_OK;
7971739a20eSAndy Ritger     PMEMORY_DESCRIPTOR   pMemDesc;
7981739a20eSAndy Ritger     GspStaticConfigInfo *pGSCI    = GPU_GET_GSP_STATIC_INFO(pGpu);
799eb5c7665SAndy Ritger     const MMU_FMT_LEVEL *pRootFmt = pKernelBus->bar2[GPU_GFID_PF].pFmt->pRoot;
8001739a20eSAndy Ritger     NvU64                entryValue;
801eb5c7665SAndy Ritger     MEMORY_DESCRIPTOR   *pOldPdb;
802eb5c7665SAndy Ritger 
803eb5c7665SAndy Ritger     pOldPdb = pKernelBus->virtualBar2[GPU_GFID_PF].pPDB;
8041739a20eSAndy Ritger 
8051739a20eSAndy Ritger     NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
8061739a20eSAndy Ritger         memdescCreate(&pMemDesc, pGpu, pKernelBus->bar2[GPU_GFID_PF].pageDirSize, RM_PAGE_SIZE, NV_TRUE,
8071739a20eSAndy Ritger                       ADDR_FBMEM, pKernelBus->PDEBAR2Attr, MEMDESC_FLAGS_NONE));
8081739a20eSAndy Ritger 
8091739a20eSAndy Ritger     memdescDescribe(pMemDesc, ADDR_FBMEM, pGSCI->bar2PdeBase, pKernelBus->bar2[GPU_GFID_PF].pageDirSize);
8101739a20eSAndy Ritger 
8111739a20eSAndy Ritger     // Update CPU-RM's SW cache of PDB to GSP-RM's PDB address
8121739a20eSAndy Ritger     pKernelBus->virtualBar2[GPU_GFID_PF].pPDB = pMemDesc;
8131739a20eSAndy Ritger 
8141739a20eSAndy Ritger     //
8151739a20eSAndy Ritger     // BAR2 page table is not yet working at this point, so retrieving the
816eb5c7665SAndy Ritger     // PDE3[0] of BAR2 page table via BAR0_WINDOW or GSP-DMA (in case BARs
817eb5c7665SAndy Ritger     // are blocked)
8181739a20eSAndy Ritger     //
819eb5c7665SAndy Ritger     if (kbusIsBarAccessBlocked(pKernelBus))
820eb5c7665SAndy Ritger     {
821eb5c7665SAndy Ritger         MemoryManager *pMemoryManager = GPU_GET_MEMORY_MANAGER(pGpu);
822eb5c7665SAndy Ritger         TRANSFER_SURFACE surf = {0};
823eb5c7665SAndy Ritger 
824eb5c7665SAndy Ritger         surf.pMemDesc = pOldPdb;
825eb5c7665SAndy Ritger         surf.offset = 0;
826eb5c7665SAndy Ritger 
827eb5c7665SAndy Ritger         NV_ASSERT_OK_OR_RETURN(
828eb5c7665SAndy Ritger             memmgrMemRead(pMemoryManager, &surf, &entryValue,
829eb5c7665SAndy Ritger                           pRootFmt->entrySize, TRANSFER_FLAGS_NONE));
830eb5c7665SAndy Ritger     }
831eb5c7665SAndy Ritger     else
832eb5c7665SAndy Ritger     {
8331739a20eSAndy Ritger         entryValue = GPU_REG_RD32(pGpu, (NvU32)pKernelBus->bar2[GPU_GFID_PF].bar2OffsetInBar0Window) |
8341739a20eSAndy Ritger                  ((NvU64)GPU_REG_RD32(pGpu, (NvU32)pKernelBus->bar2[GPU_GFID_PF].bar2OffsetInBar0Window + 4) << 32);
835eb5c7665SAndy Ritger     }
8361739a20eSAndy Ritger 
8371739a20eSAndy Ritger     //
8381739a20eSAndy Ritger     // Provide the PDE3[0] value to GSP-RM so that GSP-RM can merge CPU-RM's
8391739a20eSAndy Ritger     // page table to GSP-RM's page table
8401739a20eSAndy Ritger     //
841eb5c7665SAndy Ritger     NV_RM_RPC_UPDATE_BAR_PDE(pGpu, NV_RPC_UPDATE_PDE_BAR_2, entryValue, pRootFmt->virtAddrBitLo, status);
8421739a20eSAndy Ritger 
8431739a20eSAndy Ritger     return NV_OK;
8441739a20eSAndy Ritger }
8451739a20eSAndy Ritger 
84691676d66SBernhard Stoeckner NvBool
kbusCheckEngine_KERNEL(OBJGPU * pGpu,KernelBus * pKernelBus,ENGDESCRIPTOR engDesc)84791676d66SBernhard Stoeckner kbusCheckEngine_KERNEL
84891676d66SBernhard Stoeckner (
84991676d66SBernhard Stoeckner     OBJGPU        *pGpu,
85091676d66SBernhard Stoeckner     KernelBus     *pKernelBus,
85191676d66SBernhard Stoeckner     ENGDESCRIPTOR  engDesc
85291676d66SBernhard Stoeckner )
85391676d66SBernhard Stoeckner {
85491676d66SBernhard Stoeckner     return kbusCheckEngineWithOrderList_KERNEL(pGpu, pKernelBus, engDesc, NV_TRUE);
85591676d66SBernhard Stoeckner }
8561739a20eSAndy Ritger 
8571739a20eSAndy Ritger /*!
8581739a20eSAndy Ritger  * @brief Checks whether an engine is available or not.
8591739a20eSAndy Ritger  *
8601739a20eSAndy Ritger  * The 'engine' is an engine descriptor
8611739a20eSAndy Ritger  * This function is different from busProbeRegister in a sense that it doesn't
8621739a20eSAndy Ritger  * rely on timeouts after a read of a register in the reg space for engine.
8631739a20eSAndy Ritger  * Instead, it
8641739a20eSAndy Ritger  *  - Return TRUE for all engines which are must present in GPU.
86591676d66SBernhard Stoeckner  *  - Get information about CE, MSENC, NVJPG and OFA engines from plugin or GSP-RM.
86691676d66SBernhard Stoeckner  *  - If bCheckEngineOrder is true, the remaining engines are searched for in gpuChildOrderList_HAL.
8671739a20eSAndy Ritger  *
8681739a20eSAndy Ritger  * @param[in] pGpu       OBJGPU pointer
8691739a20eSAndy Ritger  * @param[in] pKernelBus KernelBus pointer
8701739a20eSAndy Ritger  * @param[in] engDesc    ENGDESCRIPTOR pointer used to check Engine presence
87191676d66SBernhard Stoeckner  * @param[in] bCheckEngineOrder If true, check gpuChildOrderList_HAL for engDesc as well
8721739a20eSAndy Ritger  *
8731739a20eSAndy Ritger  * @returns NV_TRUE if engine is available.
8741739a20eSAndy Ritger  *          NV_FALSE if engine is not available or floorswept.
8751739a20eSAndy Ritger  *
8761739a20eSAndy Ritger  */
8771739a20eSAndy Ritger NvBool
kbusCheckEngineWithOrderList_KERNEL(OBJGPU * pGpu,KernelBus * pKernelBus,ENGDESCRIPTOR engDesc,NvBool bCheckEngineOrder)87891676d66SBernhard Stoeckner kbusCheckEngineWithOrderList_KERNEL
8791739a20eSAndy Ritger (
8801739a20eSAndy Ritger     OBJGPU        *pGpu,
8811739a20eSAndy Ritger     KernelBus     *pKernelBus,
88291676d66SBernhard Stoeckner     ENGDESCRIPTOR  engDesc,
88391676d66SBernhard Stoeckner     NvBool         bCheckEngineOrder
8841739a20eSAndy Ritger )
8851739a20eSAndy Ritger {
886758b4ee8SAndy Ritger     NvU32     rmEngineCaps[NVGPU_ENGINE_CAPS_MASK_ARRAY_MAX] = {0};
887758b4ee8SAndy Ritger     NvU32     nv2080EngineCaps[NVGPU_ENGINE_CAPS_MASK_ARRAY_MAX] = {0};
8881739a20eSAndy Ritger     NvBool    bSupported;
889758b4ee8SAndy Ritger     NV_STATUS status;
8901739a20eSAndy Ritger 
89191676d66SBernhard Stoeckner     if (IS_VIRTUAL(pGpu))
89291676d66SBernhard Stoeckner     {
89391676d66SBernhard Stoeckner         VGPU_STATIC_INFO *pVSI = GPU_GET_STATIC_INFO(pGpu);
89491676d66SBernhard Stoeckner         if (pVSI == NULL)
89591676d66SBernhard Stoeckner         {
89691676d66SBernhard Stoeckner             return NV_FALSE;
89791676d66SBernhard Stoeckner         }
89891676d66SBernhard Stoeckner 
89991676d66SBernhard Stoeckner         ct_assert(RM_ENGINE_TYPE_LAST <= 64);
90091676d66SBernhard Stoeckner         ct_assert(NVGPU_ENGINE_CAPS_MASK_ARRAY_MAX == 2);
90191676d66SBernhard Stoeckner 
90291676d66SBernhard Stoeckner         nv2080EngineCaps[0] = NvU64_LO32(pVSI->engineList);
90391676d66SBernhard Stoeckner         nv2080EngineCaps[1] = NvU64_HI32(pVSI->engineList);
90491676d66SBernhard Stoeckner     }
90591676d66SBernhard Stoeckner     else
9061739a20eSAndy Ritger     {
907758b4ee8SAndy Ritger         NvU32 i;
9081739a20eSAndy Ritger         GspStaticConfigInfo *pGSCI = GPU_GET_GSP_STATIC_INFO(pGpu);
9091739a20eSAndy Ritger         if (pGSCI == NULL)
9101739a20eSAndy Ritger         {
9111739a20eSAndy Ritger             return NV_FALSE;
9121739a20eSAndy Ritger         }
913758b4ee8SAndy Ritger 
914758b4ee8SAndy Ritger         for (i = 0; i < NVGPU_ENGINE_CAPS_MASK_ARRAY_MAX; i++)
915758b4ee8SAndy Ritger         {
916758b4ee8SAndy Ritger             nv2080EngineCaps[i] = pGSCI->engineCaps[i];
9171739a20eSAndy Ritger         }
918758b4ee8SAndy Ritger     }
919758b4ee8SAndy Ritger 
920758b4ee8SAndy Ritger     NV_CHECK_OK_OR_ELSE(status, LEVEL_ERROR,
9214397463eSAndy Ritger         gpuGetRmEngineTypeCapMask(nv2080EngineCaps,
9224397463eSAndy Ritger                                   NVGPU_ENGINE_CAPS_MASK_ARRAY_MAX,
9234397463eSAndy Ritger                                   rmEngineCaps),
924758b4ee8SAndy Ritger         return NV_FALSE);
9251739a20eSAndy Ritger 
9261739a20eSAndy Ritger     switch (engDesc)
9271739a20eSAndy Ritger     {
9281739a20eSAndy Ritger         case ENG_LSFM:
9291739a20eSAndy Ritger         case ENG_PMU:
9301739a20eSAndy Ritger         case ENG_CLK:
9311739a20eSAndy Ritger         case ENG_ACR:
9321739a20eSAndy Ritger         case ENG_DISP:
9331739a20eSAndy Ritger             return NV_FALSE;
9341739a20eSAndy Ritger         //
9351739a20eSAndy Ritger         // This function is used in two environments:
9361739a20eSAndy Ritger         // (a) vGPU where display is not yet supported.
9371739a20eSAndy Ritger         // (b) RM offload (Kernel RM) where display is supported.
9381739a20eSAndy Ritger         //
9391739a20eSAndy Ritger         case ENG_KERNEL_DISPLAY:
9404397463eSAndy Ritger             return IS_GSP_CLIENT(pGpu);
9411739a20eSAndy Ritger 
9421739a20eSAndy Ritger         case ENG_BIF:
9431739a20eSAndy Ritger         case ENG_KERNEL_BIF:
9441739a20eSAndy Ritger         case ENG_MC:
9451739a20eSAndy Ritger         case ENG_KERNEL_MC:
9461739a20eSAndy Ritger         case ENG_PRIV_RING:
9471739a20eSAndy Ritger         case ENG_SW_INTR:
9481739a20eSAndy Ritger         case ENG_TMR:
9491739a20eSAndy Ritger         case ENG_DMA:
9501739a20eSAndy Ritger         case ENG_BUS:
9511739a20eSAndy Ritger         case ENG_GR(0):
9521739a20eSAndy Ritger         case ENG_CIPHER:
9531739a20eSAndy Ritger         case ENG_INTR:
9541739a20eSAndy Ritger         case ENG_GPULOG:
9551739a20eSAndy Ritger         case ENG_GPUMON:
9561739a20eSAndy Ritger         case ENG_FIFO:
9571739a20eSAndy Ritger             return NV_TRUE;
9581739a20eSAndy Ritger 
9591739a20eSAndy Ritger         case ENG_CE(0):
9601739a20eSAndy Ritger         case ENG_CE(1):
9611739a20eSAndy Ritger         case ENG_CE(2):
9621739a20eSAndy Ritger         case ENG_CE(3):
9631739a20eSAndy Ritger         case ENG_CE(4):
9641739a20eSAndy Ritger         case ENG_CE(5):
9651739a20eSAndy Ritger         case ENG_CE(6):
9661739a20eSAndy Ritger         case ENG_CE(7):
9671739a20eSAndy Ritger         case ENG_CE(8):
9681739a20eSAndy Ritger         case ENG_CE(9):
9694397463eSAndy Ritger             return !!NVGPU_GET_ENGINE_CAPS_MASK(rmEngineCaps,
9704397463eSAndy Ritger                 RM_ENGINE_TYPE_COPY(GET_CE_IDX(engDesc)));
9714397463eSAndy Ritger 
9721739a20eSAndy Ritger         case ENG_MSENC(0):
9731739a20eSAndy Ritger         case ENG_MSENC(1):
9741739a20eSAndy Ritger         case ENG_MSENC(2):
9754397463eSAndy Ritger             return !!NVGPU_GET_ENGINE_CAPS_MASK(rmEngineCaps,
9764397463eSAndy Ritger                 RM_ENGINE_TYPE_NVENC(GET_MSENC_IDX(engDesc)));
9771739a20eSAndy Ritger         case ENG_SEC2:
9784397463eSAndy Ritger             return !!NVGPU_GET_ENGINE_CAPS_MASK(rmEngineCaps,
9794397463eSAndy Ritger                                                 RM_ENGINE_TYPE_SEC2);
9801739a20eSAndy Ritger         case ENG_NVDEC(0):
9811739a20eSAndy Ritger         case ENG_NVDEC(1):
9821739a20eSAndy Ritger         case ENG_NVDEC(2):
9831739a20eSAndy Ritger         case ENG_NVDEC(3):
9841739a20eSAndy Ritger         case ENG_NVDEC(4):
98590eb1077SAndy Ritger         case ENG_NVDEC(5):
98690eb1077SAndy Ritger         case ENG_NVDEC(6):
98790eb1077SAndy Ritger         case ENG_NVDEC(7):
9884397463eSAndy Ritger             return !!NVGPU_GET_ENGINE_CAPS_MASK(rmEngineCaps,
9894397463eSAndy Ritger                 RM_ENGINE_TYPE_NVDEC(GET_NVDEC_IDX(engDesc)));
9904397463eSAndy Ritger 
991b5bf85a8SAndy Ritger    case ENG_OFA(0):
9924397463eSAndy Ritger             return !!NVGPU_GET_ENGINE_CAPS_MASK(rmEngineCaps,
993b5bf85a8SAndy Ritger                 RM_ENGINE_TYPE_OFA(GET_OFA_IDX(engDesc)));
994b5bf85a8SAndy Ritger 
9951739a20eSAndy Ritger         case ENG_NVJPEG(0):
99690eb1077SAndy Ritger         case ENG_NVJPEG(1):
99790eb1077SAndy Ritger         case ENG_NVJPEG(2):
99890eb1077SAndy Ritger         case ENG_NVJPEG(3):
99990eb1077SAndy Ritger         case ENG_NVJPEG(4):
100090eb1077SAndy Ritger         case ENG_NVJPEG(5):
100190eb1077SAndy Ritger         case ENG_NVJPEG(6):
100290eb1077SAndy Ritger         case ENG_NVJPEG(7):
10034397463eSAndy Ritger             return !!NVGPU_GET_ENGINE_CAPS_MASK(rmEngineCaps,
10044397463eSAndy Ritger                 RM_ENGINE_TYPE_NVJPEG(GET_NVJPEG_IDX(engDesc)));
10054397463eSAndy Ritger 
10061739a20eSAndy Ritger         case ENG_GR(1):
10071739a20eSAndy Ritger         case ENG_GR(2):
10081739a20eSAndy Ritger         case ENG_GR(3):
10091739a20eSAndy Ritger         case ENG_GR(4):
10101739a20eSAndy Ritger         case ENG_GR(5):
10111739a20eSAndy Ritger         case ENG_GR(6):
10121739a20eSAndy Ritger         case ENG_GR(7):
10131739a20eSAndy Ritger         {
10141739a20eSAndy Ritger             KernelFifo *pKernelFifo  = GPU_GET_KERNEL_FIFO(pGpu);
10151739a20eSAndy Ritger 
10161739a20eSAndy Ritger             NV_ASSERT_OR_RETURN(pKernelFifo != NULL, NV_FALSE);
10171739a20eSAndy Ritger 
10184397463eSAndy Ritger             return (kfifoCheckEngine_HAL(pGpu, pKernelFifo,
10194397463eSAndy Ritger                                          engDesc,
10204397463eSAndy Ritger                                          &bSupported) == NV_OK &&
10214397463eSAndy Ritger                     bSupported);
10221739a20eSAndy Ritger         }
10231739a20eSAndy Ritger 
10241739a20eSAndy Ritger         case ENG_INVALID:
10251739a20eSAndy Ritger             NV_PRINTF(LEVEL_ERROR,
10261739a20eSAndy Ritger                       "Query for ENG_INVALID considered erroneous: %d\n",
10271739a20eSAndy Ritger                       engDesc);
10281739a20eSAndy Ritger             return NV_TRUE;
10291739a20eSAndy Ritger         //
10301739a20eSAndy Ritger         // Check if engine descriptor is supported by current GPU.
10311739a20eSAndy Ritger         // Callee must not send engine descriptor which are not on
10321739a20eSAndy Ritger         // HAL lists of GPU. So Add ASSERT there.
10331739a20eSAndy Ritger         //
10341739a20eSAndy Ritger         default:
103591676d66SBernhard Stoeckner         {
103691676d66SBernhard Stoeckner             if (bCheckEngineOrder)
103791676d66SBernhard Stoeckner             {
10381739a20eSAndy Ritger                 bSupported = gpuIsEngDescSupported(pGpu, engDesc);
10391739a20eSAndy Ritger 
10401739a20eSAndy Ritger                 if (!bSupported)
10411739a20eSAndy Ritger                 {
104291676d66SBernhard Stoeckner                     NV_PRINTF(LEVEL_ERROR, "Unable to check engine ID: 0x%x\n",
10431739a20eSAndy Ritger                               engDesc);
10441739a20eSAndy Ritger                     NV_ASSERT(bSupported);
10451739a20eSAndy Ritger                 }
104691676d66SBernhard Stoeckner             }
104791676d66SBernhard Stoeckner             else
104891676d66SBernhard Stoeckner                 bSupported = NV_FALSE;
104991676d66SBernhard Stoeckner 
10501739a20eSAndy Ritger             return bSupported;
10511739a20eSAndy Ritger         }
10521739a20eSAndy Ritger     }
105391676d66SBernhard Stoeckner }
10541739a20eSAndy Ritger 
10551739a20eSAndy Ritger //
10561739a20eSAndy Ritger // kbusGetDeviceCaps
10571739a20eSAndy Ritger //
10581739a20eSAndy Ritger // This routine gets cap bits in unicast. If bCapsInitialized is passed as
10591739a20eSAndy Ritger // NV_FALSE, the caps will be copied into pHostCaps without OR/ANDing. Otherwise,
10601739a20eSAndy Ritger // the caps bits for the current GPU will be OR/ANDed together with pHostCaps to
10611739a20eSAndy Ritger // create a single set of caps that accurately represents the functionality of
10621739a20eSAndy Ritger // the device.
10631739a20eSAndy Ritger //
10641739a20eSAndy Ritger void
kbusGetDeviceCaps_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus,NvU8 * pHostCaps,NvBool bCapsInitialized)10651739a20eSAndy Ritger kbusGetDeviceCaps_IMPL
10661739a20eSAndy Ritger (
10671739a20eSAndy Ritger     OBJGPU    *pGpu,
10681739a20eSAndy Ritger     KernelBus *pKernelBus,
10691739a20eSAndy Ritger     NvU8      *pHostCaps,
10701739a20eSAndy Ritger     NvBool     bCapsInitialized
10711739a20eSAndy Ritger )
10721739a20eSAndy Ritger {
10731739a20eSAndy Ritger     OBJSYS *pSys = SYS_GET_INSTANCE();
10741739a20eSAndy Ritger     OBJCL  *pCl  = SYS_GET_CL(pSys);
10751739a20eSAndy Ritger     NvU8 tempCaps[NV0080_CTRL_HOST_CAPS_TBL_SIZE], temp;
10761739a20eSAndy Ritger     NvBool bExplicitCacheFlushRequired;
10771739a20eSAndy Ritger 
10781739a20eSAndy Ritger     NV_ASSERT(!gpumgrGetBcEnabledStatus(pGpu));
10791739a20eSAndy Ritger 
10801739a20eSAndy Ritger     portMemSet(tempCaps, 0, NV0080_CTRL_HOST_CAPS_TBL_SIZE);
10811739a20eSAndy Ritger 
10821739a20eSAndy Ritger     /*! DMAs to/from cached memory need to have the cache flushed explicitly */
10831739a20eSAndy Ritger     bExplicitCacheFlushRequired = NVCPU_IS_ARM &&
10841739a20eSAndy Ritger                                   (RMCFG_FEATURE_PLATFORM_UNIX || RMCFG_FEATURE_PLATFORM_MODS_UNIX);
10851739a20eSAndy Ritger     if (bExplicitCacheFlushRequired ||
1086eb5c7665SAndy Ritger         (!pCl->getProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT)))
10871739a20eSAndy Ritger         RMCTRL_SET_CAP(tempCaps, NV0080_CTRL_HOST_CAPS, _EXPLICIT_CACHE_FLUSH_REQD);
10881739a20eSAndy Ritger 
10891739a20eSAndy Ritger     if ((pCl->FHBBusInfo.vendorID == PCI_VENDOR_ID_NVIDIA) &&
10901739a20eSAndy Ritger         ((pGpu->getProperty(pGpu, PDB_PROP_GPU_IS_BR04_PRESENT)) ||
10911739a20eSAndy Ritger          ((pCl->FHBBusInfo.deviceID >= NVIDIA_C73_CPU_PCI_0_DEVICE_ID_SLI2) &&
10921739a20eSAndy Ritger           (pCl->FHBBusInfo.deviceID <= NVIDIA_C73_CPU_PCI_0_DEVICE_ID_RESERVED_3))))
10931739a20eSAndy Ritger     {
10941739a20eSAndy Ritger         RMCTRL_SET_CAP(tempCaps, NV0080_CTRL_HOST_CAPS, _CPU_WRITE_WAR_BUG_420495);
10951739a20eSAndy Ritger     }
10961739a20eSAndy Ritger 
10971739a20eSAndy Ritger     // the RM always supports GPU-coherent mappings
10981739a20eSAndy Ritger     RMCTRL_SET_CAP(tempCaps, NV0080_CTRL_HOST_CAPS, _GPU_COHERENT_MAPPING_SUPPORTED);
10991739a20eSAndy Ritger 
11001739a20eSAndy Ritger     // If we don't have existing caps with which to reconcile, then just return
11011739a20eSAndy Ritger     if (!bCapsInitialized)
11021739a20eSAndy Ritger     {
11031739a20eSAndy Ritger         portMemCopy(pHostCaps, NV0080_CTRL_HOST_CAPS_TBL_SIZE, tempCaps, NV0080_CTRL_HOST_CAPS_TBL_SIZE);
11041739a20eSAndy Ritger         return;
11051739a20eSAndy Ritger     }
11061739a20eSAndy Ritger 
11071739a20eSAndy Ritger     // factor in this GPUs caps: all these are feature caps, so use AND
11081739a20eSAndy Ritger     RMCTRL_AND_CAP(pHostCaps, tempCaps, temp,
11091739a20eSAndy Ritger                    NV0080_CTRL_HOST_CAPS, _P2P_4_WAY);
11101739a20eSAndy Ritger     RMCTRL_AND_CAP(pHostCaps, tempCaps, temp,
11111739a20eSAndy Ritger                    NV0080_CTRL_HOST_CAPS, _P2P_8_WAY);
11121739a20eSAndy Ritger     RMCTRL_AND_CAP(pHostCaps, tempCaps, temp,
11131739a20eSAndy Ritger                    NV0080_CTRL_HOST_CAPS, _GPU_COHERENT_MAPPING_SUPPORTED);
11141739a20eSAndy Ritger 
11151739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11161739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _SEMA_ACQUIRE_BUG_105665);
11171739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11181739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _SYS_SEMA_DEADLOCK_BUG_148216);
11191739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11201739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _SLOWSLI);
11211739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11221739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _SEMA_READ_ONLY_BUG);
11231739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11241739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _MEM2MEM_BUG_365782);
11251739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11261739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _LARGE_NONCOH_UPSTR_WRITE_BUG_114871);
11271739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11281739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _LARGE_UPSTREAM_WRITE_BUG_115115);
11291739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11301739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _SEP_VIDMEM_PB_NOTIFIERS_BUG_83923);
11311739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11321739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _P2P_DEADLOCK_BUG_203825);
11331739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11341739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _COMPRESSED_BL_P2P_BUG_257072);
11351739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11361739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _CROSS_BLITS_BUG_270260);
11371739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11381739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _CPU_WRITE_WAR_BUG_420495);
11391739a20eSAndy Ritger     RMCTRL_OR_CAP(pHostCaps, tempCaps, temp,
11401739a20eSAndy Ritger                   NV0080_CTRL_HOST_CAPS, _BAR1_READ_DEADLOCK_BUG_511418);
11411739a20eSAndy Ritger 
11421739a20eSAndy Ritger     return;
11431739a20eSAndy Ritger }
11441739a20eSAndy Ritger 
11451739a20eSAndy Ritger NV_STATUS
kbusMapFbApertureByHandle_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus,NvHandle hClient,NvHandle hMemory,NvU64 offset,NvU64 size,NvU64 * pBar1Va,Device * pDevice)11461739a20eSAndy Ritger kbusMapFbApertureByHandle_IMPL
11471739a20eSAndy Ritger (
11481739a20eSAndy Ritger     OBJGPU    *pGpu,
11491739a20eSAndy Ritger     KernelBus *pKernelBus,
11501739a20eSAndy Ritger     NvHandle   hClient,
11511739a20eSAndy Ritger     NvHandle   hMemory,
11521739a20eSAndy Ritger     NvU64      offset,
11531739a20eSAndy Ritger     NvU64      size,
1154eb5c7665SAndy Ritger     NvU64     *pBar1Va,
1155eb5c7665SAndy Ritger     Device    *pDevice
11561739a20eSAndy Ritger )
11571739a20eSAndy Ritger {
11581739a20eSAndy Ritger     NV_STATUS status;
11591739a20eSAndy Ritger     RsClient *pClient = NULL;
11601739a20eSAndy Ritger     RsResourceRef *pSrcMemoryRef = NULL;
11611739a20eSAndy Ritger     Memory *pSrcMemory = NULL;
11621739a20eSAndy Ritger     MEMORY_DESCRIPTOR *pMemDesc = NULL;
11631739a20eSAndy Ritger     NvU64 fbApertureOffset = 0;
11641739a20eSAndy Ritger     NvU64 fbApertureLength = size;
11651739a20eSAndy Ritger 
11661739a20eSAndy Ritger     NV_ASSERT_OK_OR_RETURN(serverGetClientUnderLock(&g_resServ, hClient, &pClient));
11671739a20eSAndy Ritger 
11681739a20eSAndy Ritger     status = clientGetResourceRef(pClient, hMemory, &pSrcMemoryRef);
11691739a20eSAndy Ritger     if (status != NV_OK)
11701739a20eSAndy Ritger     {
11711739a20eSAndy Ritger         return status;
11721739a20eSAndy Ritger     }
11731739a20eSAndy Ritger 
11741739a20eSAndy Ritger     pSrcMemory = dynamicCast(pSrcMemoryRef->pResource, Memory);
11751739a20eSAndy Ritger     if (pSrcMemory == NULL)
11761739a20eSAndy Ritger     {
11771739a20eSAndy Ritger         return NV_ERR_INVALID_OBJECT;
11781739a20eSAndy Ritger     }
11791739a20eSAndy Ritger 
11801739a20eSAndy Ritger     pMemDesc = pSrcMemory->pMemDesc;
11811739a20eSAndy Ritger 
11821739a20eSAndy Ritger     if (memdescGetAddressSpace(pMemDesc) != ADDR_FBMEM)
11831739a20eSAndy Ritger     {
11841739a20eSAndy Ritger         return NV_ERR_INVALID_ARGUMENT;
11851739a20eSAndy Ritger     }
11861739a20eSAndy Ritger 
11871739a20eSAndy Ritger     status = kbusMapFbAperture_HAL(pGpu, pKernelBus, pMemDesc, offset,
11881739a20eSAndy Ritger                                    &fbApertureOffset, &fbApertureLength,
1189eb5c7665SAndy Ritger                                    BUS_MAP_FB_FLAGS_MAP_UNICAST, pDevice);
11901739a20eSAndy Ritger     if (status != NV_OK)
11911739a20eSAndy Ritger     {
11921739a20eSAndy Ritger         return status;
11931739a20eSAndy Ritger     }
11941739a20eSAndy Ritger 
11951739a20eSAndy Ritger     NV_ASSERT_OR_GOTO(fbApertureLength >= size, failed);
11961739a20eSAndy Ritger 
11971739a20eSAndy Ritger     if ((!NV_IS_ALIGNED64(fbApertureOffset, osGetPageSize())) ||
11981739a20eSAndy Ritger         (!NV_IS_ALIGNED64(fbApertureLength, osGetPageSize())))
11991739a20eSAndy Ritger     {
12001739a20eSAndy Ritger         status = NV_ERR_NOT_SUPPORTED;
12011739a20eSAndy Ritger         goto failed;
12021739a20eSAndy Ritger     }
12031739a20eSAndy Ritger 
12041739a20eSAndy Ritger     *pBar1Va = gpumgrGetGpuPhysFbAddr(pGpu) + fbApertureOffset;
12051739a20eSAndy Ritger 
12061739a20eSAndy Ritger     if (!NV_IS_ALIGNED64(*pBar1Va, osGetPageSize()))
12071739a20eSAndy Ritger     {
12081739a20eSAndy Ritger         status = NV_ERR_INVALID_ADDRESS;
12091739a20eSAndy Ritger         goto failed;
12101739a20eSAndy Ritger     }
12111739a20eSAndy Ritger 
12121739a20eSAndy Ritger     return NV_OK;
12131739a20eSAndy Ritger 
12141739a20eSAndy Ritger failed:
12151739a20eSAndy Ritger     // Note: fbApertureLength is not used by kbusUnmapFbAperture_HAL(), so it's passed as 0
12161739a20eSAndy Ritger     kbusUnmapFbAperture_HAL(pGpu, pKernelBus, pMemDesc,
12171739a20eSAndy Ritger                             fbApertureOffset, 0,
12181739a20eSAndy Ritger                             BUS_MAP_FB_FLAGS_MAP_UNICAST);
12191739a20eSAndy Ritger 
12201739a20eSAndy Ritger     return status;
12211739a20eSAndy Ritger }
12221739a20eSAndy Ritger 
12231739a20eSAndy Ritger NV_STATUS
kbusUnmapFbApertureByHandle_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus,NvHandle hClient,NvHandle hMemory,NvU64 bar1Va)12241739a20eSAndy Ritger kbusUnmapFbApertureByHandle_IMPL
12251739a20eSAndy Ritger (
12261739a20eSAndy Ritger     OBJGPU    *pGpu,
12271739a20eSAndy Ritger     KernelBus *pKernelBus,
12281739a20eSAndy Ritger     NvHandle   hClient,
12291739a20eSAndy Ritger     NvHandle   hMemory,
12301739a20eSAndy Ritger     NvU64      bar1Va
12311739a20eSAndy Ritger )
12321739a20eSAndy Ritger {
12331739a20eSAndy Ritger     NV_STATUS status;
12341739a20eSAndy Ritger     RsClient *pClient = NULL;
12351739a20eSAndy Ritger     RsResourceRef *pSrcMemoryRef = NULL;
12361739a20eSAndy Ritger     Memory *pSrcMemory = NULL;
12371739a20eSAndy Ritger     MEMORY_DESCRIPTOR *pMemDesc = NULL;
12381739a20eSAndy Ritger 
12391739a20eSAndy Ritger     NV_ASSERT_OK_OR_RETURN(serverGetClientUnderLock(&g_resServ, hClient, &pClient));
12401739a20eSAndy Ritger 
12411739a20eSAndy Ritger     status = clientGetResourceRef(pClient, hMemory, &pSrcMemoryRef);
12421739a20eSAndy Ritger     if (status != NV_OK)
12431739a20eSAndy Ritger     {
12441739a20eSAndy Ritger         return status;
12451739a20eSAndy Ritger     }
12461739a20eSAndy Ritger 
12471739a20eSAndy Ritger     pSrcMemory = dynamicCast(pSrcMemoryRef->pResource, Memory);
12481739a20eSAndy Ritger     if (pSrcMemory == NULL)
12491739a20eSAndy Ritger     {
12501739a20eSAndy Ritger         return NV_ERR_INVALID_OBJECT;
12511739a20eSAndy Ritger     }
12521739a20eSAndy Ritger 
12531739a20eSAndy Ritger     pMemDesc = pSrcMemory->pMemDesc;
12541739a20eSAndy Ritger 
12551739a20eSAndy Ritger     // Note: fbApertureLength is not used by kbusUnmapFbAperture_HAL(), so it's passed as 0
12561739a20eSAndy Ritger     status = kbusUnmapFbAperture_HAL(pGpu, pKernelBus, pMemDesc,
12571739a20eSAndy Ritger                                      bar1Va - gpumgrGetGpuPhysFbAddr(pGpu),
12581739a20eSAndy Ritger                                      0, BUS_MAP_FB_FLAGS_MAP_UNICAST);
12591739a20eSAndy Ritger     if (status != NV_OK)
12601739a20eSAndy Ritger     {
12611739a20eSAndy Ritger         return status;
12621739a20eSAndy Ritger     }
12631739a20eSAndy Ritger 
12641739a20eSAndy Ritger     return NV_OK;
12651739a20eSAndy Ritger }
12661739a20eSAndy Ritger 
12671739a20eSAndy Ritger /*!
12681739a20eSAndy Ritger  * Helper function to determine if the requested GET_BUS_INFO ctrl call needs to be served
12691739a20eSAndy Ritger  * by GSP/host, then send RPC to GSP/host. Otherwise return directly so that the caller can
12701739a20eSAndy Ritger  * continue the execution on CPU.
12711739a20eSAndy Ritger  *
12721739a20eSAndy Ritger  *  @param[in]       pGpu       OBJGPU pointer
12731739a20eSAndy Ritger  *  @param[in/out]   pBusInfo   Pointer to NV2080_CTRL_BUS_INFO which specifies the index we want to query
12741739a20eSAndy Ritger  *
12751739a20eSAndy Ritger  *  @returns RPC status
12761739a20eSAndy Ritger  */
12771739a20eSAndy Ritger NV_STATUS
kbusSendBusInfo_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus,NV2080_CTRL_BUS_INFO * pBusInfo)12781739a20eSAndy Ritger kbusSendBusInfo_IMPL
12791739a20eSAndy Ritger (
12801739a20eSAndy Ritger     OBJGPU               *pGpu,
12811739a20eSAndy Ritger     KernelBus            *pKernelBus,
12821739a20eSAndy Ritger     NV2080_CTRL_BUS_INFO *pBusInfo
12831739a20eSAndy Ritger )
12841739a20eSAndy Ritger {
12851739a20eSAndy Ritger     NV_STATUS status = NV_OK;
12861739a20eSAndy Ritger     NV2080_CTRL_BUS_GET_INFO_V2_PARAMS busGetInfoParams = {0};
12871739a20eSAndy Ritger 
12881739a20eSAndy Ritger     busGetInfoParams.busInfoList[0] = *pBusInfo;
12891739a20eSAndy Ritger     busGetInfoParams.busInfoListSize = 1;
12901739a20eSAndy Ritger 
12911739a20eSAndy Ritger     NV_RM_RPC_CONTROL(pGpu,
12921739a20eSAndy Ritger                       pGpu->hInternalClient,
12931739a20eSAndy Ritger                       pGpu->hInternalSubdevice,
12941739a20eSAndy Ritger                       NV2080_CTRL_CMD_BUS_GET_INFO_V2,
12951739a20eSAndy Ritger                       &busGetInfoParams,
12961739a20eSAndy Ritger                       sizeof(busGetInfoParams),
12971739a20eSAndy Ritger                       status);
12981739a20eSAndy Ritger 
12991739a20eSAndy Ritger     pBusInfo->data = busGetInfoParams.busInfoList[0].data;
13001739a20eSAndy Ritger     return status;
13011739a20eSAndy Ritger }
130290eb1077SAndy Ritger 
1303758b4ee8SAndy Ritger /*!
1304758b4ee8SAndy Ritger  * @brief Returns the Nvlink peer ID from pGpu0 to pGpu1
1305758b4ee8SAndy Ritger  *
1306758b4ee8SAndy Ritger  * @param[in]   pGpu0          (local GPU)
1307758b4ee8SAndy Ritger  * @param[in]   pKernelBus0    (local GPU)
1308758b4ee8SAndy Ritger  * @param[in]   pGpu1          (remote GPU)
1309758b4ee8SAndy Ritger  * @param[in]   pKernelBus1    (remote GPU)
1310758b4ee8SAndy Ritger  * @param[out]  nvlinkPeer     NvU32 pointer
1311758b4ee8SAndy Ritger  *
1312758b4ee8SAndy Ritger  * return NV_OK on success
1313758b4ee8SAndy Ritger  */
1314758b4ee8SAndy Ritger NV_STATUS
kbusGetNvlinkP2PPeerId_VGPU(OBJGPU * pGpu0,KernelBus * pKernelBus0,OBJGPU * pGpu1,KernelBus * pKernelBus1,NvU32 * nvlinkPeer,NvU32 flags)1315758b4ee8SAndy Ritger kbusGetNvlinkP2PPeerId_VGPU
1316758b4ee8SAndy Ritger (
1317758b4ee8SAndy Ritger     OBJGPU    *pGpu0,
1318758b4ee8SAndy Ritger     KernelBus *pKernelBus0,
1319758b4ee8SAndy Ritger     OBJGPU    *pGpu1,
1320758b4ee8SAndy Ritger     KernelBus *pKernelBus1,
1321eb5c7665SAndy Ritger     NvU32     *nvlinkPeer,
1322eb5c7665SAndy Ritger     NvU32      flags
1323758b4ee8SAndy Ritger )
1324758b4ee8SAndy Ritger {
1325eb5c7665SAndy Ritger     *nvlinkPeer = kbusGetPeerId_HAL(pGpu0, pKernelBus0, pGpu1);
1326eb5c7665SAndy Ritger     if (*nvlinkPeer != BUS_INVALID_PEER)
1327eb5c7665SAndy Ritger     {
1328eb5c7665SAndy Ritger         return NV_OK;
1329eb5c7665SAndy Ritger     }
1330eb5c7665SAndy Ritger 
1331758b4ee8SAndy Ritger     *nvlinkPeer = kbusGetUnusedPeerId_HAL(pGpu0, pKernelBus0);
1332758b4ee8SAndy Ritger 
1333758b4ee8SAndy Ritger     // If could not find a free peer ID, return error
1334758b4ee8SAndy Ritger     if (*nvlinkPeer == BUS_INVALID_PEER)
1335758b4ee8SAndy Ritger     {
1336758b4ee8SAndy Ritger         NV_PRINTF(LEVEL_WARNING,
1337758b4ee8SAndy Ritger                   "GPU%d: peerID not available for NVLink P2P\n",
1338758b4ee8SAndy Ritger                   pGpu0->gpuInstance);
1339758b4ee8SAndy Ritger         return NV_ERR_GENERIC;
1340758b4ee8SAndy Ritger     }
1341758b4ee8SAndy Ritger     // Reserve the peer ID for NVLink use
1342758b4ee8SAndy Ritger     return kbusReserveP2PPeerIds_HAL(pGpu0, pKernelBus0, NVBIT(*nvlinkPeer));
1343758b4ee8SAndy Ritger }
1344758b4ee8SAndy Ritger 
134590eb1077SAndy Ritger /**
1346b5bf85a8SAndy Ritger  * @brief     Check if the static bar1 is enabled
1347b5bf85a8SAndy Ritger  *
1348b5bf85a8SAndy Ritger  * @param[in] pGpu
1349b5bf85a8SAndy Ritger  * @param[in] pKernelBus
1350b5bf85a8SAndy Ritger  */
1351b5bf85a8SAndy Ritger NvBool
kbusIsStaticBar1Enabled_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus)1352b5bf85a8SAndy Ritger kbusIsStaticBar1Enabled_IMPL
1353b5bf85a8SAndy Ritger (
1354b5bf85a8SAndy Ritger     OBJGPU    *pGpu,
1355b5bf85a8SAndy Ritger     KernelBus *pKernelBus
1356b5bf85a8SAndy Ritger )
1357b5bf85a8SAndy Ritger {
1358b5bf85a8SAndy Ritger     NvU32 gfid;
1359b5bf85a8SAndy Ritger 
1360b5bf85a8SAndy Ritger     return ((vgpuGetCallingContextGfid(pGpu, &gfid) == NV_OK) &&
1361b5bf85a8SAndy Ritger             pKernelBus->bar1[gfid].bStaticBar1Enabled);
1362b5bf85a8SAndy Ritger }
1363b5bf85a8SAndy Ritger 
1364b5bf85a8SAndy Ritger /**
136590eb1077SAndy Ritger  * @brief     Check for any P2P references in to remote GPUs
136690eb1077SAndy Ritger  *            which are still have a P2P api object alive.
136790eb1077SAndy Ritger  *
136890eb1077SAndy Ritger  * @param[in] pGpu
136990eb1077SAndy Ritger  * @param[in] pKernelBus
137090eb1077SAndy Ritger  */
137190eb1077SAndy Ritger NV_STATUS
kbusIsGpuP2pAlive_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus)137290eb1077SAndy Ritger kbusIsGpuP2pAlive_IMPL
137390eb1077SAndy Ritger (
137490eb1077SAndy Ritger     OBJGPU    *pGpu,
137590eb1077SAndy Ritger     KernelBus *pKernelBus
137690eb1077SAndy Ritger )
137790eb1077SAndy Ritger {
137890eb1077SAndy Ritger     return (pKernelBus->totalP2pObjectsAliveRefCount > 0);
137990eb1077SAndy Ritger }
138091676d66SBernhard Stoeckner 
138191676d66SBernhard Stoeckner /**
138291676d66SBernhard Stoeckner  * @brief     Gets BAR0 size in bytes for VF
138391676d66SBernhard Stoeckner  *
138491676d66SBernhard Stoeckner  * @param[in] pGpu
138591676d66SBernhard Stoeckner  * @param[in] pKernelBus
138691676d66SBernhard Stoeckner  */
kbusGetVfBar0SizeBytes_IMPL(OBJGPU * pGpu,KernelBus * pKernelBus)138791676d66SBernhard Stoeckner NvU64 kbusGetVfBar0SizeBytes_IMPL
138891676d66SBernhard Stoeckner (
138991676d66SBernhard Stoeckner     OBJGPU    *pGpu,
139091676d66SBernhard Stoeckner     KernelBus *pKernelBus
139191676d66SBernhard Stoeckner )
139291676d66SBernhard Stoeckner {
139391676d66SBernhard Stoeckner     // Bar 0 size for VF is always 16MB
139491676d66SBernhard Stoeckner     return 16llu << 20;
139591676d66SBernhard Stoeckner }
1396*476bd345SBernhard Stoeckner 
1397*476bd345SBernhard Stoeckner /**
1398*476bd345SBernhard Stoeckner  * @brief Update BAR1 size and availability in RUSD
1399*476bd345SBernhard Stoeckner  *
1400*476bd345SBernhard Stoeckner  * @param[in] pGpu
1401*476bd345SBernhard Stoeckner  */
1402*476bd345SBernhard Stoeckner NV_STATUS
kbusUpdateRusdStatistics_IMPL(OBJGPU * pGpu)1403*476bd345SBernhard Stoeckner kbusUpdateRusdStatistics_IMPL
1404*476bd345SBernhard Stoeckner (
1405*476bd345SBernhard Stoeckner     OBJGPU *pGpu
1406*476bd345SBernhard Stoeckner )
1407*476bd345SBernhard Stoeckner {
1408*476bd345SBernhard Stoeckner     KernelBus *pKernelBus = GPU_GET_KERNEL_BUS(pGpu);
1409*476bd345SBernhard Stoeckner     OBJVASPACE *pBar1VAS;
1410*476bd345SBernhard Stoeckner     OBJEHEAP *pVASHeap;
1411*476bd345SBernhard Stoeckner     NV00DE_SHARED_DATA *pSharedData;
1412*476bd345SBernhard Stoeckner     NvU64 bar1Size = 0;
1413*476bd345SBernhard Stoeckner     NvU64 bar1AvailSize = 0;
1414*476bd345SBernhard Stoeckner     NV_RANGE bar1VARange = NV_RANGE_EMPTY;
1415*476bd345SBernhard Stoeckner     NvBool bZeroRusd = KBUS_CPU_VISIBLE_BAR12_DISABLED(pGpu);
1416*476bd345SBernhard Stoeckner 
1417*476bd345SBernhard Stoeckner     bZeroRusd = bZeroRusd || IS_MIG_ENABLED(pGpu);
1418*476bd345SBernhard Stoeckner 
1419*476bd345SBernhard Stoeckner     if (!bZeroRusd)
1420*476bd345SBernhard Stoeckner     {
1421*476bd345SBernhard Stoeckner         pBar1VAS = kbusGetBar1VASpace_HAL(pGpu, pKernelBus);
1422*476bd345SBernhard Stoeckner         NV_ASSERT_OR_RETURN(pBar1VAS != NULL, NV_ERR_INVALID_STATE);
1423*476bd345SBernhard Stoeckner         pVASHeap = vaspaceGetHeap(pBar1VAS);
1424*476bd345SBernhard Stoeckner         bar1VARange = rangeMake(vaspaceGetVaStart(pBar1VAS), vaspaceGetVaLimit(pBar1VAS));
1425*476bd345SBernhard Stoeckner 
1426*476bd345SBernhard Stoeckner         bar1Size = (NvU32)(rangeLength(bar1VARange) / 1024);
1427*476bd345SBernhard Stoeckner 
1428*476bd345SBernhard Stoeckner         if (pVASHeap != NULL)
1429*476bd345SBernhard Stoeckner         {
1430*476bd345SBernhard Stoeckner             NvU64 freeSize = 0;
1431*476bd345SBernhard Stoeckner 
1432*476bd345SBernhard Stoeckner             pVASHeap->eheapInfoForRange(pVASHeap, bar1VARange, NULL, NULL, NULL, &freeSize);
1433*476bd345SBernhard Stoeckner             bar1AvailSize = (NvU32)(freeSize / 1024);
1434*476bd345SBernhard Stoeckner         }
1435*476bd345SBernhard Stoeckner     }
1436*476bd345SBernhard Stoeckner 
1437*476bd345SBernhard Stoeckner     // Minimize critical section, write data once we have it.
1438*476bd345SBernhard Stoeckner     pSharedData = gpushareddataWriteStart(pGpu);
1439*476bd345SBernhard Stoeckner     pSharedData->bar1Size = bar1Size;
1440*476bd345SBernhard Stoeckner     pSharedData->bar1AvailSize = bar1AvailSize;
1441*476bd345SBernhard Stoeckner     gpushareddataWriteFinish(pGpu);
1442*476bd345SBernhard Stoeckner 
1443*476bd345SBernhard Stoeckner     return NV_OK;
1444*476bd345SBernhard Stoeckner }
1445