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 #include "deprecated/rmapi_deprecated.h"
24
25 #include "class/cl0080.h" // NV01_DEVICE_0
26 #include "class/cl2080.h" // NV20_SUBDEVICE_0
27 #include "ctrl/ctrl0000/ctrl0000client.h" // NV0000_CTRL_CMD_CLIENT_GET_CHILD_HANDLE
28 #include "ctrl/ctrl0080/ctrl0080gpu.h" // NV0080_CTRL_CMD_GPU_FIND_SUBDEVICE_HANDLE
29 #include "nvos.h"
30
31 #include <stddef.h>
32
33 NV_STATUS
RmDeprecatedGetHandleParent(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hObject,NvHandle * phParent)34 RmDeprecatedGetHandleParent
35 (
36 DEPRECATED_CONTEXT *pContext,
37 NvHandle hClient,
38 NvHandle hObject,
39 NvHandle *phParent
40 )
41 {
42 NV0000_CTRL_CLIENT_GET_HANDLE_INFO_PARAMS parentParams = {0};
43 NV_STATUS status;
44
45 parentParams.hObject = hObject;
46 parentParams.index = NV0000_CTRL_CMD_CLIENT_GET_HANDLE_INFO_INDEX_PARENT;
47
48 status = pContext->RmControl(pContext, hClient, hClient, NV0000_CTRL_CMD_CLIENT_GET_HANDLE_INFO,
49 &parentParams, sizeof(parentParams));
50
51 *phParent = parentParams.data.hResult;
52
53 return status;
54 }
55
56 NV_STATUS
RmDeprecatedGetClassID(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hObject,NvU32 * pClassId)57 RmDeprecatedGetClassID
58 (
59 DEPRECATED_CONTEXT *pContext,
60 NvHandle hClient,
61 NvHandle hObject,
62 NvU32 *pClassId
63 )
64 {
65 NV0000_CTRL_CLIENT_GET_HANDLE_INFO_PARAMS classIdParams = {0};
66 NV_STATUS status;
67
68 classIdParams.hObject = hObject;
69 classIdParams.index = NV0000_CTRL_CMD_CLIENT_GET_HANDLE_INFO_INDEX_CLASSID;
70
71 status = pContext->RmControl(pContext, hClient, hClient,
72 NV0000_CTRL_CMD_CLIENT_GET_HANDLE_INFO,
73 &classIdParams,
74 sizeof(classIdParams));
75
76 *pClassId = NvU64_LO32(classIdParams.data.iResult);
77
78 return status;
79 }
80
81 NV_STATUS
RmDeprecatedFindOrCreateSubDeviceHandle(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvHandle hDeviceOrSubDevice,NvHandle * pHSubDevice,NvBool * pBMustFree)82 RmDeprecatedFindOrCreateSubDeviceHandle
83 (
84 DEPRECATED_CONTEXT *pContext,
85 NvHandle hClient,
86 NvHandle hDeviceOrSubDevice,
87 NvHandle *pHSubDevice,
88 NvBool *pBMustFree
89 )
90 {
91 NV0080_CTRL_GPU_FIND_SUBDEVICE_HANDLE_PARAM findParams = {0};
92 NV_STATUS status;
93 NvU32 classId;
94
95 //
96 // Step 1.) check if we already have a subdevice
97 //
98 status = RmDeprecatedGetClassID(pContext, hClient, hDeviceOrSubDevice, &classId);
99
100 if (status != NV_OK)
101 return status;
102
103 if (classId == NV20_SUBDEVICE_0)
104 {
105 *pBMustFree = NV_FALSE;
106 *pHSubDevice = hDeviceOrSubDevice;
107 return NV_OK;
108 }
109 else if (classId != NV01_DEVICE_0)
110 {
111 return NV_ERR_INVALID_ARGUMENT;
112 }
113
114 //
115 // Step 2.) check if there is a subdevice allocated under this device
116 //
117 findParams.subDeviceInst = 0;
118
119 status = pContext->RmControl(pContext, hClient, hDeviceOrSubDevice,
120 NV0080_CTRL_CMD_GPU_FIND_SUBDEVICE_HANDLE,
121 &findParams,
122 sizeof(findParams));
123
124 if (status == NV_OK && findParams.hSubDevice)
125 {
126 *pBMustFree = NV_FALSE;
127 *pHSubDevice = findParams.hSubDevice;
128 return status;
129 }
130
131 //
132 // Step 3.) if there is no device, we temporarily allocate a subdevice.
133 // Subdevice must be freed before we exit out to allow the client to reserve
134 // it if it chooses to do so later on.
135 //
136 *pBMustFree = NV_TRUE;
137
138 *pHSubDevice = 0;
139
140 status = pContext->RmAlloc(pContext, hClient, hDeviceOrSubDevice, pHSubDevice, NV20_SUBDEVICE_0, NULL, 0);
141
142 return status;
143 }
144
RmDeprecatedGetOrAllocObject(DEPRECATED_CONTEXT * pContext,NvHandle hClient,NvU32 classId,NvHandle * pHObject)145 NV_STATUS RmDeprecatedGetOrAllocObject
146 (
147 DEPRECATED_CONTEXT *pContext,
148 NvHandle hClient,
149 NvU32 classId,
150 NvHandle *pHObject
151 )
152 {
153 NV_STATUS status;
154
155 NV0000_CTRL_CMD_CLIENT_GET_CHILD_HANDLE_PARAMS params = {0};
156 params.hParent = *pHObject;
157 params.classId = classId;
158 status = pContext->RmControl(pContext, hClient, hClient,
159 NV0000_CTRL_CMD_CLIENT_GET_CHILD_HANDLE,
160 ¶ms, sizeof(params));
161 // Object already exists, just return it
162 if (status == NV_OK && params.hObject != 0)
163 {
164 *pHObject = params.hObject;
165 }
166 else
167 {
168 //
169 // Object does not exist yet, allocate.
170 // TODO: Fill alloc params for classes that need them
171 //
172 status = pContext->RmAlloc(pContext, hClient, *pHObject,
173 pHObject, classId, NULL, 0);
174 }
175 return status;
176 }
177
178 NV_STATUS
RmDeprecatedConvertOs32ToOs02Flags(NvU32 attr,NvU32 attr2,NvU32 os32Flags,NvU32 * pOs02Flags)179 RmDeprecatedConvertOs32ToOs02Flags
180 (
181 NvU32 attr,
182 NvU32 attr2,
183 NvU32 os32Flags,
184 NvU32 *pOs02Flags
185 )
186 {
187 NvU32 os02Flags = 0;
188 NV_STATUS rmStatus = NV_OK;
189
190 switch (DRF_VAL(OS32, _ATTR, _PHYSICALITY, attr))
191 {
192 case NVOS32_ATTR_PHYSICALITY_DEFAULT: // NVOS02 defaults to contiguous.
193 case NVOS32_ATTR_PHYSICALITY_CONTIGUOUS:
194 {
195 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _PHYSICALITY, _CONTIGUOUS, os02Flags);
196 break;
197 }
198 case NVOS32_ATTR_PHYSICALITY_NONCONTIGUOUS:
199 {
200 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _PHYSICALITY, _NONCONTIGUOUS, os02Flags);
201 break;
202 }
203 default:
204 {
205 rmStatus = NV_ERR_INVALID_FLAGS;
206 break;
207 }
208 }
209
210 switch (DRF_VAL(OS32, _ATTR, _LOCATION, attr))
211 {
212 case NVOS32_ATTR_LOCATION_PCI:
213 case NVOS32_ATTR_LOCATION_ANY: // NVOS02 defaults to PCI
214 {
215 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _LOCATION, _PCI, os02Flags);
216 break;
217 }
218 case NVOS32_ATTR_LOCATION_AGP:
219 {
220 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _LOCATION, _AGP, os02Flags);
221 break;
222 }
223 case NVOS32_ATTR_LOCATION_VIDMEM:
224 {
225 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _LOCATION, _VIDMEM, os02Flags);
226 break;
227 }
228 default:
229 {
230 rmStatus = NV_ERR_INVALID_FLAGS;
231 break;
232 }
233 }
234
235 switch (DRF_VAL(OS32, _ATTR, _COHERENCY, attr))
236 {
237 case NVOS32_ATTR_COHERENCY_UNCACHED:
238 {
239 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _COHERENCY, _UNCACHED, os02Flags);
240 break;
241 }
242 case NVOS32_ATTR_COHERENCY_CACHED:
243 {
244 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _COHERENCY, _CACHED, os02Flags);
245 break;
246 }
247 case NVOS32_ATTR_COHERENCY_WRITE_COMBINE:
248 {
249 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _COHERENCY, _WRITE_COMBINE, os02Flags);
250 break;
251 }
252 case NVOS32_ATTR_COHERENCY_WRITE_THROUGH:
253 {
254 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _COHERENCY, _WRITE_THROUGH, os02Flags);
255 break;
256 }
257 case NVOS32_ATTR_COHERENCY_WRITE_PROTECT:
258 {
259 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _COHERENCY, _WRITE_PROTECT, os02Flags);
260 break;
261 }
262 case NVOS32_ATTR_COHERENCY_WRITE_BACK:
263 {
264 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _COHERENCY, _WRITE_BACK, os02Flags);
265 break;
266 }
267 default:
268 {
269 rmStatus = NV_ERR_INVALID_FLAGS;
270 break;
271 }
272 }
273
274 switch (DRF_VAL(OS32, _ATTR2, _GPU_CACHEABLE, attr2))
275 {
276 case NVOS32_ATTR2_GPU_CACHEABLE_YES:
277 {
278 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _GPU_CACHEABLE, _YES, os02Flags);
279 break;
280 }
281 case NVOS32_ATTR2_GPU_CACHEABLE_DEFAULT: // NVOS02 defaults to non-cacheable
282 case NVOS32_ATTR2_GPU_CACHEABLE_NO:
283 {
284 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _GPU_CACHEABLE, _NO, os02Flags);
285 break;
286 }
287 default:
288 {
289 rmStatus = NV_ERR_INVALID_FLAGS;
290 break;
291 }
292 }
293
294 switch (DRF_VAL(OS32, _ATTR2, _REGISTER_MEMDESC_TO_PHYS_RM, attr2))
295 {
296 case NVOS32_ATTR2_REGISTER_MEMDESC_TO_PHYS_RM_TRUE:
297 {
298 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _REGISTER_MEMDESC_TO_PHYS_RM, _TRUE, os02Flags);
299 break;
300 }
301 case NVOS32_ATTR2_REGISTER_MEMDESC_TO_PHYS_RM_FALSE:
302 {
303 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _REGISTER_MEMDESC_TO_PHYS_RM, _FALSE, os02Flags);
304 break;
305 }
306 default:
307 {
308 rmStatus = NV_ERR_INVALID_FLAGS;
309 break;
310 }
311 }
312
313 // VidHeapControl never creates a mapping
314 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _MAPPING, _NO_MAP, os02Flags);
315 if (os32Flags & NVOS32_ALLOC_FLAGS_KERNEL_MAPPING_MAP)
316 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _KERNEL_MAPPING, _MAP, os02Flags);
317 else
318 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _KERNEL_MAPPING, _NO_MAP, os02Flags);
319
320 if (FLD_TEST_DRF(OS32, _ATTR2, _PROTECTION_USER, _READ_ONLY, attr2))
321 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _ALLOC_USER_READ_ONLY, _YES, os02Flags);
322
323 if (FLD_TEST_DRF(OS32, _ATTR2, _PROTECTION_DEVICE, _READ_ONLY, attr2))
324 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _ALLOC_DEVICE_READ_ONLY, _YES, os02Flags);
325
326 if (FLD_TEST_DRF(OS32, _ATTR2, _NISO_DISPLAY, _YES, attr2))
327 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _ALLOC_NISO_DISPLAY, _YES, os02Flags);
328 else
329 os02Flags = FLD_SET_DRF(OS02, _FLAGS, _ALLOC_NISO_DISPLAY, _NO, os02Flags);
330
331 if (rmStatus == NV_OK)
332 {
333 *pOs02Flags = os02Flags;
334 }
335
336 return rmStatus;
337 }
338
339 NV_STATUS
RmDeprecatedConvertOs02ToOs32Flags(NvU32 os02Flags,NvU32 * pAttr,NvU32 * pAttr2,NvU32 * pOs32Flags)340 RmDeprecatedConvertOs02ToOs32Flags
341 (
342 NvU32 os02Flags,
343 NvU32 *pAttr,
344 NvU32 *pAttr2,
345 NvU32 *pOs32Flags
346 )
347 {
348 NvU32 os32Flags = 0;
349 NvU32 attr = 0, attr2 = 0;
350 NV_STATUS rmStatus = NV_OK;
351
352 attr = FLD_SET_DRF(OS32, _ATTR, _PAGE_SIZE, _DEFAULT, attr);
353
354 if (FLD_TEST_DRF(OS02, _FLAGS, _PHYSICALITY, _CONTIGUOUS, os02Flags))
355 attr = FLD_SET_DRF(OS32, _ATTR, _PHYSICALITY, _CONTIGUOUS, attr);
356 else
357 attr = FLD_SET_DRF(OS32, _ATTR, _PHYSICALITY, _NONCONTIGUOUS, attr);
358
359 switch (DRF_VAL(OS02, _FLAGS, _LOCATION, os02Flags))
360 {
361 case NVOS02_FLAGS_LOCATION_PCI:
362 {
363 attr = FLD_SET_DRF(OS32, _ATTR, _LOCATION, _PCI, attr);
364 break;
365 }
366 case NVOS02_FLAGS_LOCATION_VIDMEM:
367 {
368 attr = FLD_SET_DRF(OS32, _ATTR, _LOCATION, _VIDMEM, attr);
369 break;
370 }
371 default:
372 {
373 rmStatus = NV_ERR_INVALID_FLAGS;
374 break;
375 }
376 }
377
378 switch (DRF_VAL(OS02, _FLAGS, _COHERENCY, os02Flags))
379 {
380 case NVOS02_FLAGS_COHERENCY_UNCACHED:
381 {
382 attr = FLD_SET_DRF(OS32, _ATTR, _COHERENCY, _UNCACHED, attr);
383 break;
384 }
385 case NVOS02_FLAGS_COHERENCY_CACHED:
386 {
387 attr = FLD_SET_DRF(OS32, _ATTR, _COHERENCY, _CACHED, attr);
388 break;
389 }
390 case NVOS02_FLAGS_COHERENCY_WRITE_COMBINE:
391 {
392 attr = FLD_SET_DRF(OS32, _ATTR, _COHERENCY, _WRITE_COMBINE, attr);
393 break;
394 }
395 case NVOS02_FLAGS_COHERENCY_WRITE_THROUGH:
396 {
397 attr = FLD_SET_DRF(OS32, _ATTR, _COHERENCY, _WRITE_THROUGH, attr);
398 break;
399 }
400 case NVOS02_FLAGS_COHERENCY_WRITE_PROTECT:
401 {
402 attr = FLD_SET_DRF(OS32, _ATTR, _COHERENCY, _WRITE_PROTECT, attr);
403 break;
404 }
405 case NVOS02_FLAGS_COHERENCY_WRITE_BACK:
406 {
407 attr = FLD_SET_DRF(OS32, _ATTR, _COHERENCY, _WRITE_BACK, attr);
408 break;
409 }
410 default:
411 {
412 rmStatus = NV_ERR_INVALID_FLAGS;
413 break;
414 }
415 }
416
417 if (FLD_TEST_DRF(OS02, _FLAGS, _GPU_CACHEABLE, _YES, os02Flags))
418 attr2 |= DRF_DEF(OS32, _ATTR2, _GPU_CACHEABLE, _YES);
419 else
420 attr2 |= DRF_DEF(OS32, _ATTR2, _GPU_CACHEABLE, _NO);
421
422 if (FLD_TEST_DRF(OS02, _FLAGS, _KERNEL_MAPPING, _MAP, os02Flags))
423 os32Flags |= NVOS32_ALLOC_FLAGS_KERNEL_MAPPING_MAP;
424
425 if (FLD_TEST_DRF(OS02, _FLAGS, _ALLOC_NISO_DISPLAY, _YES, os02Flags))
426 attr2 |= DRF_DEF(OS32, _ATTR2, _NISO_DISPLAY, _YES);
427 else
428 attr2 |= DRF_DEF(OS32, _ATTR2, _NISO_DISPLAY, _NO);
429
430 if (FLD_TEST_DRF(OS02, _FLAGS, _ALLOC_USER_READ_ONLY, _YES, os02Flags))
431 attr2 |= DRF_DEF(OS32, _ATTR2, _PROTECTION_USER, _READ_ONLY);
432
433 if (FLD_TEST_DRF(OS02, _FLAGS, _ALLOC_DEVICE_READ_ONLY, _YES, os02Flags))
434 attr2 |= DRF_DEF(OS32, _ATTR2, _PROTECTION_DEVICE, _READ_ONLY);
435
436 if (FLD_TEST_DRF(OS02, _FLAGS, _REGISTER_MEMDESC_TO_PHYS_RM, _TRUE, os02Flags))
437 attr2 |= DRF_DEF(OS32, _ATTR2, _REGISTER_MEMDESC_TO_PHYS_RM, _TRUE);
438 else
439 attr2 |= DRF_DEF(OS32, _ATTR2, _REGISTER_MEMDESC_TO_PHYS_RM, _FALSE);
440
441 if (rmStatus == NV_OK)
442 {
443 *pOs32Flags = os32Flags;
444 *pAttr = attr;
445 *pAttr2 = attr2;
446 }
447
448 return rmStatus;
449 }
450