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