11739a20eSAndy Ritger /*
21739a20eSAndy Ritger  * SPDX-FileCopyrightText: Copyright (c) 1993-2022 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 "os/os.h"
251739a20eSAndy Ritger #include "gpu/mem_sys/kern_mem_sys.h"
261739a20eSAndy Ritger #include "gpu/mem_mgr/mem_mgr.h"
271739a20eSAndy Ritger #include "virtualization/hypervisor/hypervisor.h"
281739a20eSAndy Ritger #include "vgpu/vgpu_events.h"
291739a20eSAndy Ritger #include "objrpc.h"
301739a20eSAndy Ritger #include "gpu/bif/kernel_bif.h"
311739a20eSAndy Ritger #include "gpu/bus/kern_bus.h"
321739a20eSAndy Ritger #include "os/os.h"
331739a20eSAndy Ritger #include "nvRmReg.h"
341739a20eSAndy Ritger 
351739a20eSAndy Ritger NV_STATUS
361739a20eSAndy Ritger kmemsysConstructEngine_IMPL
371739a20eSAndy Ritger (
381739a20eSAndy Ritger     OBJGPU             *pGpu,
391739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem,
401739a20eSAndy Ritger     ENGDESCRIPTOR       engDesc
411739a20eSAndy Ritger )
421739a20eSAndy Ritger {
431739a20eSAndy Ritger     pKernelMemorySystem->memPartitionNumaInfo = NULL;
441739a20eSAndy Ritger 
451739a20eSAndy Ritger     if (IS_GSP_CLIENT(pGpu))
461739a20eSAndy Ritger     {
471739a20eSAndy Ritger         // Setting up the sysmem flush buffer needs to be done very early in some cases
481739a20eSAndy Ritger         // as it's required for the GPU to perform a system flush. One such case is
491739a20eSAndy Ritger         // resetting GPU FALCONs and in particular resetting the PMU as part of VBIOS
501739a20eSAndy Ritger         // init.
511739a20eSAndy Ritger         NV_ASSERT_OK_OR_RETURN(kmemsysInitFlushSysmemBuffer_HAL(pGpu, pKernelMemorySystem));
521739a20eSAndy Ritger     }
531739a20eSAndy Ritger 
541739a20eSAndy Ritger     return NV_OK;
551739a20eSAndy Ritger }
561739a20eSAndy Ritger 
571739a20eSAndy Ritger static void
581739a20eSAndy Ritger kmemsysInitRegistryOverrides
591739a20eSAndy Ritger (
601739a20eSAndy Ritger     OBJGPU *pGpu,
611739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem
621739a20eSAndy Ritger )
631739a20eSAndy Ritger {
641739a20eSAndy Ritger     NvU32 data32;
651739a20eSAndy Ritger 
661739a20eSAndy Ritger     //
671739a20eSAndy Ritger     // Bug 1032432. Check regkey for FB pull
681739a20eSAndy Ritger     //
691739a20eSAndy Ritger     if (osReadRegistryDword(pGpu, NV_REG_STR_RM_L2_CLEAN_FB_PULL, &data32) == NV_OK)
701739a20eSAndy Ritger     {
711739a20eSAndy Ritger         if (data32 == NV_REG_STR_RM_L2_CLEAN_FB_PULL_DISABLED)
721739a20eSAndy Ritger             pKernelMemorySystem->bL2CleanFbPull = NV_FALSE;
731739a20eSAndy Ritger     }
741739a20eSAndy Ritger }
751739a20eSAndy Ritger 
761739a20eSAndy Ritger /*
771739a20eSAndy Ritger  * Initialize the Kernel Memory System state.
781739a20eSAndy Ritger  *
791739a20eSAndy Ritger  * @param[in]  pGpu pointer to the GPU instance.
801739a20eSAndy Ritger  * @param[in]  pKernelMemorySystem pointer to the kernel side KernelMemorySystem instance.
811739a20eSAndy Ritger  *
821739a20eSAndy Ritger  * @return NV_OK upon success.
831739a20eSAndy Ritger  */
841739a20eSAndy Ritger NV_STATUS kmemsysStateInitLocked_IMPL
851739a20eSAndy Ritger (
861739a20eSAndy Ritger     OBJGPU *pGpu,
871739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem
881739a20eSAndy Ritger )
891739a20eSAndy Ritger {
901739a20eSAndy Ritger     MEMORY_SYSTEM_STATIC_CONFIG *pStaticConfig;
911739a20eSAndy Ritger     NV_STATUS status = NV_OK;
921739a20eSAndy Ritger 
931739a20eSAndy Ritger     NV_ASSERT_OK_OR_GOTO(status, kmemsysEnsureSysmemFlushBufferInitialized(pGpu, pKernelMemorySystem), fail);
941739a20eSAndy Ritger 
951739a20eSAndy Ritger     pStaticConfig = portMemAllocNonPaged(sizeof(*pStaticConfig));
961739a20eSAndy Ritger     NV_CHECK_OR_RETURN(LEVEL_ERROR, pStaticConfig != NULL, NV_ERR_INSUFFICIENT_RESOURCES);
971739a20eSAndy Ritger     portMemSet(pStaticConfig, 0, sizeof(pStaticConfig));
981739a20eSAndy Ritger 
991739a20eSAndy Ritger     NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
1001739a20eSAndy Ritger         kmemsysInitStaticConfig_HAL(pGpu, pKernelMemorySystem, pStaticConfig),
1011739a20eSAndy Ritger         fail);
1021739a20eSAndy Ritger 
1031739a20eSAndy Ritger     pKernelMemorySystem->pStaticConfig = pStaticConfig;
1041739a20eSAndy Ritger 
1051739a20eSAndy Ritger     kmemsysInitRegistryOverrides(pGpu, pKernelMemorySystem);
1061739a20eSAndy Ritger 
1071739a20eSAndy Ritger fail:
1081739a20eSAndy Ritger     if (status != NV_OK)
1091739a20eSAndy Ritger     {
1101739a20eSAndy Ritger         portMemFree((void *)pKernelMemorySystem->pStaticConfig);
1111739a20eSAndy Ritger     }
1121739a20eSAndy Ritger 
1131739a20eSAndy Ritger     return status;
1141739a20eSAndy Ritger }
1151739a20eSAndy Ritger 
1161739a20eSAndy Ritger NV_STATUS
1171739a20eSAndy Ritger kmemsysStatePreLoad_IMPL
1181739a20eSAndy Ritger (
1191739a20eSAndy Ritger     OBJGPU *pGpu,
1201739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem,
1211739a20eSAndy Ritger     NvU32 flags
1221739a20eSAndy Ritger )
1231739a20eSAndy Ritger {
1241739a20eSAndy Ritger     //
1251739a20eSAndy Ritger     // Program the sysmem flush buffer address and assert that the register contents are valid.
1261739a20eSAndy Ritger     // The HAL wiring is such that a given RM build will only do one or the other (e.g., RM offloaded
1271739a20eSAndy Ritger     // to ucode won't program the register itself but will assert that its contents are valid).
1281739a20eSAndy Ritger     //
1291739a20eSAndy Ritger     kmemsysProgramSysmemFlushBuffer_HAL(pGpu, pKernelMemorySystem);
1301739a20eSAndy Ritger     kmemsysAssertSysmemFlushBufferValid_HAL(pGpu, pKernelMemorySystem);
1311739a20eSAndy Ritger 
1321739a20eSAndy Ritger     return NV_OK;
1331739a20eSAndy Ritger }
1341739a20eSAndy Ritger 
1351739a20eSAndy Ritger /*
1361739a20eSAndy Ritger  * Release the state accumulated in StateInit.
1371739a20eSAndy Ritger  * @param[in]  pGpu pointer to the GPU instance.
1381739a20eSAndy Ritger  * @param[in]  pKernelMemorySystem pointer to the kernel side KernelMemorySystem instance.
1391739a20eSAndy Ritger  */
1401739a20eSAndy Ritger void kmemsysStateDestroy_IMPL
1411739a20eSAndy Ritger (
1421739a20eSAndy Ritger     OBJGPU *pGpu,
1431739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem
1441739a20eSAndy Ritger )
1451739a20eSAndy Ritger {
1461739a20eSAndy Ritger 
1471739a20eSAndy Ritger     portMemFree((void *)pKernelMemorySystem->pStaticConfig);
1481739a20eSAndy Ritger }
1491739a20eSAndy Ritger 
1501739a20eSAndy Ritger /*!
1511739a20eSAndy Ritger  * Returns MemorySystem settings that are static after GPU state init/load is
1521739a20eSAndy Ritger  * finished.
1531739a20eSAndy Ritger  */
1541739a20eSAndy Ritger const MEMORY_SYSTEM_STATIC_CONFIG *
1551739a20eSAndy Ritger kmemsysGetStaticConfig_IMPL
1561739a20eSAndy Ritger (
1571739a20eSAndy Ritger     OBJGPU *pGpu,
1581739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem
1591739a20eSAndy Ritger )
1601739a20eSAndy Ritger {
1611739a20eSAndy Ritger     // check if state Init has not completed.
1621739a20eSAndy Ritger     NV_ASSERT_OR_ELSE(pKernelMemorySystem != NULL, return NULL);
1631739a20eSAndy Ritger 
1641739a20eSAndy Ritger     return pKernelMemorySystem->pStaticConfig;
1651739a20eSAndy Ritger }
1661739a20eSAndy Ritger 
1671739a20eSAndy Ritger void
1681739a20eSAndy Ritger kmemsysDestruct_IMPL
1691739a20eSAndy Ritger (
1701739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem
1711739a20eSAndy Ritger )
1721739a20eSAndy Ritger {
1731739a20eSAndy Ritger     pKernelMemorySystem->sysmemFlushBuffer = 0;
1741739a20eSAndy Ritger     memdescFree(pKernelMemorySystem->pSysmemFlushBufferMemDesc);
1751739a20eSAndy Ritger     memdescDestroy(pKernelMemorySystem->pSysmemFlushBufferMemDesc);
1761739a20eSAndy Ritger     pKernelMemorySystem->pSysmemFlushBufferMemDesc = NULL;
1771739a20eSAndy Ritger 
1781739a20eSAndy Ritger     portMemSet(pKernelMemorySystem->gpuInstanceMemConfig, 0, sizeof(pKernelMemorySystem->gpuInstanceMemConfig));
1791739a20eSAndy Ritger }
1801739a20eSAndy Ritger 
1811739a20eSAndy Ritger NV_STATUS
1821739a20eSAndy Ritger kmemsysAllocComprResources_KERNEL
1831739a20eSAndy Ritger (
1841739a20eSAndy Ritger     OBJGPU               *pGpu,
1851739a20eSAndy Ritger     KernelMemorySystem   *pKernelMemorySystem,
1861739a20eSAndy Ritger     FB_ALLOC_INFO        *pFbAllocInfo,
1871739a20eSAndy Ritger     NvU64                 origSize,
1881739a20eSAndy Ritger     NvU32                 kindChosen,
1891739a20eSAndy Ritger     NvU32                *pRetAttr,
1901739a20eSAndy Ritger     NvU32                 retAttr2
1911739a20eSAndy Ritger )
1921739a20eSAndy Ritger {
1931739a20eSAndy Ritger     MemoryManager                     *pMemoryManager      = GPU_GET_MEMORY_MANAGER(pGpu);
1941739a20eSAndy Ritger     const MEMORY_SYSTEM_STATIC_CONFIG *pMemorySystemConfig = kmemsysGetStaticConfig(pGpu, pKernelMemorySystem);
1951739a20eSAndy Ritger     NvU32                              gfid;
1961739a20eSAndy Ritger 
1971739a20eSAndy Ritger     NV_ASSERT_OK_OR_RETURN(vgpuGetCallingContextGfid(pGpu, &gfid));
1981739a20eSAndy Ritger 
1991739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(pMemorySystemConfig->bOneToOneComptagLineAllocation || pMemorySystemConfig->bUseRawModeComptaglineAllocation,
2001739a20eSAndy Ritger         NV_ERR_INVALID_STATE);
2011739a20eSAndy Ritger 
2021739a20eSAndy Ritger     NV_CHECK_OR_RETURN(LEVEL_ERROR,
2031739a20eSAndy Ritger         !FLD_TEST_DRF(OS32, _ALLOC, _COMPTAG_OFFSET_USAGE, _FIXED, pFbAllocInfo->ctagOffset),
2041739a20eSAndy Ritger         NV_ERR_INVALID_ARGUMENT);
2051739a20eSAndy Ritger 
2061739a20eSAndy Ritger     // Failing the allocation if scrub on free is disabled
2071739a20eSAndy Ritger     if (!memmgrIsScrubOnFreeEnabled(pMemoryManager))
2081739a20eSAndy Ritger     {
2091739a20eSAndy Ritger         if (!(IS_SIMULATION(pGpu) || IsDFPGA(pGpu) || (IS_EMULATION(pGpu) && RMCFG_FEATURE_PLATFORM_MODS)
2101739a20eSAndy Ritger             ||(RMCFG_FEATURE_PLATFORM_WINDOWS && !pGpu->getProperty(pGpu, PDB_PROP_GPU_IN_TCC_MODE))
2111739a20eSAndy Ritger             ||(IsSLIEnabled(pGpu) && !(RMCFG_FEATURE_PLATFORM_WINDOWS &&
2121739a20eSAndy Ritger                                      !pGpu->getProperty(pGpu, PDB_PROP_GPU_IN_TCC_MODE))))
2131739a20eSAndy Ritger            )
2141739a20eSAndy Ritger         {
2151739a20eSAndy Ritger             NV_PRINTF(LEVEL_ERROR, "Compressible surfaces cannot be allocated on a system, "
2161739a20eSAndy Ritger                     "where scrub on free is disabled\n");
2171739a20eSAndy Ritger             return NV_ERR_INVALID_STATE;
2181739a20eSAndy Ritger         }
2191739a20eSAndy Ritger     }
2201739a20eSAndy Ritger     else if (pMemorySystemConfig->bOneToOneComptagLineAllocation)
2211739a20eSAndy Ritger     {
2221739a20eSAndy Ritger         NV_ASSERT_OR_RETURN(memmgrUseVasForCeMemoryOps(pMemoryManager), NV_ERR_INVALID_STATE);
2231739a20eSAndy Ritger     }
2241739a20eSAndy Ritger 
2251739a20eSAndy Ritger     FB_SET_HWRESID_CTAGID_FERMI(pFbAllocInfo->hwResId, FB_HWRESID_CTAGID_VAL_FERMI(-1));
2261739a20eSAndy Ritger     *pRetAttr = FLD_SET_DRF(OS32, _ATTR, _COMPR, _REQUIRED, *pRetAttr);
2271739a20eSAndy Ritger     return NV_OK;
2281739a20eSAndy Ritger }
2291739a20eSAndy Ritger 
2301739a20eSAndy Ritger /*!
2311739a20eSAndy Ritger  * @brief Initializes static config data from the Physical side.
2321739a20eSAndy Ritger  * @param[in]  pGpu pointer to the GPU instance.
2331739a20eSAndy Ritger  * @param[in]  pKernelMemorySystem pointer to the kernel side KernelMemorySystem instance.
2341739a20eSAndy Ritger  * @param[out] pConfig pointer to the static config init on Physical driver.
2351739a20eSAndy Ritger  *
2361739a20eSAndy Ritger  * @return NV_OK upon success.
2371739a20eSAndy Ritger  *         NV_ERR* otherwise.
2381739a20eSAndy Ritger  */
2391739a20eSAndy Ritger NV_STATUS
2401739a20eSAndy Ritger kmemsysInitStaticConfig_KERNEL
2411739a20eSAndy Ritger (
2421739a20eSAndy Ritger     OBJGPU *pGpu,
2431739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem,
2441739a20eSAndy Ritger     MEMORY_SYSTEM_STATIC_CONFIG *pConfig
2451739a20eSAndy Ritger )
2461739a20eSAndy Ritger {
2471739a20eSAndy Ritger     RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
2481739a20eSAndy Ritger     NV_STATUS status;
2491739a20eSAndy Ritger 
2501739a20eSAndy Ritger     status = pRmApi->Control(pRmApi, pGpu->hInternalClient, pGpu->hInternalSubdevice,
2511739a20eSAndy Ritger                                 NV2080_CTRL_CMD_INTERNAL_MEMSYS_GET_STATIC_CONFIG,
2521739a20eSAndy Ritger                                 pConfig, sizeof(*pConfig));
2531739a20eSAndy Ritger     return status;
2541739a20eSAndy Ritger }
2551739a20eSAndy Ritger 
2561739a20eSAndy Ritger /*!
2571739a20eSAndy Ritger  * @brief   Function to map swizzId to mem size given total mem
2581739a20eSAndy Ritger  *
2591739a20eSAndy Ritger  * @param[IN]   pGpu
2601739a20eSAndy Ritger  * @param[IN]   pKernelMemorySystem
2611739a20eSAndy Ritger  * @param[IN]   swizzId
2621739a20eSAndy Ritger  * @param[IN]   totalRange          total memory range
2631739a20eSAndy Ritger  * @param[OUT]  pPartitionSizeFlag  Flag stating partition memory size
2641739a20eSAndy Ritger  * @param[OUT]  pSizeInBytes        Memory size in bytes supported by partition
2651739a20eSAndy Ritger  */
2661739a20eSAndy Ritger NV_STATUS
2671739a20eSAndy Ritger kmemsysSwizzIdToMIGMemSize_IMPL
2681739a20eSAndy Ritger (
2691739a20eSAndy Ritger     OBJGPU *pGpu,
2701739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem,
2711739a20eSAndy Ritger     NvU32 swizzId,
2721739a20eSAndy Ritger     NV_RANGE totalRange,
2731739a20eSAndy Ritger     NvU32 *pPartitionSizeFlag,
2741739a20eSAndy Ritger     NvU64 *pSizeInBytes
2751739a20eSAndy Ritger )
2761739a20eSAndy Ritger {
2771739a20eSAndy Ritger     //
2781739a20eSAndy Ritger     // To handle the straddling issue we always consider memory for different
2791739a20eSAndy Ritger     // swizzIds as addition of minimum sized segements allowed in partitioning
2801739a20eSAndy Ritger     //
2811739a20eSAndy Ritger     NvU64 memSize = rangeLength(totalRange) / KMIGMGR_MAX_GPU_INSTANCES;
2821739a20eSAndy Ritger 
2831739a20eSAndy Ritger     switch (swizzId)
2841739a20eSAndy Ritger     {
2851739a20eSAndy Ritger         case 0:
2861739a20eSAndy Ritger         {
2871739a20eSAndy Ritger             *pSizeInBytes = memSize * KMIGMGR_MAX_GPU_INSTANCES;
2881739a20eSAndy Ritger             *pPartitionSizeFlag = DRF_DEF(2080_CTRL_GPU, _PARTITION_FLAG, _MEMORY_SIZE, _FULL);
2891739a20eSAndy Ritger             break;
2901739a20eSAndy Ritger         }
2911739a20eSAndy Ritger 
2921739a20eSAndy Ritger         case 1:
2931739a20eSAndy Ritger         case 2:
2941739a20eSAndy Ritger         {
2951739a20eSAndy Ritger             *pSizeInBytes = (memSize * (KMIGMGR_MAX_GPU_INSTANCES / 2));
2961739a20eSAndy Ritger             *pPartitionSizeFlag = DRF_DEF(2080_CTRL_GPU, _PARTITION_FLAG, _MEMORY_SIZE, _HALF);
2971739a20eSAndy Ritger             break;
2981739a20eSAndy Ritger         }
2991739a20eSAndy Ritger 
3001739a20eSAndy Ritger         case 3:
3011739a20eSAndy Ritger         case 4:
3021739a20eSAndy Ritger         case 5:
3031739a20eSAndy Ritger         case 6:
3041739a20eSAndy Ritger         {
3051739a20eSAndy Ritger             *pSizeInBytes = (memSize * (KMIGMGR_MAX_GPU_INSTANCES / 4));
3061739a20eSAndy Ritger             *pPartitionSizeFlag = DRF_DEF(2080_CTRL_GPU, _PARTITION_FLAG, _MEMORY_SIZE, _QUARTER);
3071739a20eSAndy Ritger             break;
3081739a20eSAndy Ritger         }
3091739a20eSAndy Ritger 
3101739a20eSAndy Ritger         case 7:
3111739a20eSAndy Ritger         case 8:
3121739a20eSAndy Ritger         case 9:
3131739a20eSAndy Ritger         case 10:
3141739a20eSAndy Ritger         case 11:
3151739a20eSAndy Ritger         case 12:
3161739a20eSAndy Ritger         case 13:
3171739a20eSAndy Ritger         case 14:
3181739a20eSAndy Ritger         {
3191739a20eSAndy Ritger             *pSizeInBytes = memSize;
3201739a20eSAndy Ritger             *pPartitionSizeFlag = DRF_DEF(2080_CTRL_GPU, _PARTITION_FLAG, _MEMORY_SIZE, _EIGHTH);
3211739a20eSAndy Ritger             break;
3221739a20eSAndy Ritger         }
3231739a20eSAndy Ritger 
3241739a20eSAndy Ritger         default:
3251739a20eSAndy Ritger         {
3261739a20eSAndy Ritger             NV_PRINTF(LEVEL_ERROR, "Unsupported SwizzId %d\n", swizzId);
3271739a20eSAndy Ritger             DBG_BREAKPOINT();
3281739a20eSAndy Ritger             return NV_ERR_INVALID_ARGUMENT;
3291739a20eSAndy Ritger         }
3301739a20eSAndy Ritger     }
3311739a20eSAndy Ritger 
3321739a20eSAndy Ritger     if ((*pSizeInBytes == 0) &&
3331739a20eSAndy Ritger         !pGpu->getProperty(pGpu, PDB_PROP_GPU_ZERO_FB) &&
3341739a20eSAndy Ritger         !pGpu->getProperty(pGpu, PDB_PROP_GPU_BROKEN_FB))
3351739a20eSAndy Ritger     {
3361739a20eSAndy Ritger         NV_PRINTF(LEVEL_ERROR, "Insufficient memory\n");
3371739a20eSAndy Ritger         DBG_BREAKPOINT();
3381739a20eSAndy Ritger         return NV_ERR_INSUFFICIENT_RESOURCES;
3391739a20eSAndy Ritger     }
3401739a20eSAndy Ritger     return NV_OK;
3411739a20eSAndy Ritger }
3421739a20eSAndy Ritger 
3431739a20eSAndy Ritger /*!
3441739a20eSAndy Ritger  * @brief   Function to map swizzId to mem range given total range
3451739a20eSAndy Ritger  */
3461739a20eSAndy Ritger NV_STATUS
3471739a20eSAndy Ritger kmemsysSwizzIdToMIGMemRange_IMPL
3481739a20eSAndy Ritger (
3491739a20eSAndy Ritger     OBJGPU *pGpu,
3501739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem,
3511739a20eSAndy Ritger     NvU32 swizzId,
3521739a20eSAndy Ritger     NV_RANGE totalRange,
3531739a20eSAndy Ritger     NV_RANGE *pAddrRange
3541739a20eSAndy Ritger )
3551739a20eSAndy Ritger {
3561739a20eSAndy Ritger     KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
3571739a20eSAndy Ritger     NV_STATUS rmStatus = NV_OK;
3581739a20eSAndy Ritger     NvU32 memSizeFlag = 0;
3591739a20eSAndy Ritger     NvU32 minSwizzId = 0;
3601739a20eSAndy Ritger     NvU64 unalignedStartAddr = 0;
3611739a20eSAndy Ritger     NvU64 memSize = 0;
3621739a20eSAndy Ritger     NV_RANGE swizzIdRange = NV_RANGE_EMPTY;
3631739a20eSAndy Ritger 
3641739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(!rangeIsEmpty(totalRange), NV_ERR_INVALID_ARGUMENT);
3651739a20eSAndy Ritger 
3661739a20eSAndy Ritger     // Get SwizzId to size mapping
3671739a20eSAndy Ritger     NV_ASSERT_OK_OR_RETURN(
3681739a20eSAndy Ritger         kmemsysSwizzIdToMIGMemSize(pGpu, pKernelMemorySystem, swizzId, totalRange, &memSizeFlag, &memSize));
3691739a20eSAndy Ritger 
3701739a20eSAndy Ritger     swizzIdRange = kmigmgrMemSizeFlagToSwizzIdRange_HAL(pGpu, pKernelMIGManager, memSizeFlag);
3711739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(!rangeIsEmpty(swizzIdRange), NV_ERR_INVALID_ARGUMENT);
3721739a20eSAndy Ritger 
3731739a20eSAndy Ritger     minSwizzId = swizzIdRange.lo;
3741739a20eSAndy Ritger 
3751739a20eSAndy Ritger     unalignedStartAddr = (totalRange.lo + (memSize * (swizzId - minSwizzId)));
3761739a20eSAndy Ritger     *pAddrRange = rangeMake(unalignedStartAddr, unalignedStartAddr + memSize - 1);
3771739a20eSAndy Ritger 
3781739a20eSAndy Ritger     return rmStatus;
3791739a20eSAndy Ritger }
3801739a20eSAndy Ritger 
3811739a20eSAndy Ritger /*!
3821739a20eSAndy Ritger  * @brief   Function to return GPU instance memory address range
3831739a20eSAndy Ritger  */
3841739a20eSAndy Ritger NV_STATUS
3851739a20eSAndy Ritger kmemsysGetMIGGPUInstanceMemInfo_IMPL
3861739a20eSAndy Ritger (
3871739a20eSAndy Ritger     OBJGPU *pGpu,
3881739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem,
3891739a20eSAndy Ritger     NvU32 swizzId,
3901739a20eSAndy Ritger     NV_RANGE *pAddrRange
3911739a20eSAndy Ritger )
3921739a20eSAndy Ritger {
3931739a20eSAndy Ritger     MemoryManager *pMemoryManager = GPU_GET_MEMORY_MANAGER(pGpu);
3941739a20eSAndy Ritger     NvU64 vmmuSegmentSize;
3951739a20eSAndy Ritger     NvU64 startAddr;
3961739a20eSAndy Ritger     NvU64 endAddr;
3971739a20eSAndy Ritger 
3981739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(pAddrRange != NULL, NV_ERR_INVALID_ARGUMENT);
3991739a20eSAndy Ritger     *pAddrRange = NV_RANGE_EMPTY;
4001739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(swizzId < KMIGMGR_MAX_GPU_SWIZZID, NV_ERR_INVALID_STATE);
4011739a20eSAndy Ritger 
4021739a20eSAndy Ritger     // Not supported in vGPU or ZERO_FB configs
4031739a20eSAndy Ritger     NV_CHECK_OR_RETURN(LEVEL_SILENT,
4041739a20eSAndy Ritger                        !(IS_VIRTUAL(pGpu) || (pGpu->getProperty(pGpu, PDB_PROP_GPU_ZERO_FB))),
4051739a20eSAndy Ritger                        NV_OK);
4061739a20eSAndy Ritger 
4071739a20eSAndy Ritger     //
4081739a20eSAndy Ritger     // VMMU not supported in AMODEL. Use legacy swizz-ID calculation instead of relying on vMMU segments
4091739a20eSAndy Ritger     // to calculate address range
4101739a20eSAndy Ritger     //
4111739a20eSAndy Ritger     if (IsAMODEL(pGpu))
4121739a20eSAndy Ritger     {
4131739a20eSAndy Ritger         NV_RANGE partitionableMemoryRange = memmgrGetMIGPartitionableMemoryRange(pGpu, pMemoryManager);
4141739a20eSAndy Ritger         return kmemsysSwizzIdToMIGMemRange(pGpu, pKernelMemorySystem, swizzId, partitionableMemoryRange, pAddrRange);
4151739a20eSAndy Ritger     }
4161739a20eSAndy Ritger 
4171739a20eSAndy Ritger     // Get the VMMU segment size
4181739a20eSAndy Ritger     vmmuSegmentSize = gpuGetVmmuSegmentSize(pGpu);
4191739a20eSAndy Ritger     NV_ASSERT_OR_RETURN((vmmuSegmentSize != 0), NV_ERR_INVALID_STATE);
4201739a20eSAndy Ritger 
4211739a20eSAndy Ritger     startAddr = pKernelMemorySystem->gpuInstanceMemConfig[swizzId].startingVmmuSegment * vmmuSegmentSize;
4221739a20eSAndy Ritger     endAddr = startAddr + (pKernelMemorySystem->gpuInstanceMemConfig[swizzId].memSizeInVmmuSegment * vmmuSegmentSize) - 1;
4231739a20eSAndy Ritger     *pAddrRange = rangeMake(startAddr, endAddr);
4241739a20eSAndy Ritger 
4251739a20eSAndy Ritger     return NV_OK;
4261739a20eSAndy Ritger }
4271739a20eSAndy Ritger 
4281739a20eSAndy Ritger /*!
4291739a20eSAndy Ritger  * @brief   Function to populate static GPU instance memory config which will be
4301739a20eSAndy Ritger  *          utilized for GPU instance memory query and memory allocation
4311739a20eSAndy Ritger  */
4321739a20eSAndy Ritger NV_STATUS
4331739a20eSAndy Ritger kmemsysPopulateMIGGPUInstanceMemConfig_KERNEL
4341739a20eSAndy Ritger (
4351739a20eSAndy Ritger     OBJGPU *pGpu,
4361739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem
4371739a20eSAndy Ritger )
4381739a20eSAndy Ritger {
4391739a20eSAndy Ritger     MemoryManager *pMemoryManager = GPU_GET_MEMORY_MANAGER(pGpu);
4401739a20eSAndy Ritger     NV_RANGE partitionableMemoryRange = memmgrGetMIGPartitionableMemoryRange(pGpu, pMemoryManager);
4411739a20eSAndy Ritger     KernelMIGManager *pKernelMIGManager = GPU_GET_KERNEL_MIG_MANAGER(pGpu);
4421739a20eSAndy Ritger     NvU64 vmmuSegmentSize;
4431739a20eSAndy Ritger     NvU64 totalVmmuSegments;
4441739a20eSAndy Ritger     NvU64 alignedStartAddr;
4451739a20eSAndy Ritger     NvU64 alignedEndAddr;
4461739a20eSAndy Ritger     NvU32 swizzId;
4471739a20eSAndy Ritger 
4481739a20eSAndy Ritger     // Not needed in vGPU or zero_fb configs
4491739a20eSAndy Ritger     NV_CHECK_OR_RETURN(LEVEL_SILENT,
4501739a20eSAndy Ritger                        !(IS_VIRTUAL(pGpu) || (pGpu->getProperty(pGpu, PDB_PROP_GPU_ZERO_FB))),
4511739a20eSAndy Ritger                        NV_OK);
4521739a20eSAndy Ritger 
4531739a20eSAndy Ritger     // Nothing to do if MIG is not supported
4541739a20eSAndy Ritger     NV_CHECK_OR_RETURN(LEVEL_SILENT, kmigmgrIsMIGSupported(pGpu, pKernelMIGManager), NV_OK);
4551739a20eSAndy Ritger 
4561739a20eSAndy Ritger     // Get the VMMU segment size
4571739a20eSAndy Ritger     vmmuSegmentSize = gpuGetVmmuSegmentSize(pGpu);
4581739a20eSAndy Ritger     NV_ASSERT_OR_RETURN((vmmuSegmentSize != 0), NV_ERR_INVALID_STATE);
4591739a20eSAndy Ritger 
4601739a20eSAndy Ritger     alignedStartAddr = partitionableMemoryRange.lo;
4611739a20eSAndy Ritger     alignedEndAddr = partitionableMemoryRange.hi;
4621739a20eSAndy Ritger     if (alignedStartAddr != 0)
4631739a20eSAndy Ritger     {
4641739a20eSAndy Ritger         alignedStartAddr = NV_IS_ALIGNED64(alignedStartAddr, vmmuSegmentSize) ?
4651739a20eSAndy Ritger                            alignedStartAddr + vmmuSegmentSize :
4661739a20eSAndy Ritger                            NV_ALIGN_UP64(alignedStartAddr, vmmuSegmentSize);
4671739a20eSAndy Ritger     }
4681739a20eSAndy Ritger 
4691739a20eSAndy Ritger     if (NV_IS_ALIGNED64(alignedEndAddr + 1, vmmuSegmentSize))
4701739a20eSAndy Ritger     {
4711739a20eSAndy Ritger         alignedEndAddr = alignedEndAddr - vmmuSegmentSize;
4721739a20eSAndy Ritger     }
4731739a20eSAndy Ritger 
4741739a20eSAndy Ritger     totalVmmuSegments = (alignedEndAddr - alignedStartAddr + 1) / vmmuSegmentSize;
4751739a20eSAndy Ritger     for (swizzId = 0; swizzId < KMIGMGR_MAX_GPU_SWIZZID; swizzId++)
4761739a20eSAndy Ritger     {
4771739a20eSAndy Ritger         NV_CHECK_OK_OR_RETURN(LEVEL_ERROR,
4781739a20eSAndy Ritger             kmemsysSwizzIdToVmmuSegmentsRange_HAL(pGpu, pKernelMemorySystem, swizzId, vmmuSegmentSize, totalVmmuSegments));
4791739a20eSAndy Ritger     }
4801739a20eSAndy Ritger 
4811739a20eSAndy Ritger     return NV_OK;
4821739a20eSAndy Ritger }
4831739a20eSAndy Ritger 
4841739a20eSAndy Ritger /*!
4851739a20eSAndy Ritger  * @brief Gets GPU instance memory configuration based on swizzId
4861739a20eSAndy Ritger  */
4871739a20eSAndy Ritger NV_STATUS
4881739a20eSAndy Ritger kmemsysGetMIGGPUInstanceMemConfigFromSwizzId_IMPL
4891739a20eSAndy Ritger (
4901739a20eSAndy Ritger     OBJGPU *pGpu,
4911739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem,
4921739a20eSAndy Ritger     NvU32 swizzId,
4931739a20eSAndy Ritger     const MIG_GPU_INSTANCE_MEMORY_CONFIG **ppGPUInstanceMemConfig
4941739a20eSAndy Ritger )
4951739a20eSAndy Ritger {
4961739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(swizzId < KMIGMGR_MAX_GPU_SWIZZID, NV_ERR_INVALID_ARGUMENT);
4971739a20eSAndy Ritger     // MODS makes a control call to describe GPU instances before this is populated. Return invalid data anyways
4981739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(pKernelMemorySystem->gpuInstanceMemConfig[swizzId].bInitialized, NV_ERR_INVALID_STATE);
4991739a20eSAndy Ritger 
5001739a20eSAndy Ritger     *ppGPUInstanceMemConfig = &pKernelMemorySystem->gpuInstanceMemConfig[swizzId];
5011739a20eSAndy Ritger     return NV_OK;
5021739a20eSAndy Ritger }
5031739a20eSAndy Ritger 
5041739a20eSAndy Ritger /*!
5051739a20eSAndy Ritger  * @brief Set GPU Instance memory config information and mark initialized
5061739a20eSAndy Ritger  */
5071739a20eSAndy Ritger NV_STATUS
5081739a20eSAndy Ritger kmemsysInitMIGGPUInstanceMemConfigForSwizzId_IMPL
5091739a20eSAndy Ritger (
5101739a20eSAndy Ritger     OBJGPU *pGpu,
5111739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem,
5121739a20eSAndy Ritger     NvU32 swizzId,
5131739a20eSAndy Ritger     NvU64 startingVmmuSegment,
5141739a20eSAndy Ritger     NvU64 memSizeInVmmuSegment
5151739a20eSAndy Ritger )
5161739a20eSAndy Ritger {
5171739a20eSAndy Ritger     NV_ASSERT_OR_RETURN(swizzId < KMIGMGR_MAX_GPU_SWIZZID, NV_ERR_INVALID_ARGUMENT);
5181739a20eSAndy Ritger 
5191739a20eSAndy Ritger     pKernelMemorySystem->gpuInstanceMemConfig[swizzId].startingVmmuSegment = startingVmmuSegment;
5201739a20eSAndy Ritger     pKernelMemorySystem->gpuInstanceMemConfig[swizzId].memSizeInVmmuSegment = memSizeInVmmuSegment;
5211739a20eSAndy Ritger     pKernelMemorySystem->gpuInstanceMemConfig[swizzId].bInitialized = NV_TRUE;
5221739a20eSAndy Ritger 
5231739a20eSAndy Ritger     NV_PRINTF(LEVEL_INFO,
5241739a20eSAndy Ritger         "GPU Instance Mem Config for swizzId = 0x%x : MemStartSegment = 0x%llx, MemSizeInSegments = 0x%llx\n",
5251739a20eSAndy Ritger         swizzId,
5261739a20eSAndy Ritger         pKernelMemorySystem->gpuInstanceMemConfig[swizzId].startingVmmuSegment,
5271739a20eSAndy Ritger         pKernelMemorySystem->gpuInstanceMemConfig[swizzId].memSizeInVmmuSegment);
5281739a20eSAndy Ritger 
5291739a20eSAndy Ritger     return NV_OK;
5301739a20eSAndy Ritger }
5311739a20eSAndy Ritger 
5321739a20eSAndy Ritger /*!
5331739a20eSAndy Ritger  * @brief Ensure that the sysmem flush sysmem buffer has been initialized
5341739a20eSAndy Ritger  *
5351739a20eSAndy Ritger  * Setting up the sysmem flush buffer needs to be done very early in some cases
5361739a20eSAndy Ritger  * as it's required for the GPU to perform a system flush. One such case is
5371739a20eSAndy Ritger  * resetting GPU FALCONs and in particular resetting the PMU as part of VBIOS
5381739a20eSAndy Ritger  * init.
5391739a20eSAndy Ritger  *
5401739a20eSAndy Ritger  * @returns NV_OK if the sysmem flush buffer has been initialized.
5411739a20eSAndy Ritger  */
5421739a20eSAndy Ritger NV_STATUS
5431739a20eSAndy Ritger kmemsysEnsureSysmemFlushBufferInitialized_IMPL
5441739a20eSAndy Ritger (
5451739a20eSAndy Ritger     OBJGPU             *pGpu,
5461739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem
5471739a20eSAndy Ritger )
5481739a20eSAndy Ritger {
5491739a20eSAndy Ritger     if (IS_VIRTUAL(pGpu)                                       ||
5501739a20eSAndy Ritger         IS_GSP_CLIENT(pGpu)                                    ||
5511739a20eSAndy Ritger         RMCFG_FEATURE_PLATFORM_GSP)
5521739a20eSAndy Ritger     {
5531739a20eSAndy Ritger         return NV_OK;
5541739a20eSAndy Ritger     }
5551739a20eSAndy Ritger 
5561739a20eSAndy Ritger     return kmemsysInitFlushSysmemBuffer_HAL(pGpu, pKernelMemorySystem);
5571739a20eSAndy Ritger }
5581739a20eSAndy Ritger 
5591739a20eSAndy Ritger /*!
5601739a20eSAndy Ritger  * @brief Handle sysmem NVLink/C2C, NUMA and ATS functionality
5611739a20eSAndy Ritger  *
5621739a20eSAndy Ritger  * @param[in] pGpu                OBJGPU pointer
5631739a20eSAndy Ritger  * @param[in] pKernelMemorySystem pointer to the kernel side KernelMemorySystem instance.
5641739a20eSAndy Ritger  * @param[in] bFlush              Whether the CPU cache of the GPU mapping
5651739a20eSAndy Ritger  *                                should be flushed
5661739a20eSAndy Ritger  *
5671739a20eSAndy Ritger  * @return  NV_OK on success
5681739a20eSAndy Ritger  */
5691739a20eSAndy Ritger NV_STATUS
5701739a20eSAndy Ritger kmemsysSetupCoherentCpuLink_IMPL
5711739a20eSAndy Ritger (
5721739a20eSAndy Ritger     OBJGPU             *pGpu,
5731739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem,
5741739a20eSAndy Ritger     NvBool              bFlush
5751739a20eSAndy Ritger )
5761739a20eSAndy Ritger {
5771739a20eSAndy Ritger     KernelBus     *pKernelBus     = GPU_GET_KERNEL_BUS(pGpu);
5781739a20eSAndy Ritger     MemoryManager *pMemoryManager = GPU_GET_MEMORY_MANAGER(pGpu);
5791739a20eSAndy Ritger     NvU64          memblockSize   = 0;
5801739a20eSAndy Ritger     NvU64          numaOnlineBase = 0;
5811739a20eSAndy Ritger     NvU64          numaOnlineSize = 0;
5821739a20eSAndy Ritger     NvU32          data32;
5831739a20eSAndy Ritger     NvBool         bCpuMapping;
5841739a20eSAndy Ritger 
5851739a20eSAndy Ritger     //
5861739a20eSAndy Ritger     // Compute coherent link aperture range for SHH and P9 (!NV_VERIF_FEATURES) to enable
5871739a20eSAndy Ritger     // FB access via coherent link(Nvlink/C2C) path
5881739a20eSAndy Ritger     //
5891739a20eSAndy Ritger     {
5901739a20eSAndy Ritger         NV_ASSERT_OK_OR_RETURN(kmemsysGetFbNumaInfo_HAL(pGpu, pKernelMemorySystem,
5911739a20eSAndy Ritger                                                         &pKernelMemorySystem->coherentCpuFbBase,
5921739a20eSAndy Ritger                                                         &pGpu->numaNodeId));
5931739a20eSAndy Ritger         if (pKernelMemorySystem->coherentCpuFbBase != 0)
5941739a20eSAndy Ritger         {
595*94eaea97SAndy Ritger             RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
596*94eaea97SAndy Ritger             NV2080_CTRL_INTERNAL_GET_COHERENT_FB_APERTURE_SIZE_PARAMS params = {0};
597*94eaea97SAndy Ritger 
598*94eaea97SAndy Ritger             NV_ASSERT_OK_OR_RETURN(pRmApi->Control(pRmApi,
599*94eaea97SAndy Ritger                     pGpu->hInternalClient,
600*94eaea97SAndy Ritger                     pGpu->hInternalSubdevice,
601*94eaea97SAndy Ritger                     NV2080_CTRL_CMD_INTERNAL_GET_COHERENT_FB_APERTURE_SIZE,
602*94eaea97SAndy Ritger                     &params,
603*94eaea97SAndy Ritger                     sizeof(NV2080_CTRL_INTERNAL_GET_COHERENT_FB_APERTURE_SIZE_PARAMS)));
6041739a20eSAndy Ritger             pKernelMemorySystem->coherentCpuFbEnd = pKernelMemorySystem->coherentCpuFbBase +
605*94eaea97SAndy Ritger                                                     params.coherentFbApertureSize;
6061739a20eSAndy Ritger         }
6071739a20eSAndy Ritger     }
6081739a20eSAndy Ritger 
6091739a20eSAndy Ritger     // ATS mappings are currently not supported in mods
6101739a20eSAndy Ritger     if ((osReadRegistryDword(pGpu,
6111739a20eSAndy Ritger                              NV_REG_STR_OVERRIDE_GPU_NUMA_NODE_ID, &data32)) == NV_OK)
6121739a20eSAndy Ritger     {
6131739a20eSAndy Ritger         pGpu->numaNodeId = (NvS32)data32;
6141739a20eSAndy Ritger         NV_PRINTF(LEVEL_ERROR, "Override GPU NUMA node ID %d!\n",
6151739a20eSAndy Ritger                   pGpu->numaNodeId);
6161739a20eSAndy Ritger     }
6171739a20eSAndy Ritger 
6181739a20eSAndy Ritger     // Default enable
6191739a20eSAndy Ritger     bCpuMapping = NV_TRUE;
6201739a20eSAndy Ritger 
6211739a20eSAndy Ritger     // Parse regkey here
6221739a20eSAndy Ritger     if ((osReadRegistryDword(pGpu,
6231739a20eSAndy Ritger                              NV_REG_STR_RM_FORCE_BAR_PATH, &data32) == NV_OK) &&
6241739a20eSAndy Ritger         (data32 == 1))
6251739a20eSAndy Ritger     {
6261739a20eSAndy Ritger         NV_PRINTF(LEVEL_ERROR,
6271739a20eSAndy Ritger                   "Force disabling NVLINK/C2C mappings through regkey.\n");
6281739a20eSAndy Ritger 
6291739a20eSAndy Ritger         bCpuMapping = NV_FALSE;
6301739a20eSAndy Ritger     }
6311739a20eSAndy Ritger 
6321739a20eSAndy Ritger     if ((pKernelMemorySystem->coherentCpuFbBase == 0) || !bCpuMapping)
6331739a20eSAndy Ritger     {
6341739a20eSAndy Ritger         return NV_OK;
6351739a20eSAndy Ritger     }
6361739a20eSAndy Ritger     NV_ASSERT_OK_OR_RETURN(kbusCreateCoherentCpuMapping_HAL(pGpu, pKernelBus, bFlush));
6371739a20eSAndy Ritger 
6381739a20eSAndy Ritger     // Switch the toggle for coherent link mapping only if migration is successful
6391739a20eSAndy Ritger     pGpu->setProperty(pGpu, PDB_PROP_GPU_COHERENT_CPU_MAPPING, NV_TRUE);
6401739a20eSAndy Ritger 
6411739a20eSAndy Ritger     NV_ASSERT_OK_OR_RETURN(kbusVerifyCoherentLink_HAL(pGpu, pKernelBus));
6421739a20eSAndy Ritger 
6431739a20eSAndy Ritger     //
6441739a20eSAndy Ritger     // TODO clean up with bug 2020982
6451739a20eSAndy Ritger     // RM: Encapsulate NUMA-specific kernel code and logic in a new object
6461739a20eSAndy Ritger     //
6471739a20eSAndy Ritger     if (osNumaMemblockSize(&memblockSize) == NV_OK)
6481739a20eSAndy Ritger     {
6491739a20eSAndy Ritger         NvU64 rsvdFastSize   = 0;
6501739a20eSAndy Ritger         NvU64 rsvdSlowSize   = 0;
6511739a20eSAndy Ritger         NvU64 rsvdISOSize    = 0;
6521739a20eSAndy Ritger         NvU64 totalResvBytes = 0;
6531739a20eSAndy Ritger 
6541739a20eSAndy Ritger         memmgrCalcReservedFbSpaceHal_HAL(pGpu, pMemoryManager, &rsvdFastSize, &rsvdSlowSize, &rsvdISOSize);
6551739a20eSAndy Ritger         totalResvBytes = (rsvdFastSize + rsvdSlowSize + rsvdISOSize);
6561739a20eSAndy Ritger         totalResvBytes += memmgrGetRsvdMemorySize(pMemoryManager);
6571739a20eSAndy Ritger 
6581739a20eSAndy Ritger         //
6591739a20eSAndy Ritger         // Online all of FB memory less reserved memory, aligned to memblock
6601739a20eSAndy Ritger         //
6611739a20eSAndy Ritger         // TODO: make sure the onlineable memory is aligned to memblockSize
6621739a20eSAndy Ritger         // Currently, if we have leftover memory, it'll just be wasted because no
6631739a20eSAndy Ritger         // one can access it
6641739a20eSAndy Ritger         //
6651739a20eSAndy Ritger         numaOnlineSize = NV_ALIGN_DOWN(pMemoryManager->Ram.fbUsableMemSize - totalResvBytes, memblockSize);
6661739a20eSAndy Ritger         NV_PRINTF(LEVEL_INFO, "NUMA reserved memory size: 0x%llx online memory size: 0x%llx\n",
6671739a20eSAndy Ritger                   totalResvBytes, numaOnlineSize);
6681739a20eSAndy Ritger 
6691739a20eSAndy Ritger         pKernelMemorySystem->numaOnlineBase   = numaOnlineBase;
6701739a20eSAndy Ritger         pKernelMemorySystem->numaOnlineSize   = numaOnlineSize;
6711739a20eSAndy Ritger     }
6721739a20eSAndy Ritger 
6731739a20eSAndy Ritger     return NV_OK;
6741739a20eSAndy Ritger }
6751739a20eSAndy Ritger 
6761739a20eSAndy Ritger /*!
6771739a20eSAndy Ritger  * @brief Teardown sysmem NVLink/C2C NUMA and ATS functionality
6781739a20eSAndy Ritger  *
6791739a20eSAndy Ritger  * @param[in] pGpu                 OBJGPU pointer
6801739a20eSAndy Ritger  * @param[in] pKernelMemorySystem  Kernel Memory System pointer
6811739a20eSAndy Ritger  * @param[in] bFlush               Whether the CPU cache of the GPU mapping
6821739a20eSAndy Ritger  *                                 should be flushed
6831739a20eSAndy Ritger  */
6841739a20eSAndy Ritger void
6851739a20eSAndy Ritger kmemsysTeardownCoherentCpuLink_IMPL
6861739a20eSAndy Ritger (
6871739a20eSAndy Ritger     OBJGPU            *pGpu,
6881739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem,
6891739a20eSAndy Ritger     NvBool             bFlush
6901739a20eSAndy Ritger )
6911739a20eSAndy Ritger {
6921739a20eSAndy Ritger     kbusTeardownCoherentCpuMapping_HAL(pGpu, GPU_GET_KERNEL_BUS(pGpu), bFlush);
6931739a20eSAndy Ritger     pGpu->setProperty(pGpu, PDB_PROP_GPU_COHERENT_CPU_MAPPING, NV_FALSE);
6941739a20eSAndy Ritger }
6951739a20eSAndy Ritger 
6961739a20eSAndy Ritger NV_STATUS
6971739a20eSAndy Ritger kmemsysSendL2InvalidateEvict_IMPL
6981739a20eSAndy Ritger (
6991739a20eSAndy Ritger     OBJGPU             *pGpu,
7001739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem,
7011739a20eSAndy Ritger     NvU32               flags)
7021739a20eSAndy Ritger {
7031739a20eSAndy Ritger     RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
7041739a20eSAndy Ritger     NV2080_CTRL_INTERNAL_MEMSYS_L2_INVALIDATE_EVICT_PARAMS params = {0};
7051739a20eSAndy Ritger 
7061739a20eSAndy Ritger     params.flags = flags;
7071739a20eSAndy Ritger 
7081739a20eSAndy Ritger     return pRmApi->Control(pRmApi, pGpu->hInternalClient, pGpu->hInternalSubdevice,
7091739a20eSAndy Ritger                            NV2080_CTRL_CMD_INTERNAL_MEMSYS_L2_INVALIDATE_EVICT,
7101739a20eSAndy Ritger                            &params, sizeof(params));
7111739a20eSAndy Ritger }
7121739a20eSAndy Ritger 
7131739a20eSAndy Ritger NV_STATUS
7141739a20eSAndy Ritger kmemsysSendFlushL2AllRamsAndCaches_IMPL
7151739a20eSAndy Ritger (
7161739a20eSAndy Ritger     OBJGPU             *pGpu,
7171739a20eSAndy Ritger     KernelMemorySystem *pKernelMemorySystem
7181739a20eSAndy Ritger )
7191739a20eSAndy Ritger {
7201739a20eSAndy Ritger     RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
7211739a20eSAndy Ritger 
7221739a20eSAndy Ritger     return pRmApi->Control(pRmApi, pGpu->hInternalClient, pGpu->hInternalSubdevice,
7231739a20eSAndy Ritger                            NV2080_CTRL_CMD_INTERNAL_MEMSYS_FLUSH_L2_ALL_RAMS_AND_CACHES,
7241739a20eSAndy Ritger                            NULL, 0);
7251739a20eSAndy Ritger }
7261739a20eSAndy Ritger 
7271739a20eSAndy Ritger NV_STATUS
7281739a20eSAndy Ritger kmemsysGetUsableFbSize_KERNEL
7291739a20eSAndy Ritger (
7301739a20eSAndy Ritger     OBJGPU               *pGpu,
7311739a20eSAndy Ritger     KernelMemorySystem   *pKernelMemorySystem,
7321739a20eSAndy Ritger     NvU64                *pFbSize
7331739a20eSAndy Ritger )
7341739a20eSAndy Ritger {
7351739a20eSAndy Ritger     return kmemsysReadUsableFbSize_HAL(pGpu, pKernelMemorySystem, pFbSize);
7361739a20eSAndy Ritger }
737