1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2018-2019 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
25 #include "nvport/nvport.h"
26 #include "deprecated/rmapi_deprecated.h"
27
28 #include "class/cl0070.h" // NV01_MEMORY_VIRTUAL/NV01_MEMORY_SYSTEM_DYNAMIC
29
30 #include "ctrl/ctrl0002.h" // NV01_CONTEXT_DMA_FROM_MEMORY
31 #include "ctrl/ctrl2080/ctrl2080i2c.h" // NV2080_CTRL_I2C_ACCESS_PARAMS
32 #include "ctrl/ctrl0000/ctrl0000gpu.h" // NV0000_CTRL_GPU_IDLE_CHANNELS_PARAMS
33 #include "ctrl/ctrl402c.h" // NV40_I2C
34
35 void
RmDeprecatedAllocObject(DEPRECATED_CONTEXT * pContext,NVOS05_PARAMETERS * pArgs)36 RmDeprecatedAllocObject
37 (
38 DEPRECATED_CONTEXT *pContext,
39 NVOS05_PARAMETERS *pArgs
40 )
41 {
42 pArgs->status = pContext->RmAlloc(pContext, pArgs->hRoot, pArgs->hObjectParent,
43 &pArgs->hObjectNew, pArgs->hClass, NULL, 0);
44 }
45
46 void
RmDeprecatedAddVblankCallback(DEPRECATED_CONTEXT * pContext,NVOS61_PARAMETERS * pArgs)47 RmDeprecatedAddVblankCallback
48 (
49 DEPRECATED_CONTEXT *pContext,
50 NVOS61_PARAMETERS *pArgs
51 )
52 {
53 NV_STATUS status;
54
55 if (pArgs->bAdd)
56 {
57 NV_VBLANK_CALLBACK_ALLOCATION_PARAMETERS vblankArgs = {0};
58
59 vblankArgs.pProc = pArgs->pProc;
60 vblankArgs.LogicalHead = pArgs->LogicalHead;
61 vblankArgs.pParm1 = pArgs->pParm1;
62 vblankArgs.pParm2 = pArgs->pParm2;
63
64 status = pContext->RmAlloc(pContext, pArgs->hClient, pArgs->hDevice,
65 &pArgs->hVblank, NV9010_VBLANK_CALLBACK, &vblankArgs, sizeof(vblankArgs));
66 }
67 else
68 {
69 status = pContext->RmFree(pContext, pArgs->hClient, pArgs->hVblank);
70 }
71
72 pArgs->status = status;
73 }
74
75 void
RmDeprecatedAllocContextDma(DEPRECATED_CONTEXT * pContext,NVOS39_PARAMETERS * pArgs)76 RmDeprecatedAllocContextDma
77 (
78 DEPRECATED_CONTEXT *pContext,
79 NVOS39_PARAMETERS *pArgs
80 )
81 {
82 NV_CONTEXT_DMA_ALLOCATION_PARAMS allocParams = {0};
83 NV_STATUS status;
84 NvHandle hCtxDmaParent;
85 NvHandle hClient = pArgs->hObjectParent;
86 NvU32 class;
87
88 //
89 // hMemory parent is used as the parent for the context dma. The legacy
90 // RmAllocContextDma2 unfortunately never took hParent as an argument.
91 //
92 status = RmDeprecatedGetHandleParent(pContext, hClient, pArgs->hMemory, &hCtxDmaParent);
93 if (status != NV_OK)
94 goto done;
95
96 //
97 // A virtual ContextDma of a NV01_MEMORY_SYSTEM_DYNAMIC object is now implemented
98 // directly in the DynamicMemory object. We support allocation on the ContextDma
99 // path for API compatibility.
100 //
101 status = RmDeprecatedGetClassID(pContext, hClient, pArgs->hMemory, &class);
102 if ((status == NV_OK) && (class == NV01_MEMORY_SYSTEM_DYNAMIC))
103 {
104 NV_MEMORY_VIRTUAL_ALLOCATION_PARAMS allocVirtualParams = { 0 };
105
106 // Apply limit
107 allocVirtualParams.offset = pArgs->offset;
108 allocVirtualParams.limit = pArgs->limit;
109
110 // Use default address space for this context
111 allocVirtualParams.hVASpace = 0;
112
113 status = pContext->RmAlloc(pContext, hClient, hCtxDmaParent,
114 &pArgs->hObjectNew,
115 NV01_MEMORY_VIRTUAL,
116 &allocVirtualParams,
117 sizeof(allocVirtualParams));
118 goto done;
119 }
120
121 allocParams.hSubDevice = pArgs->hSubDevice;
122 allocParams.flags = pArgs->flags;
123 allocParams.hMemory = pArgs->hMemory;
124 allocParams.offset = pArgs->offset;
125 allocParams.limit = pArgs->limit;
126
127 status = pContext->RmAlloc(pContext, hClient, hCtxDmaParent,
128 &pArgs->hObjectNew, pArgs->hClass, &allocParams, sizeof(allocParams));
129
130 done:
131 pArgs->status = status;
132 }
133
134 void
RmDeprecatedBindContextDma(DEPRECATED_CONTEXT * pContext,NVOS49_PARAMETERS * pArgs)135 RmDeprecatedBindContextDma
136 (
137 DEPRECATED_CONTEXT *pContext,
138 NVOS49_PARAMETERS *pArgs
139 )
140 {
141 NV0002_CTRL_BIND_CONTEXTDMA_PARAMS bindParams = {0};
142 NV_STATUS status;
143 NvU32 class;
144
145 // Allow ContextDma promoted to DynamicMemory to be silently bound for compatibility
146 status = RmDeprecatedGetClassID(pContext, pArgs->hClient, pArgs->hCtxDma, &class);
147 if ((status == NV_OK) && (class == NV01_MEMORY_SYSTEM_DYNAMIC))
148 {
149 pArgs->status = status;
150 return;
151 }
152
153 bindParams.hChannel = pArgs->hChannel;
154
155 status = pContext->RmControl(pContext, pArgs->hClient, pArgs->hCtxDma, NV0002_CTRL_CMD_BIND_CONTEXTDMA,
156 &bindParams, sizeof(bindParams));
157
158 pArgs->status = status;
159 }
160
161 void
RmDeprecatedI2CAccess(DEPRECATED_CONTEXT * pContext,NVOS_I2C_ACCESS_PARAMS * pArgs)162 RmDeprecatedI2CAccess
163 (
164 DEPRECATED_CONTEXT *pContext,
165 NVOS_I2C_ACCESS_PARAMS *pArgs
166 )
167 {
168 NV_STATUS status = NV_OK;
169 NV_STATUS statusTmp = NV_OK;
170 NV2080_CTRL_I2C_ACCESS_PARAMS *pControlParams = 0;
171 void *pEmbeddedParams = 0;
172 NvP64 orginalEmbeddedPtr = NvP64_NULL;
173 NvHandle hSubDevice;
174 NvBool bMustFreeSubDevice = NV_FALSE;
175
176 // Param can be either a hSubdevice or hDevice, control is on subdevice
177 status = RmDeprecatedFindOrCreateSubDeviceHandle(pContext, pArgs->hClient, pArgs->hDevice,
178 &hSubDevice, &bMustFreeSubDevice);
179 if (status != NV_OK)
180 goto done;
181
182 //
183 // Need to copy fields into local address space (if kernel) before we can
184 // call RmControl. DEPRECATED_CONTEXT::RmControl expects all params to be in
185 // local address space.
186 //
187 status = pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYIN, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
188 pArgs->paramStructPtr, sizeof(NV2080_CTRL_I2C_ACCESS_PARAMS), (void**)&pControlParams);
189 if (status != NV_OK)
190 goto done;
191
192 if (pControlParams->dataBuffSize)
193 {
194 if (pControlParams->dataBuffSize <= NV402C_CTRL_I2C_MESSAGE_LENGTH_MAX)
195 {
196 status = pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYIN, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
197 pControlParams->data, pControlParams->dataBuffSize, &pEmbeddedParams);
198 if (status != NV_OK)
199 goto done;
200
201 orginalEmbeddedPtr = pControlParams->data;
202 pControlParams->data = NV_PTR_TO_NvP64(pEmbeddedParams);
203 }
204 else
205 {
206 // Invalid I2C access datasize, ignore the databuffer
207 // RS-TODO This should return an error, but ignore for now until KMD initializes their params
208 pControlParams->dataBuffSize = 0;
209 pControlParams->data = NvP64_NULL;
210 }
211 }
212
213 status = pContext->RmControl(pContext, pArgs->hClient, hSubDevice, NV2080_CTRL_CMD_I2C_ACCESS,
214 pControlParams, sizeof(NV2080_CTRL_I2C_ACCESS_PARAMS));
215
216 done:
217 if (pEmbeddedParams)
218 {
219 // Restore original value before copy back
220 pControlParams->data = orginalEmbeddedPtr;
221
222 statusTmp = pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYOUT, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
223 pControlParams->data, pControlParams->dataBuffSize, &pEmbeddedParams);
224 if (status == NV_OK)
225 status = statusTmp;
226 }
227
228 if (pControlParams)
229 {
230 statusTmp = pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYOUT, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
231 pArgs->paramStructPtr, sizeof(NV2080_CTRL_I2C_ACCESS_PARAMS), (void **)&pControlParams);
232 if (status == NV_OK)
233 status = statusTmp;
234 }
235
236 if (bMustFreeSubDevice)
237 {
238 pContext->RmFree(pContext, pArgs->hClient, hSubDevice);
239 }
240
241 pArgs->status = status;
242 }
243
244 void
RmDeprecatedIdleChannels(DEPRECATED_CONTEXT * pContext,NVOS30_PARAMETERS * pArgs)245 RmDeprecatedIdleChannels
246 (
247 DEPRECATED_CONTEXT *pContext,
248 NVOS30_PARAMETERS *pArgs
249 )
250 {
251 NV0000_CTRL_GPU_IDLE_CHANNELS_PARAMS params = {0};
252 NV_STATUS status;
253 NvU32 handleBufferSize;
254 void *phClients = 0;
255 void *phDevices = 0;
256 void *phChannels = 0;
257
258 params.hDevice = pArgs->hDevice;
259 params.hChannel = pArgs->hChannel;
260 params.numChannels = pArgs->numChannels;
261 params.flags = pArgs->flags;
262 params.timeout = pArgs->timeout;
263
264 if (!portSafeMulU32(pArgs->numChannels, sizeof(NvU32), &handleBufferSize))
265 {
266 status = NV_ERR_INVALID_ARGUMENT;
267 goto done;
268 }
269
270 // XXX this should have a max - but copying old behavior for now
271 if (DRF_VAL(OS30, _FLAGS, _CHANNEL, pArgs->flags) == NVOS30_FLAGS_CHANNEL_LIST &&
272 params.numChannels)
273 {
274 // Copy-in phClients
275 status = pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYIN, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
276 pArgs->phClients, handleBufferSize, &phClients);
277 if (status != NV_OK)
278 goto done;
279
280 params.phClients = NV_PTR_TO_NvP64(phClients);
281
282 // Copy-in phDevices
283 status = pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYIN, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
284 pArgs->phDevices, handleBufferSize, &phDevices);
285 if (status != NV_OK)
286 goto done;
287
288 params.phDevices = NV_PTR_TO_NvP64(phDevices);
289
290 // Copy-in phChannels
291 status = pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYIN, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
292 pArgs->phChannels, handleBufferSize, &phChannels);
293 if (status != NV_OK)
294 goto done;
295
296 params.phChannels = NV_PTR_TO_NvP64(phChannels);
297 }
298
299 status = pContext->RmControl(pContext, pArgs->hClient, pArgs->hClient,
300 NV0000_CTRL_CMD_IDLE_CHANNELS,
301 ¶ms, sizeof(params));
302
303 done:
304
305 if (phClients)
306 {
307 pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYRELEASE, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
308 pArgs->phClients, handleBufferSize, &phClients);
309 }
310
311 if (phDevices)
312 {
313 pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYRELEASE, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
314 pArgs->phDevices, handleBufferSize, &phDevices);
315 }
316
317 if (phChannels)
318 {
319 pContext->CopyUser(pContext, RMAPI_DEPRECATED_COPYRELEASE, RMAPI_DEPRECATED_BUFFER_ALLOCATE,
320 pArgs->phChannels, handleBufferSize, &phChannels);
321 }
322 pArgs->status = status;
323 }
324