1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2018-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: MIT
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "core/core.h"
25 #include "mem_mgr_internal.h"
26 #include "mem_mgr/hw_resources.h"
27 #include "gpu/mem_mgr/mem_desc.h"
28 #include "vgpu/vgpu_util.h"
29 #include "mem_mgr/mem.h"
30 #include "gpu/mem_mgr/mem_mgr.h"
31 #include "gpu/mem_mgr/heap.h"
32 #include "gpu/mem_sys/kern_mem_sys.h"
33 #include "rmapi/client.h"
34 #include "mmu/gmmu_fmt.h"
35 #include "gpu/device/device.h"
36
37 #include "class/cl0041.h" // NV04_MEMORY
38 #include "class/cl003e.h" // NV01_MEMORY_SYSTEM
39 #include "class/cl00b1.h" // NV01_MEMORY_HW_RESOURCES
40 #include "class/cl0040.h" // NV01_MEMORY_LOCAL_USER
41
42 NV_STATUS
hwresConstruct_IMPL(MemoryHwResources * pMemoryHwResources,CALL_CONTEXT * pCallContext,RS_RES_ALLOC_PARAMS_INTERNAL * pParams)43 hwresConstruct_IMPL
44 (
45 MemoryHwResources *pMemoryHwResources,
46 CALL_CONTEXT *pCallContext,
47 RS_RES_ALLOC_PARAMS_INTERNAL *pParams
48 )
49 {
50 NV_MEMORY_HW_RESOURCES_ALLOCATION_PARAMS *pAllocData;
51 MEMORY_HW_RESOURCES_ALLOCATION_REQUEST allocRequest = {0};
52 MEMORY_HW_RESOURCES_ALLOCATION_REQUEST *pAllocRequest = &allocRequest;
53 Memory *pMemory = staticCast(pMemoryHwResources, Memory);
54 OBJGPU *pGpu = pMemory->pGpu;
55 MemoryManager *pMemoryManager = GPU_GET_MEMORY_MANAGER(pGpu);
56 Heap *pHeap = MEMORY_MANAGER_GET_HEAP(pMemoryManager);
57 NV_STATUS status = NV_OK;
58 NvHandle hDevice = RES_GET_HANDLE(pMemory->pDevice);
59 NvHandle hMemory = pCallContext->pResourceRef->hResource;
60 NvHandle hClient = pCallContext->pClient->hClient;
61 NvU32 retAttr, retAttr2;
62 NvBool bVidmem;
63 const MEMORY_SYSTEM_STATIC_CONFIG *pMemorySystemConfig =
64 kmemsysGetStaticConfig(pGpu, GPU_GET_KERNEL_MEMORY_SYSTEM(pGpu));
65
66 // Copy-construction has already been done by the base Memory class
67 if (RS_IS_COPY_CTOR(pParams))
68 return NV_OK;
69
70 pAllocData = pParams->pAllocParams;
71
72 if (gpuIsDebuggerActive_HAL(pGpu))
73 {
74 // Bug 643431 - WAR for GR WFI timeouts when debugger is active
75 return NV_ERR_BUSY_RETRY;
76 }
77
78 // Init alloc request
79 pAllocRequest->pUserParams = pAllocData;
80 pAllocRequest->bindResultFunc = NvP64_VALUE(pAllocData->bindResultFunc);
81 pAllocRequest->pHandle = NvP64_VALUE(pAllocData->pHandle);
82 pAllocRequest->hwResId = 0;
83
84 bVidmem = FLD_TEST_DRF(OS32, _ATTR, _LOCATION, _VIDMEM, pAllocData->attr);
85
86 status = heapHwAlloc(pGpu, pHeap, hClient, hDevice, hMemory,
87 pAllocRequest, &retAttr, &retAttr2);
88
89 pAllocData->attr = retAttr;
90 pAllocData->attr2 = retAttr2;
91
92 // If Allocation succeeded then allocate a handle
93 if (status == NV_OK)
94 {
95 MEMORY_DESCRIPTOR *pMemDesc;
96
97 //
98 // Default to not GPU-cachable. This doesn't matter for the HW resources
99 // class but the lower level code expects this field to be updated.
100 //
101 if (FLD_TEST_DRF(OS32, _ATTR2, _GPU_CACHEABLE, _DEFAULT, pAllocData->attr2))
102 {
103 pAllocData->attr2 = FLD_SET_DRF(OS32, _ATTR2, _GPU_CACHEABLE, _NO,
104 pAllocData->attr2);
105 }
106
107 // comtags lines are allocated contiguously.
108 //pAllocData->attr = FLD_SET_DRF(OS32, _ATTR, _PHYSICALITY, _CONTIGUOUS,
109 //pUserParams->attr);
110
111 status = memCreateMemDesc(pGpu,
112 &pMemDesc,
113 bVidmem ? ADDR_FBMEM : ADDR_SYSMEM,
114 // Offset - do not know this yet. Must be page aligned.
115 memmgrGetInvalidOffset_HAL(pGpu, pMemoryManager),
116 pAllocData->size + pAllocRequest->pad,
117 pAllocData->attr,
118 pAllocData->attr2);
119
120 if (status == NV_OK)
121 {
122 status = memConstructCommon(pMemory,
123 bVidmem ? NV01_MEMORY_LOCAL_USER : NV01_MEMORY_SYSTEM,
124 pAllocData->flags, pMemDesc,
125 pAllocData->owner, pHeap, pAllocData->attr,
126 pAllocData->attr2, 0, pAllocData->type,
127 NVOS32_MEM_TAG_NONE, &pAllocRequest->hwResource);
128
129 if (status == NV_OK)
130 {
131 NV_ASSERT(pMemory->pMemDesc);
132 memdescSetPteKind(pMemory->pMemDesc, pAllocData->kind);
133 memdescSetHwResId(pMemory->pMemDesc, pAllocRequest->hwResId);
134
135 pMemory->osDeviceHandle = pAllocData->osDeviceHandle;
136
137 if (IS_VIRTUAL(pGpu) && vgpuIsGuestManagedHwAlloc(pGpu))
138 {
139 pAllocData->compPageShift = pMemorySystemConfig->comprPageShift;
140 pAllocData->compressedKind = pAllocData->kind;
141
142 if (memmgrIsKind_HAL(pMemoryManager, FB_IS_KIND_COMPRESSIBLE, pAllocData->kind))
143 {
144 pAllocData->uncompressedKind = memmgrGetUncompressedKind_HAL(pGpu, pMemoryManager,
145 pAllocData->kind, NV_FALSE);
146 }
147 else
148 {
149 pAllocData->uncompressedKind = pAllocData->kind;
150 }
151 }
152
153 if (!IS_VIRTUAL(pGpu) && !IS_GSP_CLIENT(pGpu))
154 {
155 NvU32 compressedKind;
156 COMPR_INFO comprInfo;
157
158 status = memmgrGetKindComprForGpu_HAL(pMemoryManager,
159 pMemory->pMemDesc,
160 pMemory->pMemDesc->pGpu,
161 0,
162 &compressedKind,
163 &comprInfo);
164
165 if (status == NV_OK)
166 {
167 pAllocData->compPageShift = pMemorySystemConfig->comprPageShift;
168 pAllocData->compressedKind = comprInfo.kind;
169 pAllocData->compTagLineMin = comprInfo.compTagLineMin;
170 pAllocData->compPageIndexLo = comprInfo.compPageIndexLo;
171 pAllocData->compPageIndexHi = comprInfo.compPageIndexHi;
172 pAllocData->compTagLineMultiplier = comprInfo.compTagLineMultiplier;
173
174 if (memmgrIsKind_HAL(pMemoryManager, FB_IS_KIND_COMPRESSIBLE, compressedKind))
175 {
176 pAllocData->uncompressedKind = memmgrGetUncompressedKind_HAL(pGpu, pMemoryManager,
177 compressedKind, NV_FALSE);
178 }
179 else
180 {
181 pAllocData->uncompressedKind = compressedKind;
182 }
183 }
184 }
185 }
186
187 if (status != NV_OK)
188 {
189 memdescDestroy(pMemDesc);
190 }
191 }
192 }
193
194 return status;
195 }
196
197 void
hwresDestruct_IMPL(MemoryHwResources * pMemoryHwResources)198 hwresDestruct_IMPL
199 (
200 MemoryHwResources *pMemoryHwResources
201 )
202 {
203 Memory *pMemory = staticCast(pMemoryHwResources, Memory);
204 OBJGPU *pGpu = pMemory->pGpu;
205 MEMORY_DESCRIPTOR *pMemDesc = pMemory->pMemDesc;
206 Heap *pHeap = GPU_GET_HEAP(pGpu);
207
208 //
209 // Must be done before memDestructCommon, as memDestructCommon will update BC state
210 // (3/8/2019 - is this comment stale?)
211 //
212 heapHwFree(pGpu, pHeap, pMemory, NVOS32_DELETE_RESOURCES_ALL);
213
214 memDestructCommon(pMemory);
215
216 NV_ASSERT(pMemDesc->Allocated == 0);
217 memdescFree(pMemDesc);
218 memdescDestroy(pMemDesc);
219 }
220
221 NvBool
hwresCanCopy_IMPL(MemoryHwResources * pMemoryHwResources)222 hwresCanCopy_IMPL
223 (
224 MemoryHwResources *pMemoryHwResources
225 )
226 {
227 return NV_TRUE;
228 }
229