1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 2019-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 * SPDX-License-Identifier: MIT 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24 #include "core/core.h" 25 #include "gpu/gpu.h" 26 #include "gpu/mem_mgr/mem_mgr.h" 27 #include "gpu/mmu/kern_gmmu.h" 28 #include "gpu/bus/kern_bus.h" 29 #include "gpu/gsp/gsp_static_config.h" 30 #include "vgpu/vgpu_events.h" 31 #include <ctrl/ctrl2080/ctrl2080fb.h> 32 #include "gpu/mem_mgr/fermi_dma.h" 33 #include "nvoc/prelude.h" 34 35 /*! 36 * @brief Initialize FB regions from static info obtained from GSP FW. Also, 37 * initialize region table related RAM fields. 38 */ 39 NV_STATUS 40 memmgrInitBaseFbRegions_FWCLIENT 41 ( 42 OBJGPU *pGpu, 43 MemoryManager *pMemoryManager 44 ) 45 { 46 NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS *pFbRegionInfoParams; 47 NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO *pFbRegionInfo; 48 GspStaticConfigInfo *pGSCI = GPU_GET_GSP_STATIC_INFO(pGpu); 49 NvU64 bias; 50 NvU32 i; 51 52 // sanity checks 53 if (pGSCI == NULL) 54 { 55 NV_PRINTF(LEVEL_ERROR, "Missing static info.\n"); 56 57 return NV_ERR_INVALID_STATE; 58 } 59 60 pFbRegionInfoParams = &pGSCI->fbRegionInfoParams; 61 if (pFbRegionInfoParams->numFBRegions == 0) 62 { 63 NV_PRINTF(LEVEL_ERROR, 64 "Missing FB region table in GSP Init arguments.\n"); 65 66 return NV_ERR_INVALID_PARAMETER; 67 } 68 69 if (pFbRegionInfoParams->numFBRegions > MAX_FB_REGIONS) 70 { 71 NV_PRINTF(LEVEL_ERROR, 72 "Static info struct has more FB regions (%u) than FB supports (%u).\n", 73 pFbRegionInfoParams->numFBRegions, MAX_FB_REGIONS); 74 75 return NV_ERR_INVALID_PARAMETER; 76 } 77 78 pMemoryManager->Ram.reservedMemSize = 0; 79 pMemoryManager->Ram.fbUsableMemSize = 0; 80 81 // Copy FB regions from static info structure 82 for (i = 0; i < pFbRegionInfoParams->numFBRegions; i++) 83 { 84 pFbRegionInfo = &pFbRegionInfoParams->fbRegion[i]; 85 pMemoryManager->Ram.fbRegion[i].base = pFbRegionInfo->base; 86 pMemoryManager->Ram.fbRegion[i].limit = pFbRegionInfo->limit; 87 pMemoryManager->Ram.fbRegion[i].bProtected = pFbRegionInfo->bProtected; 88 pMemoryManager->Ram.fbRegion[i].bInternalHeap = NV_FALSE; 89 pMemoryManager->Ram.fbRegion[i].performance = pFbRegionInfo->performance; 90 pMemoryManager->Ram.fbRegion[i].bSupportCompressed = pFbRegionInfo->supportCompressed; 91 pMemoryManager->Ram.fbRegion[i].bSupportISO = pFbRegionInfo->supportISO; 92 pMemoryManager->Ram.fbRegion[i].rsvdSize = pFbRegionInfo->reserved; 93 94 if (pFbRegionInfo->reserved) 95 { 96 pMemoryManager->Ram.fbRegion[i].bRsvdRegion = NV_TRUE; 97 pMemoryManager->Ram.reservedMemSize += pMemoryManager->Ram.fbRegion[i].rsvdSize; 98 } 99 else 100 { 101 pMemoryManager->Ram.fbRegion[i].bRsvdRegion = NV_FALSE; 102 pMemoryManager->Ram.fbUsableMemSize += (pMemoryManager->Ram.fbRegion[i].limit - 103 pMemoryManager->Ram.fbRegion[i].base + 1); 104 } 105 } 106 pMemoryManager->Ram.numFBRegions = pFbRegionInfoParams->numFBRegions; 107 108 // Round up to the closest megabyte. 109 bias = (1 << 20) - 1; 110 // 111 // fbTotalMemSizeMb was set to fbUsableMemSize. However, in RM-offload, 112 // GSP-RM reserves some FB regions for its own usage, thus fbUsableMemSize 113 // won't represent the exact FB size. Instead, we are taking the FB size 114 // from the static info provided by GSP-RM. 115 // 116 pMemoryManager->Ram.fbTotalMemSizeMb = (pGSCI->fb_length + bias) >> 20; 117 pMemoryManager->Ram.fbAddrSpaceSizeMb = 118 (pMemoryManager->Ram.fbRegion[pFbRegionInfoParams->numFBRegions - 1].limit + bias) >> 20; 119 120 NV_ASSERT(pMemoryManager->Ram.fbAddrSpaceSizeMb >= pMemoryManager->Ram.fbTotalMemSizeMb); 121 122 // Dump some stats, region table is dumped in memsysStateLoad 123 NV_PRINTF(LEVEL_INFO, "FB Memory from Static info:\n"); 124 NV_PRINTF(LEVEL_INFO, "Reserved Memory=0x%llx, Usable Memory=0x%llx\n", 125 pMemoryManager->Ram.reservedMemSize, pMemoryManager->Ram.fbUsableMemSize); 126 NV_PRINTF(LEVEL_INFO, "fbTotalMemSizeMb=0x%llx, fbAddrSpaceSizeMb=0x%llx\n", 127 pMemoryManager->Ram.fbTotalMemSizeMb, pMemoryManager->Ram.fbAddrSpaceSizeMb); 128 129 return NV_OK; 130 } 131 132 /*! 133 * @brief Set up CPU RM reserved memory space for physical carveout. 134 */ 135 NV_STATUS 136 memmgrPreInitReservedMemory_FWCLIENT 137 ( 138 OBJGPU *pGpu, 139 MemoryManager *pMemoryManager 140 ) 141 { 142 KernelBus *pKernelBus = GPU_GET_KERNEL_BUS(pGpu); 143 KernelDisplay *pKernelDisplay = GPU_GET_KERNEL_DISPLAY(pGpu); 144 NvU64 tmpAddr = 0; 145 146 if (pKernelDisplay) 147 { 148 // TODO: Determine the correct size of display instance memory 149 // via instmemGetSize_HAL(), as well as other parameters. 150 // I.e. refactor and leverage the code performing these tasks 151 // in memmgrPreInitReservedMemory_GM107() today. 152 tmpAddr += 0x10000; 153 } 154 155 if (gpuIsSelfHosted(pGpu)) 156 { 157 // 158 // Reserve space for the test buffer used in coherent link test 159 // that is run early when memory allocation is not ready yet. 160 // 161 // if Self-Hosted is running in PCIe mode then this space will 162 // will not be used, this should not cause any issue 163 // 164 pKernelBus->coherentLinkTestBufferBase = tmpAddr; 165 tmpAddr += BUS_COHERENT_LINK_TEST_BUFFER_SIZE; 166 } 167 168 if (KBUS_BAR2_ENABLED(pKernelBus)) 169 { 170 // 171 // This has to be the very *last* thing in reserved memory as it 172 // will may grow past the 1MB reserved memory window. We cannot 173 // size it until memsysStateInitLockedHal_GK104. 174 // 175 memmgrReserveBar2BackingStore(pGpu, pMemoryManager, &tmpAddr); 176 } 177 178 NV_ASSERT(NvU64_LO32(tmpAddr) == tmpAddr); 179 pMemoryManager->rsvdMemorySize = NvU64_LO32(tmpAddr); 180 181 return NV_OK; 182 } 183 184 /*! 185 * @brief Calculate the FB reserved memory requirement. 186 * 187 * @param[out] rsvdFastSize generic reserved RM memory needed in fast region 188 * @param[out] rsvdSlowSize generic reserved RM memory needed in slow region 189 * @param[out] rsvdISOSize ISO-specific reserved RM memory needed 190 */ 191 void 192 memmgrCalcReservedFbSpaceHal_FWCLIENT 193 ( 194 OBJGPU *pGpu, 195 MemoryManager *pMemoryManager, 196 NvU64 *rsvdFastSize, 197 NvU64 *rsvdSlowSize, 198 NvU64 *rsvdISOSize 199 ) 200 { 201 KernelFifo *pKernelFifo = GPU_GET_KERNEL_FIFO(pGpu); 202 KernelGmmu *pKernelGmmu = GPU_GET_KERNEL_GMMU(pGpu); 203 NvU64 rsvdSizeBytes; 204 NvU64 smallPagePte = 0; 205 NvU64 bigPagePte = 0; 206 207 // 208 // Minimum reserved memory for driver internal memdescAlloc() calls. 209 // DO NOT increase this hard-coded memory to account for more reserved 210 // FB memory, instead add individual calculations below. 211 // 212 rsvdSizeBytes = 5 * 1024 * 1024; 213 214 // Add in USERD reservation 215 rsvdSizeBytes += memmgrGetUserdReservedFbSpace_HAL(pGpu, pMemoryManager); 216 217 // Reserve FB for Fault method buffers 218 rsvdSizeBytes += kfifoCalcTotalSizeOfFaultMethodBuffers_HAL(pGpu, pKernelFifo, NV_TRUE); 219 220 // smallPagePte = FBSize /4k * 8 (Small page PTE for whole FB) 221 smallPagePte = NV_ROUNDUP((pMemoryManager->Ram.fbUsableMemSize / FERMI_SMALL_PAGESIZE) * 8, RM_PAGE_SIZE); 222 223 // bigPagePte = FBSize /bigPageSize * 8 (Big page PTE for whole FB) 224 bigPagePte = NV_ROUNDUP((pMemoryManager->Ram.fbUsableMemSize/ (kgmmuGetMaxBigPageSize_HAL(pKernelGmmu))) * 8, 225 RM_PAGE_SIZE); 226 227 rsvdSizeBytes += smallPagePte; 228 rsvdSizeBytes += bigPagePte; 229 230 if (gpuIsClientRmAllocatedCtxBufferEnabled(pGpu)) 231 { 232 rsvdSizeBytes += memmgrGetMaxContextSize_HAL(pGpu, pMemoryManager); 233 } 234 235 // Add in NV_REG_STR_RM_INCREASE_RSVD_MEMORY_SIZE_MB if applicable 236 if (pMemoryManager->rsvdMemorySizeIncrement != 0) 237 { 238 // Allow reservation up to half of usable FB size 239 if (pMemoryManager->rsvdMemorySizeIncrement > (pMemoryManager->Ram.fbUsableMemSize / 2)) 240 { 241 pMemoryManager->rsvdMemorySizeIncrement = pMemoryManager->Ram.fbUsableMemSize / 2; 242 NV_PRINTF(LEVEL_ERROR, 243 "RM can only increase reserved heap by 0x%llx bytes\n", 244 pMemoryManager->rsvdMemorySizeIncrement); 245 } 246 rsvdSizeBytes += pMemoryManager->rsvdMemorySizeIncrement; 247 } 248 249 rsvdSizeBytes = NV_ROUNDUP(rsvdSizeBytes, RM_PAGE_SIZE_64K); 250 251 // mixed memory type/density only existed in pre-Pascal chips 252 *rsvdFastSize = rsvdSizeBytes; 253 *rsvdSlowSize = 0; 254 *rsvdISOSize = 0; 255 } 256