summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'omap5/sgx_src/eurasia_km/services4/srvkm/bridged/bridged_pvr_bridge.c')
-rw-r--r--omap5/sgx_src/eurasia_km/services4/srvkm/bridged/bridged_pvr_bridge.c5512
1 files changed, 0 insertions, 5512 deletions
diff --git a/omap5/sgx_src/eurasia_km/services4/srvkm/bridged/bridged_pvr_bridge.c b/omap5/sgx_src/eurasia_km/services4/srvkm/bridged/bridged_pvr_bridge.c
deleted file mode 100644
index d98a71c..0000000
--- a/omap5/sgx_src/eurasia_km/services4/srvkm/bridged/bridged_pvr_bridge.c
+++ /dev/null
@@ -1,5512 +0,0 @@
1/*************************************************************************/ /*!
2@Title PVR Common Bridge Module (kernel side)
3@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
4@Description Receives calls from the user portion of services and
5 despatches them to functions in the kernel portion.
6@License Dual MIT/GPLv2
7
8The contents of this file are subject to the MIT license as set out below.
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in
18all copies or substantial portions of the Software.
19
20Alternatively, the contents of this file may be used under the terms of
21the GNU General Public License Version 2 ("GPL") in which case the provisions
22of GPL are applicable instead of those above.
23
24If you wish to allow use of your version of this file only under the terms of
25GPL, and not to allow others to use your version of this file under the terms
26of the MIT license, indicate your decision by deleting the provisions above
27and replace them with the notice and other provisions required by GPL as set
28out in the file called "GPL-COPYING" included in this distribution. If you do
29not delete the provisions above, a recipient may use your version of this file
30under the terms of either the MIT license or GPL.
31
32This License is also included in this distribution in the file called
33"MIT-COPYING".
34
35EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
36PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
37BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
39COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
40IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42*/ /**************************************************************************/
43
44
45
46#include <stddef.h>
47
48#include "img_defs.h"
49#include "services.h"
50#include "pvr_bridge_km.h"
51#include "pvr_debug.h"
52#include "ra.h"
53#include "pvr_bridge.h"
54#if defined(SUPPORT_SGX)
55#include "sgx_bridge.h"
56#endif
57#if defined(SUPPORT_VGX)
58#include "vgx_bridge.h"
59#endif
60#if defined(SUPPORT_MSVDX)
61#include "msvdx_bridge.h"
62#endif
63#include "perproc.h"
64#include "device.h"
65#include "buffer_manager.h"
66#include "refcount.h"
67
68#include "pdump_km.h"
69#include "syscommon.h"
70
71#include "bridged_pvr_bridge.h"
72#if defined(SUPPORT_SGX)
73#include "bridged_sgx_bridge.h"
74#endif
75#if defined(SUPPORT_VGX)
76#include "bridged_vgx_bridge.h"
77#endif
78#if defined(SUPPORT_MSVDX)
79#include "bridged_msvdx_bridge.h"
80#endif
81
82#include "env_data.h"
83
84#if defined (__linux__) || defined(__QNXNTO__)
85#include "mmap.h"
86#endif
87
88
89#include "srvkm.h"
90
91/* FIXME: we should include an OS specific header here to allow configuration of
92 * which functions should be excluded (like the shared srvclient bridge code)
93 * so that ports may choose to override certain things. */
94
95/* For the purpose of maintainability, it is intended that this file should not
96 * contain large amounts of OS specific #ifdefs. Headers are fine, and perhaps
97 * a few one liners, but for anything more, please find a way to add e.g.
98 * an osfunc.c abstraction or override the entire function in question within
99 * env,*,pvr_bridge_k.c
100 */
101
102
103PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
104
105#if defined(DEBUG_BRIDGE_KM)
106PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
107#endif
108
109#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
110static IMG_BOOL abSharedDeviceMemHeap[PVRSRV_MAX_CLIENT_HEAPS];
111static IMG_BOOL *pbSharedDeviceMemHeap = abSharedDeviceMemHeap;
112#else
113static IMG_BOOL *pbSharedDeviceMemHeap = (IMG_BOOL*)IMG_NULL;
114#endif
115
116
117#if defined(DEBUG_BRIDGE_KM)
118PVRSRV_ERROR
119CopyFromUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
120 IMG_UINT32 ui32BridgeID,
121 IMG_VOID *pvDest,
122 IMG_VOID *pvSrc,
123 IMG_UINT32 ui32Size)
124{
125 g_BridgeDispatchTable[ui32BridgeID].ui32CopyFromUserTotalBytes+=ui32Size;
126 g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+=ui32Size;
127 return OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size);
128}
129PVRSRV_ERROR
130CopyToUserWrapper(PVRSRV_PER_PROCESS_DATA *pProcData,
131 IMG_UINT32 ui32BridgeID,
132 IMG_VOID *pvDest,
133 IMG_VOID *pvSrc,
134 IMG_UINT32 ui32Size)
135{
136 g_BridgeDispatchTable[ui32BridgeID].ui32CopyToUserTotalBytes+=ui32Size;
137 g_BridgeGlobalStats.ui32TotalCopyToUserBytes+=ui32Size;
138 return OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size);
139}
140#endif
141
142
143static IMG_INT
144PVRSRVEnumerateDevicesBW(IMG_UINT32 ui32BridgeID,
145 IMG_VOID *psBridgeIn,
146 PVRSRV_BRIDGE_OUT_ENUMDEVICE *psEnumDeviceOUT,
147 PVRSRV_PER_PROCESS_DATA *psPerProc)
148{
149 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DEVICES);
150
151 PVR_UNREFERENCED_PARAMETER(psPerProc);
152 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
153
154 psEnumDeviceOUT->eError =
155 PVRSRVEnumerateDevicesKM(&psEnumDeviceOUT->ui32NumDevices,
156 psEnumDeviceOUT->asDeviceIdentifier);
157
158 return 0;
159}
160
161static IMG_INT
162PVRSRVAcquireDeviceDataBW(IMG_UINT32 ui32BridgeID,
163 PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO *psAcquireDevInfoIN,
164 PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO *psAcquireDevInfoOUT,
165 PVRSRV_PER_PROCESS_DATA *psPerProc)
166{
167 IMG_HANDLE hDevCookieInt;
168
169 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO);
170
171 psAcquireDevInfoOUT->eError =
172 PVRSRVAcquireDeviceDataKM(psAcquireDevInfoIN->uiDevIndex,
173 psAcquireDevInfoIN->eDeviceType,
174 &hDevCookieInt);
175 if(psAcquireDevInfoOUT->eError != PVRSRV_OK)
176 {
177 return 0;
178 }
179
180 /*
181 * Handle is not allocated in batch mode, as there is no resource
182 * allocation to undo if the handle allocation fails.
183 */
184 psAcquireDevInfoOUT->eError =
185 PVRSRVAllocHandle(psPerProc->psHandleBase,
186 &psAcquireDevInfoOUT->hDevCookie,
187 hDevCookieInt,
188 PVRSRV_HANDLE_TYPE_DEV_NODE,
189 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
190
191 return 0;
192}
193
194
195static IMG_INT
196PVRSRVCreateDeviceMemContextBW(IMG_UINT32 ui32BridgeID,
197 PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT *psCreateDevMemContextIN,
198 PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT *psCreateDevMemContextOUT,
199 PVRSRV_PER_PROCESS_DATA *psPerProc)
200{
201 IMG_HANDLE hDevCookieInt;
202 IMG_HANDLE hDevMemContextInt;
203 IMG_UINT32 i;
204 IMG_BOOL bCreated;
205#if defined (SUPPORT_SID_INTERFACE)
206 PVRSRV_HEAP_INFO_KM asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
207#endif
208
209 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT);
210
211 /*
212 * We potentially need one handle for the device memory context,
213 * and one handle for each client heap.
214 */
215 NEW_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS + 1)
216
217 psCreateDevMemContextOUT->eError =
218 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
219 psCreateDevMemContextIN->hDevCookie,
220 PVRSRV_HANDLE_TYPE_DEV_NODE);
221
222 if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
223 {
224 return 0;
225 }
226
227 psCreateDevMemContextOUT->eError =
228 PVRSRVCreateDeviceMemContextKM(hDevCookieInt,
229 psPerProc,
230 &hDevMemContextInt,
231 &psCreateDevMemContextOUT->ui32ClientHeapCount,
232#if defined (SUPPORT_SID_INTERFACE)
233 &asHeapInfo[0],
234#else
235 &psCreateDevMemContextOUT->sHeapInfo[0],
236#endif
237 &bCreated,
238 pbSharedDeviceMemHeap);
239
240 if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
241 {
242 return 0;
243 }
244
245 /*
246 * Only allocate a handle if the device memory context was created.
247 * If an existing context was returned, lookup the existing
248 * handle.
249 */
250 if(bCreated)
251 {
252 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
253 &psCreateDevMemContextOUT->hDevMemContext,
254 hDevMemContextInt,
255 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT,
256 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
257 }
258 else
259 {
260 psCreateDevMemContextOUT->eError =
261 PVRSRVFindHandle(psPerProc->psHandleBase,
262 &psCreateDevMemContextOUT->hDevMemContext,
263 hDevMemContextInt,
264 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
265 if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
266 {
267 return 0;
268 }
269 }
270
271 for(i = 0; i < psCreateDevMemContextOUT->ui32ClientHeapCount; i++)
272 {
273#if defined (SUPPORT_SID_INTERFACE)
274 IMG_SID hDevMemHeapExt;
275#else
276 IMG_HANDLE hDevMemHeapExt;
277#endif
278
279#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
280 if(abSharedDeviceMemHeap[i])
281#endif
282 {
283 /*
284 * Heaps shared by everybody. These heaps are not
285 * created as part of the device memory context
286 * creation, and exist for the lifetime of the
287 * driver, hence, we use shared handles for these
288 * heaps.
289 */
290#if defined (SUPPORT_SID_INTERFACE)
291 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
292 &hDevMemHeapExt,
293 asHeapInfo[i].hDevMemHeap,
294 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
295 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
296#else
297 PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
298 psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
299 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
300 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
301#endif
302 }
303#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
304 else
305 {
306 /*
307 * Heaps belonging to this context. The handles for
308 * these are made subhandles of the memory context
309 * handle, so that they are automatically deallocated
310 * when the memory context handle is deallocated.
311 */
312 if(bCreated)
313 {
314#if defined (SUPPORT_SID_INTERFACE)
315 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
316 &hDevMemHeapExt,
317 asHeapInfo[i].hDevMemHeap,
318 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
319 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
320 psCreateDevMemContextOUT->hDevMemContext);
321#else
322 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
323 psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
324 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
325 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
326 psCreateDevMemContextOUT->hDevMemContext);
327#endif
328 }
329 else
330 {
331 psCreateDevMemContextOUT->eError =
332 PVRSRVFindHandle(psPerProc->psHandleBase,
333 &hDevMemHeapExt,
334#if defined (SUPPORT_SID_INTERFACE)
335 asHeapInfo[i].hDevMemHeap,
336#else
337 psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap,
338#endif
339 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
340 if(psCreateDevMemContextOUT->eError != PVRSRV_OK)
341 {
342 return 0;
343 }
344 }
345 }
346#endif
347 psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
348#if defined (SUPPORT_SID_INTERFACE)
349 psCreateDevMemContextOUT->sHeapInfo[i].ui32HeapID = asHeapInfo[i].ui32HeapID;
350 psCreateDevMemContextOUT->sHeapInfo[i].sDevVAddrBase = asHeapInfo[i].sDevVAddrBase;
351 psCreateDevMemContextOUT->sHeapInfo[i].ui32HeapByteSize = asHeapInfo[i].ui32HeapByteSize;
352 psCreateDevMemContextOUT->sHeapInfo[i].ui32Attribs = asHeapInfo[i].ui32Attribs;
353 psCreateDevMemContextOUT->sHeapInfo[i].ui32XTileStride = asHeapInfo[i].ui32XTileStride;
354#endif
355 }
356
357 COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc)
358
359 return 0;
360}
361
362static IMG_INT
363PVRSRVDestroyDeviceMemContextBW(IMG_UINT32 ui32BridgeID,
364 PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT *psDestroyDevMemContextIN,
365 PVRSRV_BRIDGE_RETURN *psRetOUT,
366 PVRSRV_PER_PROCESS_DATA *psPerProc)
367{
368 IMG_HANDLE hDevCookieInt;
369 IMG_HANDLE hDevMemContextInt;
370 IMG_BOOL bDestroyed;
371
372 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT);
373
374 psRetOUT->eError =
375 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
376 psDestroyDevMemContextIN->hDevCookie,
377 PVRSRV_HANDLE_TYPE_DEV_NODE);
378
379 if(psRetOUT->eError != PVRSRV_OK)
380 {
381 return 0;
382 }
383
384 psRetOUT->eError =
385 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
386 psDestroyDevMemContextIN->hDevMemContext,
387 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
388
389 if(psRetOUT->eError != PVRSRV_OK)
390 {
391 return 0;
392 }
393
394 psRetOUT->eError =
395 PVRSRVDestroyDeviceMemContextKM(hDevCookieInt, hDevMemContextInt, &bDestroyed);
396
397 if(psRetOUT->eError != PVRSRV_OK)
398 {
399 return 0;
400 }
401
402 if(bDestroyed)
403 {
404 psRetOUT->eError =
405 PVRSRVReleaseHandle(psPerProc->psHandleBase,
406 psDestroyDevMemContextIN->hDevMemContext,
407 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
408 }
409
410 return 0;
411}
412
413
414static IMG_INT
415PVRSRVGetDeviceMemHeapInfoBW(IMG_UINT32 ui32BridgeID,
416 PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoIN,
417 PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoOUT,
418 PVRSRV_PER_PROCESS_DATA *psPerProc)
419{
420 IMG_HANDLE hDevCookieInt;
421 IMG_HANDLE hDevMemContextInt;
422 IMG_UINT32 i;
423#if defined (SUPPORT_SID_INTERFACE)
424 PVRSRV_HEAP_INFO_KM asHeapInfo[PVRSRV_MAX_CLIENT_HEAPS];
425#endif
426
427 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO);
428
429 NEW_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc, PVRSRV_MAX_CLIENT_HEAPS)
430
431 psGetDevMemHeapInfoOUT->eError =
432 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
433 psGetDevMemHeapInfoIN->hDevCookie,
434 PVRSRV_HANDLE_TYPE_DEV_NODE);
435
436 if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
437 {
438 return 0;
439 }
440
441 psGetDevMemHeapInfoOUT->eError =
442 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
443 psGetDevMemHeapInfoIN->hDevMemContext,
444 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
445
446 if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
447 {
448 return 0;
449 }
450
451 psGetDevMemHeapInfoOUT->eError =
452 PVRSRVGetDeviceMemHeapInfoKM(hDevCookieInt,
453 hDevMemContextInt,
454 &psGetDevMemHeapInfoOUT->ui32ClientHeapCount,
455#if defined (SUPPORT_SID_INTERFACE)
456 &asHeapInfo[0],
457#else
458 &psGetDevMemHeapInfoOUT->sHeapInfo[0],
459#endif
460 pbSharedDeviceMemHeap);
461
462 if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
463 {
464 return 0;
465 }
466
467 for(i = 0; i < psGetDevMemHeapInfoOUT->ui32ClientHeapCount; i++)
468 {
469#if defined (SUPPORT_SID_INTERFACE)
470 IMG_SID hDevMemHeapExt;
471#else
472 IMG_HANDLE hDevMemHeapExt;
473#endif
474
475#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
476 if(abSharedDeviceMemHeap[i])
477#endif
478 {
479 /*
480 * Heaps shared by everybody. These heaps are not
481 * created as part of the device memory context
482 * creation, and exist for the lifetime of the
483 * driver, hence, we use shared handles for these
484 * heaps.
485 */
486#if defined (SUPPORT_SID_INTERFACE)
487 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
488 &hDevMemHeapExt,
489 asHeapInfo[i].hDevMemHeap,
490 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
491 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
492#else
493 PVRSRVAllocHandleNR(psPerProc->psHandleBase, &hDevMemHeapExt,
494 psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
495 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
496 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
497#endif
498 }
499#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
500 else
501 {
502 /*
503 * Heaps belonging to this context. The handles for
504 * these are made subhandles of the memory context
505 * handle, so that they are automatically deallocated
506 * when the memory context handle is deallocated.
507 */
508 psGetDevMemHeapInfoOUT->eError =
509 PVRSRVFindHandle(psPerProc->psHandleBase,
510 &hDevMemHeapExt,
511#if defined (SUPPORT_SID_INTERFACE)
512 asHeapInfo[i].hDevMemHeap,
513#else
514 psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
515#endif
516 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
517 if(psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
518 {
519 return 0;
520 }
521 }
522#endif
523 psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap = hDevMemHeapExt;
524#if defined (SUPPORT_SID_INTERFACE)
525 psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32HeapID = asHeapInfo[i].ui32HeapID;
526 psGetDevMemHeapInfoOUT->sHeapInfo[i].sDevVAddrBase = asHeapInfo[i].sDevVAddrBase;
527 psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32HeapByteSize = asHeapInfo[i].ui32HeapByteSize;
528 psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32Attribs = asHeapInfo[i].ui32Attribs;
529 psGetDevMemHeapInfoOUT->sHeapInfo[i].ui32XTileStride = asHeapInfo[i].ui32XTileStride;
530#endif
531 }
532
533 COMMIT_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc)
534
535 return 0;
536}
537
538
539#if defined(OS_PVRSRV_ALLOC_DEVICE_MEM_BW)
540/* customised version */
541IMG_INT
542PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID,
543 PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN,
544 PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT,
545 PVRSRV_PER_PROCESS_DATA *psPerProc);
546#else
547static IMG_INT
548PVRSRVAllocDeviceMemBW(IMG_UINT32 ui32BridgeID,
549 PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN,
550 PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT,
551 PVRSRV_PER_PROCESS_DATA *psPerProc)
552{
553 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
554 IMG_HANDLE hDevCookieInt;
555 IMG_HANDLE hDevMemHeapInt;
556 IMG_UINT32 ui32ShareIndex;
557 IMG_BOOL bUseShareMemWorkaround;
558 IMG_BOOL *pabMapChunk = IMG_NULL;
559
560 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_DEVICEMEM);
561
562 NEW_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc, 2)
563
564 /* Do same sanity checking */
565 if (psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_SPARSE)
566 {
567 if (psAllocDeviceMemIN->ui32NumPhysChunks > psAllocDeviceMemIN->ui32NumVirtChunks)
568 {
569 PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: more physical chunks then virtual space"));
570 psAllocDeviceMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
571 return 0;
572 }
573
574 if (psAllocDeviceMemIN->pabMapChunk == IMG_NULL)
575 {
576 PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: Called in sparse mapping mode but without MapChunk array"));
577 psAllocDeviceMemOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
578 return 0;
579 }
580 }
581
582 psAllocDeviceMemOUT->eError =
583 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
584 psAllocDeviceMemIN->hDevCookie,
585 PVRSRV_HANDLE_TYPE_DEV_NODE);
586
587 if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
588 {
589 return 0;
590 }
591
592 psAllocDeviceMemOUT->eError =
593 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemHeapInt,
594 psAllocDeviceMemIN->hDevMemHeap,
595 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
596
597 if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
598 {
599 return 0;
600 }
601
602 /* Memory sharing workaround, version 2 */
603
604 bUseShareMemWorkaround = ((psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_XPROC) != 0) ? IMG_TRUE : IMG_FALSE;
605 ui32ShareIndex = 7654321; /* stops MSVC compiler warning */
606
607 if (bUseShareMemWorkaround)
608 {
609 /* allocate a shared-surface ID, prior to the call to AllocDeviceMem */
610 /* We could plumb in an extra argument, but for now, we'll keep the
611 shared-surface ID as a piece of global state, and rely upon the
612 bridge mutex to make it safe for us */
613
614 psAllocDeviceMemOUT->eError =
615 BM_XProcWorkaroundFindNewBufferAndSetShareIndex(&ui32ShareIndex);
616 if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
617 {
618 return 0;
619 }
620 }
621
622 /* Check access to private data, if provided */
623 if(psAllocDeviceMemIN->pvPrivData)
624 {
625 if(!OSAccessOK(PVR_VERIFY_READ,
626 psAllocDeviceMemIN->pvPrivData,
627 psAllocDeviceMemIN->ui32PrivDataLength))
628 {
629 PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: Access check failed for pvPrivData"));
630 return -EFAULT;
631 }
632 }
633
634 if (psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_SPARSE)
635 {
636 /* Check access to the sparse mapping table, if provided */
637 if(!OSAccessOK(PVR_VERIFY_READ,
638 psAllocDeviceMemIN->pabMapChunk,
639 psAllocDeviceMemIN->ui32NumVirtChunks))
640 {
641 PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocDeviceMemBW: Access check failed for pabMapChunk"));
642 return -EFAULT;
643 }
644
645 psAllocDeviceMemOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
646 sizeof(IMG_BOOL) * psAllocDeviceMemIN->ui32NumVirtChunks,
647 (IMG_VOID **) &pabMapChunk,
648 0,
649 "MapChunk kernel copy");
650 if (psAllocDeviceMemOUT->eError != PVRSRV_OK)
651 {
652 return 0;
653 }
654
655 psAllocDeviceMemOUT->eError = OSCopyFromUser(psPerProc,
656 pabMapChunk,
657 psAllocDeviceMemIN->pabMapChunk,
658 sizeof(IMG_BOOL) * psAllocDeviceMemIN->ui32NumVirtChunks);
659 if (psAllocDeviceMemOUT->eError != PVRSRV_OK)
660 {
661 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
662 sizeof(IMG_BOOL) * psAllocDeviceMemIN->ui32NumVirtChunks,
663 pabMapChunk,
664 0);
665 return 0;
666 }
667 }
668
669
670 psAllocDeviceMemOUT->eError =
671 PVRSRVAllocDeviceMemKM(hDevCookieInt,
672 psPerProc,
673 hDevMemHeapInt,
674 psAllocDeviceMemIN->ui32Attribs,
675 psAllocDeviceMemIN->ui32Size,
676 psAllocDeviceMemIN->ui32Alignment,
677 psAllocDeviceMemIN->pvPrivData,
678 psAllocDeviceMemIN->ui32PrivDataLength,
679 psAllocDeviceMemIN->ui32ChunkSize,
680 psAllocDeviceMemIN->ui32NumVirtChunks,
681 psAllocDeviceMemIN->ui32NumPhysChunks,
682 pabMapChunk,
683 &psMemInfo,
684 "" /*FIXME: add something meaningful*/);
685
686 /* Allow mapping this buffer to the GC MMU only on allocation time, if
687 * this buffer is mapped into another process context we don't want the
688 * GC MMU mapping to happen.
689 */
690 psAllocDeviceMemIN->ui32Attribs &= ~PVRSRV_MAP_GC_MMU;
691
692 if (bUseShareMemWorkaround)
693 {
694 PVR_ASSERT(ui32ShareIndex != 7654321);
695 BM_XProcWorkaroundUnsetShareIndex(ui32ShareIndex);
696 }
697
698 if(psAllocDeviceMemOUT->eError != PVRSRV_OK)
699 {
700 return 0;
701 }
702
703 psMemInfo->sShareMemWorkaround.bInUse = bUseShareMemWorkaround;
704 if (bUseShareMemWorkaround)
705 {
706 PVR_ASSERT(ui32ShareIndex != 7654321);
707 psMemInfo->sShareMemWorkaround.ui32ShareIndex = ui32ShareIndex;
708 psMemInfo->sShareMemWorkaround.hDevCookieInt = hDevCookieInt;
709 psMemInfo->sShareMemWorkaround.ui32OrigReqAttribs = psAllocDeviceMemIN->ui32Attribs;
710 psMemInfo->sShareMemWorkaround.ui32OrigReqSize = (IMG_UINT32)psAllocDeviceMemIN->ui32Size;
711 psMemInfo->sShareMemWorkaround.ui32OrigReqAlignment = (IMG_UINT32)psAllocDeviceMemIN->ui32Alignment;
712 }
713
714 OSMemSet(&psAllocDeviceMemOUT->sClientMemInfo,
715 0,
716 sizeof(psAllocDeviceMemOUT->sClientMemInfo));
717
718 psAllocDeviceMemOUT->sClientMemInfo.pvLinAddrKM =
719 psMemInfo->pvLinAddrKM;
720
721#if defined (__linux__)
722 psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = 0;
723#else
724 psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = psMemInfo->pvLinAddrKM;
725#endif
726 psAllocDeviceMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
727 psAllocDeviceMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
728 psAllocDeviceMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize;
729 OSMemCopy(psAllocDeviceMemOUT->sClientMemInfo.planeOffsets, psMemInfo->planeOffsets,
730 sizeof(psMemInfo->planeOffsets));
731#if defined (SUPPORT_SID_INTERFACE)
732 /* see below */
733#else
734 psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
735#endif
736
737 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
738 &psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo,
739 psMemInfo,
740 PVRSRV_HANDLE_TYPE_MEM_INFO,
741 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
742
743#if defined (SUPPORT_SID_INTERFACE)
744 PVR_ASSERT(psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo != 0);
745
746 if (psMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
747 {
748 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
749 &psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo,
750 psMemInfo->sMemBlk.hOSMemHandle,
751 PVRSRV_HANDLE_TYPE_MEM_INFO,
752 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
753 psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
754 }
755 else
756 {
757 psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo = 0;
758 }
759#endif
760
761 if(psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ)
762 {
763 /* signal no syncinfo */
764 OSMemSet(&psAllocDeviceMemOUT->sClientSyncInfo,
765 0,
766 sizeof (PVRSRV_CLIENT_SYNC_INFO));
767 psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = IMG_NULL;
768 }
769 else
770 {
771 /* and setup the sync info */
772
773#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
774 psAllocDeviceMemOUT->sClientSyncInfo.psSyncData =
775 psMemInfo->psKernelSyncInfo->psSyncData;
776 psAllocDeviceMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
777 psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
778 psAllocDeviceMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
779 psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
780 psAllocDeviceMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
781 psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
782
783#if defined (SUPPORT_SID_INTERFACE)
784 if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
785 {
786 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
787 &psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo,
788 psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
789 PVRSRV_HANDLE_TYPE_SYNC_INFO,
790 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
791 psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
792 }
793 else
794 {
795 psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo = 0;
796 }
797#else
798 psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo =
799 psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
800#endif
801#endif
802
803 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
804 &psAllocDeviceMemOUT->sClientSyncInfo.hKernelSyncInfo,
805 psMemInfo->psKernelSyncInfo,
806 PVRSRV_HANDLE_TYPE_SYNC_INFO,
807 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
808 psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo);
809
810 psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo =
811 &psAllocDeviceMemOUT->sClientSyncInfo;
812 }
813
814 COMMIT_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc)
815
816 return 0;
817}
818
819#endif /* OS_PVRSRV_ALLOC_DEVICE_MEM_BW */
820
821static IMG_INT
822PVRSRVFreeDeviceMemBW(IMG_UINT32 ui32BridgeID,
823 PVRSRV_BRIDGE_IN_FREEDEVICEMEM *psFreeDeviceMemIN,
824 PVRSRV_BRIDGE_RETURN *psRetOUT,
825 PVRSRV_PER_PROCESS_DATA *psPerProc)
826{
827 IMG_HANDLE hDevCookieInt;
828 IMG_VOID *pvKernelMemInfo;
829
830 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_DEVICEMEM);
831
832 psRetOUT->eError =
833 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
834 psFreeDeviceMemIN->hDevCookie,
835 PVRSRV_HANDLE_TYPE_DEV_NODE);
836
837 if(psRetOUT->eError != PVRSRV_OK)
838 {
839 return 0;
840 }
841
842 psRetOUT->eError =
843 PVRSRVLookupHandle(psPerProc->psHandleBase,
844 &pvKernelMemInfo,
845#if defined (SUPPORT_SID_INTERFACE)
846 psFreeDeviceMemIN->hKernelMemInfo,
847#else
848 psFreeDeviceMemIN->psKernelMemInfo,
849#endif
850 PVRSRV_HANDLE_TYPE_MEM_INFO);
851
852 if(psRetOUT->eError != PVRSRV_OK)
853 {
854 return 0;
855 }
856
857 psRetOUT->eError = PVRSRVFreeDeviceMemKM(hDevCookieInt, pvKernelMemInfo);
858
859 if(psRetOUT->eError != PVRSRV_OK)
860 {
861 return 0;
862 }
863
864 psRetOUT->eError =
865 PVRSRVReleaseHandle(psPerProc->psHandleBase,
866#if defined (SUPPORT_SID_INTERFACE)
867 psFreeDeviceMemIN->hKernelMemInfo,
868#else
869 psFreeDeviceMemIN->psKernelMemInfo,
870#endif
871 PVRSRV_HANDLE_TYPE_MEM_INFO);
872
873 return 0;
874}
875
876
877static IMG_INT
878PVRSRVMultiManageDevMemBW(IMG_UINT32 ui32BridgeID,
879 PVRSRV_BRIDGE_IN_MULTI_MANAGE_DEV_MEM *psMultiMemDevRequestIN,
880 PVRSRV_BRIDGE_OUT_MULTI_MANAGE_DEV_MEM *psMultiMemDevRequestOUT,
881 PVRSRV_PER_PROCESS_DATA *psPerProc)
882{
883 IMG_HANDLE hDevCookieInt;
884 PVRSRV_KERNEL_MEM_INFO *psSharedBuffKernelMemInfo = NULL;
885 PVRSRV_MANAGE_DEV_MEM_REQUEST* pRequestsArray;
886 PVRSRV_MANAGE_DEV_MEM_RESPONSE* pResponseArray;
887 IMG_UINT32 reqNum;
888
889 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MULTI_MANAGE_DEV_MEM);
890
891 psMultiMemDevRequestOUT->eError =
892 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
893 psMultiMemDevRequestIN->hDevCookie,
894 PVRSRV_HANDLE_TYPE_DEV_NODE);
895
896 if(psMultiMemDevRequestOUT->eError != PVRSRV_OK)
897 {
898 PVR_DPF((PVR_DBG_ERROR,"%s: invalid hDevCookie", __FUNCTION__));
899 return 0;
900 }
901
902 if(psMultiMemDevRequestIN->hKernelMemInfo)
903 {
904 PVRSRV_MULTI_MANAGE_DEV_MEM_REQUESTS* psMultiMemDevRequest;
905 psMultiMemDevRequestOUT->eError =
906 PVRSRVLookupHandle(psPerProc->psHandleBase,
907 (IMG_VOID **)&psSharedBuffKernelMemInfo,
908 #if defined (SUPPORT_SID_INTERFACE)
909 psMultiMemDevRequestIN->hKernelMemInfo,
910 #else
911 psMultiMemDevRequestIN->hKernelMemInfo,
912 #endif
913 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
914
915 if(psMultiMemDevRequestOUT->eError != PVRSRV_OK)
916 {
917 PVR_DPF((PVR_DBG_ERROR,"%s: invalid shared memory hKernelMemInfo", __FUNCTION__));
918 return 0;
919 }
920
921 psMultiMemDevRequest = (PVRSRV_MULTI_MANAGE_DEV_MEM_REQUESTS*)psSharedBuffKernelMemInfo->pvLinAddrKM;
922 if( (psMultiMemDevRequest->psSharedMemClientMemInfo != psMultiMemDevRequestIN->psSharedMemClientMemInfo ) ||
923 (psMultiMemDevRequest->ui32MaxNumberOfRequests != psMultiMemDevRequestIN->ui32MaxNumberOfRequests) ||
924 psMultiMemDevRequest->ui32NumberOfValidRequests != psMultiMemDevRequestIN->ui32NumberOfValidRequests ||
925 psMultiMemDevRequest->ui32CtrlFlags != psMultiMemDevRequestIN->ui32CtrlFlags)
926 {
927 psMultiMemDevRequestOUT->eError = PVRSRV_ERROR_BAD_MAPPING;
928 return 0;
929 }
930 pRequestsArray = psMultiMemDevRequest->sMemRequests;
931 pResponseArray = psMultiMemDevRequest->sMemRequests;
932 }
933 else
934 {
935 pRequestsArray = psMultiMemDevRequestIN->sMemRequests;
936 pResponseArray = psMultiMemDevRequestOUT->sMemResponse;
937 }
938
939 PVR_DPF((PVR_DBG_MESSAGE, "\n%s: %s %d Number of request/s, Control flag = 0x%08x\n",
940 __FUNCTION__,
941 (psMultiMemDevRequestIN->hKernelMemInfo ? "Shared" : "Direct"),
942 psMultiMemDevRequestIN->ui32NumberOfValidRequests,
943 psMultiMemDevRequestIN->ui32CtrlFlags));
944
945 for(reqNum = 0; reqNum < psMultiMemDevRequestIN->ui32NumberOfValidRequests; reqNum++)
946 {
947 PVRSRV_MANAGE_DEV_MEM_REQUEST *pRequest = &pRequestsArray[reqNum];
948 PVRSRV_MANAGE_DEV_MEM_REQUEST *pResponse = &pResponseArray[reqNum];
949 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = NULL;
950
951 /* At the kernel size, psClientMemInfo only works as a verification token */
952 if(psMultiMemDevRequestIN->hKernelMemInfo == NULL)
953 {
954 pResponse->psClientMemInfo = pRequest->psClientMemInfo;
955 pResponse->eReqType = pRequest->eReqType;
956 }
957
958 PVR_DPF((PVR_DBG_MESSAGE, "%s: Request %d for ClientMemInfo %p\n"
959 "DevVirtAddr 0x%08x, GpuRefCount %d "
960 "CpuVirtAddr %p, CpuRefCount %d, Kernel Handle %p, sync %p\n"
961 "Size %d, Attrib 0x%08x, Align %d, Subsystem 0x%llx, Hints 0x%08x "
962 "transfer slot %d\n",
963 __FUNCTION__, pResponse->eReqType,
964 pRequest->psClientMemInfo,
965 pRequest->sDevVAddr.uiAddr,
966 pRequest->ui32GpuMapRefCount,
967 pRequest->pvLinAddr,
968 pRequest->ui32CpuMapRefCount,
969 pRequest->hKernelMemInfo,
970 pRequest->hKernelSyncInfo,
971 pRequest->uSize,
972 pRequest->ui32Attribs,
973 pRequest->uAlignment,
974 pRequest->uiSubSystem,
975 pRequest->ui32Hints,
976 pRequest->ui32TransferFromToReqSlotIndx));
977
978 pResponse->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
979 (IMG_PVOID *)&psKernelMemInfo,
980 #if defined (SUPPORT_SID_INTERFACE)
981 pRequest->hKernelMemInfo,
982 #else
983 pRequest->hKernelMemInfo,
984 #endif
985 PVRSRV_HANDLE_TYPE_MEM_INFO);
986 if(pResponse->eError != PVRSRV_OK)
987 {
988 PVR_DPF((PVR_DBG_ERROR,"%s: invalid hKernelMemInfo for slot %d",
989 __FUNCTION__, reqNum));
990 continue;
991 }
992
993 PVR_DPF((PVR_DBG_MESSAGE, "%s: KernelMemInfo %p -%s SHARED\n"
994 "DevVirtAddr 0x%08x, RefCount %d "
995 "Size %d, Flags 0x%08x, OrigAlign %d, Subsystem 0x%llx, Hints 0x%08x\n",
996 __FUNCTION__, psKernelMemInfo,
997 (psKernelMemInfo->sShareMemWorkaround.bInUse ? "" : "NOT"),
998 psKernelMemInfo->sDevVAddr.uiAddr,
999 psKernelMemInfo->ui32RefCount,
1000 psKernelMemInfo->uAllocSize,
1001 psKernelMemInfo->ui32Flags,
1002 psKernelMemInfo->sShareMemWorkaround.ui32OrigReqAlignment,
1003 (IMG_UINT64)0, 0));
1004
1005 if(psKernelMemInfo->sDevVAddr.uiAddr != pRequest->sDevVAddr.uiAddr)
1006 {
1007 PVR_DPF((PVR_DBG_WARNING, "%s: Kernel and Client MemInfo's "
1008 "virtual addresses are not equal\n"
1009 "Kernel DevVirtAddr 0x%08x != Client DevVirtAddr 0x%08x",
1010 __FUNCTION__,
1011 psKernelMemInfo->sDevVAddr.uiAddr, pRequest->sDevVAddr.uiAddr));
1012 }
1013
1014 switch(pResponse->eReqType)
1015 {
1016 case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_MAP:
1017 case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_LOCK_MAP:
1018 {
1019 IMG_INT32 result = PVRSRVRemapToDevKM(hDevCookieInt,
1020 psKernelMemInfo, &pResponse->sDevVAddr);
1021
1022 if(result < 0)
1023 {
1024 pResponse->eError = -result;
1025 PVR_DPF((PVR_DBG_ERROR, "Request for GPU Virtual "
1026 "memory mapping had failed "
1027 "with error %d",
1028 pResponse->eError));
1029 }
1030 else
1031 {
1032 pResponse->ui32GpuMapRefCount = result;
1033 pResponse->eError = PVRSRV_OK;
1034 }
1035 }
1036 break;
1037 case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_SWAP_MAP_TO_NEXT:
1038 pResponse->eError = PVRSRV_OK;
1039 pResponse->ui32GpuMapRefCount = 1;
1040 pResponse->sDevVAddr = psKernelMemInfo->sDevVAddr;
1041 break;
1042 case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_UNMAP:
1043 case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_UNLOCK_MAP:
1044 {
1045 IMG_INT32 result = PVRSRVUnmapFromDevKM(hDevCookieInt, psKernelMemInfo);
1046 if(result < 0)
1047 {
1048 pResponse->eError = -result;
1049 PVR_DPF((PVR_DBG_ERROR, "Request for GPU Virtual memory "
1050 "un-mapping had failed "
1051 "with error %d",
1052 pResponse->eError));
1053 }
1054 else
1055 {
1056 pResponse->ui32GpuMapRefCount = result;
1057 pResponse->eError = PVRSRV_OK;
1058 }
1059 pResponse->sDevVAddr = psKernelMemInfo->sDevVAddr;
1060 }
1061 break;
1062 case PVRSRV_MULTI_MANAGE_DEV_MEM_RQST_SWAP_MAP_FROM_PREV:
1063 pResponse->eError = PVRSRV_OK;
1064 pResponse->ui32GpuMapRefCount = 1;
1065 pResponse->sDevVAddr = psKernelMemInfo->sDevVAddr;
1066 break;
1067 default:
1068 pResponse->eError = PVRSRV_ERROR_INVALID_PARAMS;
1069 break;
1070 }
1071
1072 PVR_DPF((PVR_DBG_MESSAGE, "%s: RETURN: ClientMemInfo %p "
1073 "DevVirtAddr 0x%08x, GpuMapRefCount %d, err %d\n",
1074 __FUNCTION__, pRequest->psClientMemInfo,
1075 pResponse->sDevVAddr.uiAddr,
1076 pResponse->ui32GpuMapRefCount,
1077 pResponse->eError));
1078 }
1079
1080 if(psMultiMemDevRequestIN->hKernelMemInfo == NULL)
1081 psMultiMemDevRequestOUT->ui32CtrlFlags = psMultiMemDevRequestIN->ui32CtrlFlags;
1082 /* No status implemented yet */
1083 psMultiMemDevRequestOUT->ui32StatusFlags = 0;
1084
1085 return 0;
1086}
1087
1088static IMG_INT
1089PVRSRVExportDeviceMemBW(IMG_UINT32 ui32BridgeID,
1090 PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM *psExportDeviceMemIN,
1091 PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT,
1092 PVRSRV_PER_PROCESS_DATA *psPerProc)
1093{
1094 IMG_HANDLE hDevCookieInt;
1095#if defined (SUPPORT_SID_INTERFACE)
1096 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
1097#else
1098 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
1099#endif
1100
1101 PVR_ASSERT(ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_EXPORT_DEVICEMEM) ||
1102 ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2));
1103 PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
1104
1105 /* find the device cookie */
1106 psExportDeviceMemOUT->eError =
1107 PVRSRVLookupHandle(psPerProc->psHandleBase,
1108 &hDevCookieInt,
1109 psExportDeviceMemIN->hDevCookie,
1110 PVRSRV_HANDLE_TYPE_DEV_NODE);
1111
1112 if(psExportDeviceMemOUT->eError != PVRSRV_OK)
1113 {
1114 PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find devcookie"));
1115 return 0;
1116 }
1117
1118 /* find the kernel meminfo from the process handle list */
1119 psExportDeviceMemOUT->eError =
1120 PVRSRVLookupHandle(psPerProc->psHandleBase,
1121 (IMG_PVOID *)&psKernelMemInfo,
1122#if defined (SUPPORT_SID_INTERFACE)
1123 psExportDeviceMemIN->hKernelMemInfo,
1124#else
1125 psExportDeviceMemIN->psKernelMemInfo,
1126#endif
1127 PVRSRV_HANDLE_TYPE_MEM_INFO);
1128
1129 if(psExportDeviceMemOUT->eError != PVRSRV_OK)
1130 {
1131 PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: can't find kernel meminfo"));
1132 return 0;
1133 }
1134
1135 /* see if it's already exported */
1136 psExportDeviceMemOUT->eError =
1137 PVRSRVFindHandle(KERNEL_HANDLE_BASE,
1138 &psExportDeviceMemOUT->hMemInfo,
1139 psKernelMemInfo,
1140 PVRSRV_HANDLE_TYPE_MEM_INFO);
1141 if(psExportDeviceMemOUT->eError == PVRSRV_OK)
1142 {
1143 /* it's already exported */
1144 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVExportDeviceMemBW: allocation is already exported"));
1145 return 0;
1146 }
1147
1148 /* export the allocation */
1149 psExportDeviceMemOUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
1150 &psExportDeviceMemOUT->hMemInfo,
1151 psKernelMemInfo,
1152 PVRSRV_HANDLE_TYPE_MEM_INFO,
1153 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1154 if (psExportDeviceMemOUT->eError != PVRSRV_OK)
1155 {
1156 PVR_DPF((PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: failed to allocate handle from global handle list"));
1157 return 0;
1158 }
1159
1160 /* mark the meminfo as 'exported' */
1161 psKernelMemInfo->ui32Flags |= PVRSRV_MEM_EXPORTED;
1162
1163 return 0;
1164}
1165
1166
1167static IMG_INT
1168PVRSRVMapDeviceMemoryBW(IMG_UINT32 ui32BridgeID,
1169 PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN,
1170 PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDevMemOUT,
1171 PVRSRV_PER_PROCESS_DATA *psPerProc)
1172{
1173 PVRSRV_KERNEL_MEM_INFO *psSrcKernelMemInfo = IMG_NULL;
1174 PVRSRV_KERNEL_MEM_INFO *psDstKernelMemInfo = IMG_NULL;
1175 IMG_HANDLE hDstDevMemHeap = IMG_NULL;
1176
1177 PVR_ASSERT(ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_MAP_DEV_MEMORY) ||
1178 ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_MAP_DEV_MEMORY_2));
1179 PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
1180
1181 NEW_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc, 2)
1182
1183 /* lookup srcmeminfo handle */
1184 psMapDevMemOUT->eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
1185 (IMG_VOID**)&psSrcKernelMemInfo,
1186 psMapDevMemIN->hKernelMemInfo,
1187 PVRSRV_HANDLE_TYPE_MEM_INFO);
1188 if(psMapDevMemOUT->eError != PVRSRV_OK)
1189 {
1190 return 0;
1191 }
1192
1193 /* lookup dev mem heap handle */
1194 psMapDevMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1195 &hDstDevMemHeap,
1196 psMapDevMemIN->hDstDevMemHeap,
1197 PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
1198 if(psMapDevMemOUT->eError != PVRSRV_OK)
1199 {
1200 return 0;
1201 }
1202
1203 /* check for workaround */
1204 if (psSrcKernelMemInfo->sShareMemWorkaround.bInUse)
1205 {
1206 PVR_DPF((PVR_DBG_MESSAGE, "using the mem wrap workaround."));
1207
1208 /* Check the XPROC mapping count -if it is "0",
1209 * then the object is about to go away - do not allow mapping */
1210 if(BM_XProcGetShareDataRefCount(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex) < 1)
1211 {
1212 psMapDevMemOUT->eError = PVRSRV_ERROR_MAPPING_NOT_FOUND;
1213 PVR_DPF((PVR_DBG_WARNING, "%s: Can't map buffer with slot %d, size %d "
1214 "and refcount %d\n\t Invalid XPROC refcount of %d",
1215 __FUNCTION__, psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex,
1216 psSrcKernelMemInfo->uAllocSize, psSrcKernelMemInfo->ui32RefCount,
1217 BM_XProcGetShareDataRefCount(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex)));
1218 return 0;
1219 }
1220
1221 /* Ensure we get the same ID for this allocation, such that it
1222 inherits the same physical block. Rather than add a lot of
1223 plumbing to several APIs, we call into buffer manager directly
1224 to set "global" state. This works only if we make
1225 this allocation while holding the bridge mutex and don't
1226 make any other allocations (because the state persists and
1227 would affect other device memory allocations too). It is
1228 important that we bracket the PVRSRVAllocDeviceMemKM() call
1229 with this Set/Unset pair. */
1230 psMapDevMemOUT->eError = BM_XProcWorkaroundSetShareIndex(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
1231 if(psMapDevMemOUT->eError != PVRSRV_OK)
1232 {
1233 PVR_DPF((PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryBW(): failed to recycle shared buffer"));
1234 return 0;
1235 }
1236
1237 psMapDevMemOUT->eError =
1238 PVRSRVAllocDeviceMemKM(psSrcKernelMemInfo->sShareMemWorkaround.hDevCookieInt,
1239 psPerProc,
1240 hDstDevMemHeap,
1241 psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqAttribs | PVRSRV_MEM_NO_SYNCOBJ,
1242 psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqSize,
1243 psSrcKernelMemInfo->sShareMemWorkaround.ui32OrigReqAlignment,
1244 IMG_NULL,
1245 0,
1246 /* FIXME: Do we need to be able to export sparse memory? */
1247 0,0,0,IMG_NULL, /* No sparse mapping data */
1248 &psDstKernelMemInfo,
1249 "" /*FIXME: add something meaningful*/);
1250 /* counterpart of the above "SetShareIndex". NB: this must be
1251 done in both the success and failure paths of the
1252 AllocDeviceMemKM() call */
1253 BM_XProcWorkaroundUnsetShareIndex(psSrcKernelMemInfo->sShareMemWorkaround.ui32ShareIndex);
1254 if(psMapDevMemOUT->eError != PVRSRV_OK)
1255 {
1256 PVR_DPF((PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryBW: Failed to create allocation for cross-process memory map"));
1257 return 0;
1258 }
1259
1260 if(psSrcKernelMemInfo->psKernelSyncInfo)
1261 {
1262 PVRSRVKernelSyncInfoIncRef(psSrcKernelMemInfo->psKernelSyncInfo, psSrcKernelMemInfo);
1263 }
1264
1265 psDstKernelMemInfo->psKernelSyncInfo = psSrcKernelMemInfo->psKernelSyncInfo;
1266 }
1267 else
1268 {
1269 /* map the meminfo to the target heap and memory context */
1270 psMapDevMemOUT->eError = PVRSRVMapDeviceMemoryKM(psPerProc,
1271 psSrcKernelMemInfo,
1272 hDstDevMemHeap,
1273 &psDstKernelMemInfo);
1274 if(psMapDevMemOUT->eError != PVRSRV_OK)
1275 {
1276 return 0;
1277 }
1278 }
1279
1280 /* copy the workaround info */
1281 psDstKernelMemInfo->sShareMemWorkaround = psSrcKernelMemInfo->sShareMemWorkaround;
1282
1283 OSMemSet(&psMapDevMemOUT->sDstClientMemInfo,
1284 0,
1285 sizeof(psMapDevMemOUT->sDstClientMemInfo));
1286 OSMemSet(&psMapDevMemOUT->sDstClientSyncInfo,
1287 0,
1288 sizeof(psMapDevMemOUT->sDstClientSyncInfo));
1289
1290 psMapDevMemOUT->sDstClientMemInfo.pvLinAddrKM =
1291 psDstKernelMemInfo->pvLinAddrKM;
1292
1293 psMapDevMemOUT->sDstClientMemInfo.pvLinAddr = 0;
1294 psMapDevMemOUT->sDstClientMemInfo.sDevVAddr = psDstKernelMemInfo->sDevVAddr;
1295 psMapDevMemOUT->sDstClientMemInfo.ui32Flags = psDstKernelMemInfo->ui32Flags;
1296 psMapDevMemOUT->sDstClientMemInfo.uAllocSize = psDstKernelMemInfo->uAllocSize;
1297 OSMemCopy(psMapDevMemOUT->sDstClientMemInfo.planeOffsets, psDstKernelMemInfo->planeOffsets,
1298 sizeof(psDstKernelMemInfo->planeOffsets));
1299#if defined (SUPPORT_SID_INTERFACE)
1300 /* see below */
1301#else
1302 psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = psDstKernelMemInfo->sMemBlk.hOSMemHandle;
1303#endif
1304
1305 /* allocate handle to the DST kernel meminfo */
1306 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1307 &psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo,
1308 psDstKernelMemInfo,
1309 PVRSRV_HANDLE_TYPE_MEM_INFO,
1310 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1311 psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo = IMG_NULL;
1312
1313#if defined (SUPPORT_SID_INTERFACE)
1314 /* alloc subhandle for the mapping info */
1315 if (psDstKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
1316 {
1317 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1318 &psMapDevMemOUT->sDstClientMemInfo.hMappingInfo,
1319 psDstKernelMemInfo->sMemBlk.hOSMemHandle,
1320 PVRSRV_HANDLE_TYPE_MEM_INFO,
1321 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1322 psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
1323 }
1324 else
1325 {
1326 psMapDevMemOUT->sDstClientMemInfo.hMappingInfo = 0;
1327 }
1328#endif
1329
1330 /* and setup the sync info */
1331 if(psDstKernelMemInfo->psKernelSyncInfo)
1332 {
1333#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
1334 psMapDevMemOUT->sDstClientSyncInfo.psSyncData =
1335 psDstKernelMemInfo->psKernelSyncInfo->psSyncData;
1336 psMapDevMemOUT->sDstClientSyncInfo.sWriteOpsCompleteDevVAddr =
1337 psDstKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
1338 psMapDevMemOUT->sDstClientSyncInfo.sReadOpsCompleteDevVAddr =
1339 psDstKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
1340 psMapDevMemOUT->sDstClientSyncInfo.sReadOps2CompleteDevVAddr =
1341 psDstKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
1342
1343#if defined (SUPPORT_SID_INTERFACE)
1344 /* alloc subhandle for the mapping info */
1345 if (psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
1346 {
1347 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1348 &psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo,
1349 psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
1350 PVRSRV_HANDLE_TYPE_MEM_INFO,
1351 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1352 psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
1353 }
1354 else
1355 {
1356 psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo = 0;
1357 }
1358#else
1359 psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo =
1360 psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
1361#endif
1362#endif
1363
1364 psMapDevMemOUT->sDstClientMemInfo.psClientSyncInfo = &psMapDevMemOUT->sDstClientSyncInfo;
1365 /*
1366 * The sync info is associated with the device buffer,
1367 * and not allocated here. It isn't exported when created,
1368 * hence the handle allocation rather than a lookup.
1369 */
1370 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1371 &psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo,
1372 psDstKernelMemInfo->psKernelSyncInfo,
1373 PVRSRV_HANDLE_TYPE_SYNC_INFO,
1374 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1375 psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo);
1376 }
1377
1378 COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc)
1379
1380 return 0;
1381}
1382
1383
1384static IMG_INT
1385PVRSRVUnmapDeviceMemoryBW(IMG_UINT32 ui32BridgeID,
1386 PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY *psUnmapDevMemIN,
1387 PVRSRV_BRIDGE_RETURN *psRetOUT,
1388 PVRSRV_PER_PROCESS_DATA *psPerProc)
1389{
1390 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
1391
1392 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEV_MEMORY);
1393
1394 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1395 (IMG_VOID**)&psKernelMemInfo,
1396#if defined (SUPPORT_SID_INTERFACE)
1397 psUnmapDevMemIN->hKernelMemInfo,
1398#else
1399 psUnmapDevMemIN->psKernelMemInfo,
1400#endif
1401 PVRSRV_HANDLE_TYPE_MEM_INFO);
1402 if(psRetOUT->eError != PVRSRV_OK)
1403 {
1404 return 0;
1405 }
1406
1407 if (psKernelMemInfo->sShareMemWorkaround.bInUse)
1408 {
1409 psRetOUT->eError = PVRSRVFreeDeviceMemKM(psKernelMemInfo->sShareMemWorkaround.hDevCookieInt, psKernelMemInfo);
1410 if(psRetOUT->eError != PVRSRV_OK)
1411 {
1412 PVR_DPF((PVR_DBG_ERROR, "PVRSRVUnmapDeviceMemoryBW: internal error, should expect FreeDeviceMem to fail"));
1413 return 0;
1414 }
1415 }
1416 else
1417 {
1418 psRetOUT->eError = PVRSRVUnmapDeviceMemoryKM(psKernelMemInfo);
1419 if(psRetOUT->eError != PVRSRV_OK)
1420 {
1421 return 0;
1422 }
1423 }
1424
1425 psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
1426#if defined (SUPPORT_SID_INTERFACE)
1427 psUnmapDevMemIN->hKernelMemInfo,
1428#else
1429 psUnmapDevMemIN->psKernelMemInfo,
1430#endif
1431 PVRSRV_HANDLE_TYPE_MEM_INFO);
1432
1433 return 0;
1434}
1435
1436
1437
1438static IMG_INT
1439PVRSRVMapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID,
1440 PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY *psMapDevClassMemIN,
1441 PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psMapDevClassMemOUT,
1442 PVRSRV_PER_PROCESS_DATA *psPerProc)
1443{
1444 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
1445 IMG_HANDLE hOSMapInfo;
1446 IMG_HANDLE hDeviceClassBufferInt;
1447 IMG_HANDLE hDevMemContextInt;
1448 PVRSRV_HANDLE_TYPE eHandleType;
1449
1450 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY);
1451
1452 NEW_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc, 2)
1453
1454 /*
1455 * The buffer to be mapped can belong to a 3rd party display or
1456 * buffer driver, and we don't know which type we have at this
1457 * point.
1458 */
1459 psMapDevClassMemOUT->eError =
1460 PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
1461 &hDeviceClassBufferInt,
1462 &eHandleType,
1463 psMapDevClassMemIN->hDeviceClassBuffer);
1464
1465 if(psMapDevClassMemOUT->eError != PVRSRV_OK)
1466 {
1467 return 0;
1468 }
1469
1470 /* get the device memory context */
1471 psMapDevClassMemOUT->eError =
1472 PVRSRVLookupHandle(psPerProc->psHandleBase,
1473 &hDevMemContextInt,
1474 psMapDevClassMemIN->hDevMemContext,
1475 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
1476
1477 if(psMapDevClassMemOUT->eError != PVRSRV_OK)
1478 {
1479 return 0;
1480 }
1481
1482 /* Having looked up the handle, now check its type */
1483 switch(eHandleType)
1484 {
1485#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
1486 case PVRSRV_HANDLE_TYPE_DISP_BUFFER:
1487 case PVRSRV_HANDLE_TYPE_BUF_BUFFER:
1488#else
1489 case PVRSRV_HANDLE_TYPE_NONE:
1490#endif
1491 break;
1492 default:
1493 psMapDevClassMemOUT->eError = PVRSRV_ERROR_INVALID_HANDLE_TYPE;
1494 return 0;
1495 }
1496
1497 psMapDevClassMemOUT->eError =
1498 PVRSRVMapDeviceClassMemoryKM(psPerProc,
1499 hDevMemContextInt,
1500 hDeviceClassBufferInt,
1501 &psMemInfo,
1502 &hOSMapInfo);
1503 if(psMapDevClassMemOUT->eError != PVRSRV_OK)
1504 {
1505 return 0;
1506 }
1507
1508 OSMemSet(&psMapDevClassMemOUT->sClientMemInfo,
1509 0,
1510 sizeof(psMapDevClassMemOUT->sClientMemInfo));
1511 OSMemSet(&psMapDevClassMemOUT->sClientSyncInfo,
1512 0,
1513 sizeof(psMapDevClassMemOUT->sClientSyncInfo));
1514
1515 psMapDevClassMemOUT->sClientMemInfo.pvLinAddrKM =
1516 psMemInfo->pvLinAddrKM;
1517
1518 psMapDevClassMemOUT->sClientMemInfo.pvLinAddr = 0;
1519 psMapDevClassMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
1520 psMapDevClassMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
1521 psMapDevClassMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize;
1522#if defined (SUPPORT_SID_INTERFACE)
1523 if (psMemInfo->sMemBlk.hOSMemHandle != 0)
1524 {
1525 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1526 &psMapDevClassMemOUT->sClientMemInfo.hMappingInfo,
1527 psMemInfo->sMemBlk.hOSMemHandle,
1528 PVRSRV_HANDLE_TYPE_MEM_INFO,
1529 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1530 psMapDevClassMemIN->hDeviceClassBuffer);
1531 }
1532 else
1533 {
1534 psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = 0;
1535 }
1536#else
1537 psMapDevClassMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
1538#endif
1539
1540 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1541 &psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo,
1542 psMemInfo,
1543 PVRSRV_HANDLE_TYPE_MEM_INFO,
1544 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1545 psMapDevClassMemIN->hDeviceClassBuffer);
1546
1547 psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo = IMG_NULL;
1548
1549 /* and setup the sync info */
1550 if(psMemInfo->psKernelSyncInfo)
1551 {
1552#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
1553 psMapDevClassMemOUT->sClientSyncInfo.psSyncData =
1554 psMemInfo->psKernelSyncInfo->psSyncData;
1555 psMapDevClassMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
1556 psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
1557 psMapDevClassMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
1558 psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
1559 psMapDevClassMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
1560 psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
1561
1562#if defined (SUPPORT_SID_INTERFACE)
1563 if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != 0)
1564 {
1565 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1566 &psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo,
1567 psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
1568 PVRSRV_HANDLE_TYPE_SYNC_INFO,
1569 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1570 psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo);
1571 }
1572 else
1573 {
1574 psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo = 0;
1575 }
1576#else
1577 psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo =
1578 psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
1579#endif
1580#endif
1581
1582 psMapDevClassMemOUT->sClientMemInfo.psClientSyncInfo = &psMapDevClassMemOUT->sClientSyncInfo;
1583 /*
1584 * The sync info is associated with the device buffer,
1585 * and not allocated here. It isn't exported when
1586 * created, hence the handle allocation rather than a
1587 * lookup.
1588 */
1589 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1590 &psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo,
1591 psMemInfo->psKernelSyncInfo,
1592 PVRSRV_HANDLE_TYPE_SYNC_INFO,
1593 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1594 psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo);
1595 }
1596
1597 COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc)
1598
1599 return 0;
1600}
1601
1602static IMG_INT
1603PVRSRVUnmapDeviceClassMemoryBW(IMG_UINT32 ui32BridgeID,
1604 PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY *psUnmapDevClassMemIN,
1605 PVRSRV_BRIDGE_RETURN *psRetOUT,
1606 PVRSRV_PER_PROCESS_DATA *psPerProc)
1607{
1608 IMG_VOID *pvKernelMemInfo;
1609
1610 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY);
1611
1612 psRetOUT->eError =
1613 PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo,
1614#if defined (SUPPORT_SID_INTERFACE)
1615 psUnmapDevClassMemIN->hKernelMemInfo,
1616#else
1617 psUnmapDevClassMemIN->psKernelMemInfo,
1618#endif
1619 PVRSRV_HANDLE_TYPE_MEM_INFO);
1620 if(psRetOUT->eError != PVRSRV_OK)
1621 {
1622 return 0;
1623 }
1624
1625 psRetOUT->eError = PVRSRVUnmapDeviceClassMemoryKM(pvKernelMemInfo);
1626
1627 if(psRetOUT->eError != PVRSRV_OK)
1628 {
1629 return 0;
1630 }
1631
1632 psRetOUT->eError =
1633 PVRSRVReleaseHandle(psPerProc->psHandleBase,
1634#if defined (SUPPORT_SID_INTERFACE)
1635 psUnmapDevClassMemIN->hKernelMemInfo,
1636#else
1637 psUnmapDevClassMemIN->psKernelMemInfo,
1638#endif
1639 PVRSRV_HANDLE_TYPE_MEM_INFO);
1640
1641 return 0;
1642}
1643
1644
1645#if defined(OS_PVRSRV_WRAP_EXT_MEM_BW)
1646IMG_INT
1647PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
1648 PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN,
1649 PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT,
1650 PVRSRV_PER_PROCESS_DATA *psPerProc);
1651#else /* OS_PVRSRV_WRAP_EXT_MEM_BW */
1652static IMG_INT
1653PVRSRVWrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
1654 PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN,
1655 PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT,
1656 PVRSRV_PER_PROCESS_DATA *psPerProc)
1657{
1658 IMG_HANDLE hDevCookieInt;
1659 IMG_HANDLE hDevMemContextInt;
1660 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
1661 IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL;
1662 IMG_UINT32 ui32PageTableSize = 0;
1663
1664 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_WRAP_EXT_MEMORY);
1665
1666 NEW_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc, 2)
1667
1668 /*
1669 * FIXME: This needs reworking - don't use the user supplied page
1670 * table list, get the list from the OS.
1671 */
1672 psWrapExtMemOUT->eError =
1673 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
1674 psWrapExtMemIN->hDevCookie,
1675 PVRSRV_HANDLE_TYPE_DEV_NODE);
1676 if(psWrapExtMemOUT->eError != PVRSRV_OK)
1677 {
1678 return 0;
1679 }
1680
1681 /* get the device memory context */
1682 psWrapExtMemOUT->eError =
1683 PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
1684 psWrapExtMemIN->hDevMemContext,
1685 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
1686
1687 if(psWrapExtMemOUT->eError != PVRSRV_OK)
1688 {
1689 return 0;
1690 }
1691
1692 if(psWrapExtMemIN->ui32NumPageTableEntries)
1693 {
1694 ui32PageTableSize = psWrapExtMemIN->ui32NumPageTableEntries
1695 * sizeof(IMG_SYS_PHYADDR);
1696
1697 ASSIGN_AND_EXIT_ON_ERROR(psWrapExtMemOUT->eError,
1698 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1699 ui32PageTableSize,
1700 (IMG_VOID **)&psSysPAddr, 0,
1701 "Page Table"));
1702
1703 if(CopyFromUserWrapper(psPerProc,
1704 ui32BridgeID,
1705 psSysPAddr,
1706 psWrapExtMemIN->psSysPAddr,
1707 ui32PageTableSize) != PVRSRV_OK)
1708 {
1709 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize, (IMG_VOID *)psSysPAddr, 0);
1710 /*not nulling pointer, out of scope*/
1711 return -EFAULT;
1712 }
1713 }
1714
1715 psWrapExtMemOUT->eError =
1716 PVRSRVWrapExtMemoryKM(hDevCookieInt,
1717 psPerProc,
1718 hDevMemContextInt,
1719 psWrapExtMemIN->ui32ByteSize,
1720 psWrapExtMemIN->ui32PageOffset,
1721 psWrapExtMemIN->bPhysContig,
1722 psSysPAddr,
1723 psWrapExtMemIN->pvLinAddr,
1724 psWrapExtMemIN->ui32Flags,
1725 &psMemInfo);
1726
1727 if(psWrapExtMemIN->ui32NumPageTableEntries)
1728 {
1729 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1730 ui32PageTableSize,
1731 (IMG_VOID *)psSysPAddr, 0);
1732 /*not nulling pointer, out of scope*/
1733 }
1734
1735 if(psWrapExtMemOUT->eError != PVRSRV_OK)
1736 {
1737 return 0;
1738 }
1739
1740 psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM =
1741 psMemInfo->pvLinAddrKM;
1742
1743 /* setup the mem info */
1744 psWrapExtMemOUT->sClientMemInfo.pvLinAddr = 0;
1745 psWrapExtMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
1746 psWrapExtMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
1747 psWrapExtMemOUT->sClientMemInfo.uAllocSize = psMemInfo->uAllocSize;
1748#if defined (SUPPORT_SID_INTERFACE)
1749/* see below */
1750#else
1751 psWrapExtMemOUT->sClientMemInfo.hMappingInfo = psMemInfo->sMemBlk.hOSMemHandle;
1752#endif
1753
1754 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1755 &psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo,
1756 psMemInfo,
1757 PVRSRV_HANDLE_TYPE_MEM_INFO,
1758 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1759
1760#if defined (SUPPORT_SID_INTERFACE)
1761 /* alloc subhandle for the mapping info */
1762 if (psMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
1763 {
1764 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1765 &psWrapExtMemOUT->sClientMemInfo.hMappingInfo,
1766 psMemInfo->sMemBlk.hOSMemHandle,
1767 PVRSRV_HANDLE_TYPE_MEM_INFO,
1768 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1769 psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
1770 }
1771 else
1772 {
1773 psWrapExtMemOUT->sClientMemInfo.hMappingInfo = 0;
1774 }
1775#endif
1776
1777 /* setup the sync info */
1778#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
1779 psWrapExtMemOUT->sClientSyncInfo.psSyncData =
1780 psMemInfo->psKernelSyncInfo->psSyncData;
1781 psWrapExtMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
1782 psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
1783 psWrapExtMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
1784 psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
1785 psWrapExtMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
1786 psMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
1787
1788#if defined (SUPPORT_SID_INTERFACE)
1789 /* alloc subhandle for the mapping info */
1790 if (psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
1791 {
1792 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1793 &psWrapExtMemOUT->sClientSyncInfo.hMappingInfo,
1794 psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
1795 PVRSRV_HANDLE_TYPE_MEM_INFO,
1796 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1797 psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
1798 }
1799 else
1800 {
1801 psWrapExtMemOUT->sClientSyncInfo.hMappingInfo = 0;
1802 }
1803#else
1804 psWrapExtMemOUT->sClientSyncInfo.hMappingInfo =
1805 psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
1806#endif
1807#endif
1808
1809 psWrapExtMemOUT->sClientMemInfo.psClientSyncInfo = &psWrapExtMemOUT->sClientSyncInfo;
1810
1811 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1812 &psWrapExtMemOUT->sClientSyncInfo.hKernelSyncInfo,
1813 (IMG_HANDLE)psMemInfo->psKernelSyncInfo,
1814 PVRSRV_HANDLE_TYPE_SYNC_INFO,
1815 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1816 psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
1817
1818 COMMIT_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc)
1819
1820 return 0;
1821}
1822#endif /* OS_PVRSRV_WRAP_EXT_MEM_BW */
1823
1824static IMG_INT
1825PVRSRVUnwrapExtMemoryBW(IMG_UINT32 ui32BridgeID,
1826 PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY *psUnwrapExtMemIN,
1827 PVRSRV_BRIDGE_RETURN *psRetOUT,
1828 PVRSRV_PER_PROCESS_DATA *psPerProc)
1829{
1830 IMG_VOID *pvMemInfo;
1831
1832 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY);
1833
1834 psRetOUT->eError =
1835 PVRSRVLookupHandle(psPerProc->psHandleBase,
1836 &pvMemInfo,
1837 psUnwrapExtMemIN->hKernelMemInfo,
1838 PVRSRV_HANDLE_TYPE_MEM_INFO);
1839 if(psRetOUT->eError != PVRSRV_OK)
1840 {
1841 return 0;
1842 }
1843
1844 psRetOUT->eError =
1845 PVRSRVUnwrapExtMemoryKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo);
1846 if(psRetOUT->eError != PVRSRV_OK)
1847 {
1848 return 0;
1849 }
1850
1851 psRetOUT->eError =
1852 PVRSRVReleaseHandle(psPerProc->psHandleBase,
1853 psUnwrapExtMemIN->hKernelMemInfo,
1854 PVRSRV_HANDLE_TYPE_MEM_INFO);
1855
1856 return 0;
1857}
1858
1859#if defined(SUPPORT_ION)
1860static IMG_INT
1861PVRSRVMapIonHandleBW(IMG_UINT32 ui32BridgeID,
1862 PVRSRV_BRIDGE_IN_MAP_ION_HANDLE *psMapIonIN,
1863 PVRSRV_BRIDGE_OUT_MAP_ION_HANDLE *psMapIonOUT,
1864 PVRSRV_PER_PROCESS_DATA *psPerProc)
1865{
1866 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
1867
1868 psMapIonOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1869 &psMapIonIN->hDevCookie,
1870 psMapIonIN->hDevCookie,
1871 PVRSRV_HANDLE_TYPE_DEV_NODE);
1872 if (psMapIonOUT->eError != PVRSRV_OK)
1873 {
1874 PVR_DPF((PVR_DBG_ERROR, "%s: Failed to lookup device node handle", __FUNCTION__));
1875 return 0;
1876 }
1877
1878 psMapIonOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1879 &psMapIonIN->hDevMemContext,
1880 psMapIonIN->hDevMemContext,
1881 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
1882 if (psMapIonOUT->eError != PVRSRV_OK)
1883 {
1884 PVR_DPF((PVR_DBG_ERROR, "%s: Failed to lookup memory context handle", __FUNCTION__));
1885 return 0;
1886 }
1887
1888 psMapIonOUT->eError = PVRSRVMapIonHandleKM(psPerProc,
1889 psMapIonIN->hDevCookie,
1890 psMapIonIN->hDevMemContext,
1891 psMapIonIN->handle,
1892 psMapIonIN->ui32Attribs,
1893 psMapIonIN->ui32Size,
1894 &psKernelMemInfo);
1895 if (psMapIonOUT->eError != PVRSRV_OK)
1896 {
1897 PVR_DPF((PVR_DBG_ERROR, "%s: Failed to map ion handle", __FUNCTION__));
1898 return 0;
1899 }
1900
1901 OSMemSet(&psMapIonOUT->sClientMemInfo,
1902 0,
1903 sizeof(psMapIonOUT->sClientMemInfo));
1904
1905 psMapIonOUT->sClientMemInfo.pvLinAddrKM =
1906 psKernelMemInfo->pvLinAddrKM;
1907
1908 psMapIonOUT->sClientMemInfo.pvLinAddr = 0;
1909 psMapIonOUT->sClientMemInfo.sDevVAddr = psKernelMemInfo->sDevVAddr;
1910 psMapIonOUT->sClientMemInfo.ui32Flags = psKernelMemInfo->ui32Flags;
1911 psMapIonOUT->sClientMemInfo.uAllocSize = psKernelMemInfo->uAllocSize;
1912
1913 /* No mapping info, we map through ion */
1914 psMapIonOUT->sClientMemInfo.hMappingInfo = IMG_NULL;
1915
1916
1917 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1918 &psMapIonOUT->sClientMemInfo.hKernelMemInfo,
1919 psKernelMemInfo,
1920 PVRSRV_HANDLE_TYPE_MEM_INFO,
1921 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1922
1923 if(psMapIonIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ)
1924 {
1925 /* signal no syncinfo */
1926 OSMemSet(&psMapIonOUT->sClientSyncInfo,
1927 0,
1928 sizeof (PVRSRV_CLIENT_SYNC_INFO));
1929 psMapIonOUT->sClientMemInfo.psClientSyncInfo = IMG_NULL;
1930 }
1931 else
1932 {
1933 /* and setup the sync info */
1934#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
1935 psMapIonOUT->sClientSyncInfo.psSyncData =
1936 psKernelMemInfo->psKernelSyncInfo->psSyncData;
1937 psMapIonOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
1938 psKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
1939 psMapIonOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
1940 psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
1941 psMapIonOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
1942 psKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
1943
1944#if defined (SUPPORT_SID_INTERFACE)
1945 if (psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
1946 {
1947 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1948 &psMapIonOUT->sClientSyncInfo.hMappingInfo,
1949 psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
1950 PVRSRV_HANDLE_TYPE_SYNC_INFO,
1951 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1952 psMapIonOUT->sClientMemInfo.hKernelMemInfo);
1953 }
1954 else
1955 {
1956 psMapIonOUT->sClientSyncInfo.hMappingInfo = 0;
1957 }
1958#else
1959 psMapIonOUT->sClientSyncInfo.hMappingInfo =
1960 psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
1961#endif
1962#endif
1963
1964 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1965 &psMapIonOUT->sClientSyncInfo.hKernelSyncInfo,
1966 psKernelMemInfo->psKernelSyncInfo,
1967 PVRSRV_HANDLE_TYPE_SYNC_INFO,
1968 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1969 psMapIonOUT->sClientMemInfo.hKernelMemInfo);
1970
1971 psMapIonOUT->sClientMemInfo.psClientSyncInfo =
1972 &psMapIonOUT->sClientSyncInfo;
1973 }
1974 return 0;
1975}
1976
1977static IMG_INT
1978PVRSRVUnmapIonHandleBW(IMG_UINT32 ui32BridgeID,
1979 PVRSRV_BRIDGE_IN_UNMAP_ION_HANDLE *psUnmapIonIN,
1980 PVRSRV_BRIDGE_RETURN *psUnmapIonOUT,
1981 PVRSRV_PER_PROCESS_DATA *psPerProc)
1982{
1983 IMG_VOID *pvKernelMemInfo;
1984
1985 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_ION_HANDLE);
1986
1987 psUnmapIonOUT->eError =
1988 PVRSRVLookupHandle(psPerProc->psHandleBase,
1989 &pvKernelMemInfo,
1990#if defined (SUPPORT_SID_INTERFACE)
1991 psUnmapIonIN->hKernelMemInfo,
1992#else
1993 psUnmapIonIN->psKernelMemInfo,
1994#endif
1995 PVRSRV_HANDLE_TYPE_MEM_INFO);
1996
1997 if(psUnmapIonOUT->eError != PVRSRV_OK)
1998 {
1999 return 0;
2000 }
2001
2002 psUnmapIonOUT->eError = PVRSRVUnmapIonHandleKM(pvKernelMemInfo);
2003
2004 if(psUnmapIonOUT->eError != PVRSRV_OK)
2005 {
2006 return 0;
2007 }
2008
2009 psUnmapIonOUT->eError =
2010 PVRSRVReleaseHandle(psPerProc->psHandleBase,
2011#if defined (SUPPORT_SID_INTERFACE)
2012 psUnmapIonIN->hKernelMemInfo,
2013#else
2014 psUnmapIonIN->psKernelMemInfo,
2015#endif
2016 PVRSRV_HANDLE_TYPE_MEM_INFO);
2017
2018 return 0;
2019}
2020#endif /* SUPPORT_ION */
2021
2022static IMG_INT
2023PVRSRVGetFreeDeviceMemBW(IMG_UINT32 ui32BridgeID,
2024 PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM *psGetFreeDeviceMemIN,
2025 PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM *psGetFreeDeviceMemOUT,
2026 PVRSRV_PER_PROCESS_DATA *psPerProc)
2027{
2028 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETFREE_DEVICEMEM);
2029
2030 PVR_UNREFERENCED_PARAMETER(psPerProc);
2031
2032 psGetFreeDeviceMemOUT->eError =
2033 PVRSRVGetFreeDeviceMemKM(psGetFreeDeviceMemIN->ui32Flags,
2034 &psGetFreeDeviceMemOUT->ui32Total,
2035 &psGetFreeDeviceMemOUT->ui32Free,
2036 &psGetFreeDeviceMemOUT->ui32LargestBlock);
2037
2038 return 0;
2039}
2040
2041static IMG_INT
2042PVRMMapOSMemHandleToMMapDataBW(IMG_UINT32 ui32BridgeID,
2043 PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA *psMMapDataIN,
2044 PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA *psMMapDataOUT,
2045 PVRSRV_PER_PROCESS_DATA *psPerProc)
2046{
2047 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA);
2048
2049#if defined (__linux__) || defined (__QNXNTO__)
2050 psMMapDataOUT->eError =
2051 PVRMMapOSMemHandleToMMapData(psPerProc,
2052 psMMapDataIN->hMHandle,
2053 &psMMapDataOUT->ui32MMapOffset,
2054 &psMMapDataOUT->ui32ByteOffset,
2055 &psMMapDataOUT->ui32RealByteSize,
2056 &psMMapDataOUT->ui32UserVAddr);
2057#else
2058 PVR_UNREFERENCED_PARAMETER(psPerProc);
2059 PVR_UNREFERENCED_PARAMETER(psMMapDataIN);
2060
2061 psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
2062#endif
2063 return 0;
2064}
2065
2066
2067static IMG_INT
2068PVRMMapReleaseMMapDataBW(IMG_UINT32 ui32BridgeID,
2069 PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA *psMMapDataIN,
2070 PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA *psMMapDataOUT,
2071 PVRSRV_PER_PROCESS_DATA *psPerProc)
2072{
2073 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RELEASE_MMAP_DATA);
2074
2075#if defined (__linux__) || defined (__QNXNTO__)
2076 psMMapDataOUT->eError =
2077 PVRMMapReleaseMMapData(psPerProc,
2078 psMMapDataIN->hMHandle,
2079 &psMMapDataOUT->bMUnmap,
2080 &psMMapDataOUT->ui32RealByteSize,
2081 &psMMapDataOUT->ui32UserVAddr);
2082#else
2083
2084 PVR_UNREFERENCED_PARAMETER(psPerProc);
2085 PVR_UNREFERENCED_PARAMETER(psMMapDataIN);
2086
2087 psMMapDataOUT->eError = PVRSRV_ERROR_NOT_SUPPORTED;
2088#endif
2089 return 0;
2090}
2091
2092
2093#if defined (SUPPORT_SID_INTERFACE)
2094static IMG_INT
2095PVRSRVChangeDeviceMemoryAttributesBW(IMG_UINT32 ui32BridgeID,
2096 PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS *psChgMemAttribIN,
2097 PVRSRV_BRIDGE_RETURN *psRetOUT,
2098 PVRSRV_PER_PROCESS_DATA *psPerProc)
2099{
2100 IMG_HANDLE hKernelMemInfo;
2101
2102 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CHG_DEV_MEM_ATTRIBS);
2103
2104 psRetOUT->eError =
2105 PVRSRVLookupHandle(psPerProc->psHandleBase,
2106 &hKernelMemInfo,
2107 psChgMemAttribIN->hKernelMemInfo,
2108 PVRSRV_HANDLE_TYPE_MEM_INFO);
2109
2110 if(psRetOUT->eError != PVRSRV_OK)
2111 {
2112 return 0;
2113 }
2114
2115 psRetOUT->eError =
2116 PVRSRVChangeDeviceMemoryAttributesKM(hKernelMemInfo, psChgMemAttribIN->ui32Attribs);
2117
2118 return 0;
2119}
2120#else
2121static IMG_INT
2122PVRSRVChangeDeviceMemoryAttributesBW(IMG_UINT32 ui32BridgeID,
2123 PVRSRV_BRIDGE_IN_CHG_DEV_MEM_ATTRIBS *psChgMemAttribIN,
2124 PVRSRV_BRIDGE_RETURN *psRetOUT,
2125 PVRSRV_PER_PROCESS_DATA *psPerProc)
2126{
2127 PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
2128 PVR_UNREFERENCED_PARAMETER(psChgMemAttribIN);
2129 PVR_UNREFERENCED_PARAMETER(psRetOUT);
2130 PVR_UNREFERENCED_PARAMETER(psPerProc);
2131
2132 return 0;
2133}
2134#endif
2135
2136#ifdef PDUMP
2137static IMG_INT
2138PDumpIsCaptureFrameBW(IMG_UINT32 ui32BridgeID,
2139 IMG_VOID *psBridgeIn,
2140 PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING *psPDumpIsCapturingOUT,
2141 PVRSRV_PER_PROCESS_DATA *psPerProc)
2142{
2143 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_ISCAPTURING);
2144 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2145 PVR_UNREFERENCED_PARAMETER(psPerProc);
2146
2147 psPDumpIsCapturingOUT->bIsCapturing = PDumpIsCaptureFrameKM();
2148 psPDumpIsCapturingOUT->eError = PVRSRV_OK;
2149
2150 return 0;
2151}
2152
2153static IMG_INT
2154PDumpCommentBW(IMG_UINT32 ui32BridgeID,
2155 PVRSRV_BRIDGE_IN_PDUMP_COMMENT *psPDumpCommentIN,
2156 PVRSRV_BRIDGE_RETURN *psRetOUT,
2157 PVRSRV_PER_PROCESS_DATA *psPerProc)
2158{
2159 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_COMMENT);
2160 PVR_UNREFERENCED_PARAMETER(psPerProc);
2161
2162 psRetOUT->eError = PDumpCommentKM(&psPDumpCommentIN->szComment[0],
2163 psPDumpCommentIN->ui32Flags);
2164 return 0;
2165}
2166
2167static IMG_INT
2168PDumpSetFrameBW(IMG_UINT32 ui32BridgeID,
2169 PVRSRV_BRIDGE_IN_PDUMP_SETFRAME *psPDumpSetFrameIN,
2170 PVRSRV_BRIDGE_RETURN *psRetOUT,
2171 PVRSRV_PER_PROCESS_DATA *psPerProc)
2172{
2173 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SETFRAME);
2174 PVR_UNREFERENCED_PARAMETER(psPerProc);
2175
2176 psRetOUT->eError = PDumpSetFrameKM(psPDumpSetFrameIN->ui32Frame);
2177
2178 return 0;
2179}
2180
2181static IMG_INT
2182PDumpRegWithFlagsBW(IMG_UINT32 ui32BridgeID,
2183 PVRSRV_BRIDGE_IN_PDUMP_DUMPREG *psPDumpRegDumpIN,
2184 PVRSRV_BRIDGE_RETURN *psRetOUT,
2185 PVRSRV_PER_PROCESS_DATA *psPerProc)
2186{
2187 PVRSRV_DEVICE_NODE *psDeviceNode;
2188
2189 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REG);
2190
2191 psRetOUT->eError =
2192 PVRSRVLookupHandle(psPerProc->psHandleBase,
2193 (IMG_VOID **)&psDeviceNode,
2194 psPDumpRegDumpIN->hDevCookie,
2195 PVRSRV_HANDLE_TYPE_DEV_NODE);
2196 if(psRetOUT->eError != PVRSRV_OK)
2197 {
2198 return 0;
2199 }
2200
2201 psRetOUT->eError = PDumpRegWithFlagsKM (psPDumpRegDumpIN->szRegRegion,
2202 psPDumpRegDumpIN->sHWReg.ui32RegAddr,
2203 psPDumpRegDumpIN->sHWReg.ui32RegVal,
2204 psPDumpRegDumpIN->ui32Flags);
2205
2206 return 0;
2207}
2208
2209static IMG_INT
2210PDumpRegPolBW(IMG_UINT32 ui32BridgeID,
2211 PVRSRV_BRIDGE_IN_PDUMP_REGPOL *psPDumpRegPolIN,
2212 PVRSRV_BRIDGE_RETURN *psRetOUT,
2213 PVRSRV_PER_PROCESS_DATA *psPerProc)
2214{
2215 PVRSRV_DEVICE_NODE *psDeviceNode;
2216
2217 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REGPOL);
2218
2219 psRetOUT->eError =
2220 PVRSRVLookupHandle(psPerProc->psHandleBase,
2221 (IMG_VOID **)&psDeviceNode,
2222 psPDumpRegPolIN->hDevCookie,
2223 PVRSRV_HANDLE_TYPE_DEV_NODE);
2224 if(psRetOUT->eError != PVRSRV_OK)
2225 {
2226 return 0;
2227 }
2228
2229
2230 psRetOUT->eError =
2231 PDumpRegPolWithFlagsKM(psPDumpRegPolIN->szRegRegion,
2232 psPDumpRegPolIN->sHWReg.ui32RegAddr,
2233 psPDumpRegPolIN->sHWReg.ui32RegVal,
2234 psPDumpRegPolIN->ui32Mask,
2235 psPDumpRegPolIN->ui32Flags,
2236 PDUMP_POLL_OPERATOR_EQUAL);
2237
2238 return 0;
2239}
2240
2241static IMG_INT
2242PDumpMemPolBW(IMG_UINT32 ui32BridgeID,
2243 PVRSRV_BRIDGE_IN_PDUMP_MEMPOL *psPDumpMemPolIN,
2244 PVRSRV_BRIDGE_RETURN *psRetOUT,
2245 PVRSRV_PER_PROCESS_DATA *psPerProc)
2246{
2247 IMG_VOID *pvMemInfo;
2248
2249 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPOL);
2250
2251 psRetOUT->eError =
2252 PVRSRVLookupHandle(psPerProc->psHandleBase,
2253 &pvMemInfo,
2254#if defined (SUPPORT_SID_INTERFACE)
2255 psPDumpMemPolIN->hKernelMemInfo,
2256#else
2257 psPDumpMemPolIN->psKernelMemInfo,
2258#endif
2259 PVRSRV_HANDLE_TYPE_MEM_INFO);
2260 if(psRetOUT->eError != PVRSRV_OK)
2261 {
2262 return 0;
2263 }
2264
2265 psRetOUT->eError =
2266 PDumpMemPolKM(((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo),
2267 psPDumpMemPolIN->ui32Offset,
2268 psPDumpMemPolIN->ui32Value,
2269 psPDumpMemPolIN->ui32Mask,
2270 psPDumpMemPolIN->eOperator,
2271 psPDumpMemPolIN->ui32Flags,
2272 MAKEUNIQUETAG(pvMemInfo));
2273
2274 return 0;
2275}
2276
2277static IMG_INT
2278PDumpMemBW(IMG_UINT32 ui32BridgeID,
2279 PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM *psPDumpMemDumpIN,
2280 PVRSRV_BRIDGE_RETURN *psRetOUT,
2281 PVRSRV_PER_PROCESS_DATA *psPerProc)
2282{
2283 IMG_VOID *pvMemInfo;
2284
2285 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPMEM);
2286
2287 psRetOUT->eError =
2288 PVRSRVLookupHandle(psPerProc->psHandleBase,
2289 &pvMemInfo,
2290#if defined (SUPPORT_SID_INTERFACE)
2291 psPDumpMemDumpIN->hKernelMemInfo,
2292#else
2293 psPDumpMemDumpIN->psKernelMemInfo,
2294#endif
2295 PVRSRV_HANDLE_TYPE_MEM_INFO);
2296 if(psRetOUT->eError != PVRSRV_OK)
2297 {
2298 return 0;
2299 }
2300
2301 psRetOUT->eError =
2302 PDumpMemUM(psPerProc,
2303 psPDumpMemDumpIN->pvAltLinAddr,
2304 psPDumpMemDumpIN->pvLinAddr,
2305 pvMemInfo,
2306 psPDumpMemDumpIN->ui32Offset,
2307 psPDumpMemDumpIN->ui32Bytes,
2308 psPDumpMemDumpIN->ui32Flags,
2309 MAKEUNIQUETAG(pvMemInfo));
2310
2311 return 0;
2312}
2313
2314static IMG_INT
2315PDumpBitmapBW(IMG_UINT32 ui32BridgeID,
2316 PVRSRV_BRIDGE_IN_PDUMP_BITMAP *psPDumpBitmapIN,
2317 PVRSRV_BRIDGE_RETURN *psRetOUT,
2318 PVRSRV_PER_PROCESS_DATA *psPerProc)
2319{
2320 PVRSRV_DEVICE_NODE *psDeviceNode;
2321 IMG_HANDLE hDevMemContextInt;
2322
2323 PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
2324
2325 psRetOUT->eError =
2326 PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode,
2327 psPDumpBitmapIN->hDevCookie,
2328 PVRSRV_HANDLE_TYPE_DEV_NODE);
2329
2330 psRetOUT->eError =
2331 PVRSRVLookupHandle( psPerProc->psHandleBase,
2332 &hDevMemContextInt,
2333 psPDumpBitmapIN->hDevMemContext,
2334 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
2335
2336 if(psRetOUT->eError != PVRSRV_OK)
2337 {
2338 return 0;
2339 }
2340
2341 psRetOUT->eError =
2342 PDumpBitmapKM(psDeviceNode,
2343 &psPDumpBitmapIN->szFileName[0],
2344 psPDumpBitmapIN->ui32FileOffset,
2345 psPDumpBitmapIN->ui32Width,
2346 psPDumpBitmapIN->ui32Height,
2347 psPDumpBitmapIN->ui32StrideInBytes,
2348 psPDumpBitmapIN->sDevBaseAddr,
2349 hDevMemContextInt,
2350 psPDumpBitmapIN->ui32Size,
2351 psPDumpBitmapIN->ePixelFormat,
2352 psPDumpBitmapIN->eMemFormat,
2353 psPDumpBitmapIN->ui32Flags);
2354
2355 return 0;
2356}
2357
2358static IMG_INT
2359PDumpReadRegBW(IMG_UINT32 ui32BridgeID,
2360 PVRSRV_BRIDGE_IN_PDUMP_READREG *psPDumpReadRegIN,
2361 PVRSRV_BRIDGE_RETURN *psRetOUT,
2362 PVRSRV_PER_PROCESS_DATA *psPerProc)
2363{
2364 PVRSRV_DEVICE_NODE *psDeviceNode;
2365
2366 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPREADREG);
2367
2368 psRetOUT->eError =
2369 PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_VOID **)&psDeviceNode,
2370 psPDumpReadRegIN->hDevCookie,
2371 PVRSRV_HANDLE_TYPE_DEV_NODE);
2372
2373 psRetOUT->eError =
2374 PDumpReadRegKM(&psPDumpReadRegIN->szRegRegion[0],
2375 &psPDumpReadRegIN->szFileName[0],
2376 psPDumpReadRegIN->ui32FileOffset,
2377 psPDumpReadRegIN->ui32Address,
2378 psPDumpReadRegIN->ui32Size,
2379 psPDumpReadRegIN->ui32Flags);
2380
2381 return 0;
2382}
2383
2384static IMG_INT
2385PDumpMemPagesBW(IMG_UINT32 ui32BridgeID,
2386 PVRSRV_BRIDGE_IN_PDUMP_MEMPAGES *psPDumpMemPagesIN,
2387 PVRSRV_BRIDGE_RETURN *psRetOUT,
2388 PVRSRV_PER_PROCESS_DATA *psPerProc)
2389{
2390 PVRSRV_DEVICE_NODE *psDeviceNode;
2391
2392 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPAGES);
2393
2394 psRetOUT->eError =
2395 PVRSRVLookupHandle(psPerProc->psHandleBase,
2396 (IMG_VOID **)&psDeviceNode,
2397 psPDumpMemPagesIN->hDevCookie,
2398 PVRSRV_HANDLE_TYPE_DEV_NODE);
2399
2400 if(psRetOUT->eError != PVRSRV_OK)
2401 {
2402 return 0;
2403 }
2404
2405
2406 return 0;
2407}
2408
2409static IMG_INT
2410PDumpDriverInfoBW(IMG_UINT32 ui32BridgeID,
2411 PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO *psPDumpDriverInfoIN,
2412 PVRSRV_BRIDGE_RETURN *psRetOUT,
2413 PVRSRV_PER_PROCESS_DATA *psPerProc)
2414{
2415 IMG_UINT32 ui32PDumpFlags;
2416
2417 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DRIVERINFO);
2418 PVR_UNREFERENCED_PARAMETER(psPerProc);
2419
2420 ui32PDumpFlags = 0;
2421 if(psPDumpDriverInfoIN->bContinuous)
2422 {
2423 ui32PDumpFlags |= PDUMP_FLAGS_CONTINUOUS;
2424 }
2425 psRetOUT->eError =
2426 PDumpDriverInfoKM(&psPDumpDriverInfoIN->szString[0],
2427 ui32PDumpFlags);
2428
2429 return 0;
2430}
2431
2432static IMG_INT
2433PDumpSyncDumpBW(IMG_UINT32 ui32BridgeID,
2434 PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC *psPDumpSyncDumpIN,
2435 PVRSRV_BRIDGE_RETURN *psRetOUT,
2436 PVRSRV_PER_PROCESS_DATA *psPerProc)
2437{
2438 IMG_UINT32 ui32Bytes = psPDumpSyncDumpIN->ui32Bytes;
2439 IMG_VOID *pvSyncInfo;
2440
2441 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPSYNC);
2442
2443 psRetOUT->eError =
2444 PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
2445#if defined (SUPPORT_SID_INTERFACE)
2446 psPDumpSyncDumpIN->hKernelSyncInfo,
2447#else
2448 psPDumpSyncDumpIN->psKernelSyncInfo,
2449#endif
2450 PVRSRV_HANDLE_TYPE_SYNC_INFO);
2451 if(psRetOUT->eError != PVRSRV_OK)
2452 {
2453 return 0;
2454 }
2455
2456 psRetOUT->eError =
2457 PDumpMemUM(psPerProc,
2458 psPDumpSyncDumpIN->pvAltLinAddr,
2459 IMG_NULL,
2460 ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM,
2461 psPDumpSyncDumpIN->ui32Offset,
2462 ui32Bytes,
2463 0,
2464 MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM));
2465
2466 return 0;
2467}
2468
2469static IMG_INT
2470PDumpSyncPolBW(IMG_UINT32 ui32BridgeID,
2471 PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL *psPDumpSyncPolIN,
2472 PVRSRV_BRIDGE_RETURN *psRetOUT,
2473 PVRSRV_PER_PROCESS_DATA *psPerProc)
2474{
2475 IMG_UINT32 ui32Offset;
2476 IMG_VOID *pvSyncInfo;
2477 IMG_UINT32 ui32Value;
2478 IMG_UINT32 ui32Mask;
2479
2480 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SYNCPOL);
2481
2482 psRetOUT->eError =
2483 PVRSRVLookupHandle(psPerProc->psHandleBase,
2484 &pvSyncInfo,
2485#if defined (SUPPORT_SID_INTERFACE)
2486 psPDumpSyncPolIN->hKernelSyncInfo,
2487#else
2488 psPDumpSyncPolIN->psKernelSyncInfo,
2489#endif
2490 PVRSRV_HANDLE_TYPE_SYNC_INFO);
2491 if(psRetOUT->eError != PVRSRV_OK)
2492 {
2493 return 0;
2494 }
2495
2496 if(psPDumpSyncPolIN->bIsRead)
2497 {
2498 ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
2499 }
2500 else
2501 {
2502 ui32Offset = offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete);
2503 }
2504
2505 /* FIXME: Move this code to somewhere outside of the bridge */
2506 if (psPDumpSyncPolIN->bUseLastOpDumpVal)
2507 {
2508 if(psPDumpSyncPolIN->bIsRead)
2509 {
2510 ui32Value = ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncData->ui32LastReadOpDumpVal;
2511 }
2512 else
2513 {
2514 ui32Value = ((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncData->ui32LastOpDumpVal;
2515 }
2516 ui32Mask = 0xffffffff;
2517 }
2518 else
2519 {
2520 ui32Value = psPDumpSyncPolIN->ui32Value;
2521 ui32Mask = psPDumpSyncPolIN->ui32Mask;
2522 }
2523
2524 psRetOUT->eError =
2525 PDumpMemPolKM(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM,
2526 ui32Offset,
2527 ui32Value,
2528 ui32Mask,
2529 PDUMP_POLL_OPERATOR_EQUAL,
2530 0,
2531 MAKEUNIQUETAG(((PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->psSyncDataMemInfoKM));
2532
2533 return 0;
2534}
2535
2536
2537static IMG_INT
2538PDumpCycleCountRegReadBW(IMG_UINT32 ui32BridgeID,
2539 PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ *psPDumpCycleCountRegReadIN,
2540 PVRSRV_BRIDGE_RETURN *psRetOUT,
2541 PVRSRV_PER_PROCESS_DATA *psPerProc)
2542{
2543 PVRSRV_DEVICE_NODE *psDeviceNode;
2544
2545 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ);
2546
2547 psRetOUT->eError =
2548 PVRSRVLookupHandle(psPerProc->psHandleBase,
2549 (IMG_VOID **)&psDeviceNode,
2550 psPDumpCycleCountRegReadIN->hDevCookie,
2551 PVRSRV_HANDLE_TYPE_DEV_NODE);
2552 if(psRetOUT->eError != PVRSRV_OK)
2553 {
2554 return 0;
2555 }
2556
2557 PDumpCycleCountRegRead(&psDeviceNode->sDevId,
2558 psPDumpCycleCountRegReadIN->ui32RegOffset,
2559 psPDumpCycleCountRegReadIN->bLastFrame);
2560
2561 psRetOUT->eError = PVRSRV_OK;
2562
2563 return 0;
2564}
2565
2566static IMG_INT
2567PDumpPDDevPAddrBW(IMG_UINT32 ui32BridgeID,
2568 PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR *psPDumpPDDevPAddrIN,
2569 PVRSRV_BRIDGE_RETURN *psRetOUT,
2570 PVRSRV_PER_PROCESS_DATA *psPerProc)
2571{
2572 IMG_VOID *pvMemInfo;
2573
2574 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR);
2575
2576 psRetOUT->eError =
2577 PVRSRVLookupHandle(psPerProc->psHandleBase, &pvMemInfo,
2578 psPDumpPDDevPAddrIN->hKernelMemInfo,
2579 PVRSRV_HANDLE_TYPE_MEM_INFO);
2580 if(psRetOUT->eError != PVRSRV_OK)
2581 {
2582 return 0;
2583 }
2584
2585 psRetOUT->eError =
2586 PDumpPDDevPAddrKM((PVRSRV_KERNEL_MEM_INFO *)pvMemInfo,
2587 psPDumpPDDevPAddrIN->ui32Offset,
2588 psPDumpPDDevPAddrIN->sPDDevPAddr,
2589 MAKEUNIQUETAG(pvMemInfo),
2590 PDUMP_PD_UNIQUETAG);
2591 return 0;
2592}
2593
2594static IMG_INT
2595PDumpStartInitPhaseBW(IMG_UINT32 ui32BridgeID,
2596 IMG_VOID *psBridgeIn,
2597 PVRSRV_BRIDGE_RETURN *psRetOUT,
2598 PVRSRV_PER_PROCESS_DATA *psPerProc)
2599{
2600 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STARTINITPHASE);
2601 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2602 PVR_UNREFERENCED_PARAMETER(psPerProc);
2603
2604 psRetOUT->eError = PDumpStartInitPhaseKM();
2605
2606 return 0;
2607}
2608
2609static IMG_INT
2610PDumpStopInitPhaseBW(IMG_UINT32 ui32BridgeID,
2611 IMG_VOID *psBridgeIn,
2612 PVRSRV_BRIDGE_RETURN *psRetOUT,
2613 PVRSRV_PER_PROCESS_DATA *psPerProc)
2614{
2615 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_STOPINITPHASE);
2616 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2617 PVR_UNREFERENCED_PARAMETER(psPerProc);
2618
2619 psRetOUT->eError = PDumpStopInitPhaseKM();
2620
2621 return 0;
2622}
2623
2624#endif /* PDUMP */
2625
2626
2627static IMG_INT
2628PVRSRVGetMiscInfoBW(IMG_UINT32 ui32BridgeID,
2629 PVRSRV_BRIDGE_IN_GET_MISC_INFO *psGetMiscInfoIN,
2630 PVRSRV_BRIDGE_OUT_GET_MISC_INFO *psGetMiscInfoOUT,
2631 PVRSRV_PER_PROCESS_DATA *psPerProc)
2632{
2633#if defined (SUPPORT_SID_INTERFACE)
2634 PVRSRV_MISC_INFO_KM sMiscInfo = {0};
2635#endif
2636 PVRSRV_ERROR eError;
2637
2638 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_MISC_INFO);
2639
2640#if defined (SUPPORT_SID_INTERFACE)
2641 sMiscInfo.ui32StateRequest = psGetMiscInfoIN->sMiscInfo.ui32StateRequest;
2642 sMiscInfo.ui32StatePresent = psGetMiscInfoIN->sMiscInfo.ui32StatePresent;
2643 sMiscInfo.ui32MemoryStrLen = psGetMiscInfoIN->sMiscInfo.ui32MemoryStrLen;
2644 sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
2645
2646 OSMemCopy(&sMiscInfo.sCacheOpCtl,
2647 &psGetMiscInfoIN->sMiscInfo.sCacheOpCtl,
2648 sizeof(sMiscInfo.sCacheOpCtl));
2649 OSMemCopy(&sMiscInfo.sGetRefCountCtl,
2650 &psGetMiscInfoIN->sMiscInfo.sGetRefCountCtl,
2651 sizeof(sMiscInfo.sGetRefCountCtl));
2652#else
2653 OSMemCopy(&psGetMiscInfoOUT->sMiscInfo,
2654 &psGetMiscInfoIN->sMiscInfo,
2655 sizeof(PVRSRV_MISC_INFO));
2656#endif
2657
2658 if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) &&
2659 ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0) &&
2660 ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0))
2661 {
2662 /* Client must choose which of memstats and DDK version will be written to
2663 * kernel side buffer */
2664 psGetMiscInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
2665 return 0;
2666 }
2667
2668 if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) ||
2669 ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0) ||
2670 ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0))
2671 {
2672 /* Alloc kernel side buffer to write into */
2673#if defined (SUPPORT_SID_INTERFACE)
2674 ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError,
2675 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
2676 psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
2677 (IMG_VOID **)&sMiscInfo.pszMemoryStr, 0,
2678 "Output string buffer"));
2679 psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&sMiscInfo);
2680
2681 /* Copy result to user */
2682 eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
2683 psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
2684 sMiscInfo.pszMemoryStr,
2685 sMiscInfo.ui32MemoryStrLen);
2686#else
2687 ASSIGN_AND_EXIT_ON_ERROR(psGetMiscInfoOUT->eError,
2688 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
2689 psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
2690 (IMG_VOID **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0,
2691 "Output string buffer"));
2692
2693 psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
2694
2695 /* Copy result to user */
2696 eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
2697 psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
2698 psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
2699 psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen);
2700#endif
2701
2702 /* Free kernel side buffer again */
2703#if defined (SUPPORT_SID_INTERFACE)
2704 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
2705 sMiscInfo.ui32MemoryStrLen,
2706 (IMG_VOID *)sMiscInfo.pszMemoryStr, 0);
2707#else
2708 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
2709 psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
2710 (IMG_VOID *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr, 0);
2711#endif
2712
2713 /* Replace output buffer pointer with input pointer, as both are expected
2714 * to point to the same userspace memory.
2715 */
2716 psGetMiscInfoOUT->sMiscInfo.pszMemoryStr = psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
2717
2718 if(eError != PVRSRV_OK)
2719 {
2720 /* Do error check at the end as we always have to free and reset the
2721 * pointer.
2722 */
2723 PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoBW Error copy to user"));
2724 return -EFAULT;
2725 }
2726 }
2727 else
2728 {
2729#if defined (SUPPORT_SID_INTERFACE)
2730 psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&sMiscInfo);
2731#else
2732 psGetMiscInfoOUT->eError = PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
2733#endif
2734 }
2735
2736 /* Return on error so exit status of PVRSRVGetMiscInfoKM is propagated to client.
2737 * Don't alloc handles for event object or timer; if error exit status is returned
2738 * the handles should not be used (even if not null) */
2739 if (psGetMiscInfoOUT->eError != PVRSRV_OK)
2740 {
2741 return 0;
2742 }
2743
2744 /*
2745 * The handles are not allocated in batch mode as they are shared
2746 * (a shared handle is allocated at most once), and there is no
2747 * resource allocation to undo if the handle allocation fails.
2748 */
2749#if defined (SUPPORT_SID_INTERFACE)
2750 if (sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT)
2751#else
2752 if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT)
2753#endif
2754 {
2755 psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
2756 &psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
2757#if defined (SUPPORT_SID_INTERFACE)
2758 sMiscInfo.sGlobalEventObject.hOSEventKM,
2759#else
2760 psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.hOSEventKM,
2761#endif
2762 PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
2763 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
2764
2765 if (psGetMiscInfoOUT->eError != PVRSRV_OK)
2766 {
2767 return 0;
2768 }
2769
2770#if defined (SUPPORT_SID_INTERFACE)
2771 OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.sGlobalEventObject.szName,
2772 sMiscInfo.sGlobalEventObject.szName,
2773 EVENTOBJNAME_MAXLENGTH);
2774#endif
2775 }
2776
2777#if defined (SUPPORT_SID_INTERFACE)
2778 if (sMiscInfo.hSOCTimerRegisterOSMemHandle)
2779#else
2780 if (psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle)
2781#endif
2782 {
2783 /* Allocate handle for SOC OSMemHandle */
2784 psGetMiscInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
2785 &psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
2786#if defined (SUPPORT_SID_INTERFACE)
2787 sMiscInfo.hSOCTimerRegisterOSMemHandle,
2788#else
2789 psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle,
2790#endif
2791 PVRSRV_HANDLE_TYPE_SOC_TIMER,
2792 PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
2793
2794 if (psGetMiscInfoOUT->eError != PVRSRV_OK)
2795 {
2796 return 0;
2797 }
2798 }
2799#if defined (SUPPORT_SID_INTERFACE)
2800 else
2801 {
2802 psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle = 0;
2803 }
2804
2805 /* copy data from local sMiscInfo to OUT */
2806 psGetMiscInfoOUT->sMiscInfo.ui32StateRequest = sMiscInfo.ui32StateRequest;
2807 psGetMiscInfoOUT->sMiscInfo.ui32StatePresent = sMiscInfo.ui32StatePresent;
2808
2809 psGetMiscInfoOUT->sMiscInfo.pvSOCTimerRegisterKM = sMiscInfo.pvSOCTimerRegisterKM;
2810 psGetMiscInfoOUT->sMiscInfo.pvSOCTimerRegisterUM = sMiscInfo.pvSOCTimerRegisterUM;
2811 psGetMiscInfoOUT->sMiscInfo.pvSOCClockGateRegs = sMiscInfo.pvSOCClockGateRegs;
2812
2813 psGetMiscInfoOUT->sMiscInfo.ui32SOCClockGateRegsSize = sMiscInfo.ui32SOCClockGateRegsSize;
2814
2815 OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.aui32DDKVersion,
2816 &sMiscInfo.aui32DDKVersion,
2817 sizeof(psGetMiscInfoOUT->sMiscInfo.aui32DDKVersion));
2818 OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.sCacheOpCtl,
2819 &sMiscInfo.sCacheOpCtl,
2820 sizeof(psGetMiscInfoOUT->sMiscInfo.sCacheOpCtl));
2821 OSMemCopy(&psGetMiscInfoOUT->sMiscInfo.sGetRefCountCtl,
2822 &sMiscInfo.sGetRefCountCtl,
2823 sizeof(psGetMiscInfoOUT->sMiscInfo.sGetRefCountCtl));
2824#endif
2825
2826 return 0;
2827}
2828
2829static IMG_INT
2830PVRSRVConnectBW(IMG_UINT32 ui32BridgeID,
2831 PVRSRV_BRIDGE_IN_CONNECT_SERVICES *psConnectServicesIN,
2832 PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *psConnectServicesOUT,
2833 PVRSRV_PER_PROCESS_DATA *psPerProc)
2834{
2835 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CONNECT_SERVICES);
2836
2837#if defined(PDUMP)
2838 /* Store the per process connection info.
2839 * The Xserver initially connects via PVR2D which sets the persistent flag.
2840 * But, later the Xserver may connect via SGL which doesn't carry the flag (in
2841 * general SGL clients aren't persistent). So we OR in the flag so if it was set
2842 * before it remains set.
2843 */
2844 if ((psConnectServicesIN->ui32Flags & SRV_FLAGS_PERSIST) != 0)
2845 {
2846 psPerProc->bPDumpPersistent = IMG_TRUE;
2847 }
2848
2849#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
2850 /* Select whether this client is our 'active' target for pdumping in a
2851 * multi-process environment.
2852 * NOTE: only 1 active target is supported at present.
2853 */
2854 if ((psConnectServicesIN->ui32Flags & SRV_FLAGS_PDUMP_ACTIVE) != 0)
2855 {
2856 psPerProc->bPDumpActive = IMG_TRUE;
2857 }
2858#endif /* SUPPORT_PDUMP_MULTI_PROCESS */
2859#else
2860 PVR_UNREFERENCED_PARAMETER(psConnectServicesIN);
2861#endif
2862 psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData;
2863 psConnectServicesOUT->eError = PVRSRV_OK;
2864
2865 return 0;
2866}
2867
2868static IMG_INT
2869PVRSRVDisconnectBW(IMG_UINT32 ui32BridgeID,
2870 IMG_VOID *psBridgeIn,
2871 PVRSRV_BRIDGE_RETURN *psRetOUT,
2872 PVRSRV_PER_PROCESS_DATA *psPerProc)
2873{
2874 PVR_UNREFERENCED_PARAMETER(psPerProc);
2875 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2876
2877 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DISCONNECT_SERVICES);
2878
2879 /* just return OK, per-process data is cleaned up by resmgr */
2880 psRetOUT->eError = PVRSRV_OK;
2881
2882 return 0;
2883}
2884
2885static IMG_INT
2886PVRSRVEnumerateDCBW(IMG_UINT32 ui32BridgeID,
2887 PVRSRV_BRIDGE_IN_ENUMCLASS *psEnumDispClassIN,
2888 PVRSRV_BRIDGE_OUT_ENUMCLASS *psEnumDispClassOUT,
2889 PVRSRV_PER_PROCESS_DATA *psPerProc)
2890{
2891 PVR_UNREFERENCED_PARAMETER(psPerProc);
2892
2893 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_CLASS);
2894
2895 psEnumDispClassOUT->eError =
2896 PVRSRVEnumerateDCKM(psEnumDispClassIN->sDeviceClass,
2897 &psEnumDispClassOUT->ui32NumDevices,
2898 &psEnumDispClassOUT->ui32DevID[0]);
2899
2900 return 0;
2901}
2902
2903static IMG_INT
2904PVRSRVOpenDCDeviceBW(IMG_UINT32 ui32BridgeID,
2905 PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceIN,
2906 PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceOUT,
2907 PVRSRV_PER_PROCESS_DATA *psPerProc)
2908{
2909 IMG_HANDLE hDevCookieInt;
2910 IMG_HANDLE hDispClassInfoInt;
2911
2912 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE);
2913
2914 NEW_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc, 1)
2915
2916 psOpenDispClassDeviceOUT->eError =
2917 PVRSRVLookupHandle(psPerProc->psHandleBase,
2918 &hDevCookieInt,
2919 psOpenDispClassDeviceIN->hDevCookie,
2920 PVRSRV_HANDLE_TYPE_DEV_NODE);
2921 if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
2922 {
2923 return 0;
2924 }
2925
2926 psOpenDispClassDeviceOUT->eError =
2927 PVRSRVOpenDCDeviceKM(psPerProc,
2928 psOpenDispClassDeviceIN->ui32DeviceID,
2929 hDevCookieInt,
2930 &hDispClassInfoInt);
2931
2932 if(psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
2933 {
2934 return 0;
2935 }
2936
2937 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
2938 &psOpenDispClassDeviceOUT->hDeviceKM,
2939 hDispClassInfoInt,
2940 PVRSRV_HANDLE_TYPE_DISP_INFO,
2941 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
2942 COMMIT_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc)
2943
2944 return 0;
2945}
2946
2947static IMG_INT
2948PVRSRVCloseDCDeviceBW(IMG_UINT32 ui32BridgeID,
2949 PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE *psCloseDispClassDeviceIN,
2950 PVRSRV_BRIDGE_RETURN *psRetOUT,
2951 PVRSRV_PER_PROCESS_DATA *psPerProc)
2952{
2953 IMG_VOID *pvDispClassInfoInt;
2954
2955 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE);
2956
2957 psRetOUT->eError =
2958 PVRSRVLookupHandle(psPerProc->psHandleBase,
2959 &pvDispClassInfoInt,
2960 psCloseDispClassDeviceIN->hDeviceKM,
2961 PVRSRV_HANDLE_TYPE_DISP_INFO);
2962
2963 if(psRetOUT->eError != PVRSRV_OK)
2964 {
2965 return 0;
2966 }
2967
2968 psRetOUT->eError = PVRSRVCloseDCDeviceKM(pvDispClassInfoInt);
2969 if(psRetOUT->eError != PVRSRV_OK)
2970 {
2971 return 0;
2972 }
2973
2974 psRetOUT->eError =
2975 PVRSRVReleaseHandle(psPerProc->psHandleBase,
2976 psCloseDispClassDeviceIN->hDeviceKM,
2977 PVRSRV_HANDLE_TYPE_DISP_INFO);
2978 return 0;
2979}
2980
2981static IMG_INT
2982PVRSRVEnumDCFormatsBW(IMG_UINT32 ui32BridgeID,
2983 PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsIN,
2984 PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsOUT,
2985 PVRSRV_PER_PROCESS_DATA *psPerProc)
2986{
2987 IMG_VOID *pvDispClassInfoInt;
2988
2989 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS);
2990
2991 psEnumDispClassFormatsOUT->eError =
2992 PVRSRVLookupHandle(psPerProc->psHandleBase,
2993 &pvDispClassInfoInt,
2994 psEnumDispClassFormatsIN->hDeviceKM,
2995 PVRSRV_HANDLE_TYPE_DISP_INFO);
2996 if(psEnumDispClassFormatsOUT->eError != PVRSRV_OK)
2997 {
2998 return 0;
2999 }
3000
3001 psEnumDispClassFormatsOUT->eError =
3002 PVRSRVEnumDCFormatsKM(pvDispClassInfoInt,
3003 &psEnumDispClassFormatsOUT->ui32Count,
3004 psEnumDispClassFormatsOUT->asFormat);
3005
3006 return 0;
3007}
3008
3009static IMG_INT
3010PVRSRVEnumDCDimsBW(IMG_UINT32 ui32BridgeID,
3011 PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsIN,
3012 PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsOUT,
3013 PVRSRV_PER_PROCESS_DATA *psPerProc)
3014{
3015 IMG_VOID *pvDispClassInfoInt;
3016
3017 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS);
3018
3019 psEnumDispClassDimsOUT->eError =
3020 PVRSRVLookupHandle(psPerProc->psHandleBase,
3021 &pvDispClassInfoInt,
3022 psEnumDispClassDimsIN->hDeviceKM,
3023 PVRSRV_HANDLE_TYPE_DISP_INFO);
3024
3025 if(psEnumDispClassDimsOUT->eError != PVRSRV_OK)
3026 {
3027 return 0;
3028 }
3029
3030 psEnumDispClassDimsOUT->eError =
3031 PVRSRVEnumDCDimsKM(pvDispClassInfoInt,
3032 &psEnumDispClassDimsIN->sFormat,
3033 &psEnumDispClassDimsOUT->ui32Count,
3034 psEnumDispClassDimsOUT->asDim);
3035
3036 return 0;
3037}
3038
3039#if defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER)
3040static IMG_INT
3041PVRSRVGetDCSystemBufferBW(IMG_UINT32 ui32BridgeID,
3042 PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferIN, //IMG_HANDLE *phGetDispClassSysBufferIN,
3043 PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferOUT,
3044 PVRSRV_PER_PROCESS_DATA *psPerProc)
3045{
3046 IMG_HANDLE hBufferInt;
3047 IMG_VOID *pvDispClassInfoInt;
3048
3049 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER);
3050
3051 NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc, 1)
3052
3053 psGetDispClassSysBufferOUT->eError =
3054 PVRSRVLookupHandle(psPerProc->psHandleBase,
3055 &pvDispClassInfoInt,
3056 psGetDispClassSysBufferIN->hDeviceKM,
3057 PVRSRV_HANDLE_TYPE_DISP_INFO);
3058 if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
3059 {
3060 return 0;
3061 }
3062
3063 psGetDispClassSysBufferOUT->eError =
3064 PVRSRVGetDCSystemBufferKM(pvDispClassInfoInt,
3065 &hBufferInt);
3066
3067 if(psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
3068 {
3069 return 0;
3070 }
3071
3072 /* PRQA S 1461 6 */ /* ignore warning about enum type being converted */
3073 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
3074 &psGetDispClassSysBufferOUT->hBuffer,
3075 hBufferInt,
3076 PVRSRV_HANDLE_TYPE_DISP_BUFFER,
3077 (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
3078 psGetDispClassSysBufferIN->hDeviceKM);
3079
3080 COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc)
3081
3082 return 0;
3083}
3084#endif
3085
3086static IMG_INT
3087PVRSRVGetDCInfoBW(IMG_UINT32 ui32BridgeID,
3088 PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO *psGetDispClassInfoIN,
3089 PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO *psGetDispClassInfoOUT,
3090 PVRSRV_PER_PROCESS_DATA *psPerProc)
3091{
3092 IMG_VOID *pvDispClassInfo;
3093
3094 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_INFO);
3095
3096 psGetDispClassInfoOUT->eError =
3097 PVRSRVLookupHandle(psPerProc->psHandleBase,
3098 &pvDispClassInfo,
3099 psGetDispClassInfoIN->hDeviceKM,
3100 PVRSRV_HANDLE_TYPE_DISP_INFO);
3101 if(psGetDispClassInfoOUT->eError != PVRSRV_OK)
3102 {
3103 return 0;
3104 }
3105
3106 psGetDispClassInfoOUT->eError =
3107 PVRSRVGetDCInfoKM(pvDispClassInfo,
3108 &psGetDispClassInfoOUT->sDisplayInfo);
3109
3110 return 0;
3111}
3112
3113static IMG_INT
3114PVRSRVCreateDCSwapChainBW(IMG_UINT32 ui32BridgeID,
3115 PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainIN,
3116 PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN *psCreateDispClassSwapChainOUT,
3117 PVRSRV_PER_PROCESS_DATA *psPerProc)
3118{
3119 IMG_VOID *pvDispClassInfo;
3120 IMG_HANDLE hSwapChainInt;
3121 IMG_UINT32 ui32SwapChainID;
3122
3123 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN);
3124
3125 NEW_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc, 1)
3126
3127 psCreateDispClassSwapChainOUT->eError =
3128 PVRSRVLookupHandle(psPerProc->psHandleBase,
3129 &pvDispClassInfo,
3130 psCreateDispClassSwapChainIN->hDeviceKM,
3131 PVRSRV_HANDLE_TYPE_DISP_INFO);
3132
3133 if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
3134 {
3135 return 0;
3136 }
3137
3138 /* Get ui32SwapChainID from input */
3139 ui32SwapChainID = psCreateDispClassSwapChainIN->ui32SwapChainID;
3140
3141 psCreateDispClassSwapChainOUT->eError =
3142 PVRSRVCreateDCSwapChainKM(psPerProc, pvDispClassInfo,
3143 psCreateDispClassSwapChainIN->ui32Flags,
3144 &psCreateDispClassSwapChainIN->sDstSurfAttrib,
3145 &psCreateDispClassSwapChainIN->sSrcSurfAttrib,
3146 psCreateDispClassSwapChainIN->ui32BufferCount,
3147 psCreateDispClassSwapChainIN->ui32OEMFlags,
3148 &hSwapChainInt,
3149 &ui32SwapChainID);
3150
3151 if(psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
3152 {
3153 return 0;
3154 }
3155
3156 /* Pass ui32SwapChainID to output */
3157 psCreateDispClassSwapChainOUT->ui32SwapChainID = ui32SwapChainID;
3158
3159 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
3160 &psCreateDispClassSwapChainOUT->hSwapChain,
3161 hSwapChainInt,
3162 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
3163 PVRSRV_HANDLE_ALLOC_FLAG_NONE,
3164 psCreateDispClassSwapChainIN->hDeviceKM);
3165
3166 COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError, psPerProc)
3167
3168 return 0;
3169}
3170
3171static IMG_INT
3172PVRSRVDestroyDCSwapChainBW(IMG_UINT32 ui32BridgeID,
3173 PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN *psDestroyDispClassSwapChainIN,
3174 PVRSRV_BRIDGE_RETURN *psRetOUT,
3175 PVRSRV_PER_PROCESS_DATA *psPerProc)
3176{
3177 IMG_VOID *pvSwapChain;
3178
3179 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN);
3180
3181 psRetOUT->eError =
3182 PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSwapChain,
3183 psDestroyDispClassSwapChainIN->hSwapChain,
3184 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
3185 if(psRetOUT->eError != PVRSRV_OK)
3186 {
3187 return 0;
3188 }
3189
3190 psRetOUT->eError =
3191 PVRSRVDestroyDCSwapChainKM(pvSwapChain);
3192
3193 if(psRetOUT->eError != PVRSRV_OK)
3194 {
3195 return 0;
3196 }
3197
3198 psRetOUT->eError =
3199 PVRSRVReleaseHandle(psPerProc->psHandleBase,
3200 psDestroyDispClassSwapChainIN->hSwapChain,
3201 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
3202
3203 return 0;
3204}
3205
3206static IMG_INT
3207PVRSRVSetDCDstRectBW(IMG_UINT32 ui32BridgeID,
3208 PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassDstRectIN,
3209 PVRSRV_BRIDGE_RETURN *psRetOUT,
3210 PVRSRV_PER_PROCESS_DATA *psPerProc)
3211{
3212 IMG_VOID *pvDispClassInfo;
3213 IMG_VOID *pvSwapChain;
3214
3215 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT);
3216
3217 psRetOUT->eError =
3218 PVRSRVLookupHandle(psPerProc->psHandleBase,
3219 &pvDispClassInfo,
3220 psSetDispClassDstRectIN->hDeviceKM,
3221 PVRSRV_HANDLE_TYPE_DISP_INFO);
3222 if(psRetOUT->eError != PVRSRV_OK)
3223 {
3224 return 0;
3225 }
3226
3227 psRetOUT->eError =
3228 PVRSRVLookupHandle(psPerProc->psHandleBase,
3229 &pvSwapChain,
3230 psSetDispClassDstRectIN->hSwapChain,
3231 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
3232
3233 if(psRetOUT->eError != PVRSRV_OK)
3234 {
3235 return 0;
3236 }
3237
3238 psRetOUT->eError =
3239 PVRSRVSetDCDstRectKM(pvDispClassInfo,
3240 pvSwapChain,
3241 &psSetDispClassDstRectIN->sRect);
3242
3243 return 0;
3244}
3245
3246static IMG_INT
3247PVRSRVSetDCSrcRectBW(IMG_UINT32 ui32BridgeID,
3248 PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassSrcRectIN,
3249 PVRSRV_BRIDGE_RETURN *psRetOUT,
3250 PVRSRV_PER_PROCESS_DATA *psPerProc)
3251{
3252 IMG_VOID *pvDispClassInfo;
3253 IMG_VOID *pvSwapChain;
3254
3255 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT);
3256
3257 psRetOUT->eError =
3258 PVRSRVLookupHandle(psPerProc->psHandleBase,
3259 &pvDispClassInfo,
3260 psSetDispClassSrcRectIN->hDeviceKM,
3261 PVRSRV_HANDLE_TYPE_DISP_INFO);
3262 if(psRetOUT->eError != PVRSRV_OK)
3263 {
3264 return 0;
3265 }
3266
3267 psRetOUT->eError =
3268 PVRSRVLookupHandle(psPerProc->psHandleBase,
3269 &pvSwapChain,
3270 psSetDispClassSrcRectIN->hSwapChain,
3271 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
3272 if(psRetOUT->eError != PVRSRV_OK)
3273 {
3274 return 0;
3275 }
3276
3277 psRetOUT->eError =
3278 PVRSRVSetDCSrcRectKM(pvDispClassInfo,
3279 pvSwapChain,
3280 &psSetDispClassSrcRectIN->sRect);
3281
3282 return 0;
3283}
3284
3285static IMG_INT
3286PVRSRVSetDCDstColourKeyBW(IMG_UINT32 ui32BridgeID,
3287 PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
3288 PVRSRV_BRIDGE_RETURN *psRetOUT,
3289 PVRSRV_PER_PROCESS_DATA *psPerProc)
3290{
3291 IMG_VOID *pvDispClassInfo;
3292 IMG_VOID *pvSwapChain;
3293
3294 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY);
3295
3296 psRetOUT->eError =
3297 PVRSRVLookupHandle(psPerProc->psHandleBase,
3298 &pvDispClassInfo,
3299 psSetDispClassColKeyIN->hDeviceKM,
3300 PVRSRV_HANDLE_TYPE_DISP_INFO);
3301 if(psRetOUT->eError != PVRSRV_OK)
3302 {
3303 return 0;
3304 }
3305
3306 psRetOUT->eError =
3307 PVRSRVLookupHandle(psPerProc->psHandleBase,
3308 &pvSwapChain,
3309 psSetDispClassColKeyIN->hSwapChain,
3310 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
3311 if(psRetOUT->eError != PVRSRV_OK)
3312 {
3313 return 0;
3314 }
3315
3316 psRetOUT->eError =
3317 PVRSRVSetDCDstColourKeyKM(pvDispClassInfo,
3318 pvSwapChain,
3319 psSetDispClassColKeyIN->ui32CKColour);
3320
3321 return 0;
3322}
3323
3324static IMG_INT
3325PVRSRVSetDCSrcColourKeyBW(IMG_UINT32 ui32BridgeID,
3326 PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
3327 PVRSRV_BRIDGE_RETURN *psRetOUT,
3328 PVRSRV_PER_PROCESS_DATA *psPerProc)
3329{
3330 IMG_VOID *pvDispClassInfo;
3331 IMG_VOID *pvSwapChain;
3332
3333 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY);
3334
3335 psRetOUT->eError =
3336 PVRSRVLookupHandle(psPerProc->psHandleBase,
3337 &pvDispClassInfo,
3338 psSetDispClassColKeyIN->hDeviceKM,
3339 PVRSRV_HANDLE_TYPE_DISP_INFO);
3340 if(psRetOUT->eError != PVRSRV_OK)
3341 {
3342 return 0;
3343 }
3344
3345 psRetOUT->eError =
3346 PVRSRVLookupHandle(psPerProc->psHandleBase,
3347 &pvSwapChain,
3348 psSetDispClassColKeyIN->hSwapChain,
3349 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
3350 if(psRetOUT->eError != PVRSRV_OK)
3351 {
3352 return 0;
3353 }
3354
3355 psRetOUT->eError =
3356 PVRSRVSetDCSrcColourKeyKM(pvDispClassInfo,
3357 pvSwapChain,
3358 psSetDispClassColKeyIN->ui32CKColour);
3359
3360 return 0;
3361}
3362
3363static IMG_INT
3364PVRSRVGetDCBuffersBW(IMG_UINT32 ui32BridgeID,
3365 PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersIN,
3366 PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersOUT,
3367 PVRSRV_PER_PROCESS_DATA *psPerProc)
3368{
3369 IMG_VOID *pvDispClassInfo;
3370 IMG_VOID *pvSwapChain;
3371 IMG_UINT32 i;
3372#if defined (SUPPORT_SID_INTERFACE)
3373 IMG_HANDLE *pahBuffer;
3374#endif
3375
3376 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS);
3377
3378 NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc, PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS)
3379
3380 psGetDispClassBuffersOUT->eError =
3381 PVRSRVLookupHandle(psPerProc->psHandleBase,
3382 &pvDispClassInfo,
3383 psGetDispClassBuffersIN->hDeviceKM,
3384 PVRSRV_HANDLE_TYPE_DISP_INFO);
3385 if(psGetDispClassBuffersOUT->eError != PVRSRV_OK)
3386 {
3387 return 0;
3388 }
3389
3390 psGetDispClassBuffersOUT->eError =
3391 PVRSRVLookupHandle(psPerProc->psHandleBase,
3392 &pvSwapChain,
3393 psGetDispClassBuffersIN->hSwapChain,
3394 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
3395 if(psGetDispClassBuffersOUT->eError != PVRSRV_OK)
3396 {
3397 return 0;
3398 }
3399
3400#if defined (SUPPORT_SID_INTERFACE)
3401 psGetDispClassBuffersOUT->eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
3402 sizeof(IMG_HANDLE) * PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS,
3403 (IMG_PVOID *)&pahBuffer, 0,
3404 "Temp Swapchain Buffers");
3405
3406 if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
3407 {
3408 return 0;
3409 }
3410#endif
3411
3412 psGetDispClassBuffersOUT->eError =
3413 PVRSRVGetDCBuffersKM(pvDispClassInfo,
3414 pvSwapChain,
3415 &psGetDispClassBuffersOUT->ui32BufferCount,
3416#if defined (SUPPORT_SID_INTERFACE)
3417 pahBuffer,
3418#else
3419 psGetDispClassBuffersOUT->ahBuffer,
3420#endif
3421 psGetDispClassBuffersOUT->asPhyAddr);
3422 if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
3423 {
3424 return 0;
3425 }
3426
3427 PVR_ASSERT(psGetDispClassBuffersOUT->ui32BufferCount <= PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
3428
3429 for(i = 0; i < psGetDispClassBuffersOUT->ui32BufferCount; i++)
3430 {
3431#if defined (SUPPORT_SID_INTERFACE)
3432 IMG_SID hBufferExt;
3433#else
3434 IMG_HANDLE hBufferExt;
3435#endif
3436
3437 /* PRQA S 1461 15 */ /* ignore warning about enum type being converted */
3438#if defined (SUPPORT_SID_INTERFACE)
3439 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
3440 &hBufferExt,
3441 pahBuffer[i],
3442 PVRSRV_HANDLE_TYPE_DISP_BUFFER,
3443 (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
3444 psGetDispClassBuffersIN->hSwapChain);
3445#else
3446 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
3447 &hBufferExt,
3448 psGetDispClassBuffersOUT->ahBuffer[i],
3449 PVRSRV_HANDLE_TYPE_DISP_BUFFER,
3450 (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
3451 psGetDispClassBuffersIN->hSwapChain);
3452#endif
3453
3454 psGetDispClassBuffersOUT->ahBuffer[i] = hBufferExt;
3455 }
3456
3457#if defined (SUPPORT_SID_INTERFACE)
3458 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
3459 sizeof(IMG_HANDLE) * PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS,
3460 (IMG_PVOID)pahBuffer, 0);
3461#endif
3462
3463 COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc)
3464
3465 return 0;
3466}
3467
3468static IMG_INT
3469PVRSRVSwapToDCBufferBW(IMG_UINT32 ui32BridgeID,
3470 PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER *psSwapDispClassBufferIN,
3471 PVRSRV_BRIDGE_RETURN *psRetOUT,
3472 PVRSRV_PER_PROCESS_DATA *psPerProc)
3473{
3474 IMG_VOID *pvDispClassInfo;
3475 IMG_VOID *pvSwapChainBuf;
3476#if defined (SUPPORT_SID_INTERFACE)
3477 IMG_HANDLE hPrivateTag;
3478#endif
3479
3480 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER);
3481
3482 psRetOUT->eError =
3483 PVRSRVLookupHandle(psPerProc->psHandleBase,
3484 &pvDispClassInfo,
3485 psSwapDispClassBufferIN->hDeviceKM,
3486 PVRSRV_HANDLE_TYPE_DISP_INFO);
3487 if(psRetOUT->eError != PVRSRV_OK)
3488 {
3489 return 0;
3490 }
3491
3492 psRetOUT->eError =
3493 PVRSRVLookupSubHandle(psPerProc->psHandleBase,
3494 &pvSwapChainBuf,
3495 psSwapDispClassBufferIN->hBuffer,
3496 PVRSRV_HANDLE_TYPE_DISP_BUFFER,
3497 psSwapDispClassBufferIN->hDeviceKM);
3498 if(psRetOUT->eError != PVRSRV_OK)
3499 {
3500 return 0;
3501 }
3502
3503#if defined (SUPPORT_SID_INTERFACE)
3504 if (psSwapDispClassBufferIN->hPrivateTag != 0)
3505 {
3506 psRetOUT->eError =
3507 PVRSRVLookupSubHandle(psPerProc->psHandleBase,
3508 &hPrivateTag,
3509 psSwapDispClassBufferIN->hPrivateTag,
3510 PVRSRV_HANDLE_TYPE_DISP_BUFFER,
3511 psSwapDispClassBufferIN->hDeviceKM);
3512 if(psRetOUT->eError != PVRSRV_OK)
3513 {
3514 return 0;
3515 }
3516 }
3517 else
3518 {
3519 hPrivateTag = IMG_NULL;
3520 }
3521#endif
3522
3523 psRetOUT->eError =
3524 PVRSRVSwapToDCBufferKM(pvDispClassInfo,
3525 pvSwapChainBuf,
3526 psSwapDispClassBufferIN->ui32SwapInterval,
3527#if defined (SUPPORT_SID_INTERFACE)
3528 hPrivateTag,
3529#else
3530 psSwapDispClassBufferIN->hPrivateTag,
3531#endif
3532 psSwapDispClassBufferIN->ui32ClipRectCount,
3533 psSwapDispClassBufferIN->sClipRect);
3534
3535 return 0;
3536}
3537
3538static IMG_INT
3539PVRSRVSwapToDCBuffer2BW(IMG_UINT32 ui32BridgeID,
3540 PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER2 *psSwapDispClassBufferIN,
3541 PVRSRV_BRIDGE_RETURN *psRetOUT,
3542 PVRSRV_PER_PROCESS_DATA *psPerProc)
3543{
3544 IMG_VOID *pvPrivData = IMG_NULL;
3545 IMG_VOID *pvDispClassInfo;
3546 IMG_VOID *pvSwapChain;
3547 IMG_UINT32 i;
3548
3549 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER2);
3550
3551 psRetOUT->eError =
3552 PVRSRVLookupHandle(psPerProc->psHandleBase,
3553 &pvDispClassInfo,
3554 psSwapDispClassBufferIN->hDeviceKM,
3555 PVRSRV_HANDLE_TYPE_DISP_INFO);
3556 if(psRetOUT->eError != PVRSRV_OK)
3557 {
3558 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up DISP_INFO handle"));
3559 return 0;
3560 }
3561
3562 psRetOUT->eError =
3563 PVRSRVLookupSubHandle(psPerProc->psHandleBase,
3564 &pvSwapChain,
3565 psSwapDispClassBufferIN->hSwapChain,
3566 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
3567 psSwapDispClassBufferIN->hDeviceKM);
3568 if(psRetOUT->eError != PVRSRV_OK)
3569 {
3570 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up DISP_BUFFER handle"));
3571 return 0;
3572 }
3573
3574 if(!OSAccessOK(PVR_VERIFY_WRITE,
3575 psSwapDispClassBufferIN->ppsKernelMemInfos,
3576 sizeof(IMG_HANDLE) * psSwapDispClassBufferIN->ui32NumMemInfos))
3577 {
3578 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Access check failed for ppsKernelMemInfos"));
3579 return -EFAULT;
3580 }
3581
3582 if(!OSAccessOK(PVR_VERIFY_WRITE,
3583 psSwapDispClassBufferIN->ppsKernelSyncInfos,
3584 sizeof(IMG_HANDLE) * psSwapDispClassBufferIN->ui32NumMemInfos))
3585 {
3586 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Access check failed for ppsKernelSyncInfos"));
3587 return -EFAULT;
3588 }
3589
3590 for (i = 0; i < psSwapDispClassBufferIN->ui32NumMemInfos; i++)
3591 {
3592 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
3593 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
3594
3595 psRetOUT->eError =
3596 PVRSRVLookupHandle(psPerProc->psHandleBase,
3597 (IMG_PVOID *)&psKernelMemInfo,
3598 psSwapDispClassBufferIN->ppsKernelMemInfos[i],
3599 PVRSRV_HANDLE_TYPE_MEM_INFO);
3600 if(psRetOUT->eError != PVRSRV_OK)
3601 {
3602 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up MEM_INFO handle"));
3603 return 0;
3604 }
3605
3606 psRetOUT->eError =
3607 PVRSRVLookupHandle(psPerProc->psHandleBase,
3608 (IMG_PVOID *)&psKernelSyncInfo,
3609 psSwapDispClassBufferIN->ppsKernelSyncInfos[i],
3610 PVRSRV_HANDLE_TYPE_SYNC_INFO);
3611 if(psRetOUT->eError != PVRSRV_OK)
3612 {
3613 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to look up SYNC_INFO handle"));
3614 return 0;
3615 }
3616
3617 psSwapDispClassBufferIN->ppsKernelMemInfos[i] = psKernelMemInfo;
3618 psSwapDispClassBufferIN->ppsKernelSyncInfos[i] = psKernelSyncInfo;
3619 }
3620
3621 if(psSwapDispClassBufferIN->ui32PrivDataLength > 0)
3622 {
3623 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
3624 psSwapDispClassBufferIN->ui32PrivDataLength,
3625 (IMG_VOID **)&pvPrivData, IMG_NULL,
3626 "Swap Command Private Data") != PVRSRV_OK)
3627 {
3628 PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCBuffer2BW: Failed to allocate private data space"));
3629 return -ENOMEM;
3630 }
3631
3632 if(CopyFromUserWrapper(psPerProc,
3633 ui32BridgeID,
3634 pvPrivData,
3635 psSwapDispClassBufferIN->pvPrivData,
3636 psSwapDispClassBufferIN->ui32PrivDataLength) != PVRSRV_OK)
3637 {
3638 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSwapToDCBuffer2BW: Failed to copy private data"));
3639 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
3640 psSwapDispClassBufferIN->ui32PrivDataLength,
3641 pvPrivData, IMG_NULL);
3642 return -EFAULT;
3643 }
3644 }
3645
3646 psRetOUT->eError =
3647 PVRSRVSwapToDCBuffer2KM(pvDispClassInfo,
3648 pvSwapChain,
3649 psSwapDispClassBufferIN->ui32SwapInterval,
3650 psSwapDispClassBufferIN->ppsKernelMemInfos,
3651 psSwapDispClassBufferIN->ppsKernelSyncInfos,
3652 psSwapDispClassBufferIN->ui32NumMemInfos,
3653 pvPrivData,
3654 psSwapDispClassBufferIN->ui32PrivDataLength);
3655
3656 if(psRetOUT->eError != PVRSRV_OK)
3657 {
3658 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
3659 psSwapDispClassBufferIN->ui32PrivDataLength,
3660 pvPrivData, IMG_NULL);
3661 }
3662
3663 return 0;
3664}
3665
3666
3667
3668static IMG_INT
3669PVRSRVSwapToDCSystemBW(IMG_UINT32 ui32BridgeID,
3670 PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM *psSwapDispClassSystemIN,
3671 PVRSRV_BRIDGE_RETURN *psRetOUT,
3672 PVRSRV_PER_PROCESS_DATA *psPerProc)
3673{
3674 IMG_VOID *pvDispClassInfo;
3675 IMG_VOID *pvSwapChain;
3676
3677 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM);
3678
3679 psRetOUT->eError =
3680 PVRSRVLookupHandle(psPerProc->psHandleBase,
3681 &pvDispClassInfo,
3682 psSwapDispClassSystemIN->hDeviceKM,
3683 PVRSRV_HANDLE_TYPE_DISP_INFO);
3684 if(psRetOUT->eError != PVRSRV_OK)
3685 {
3686 return 0;
3687 }
3688
3689 psRetOUT->eError =
3690 PVRSRVLookupSubHandle(psPerProc->psHandleBase,
3691 &pvSwapChain,
3692 psSwapDispClassSystemIN->hSwapChain,
3693 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
3694 psSwapDispClassSystemIN->hDeviceKM);
3695 if(psRetOUT->eError != PVRSRV_OK)
3696 {
3697 return 0;
3698 }
3699 psRetOUT->eError =
3700 PVRSRVSwapToDCSystemKM(pvDispClassInfo,
3701 pvSwapChain);
3702
3703 return 0;
3704}
3705
3706static IMG_INT
3707PVRSRVOpenBCDeviceBW(IMG_UINT32 ui32BridgeID,
3708 PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceIN,
3709 PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceOUT,
3710 PVRSRV_PER_PROCESS_DATA *psPerProc)
3711{
3712 IMG_HANDLE hDevCookieInt;
3713 IMG_HANDLE hBufClassInfo;
3714
3715 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE);
3716
3717 NEW_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc, 1)
3718
3719 psOpenBufferClassDeviceOUT->eError =
3720 PVRSRVLookupHandle(psPerProc->psHandleBase,
3721 &hDevCookieInt,
3722 psOpenBufferClassDeviceIN->hDevCookie,
3723 PVRSRV_HANDLE_TYPE_DEV_NODE);
3724 if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
3725 {
3726 return 0;
3727 }
3728
3729 psOpenBufferClassDeviceOUT->eError =
3730 PVRSRVOpenBCDeviceKM(psPerProc,
3731 psOpenBufferClassDeviceIN->ui32DeviceID,
3732 hDevCookieInt,
3733 &hBufClassInfo);
3734 if(psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
3735 {
3736 return 0;
3737 }
3738
3739 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
3740 &psOpenBufferClassDeviceOUT->hDeviceKM,
3741 hBufClassInfo,
3742 PVRSRV_HANDLE_TYPE_BUF_INFO,
3743 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
3744
3745 COMMIT_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc)
3746
3747 return 0;
3748}
3749
3750static IMG_INT
3751PVRSRVCloseBCDeviceBW(IMG_UINT32 ui32BridgeID,
3752 PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE *psCloseBufferClassDeviceIN,
3753 PVRSRV_BRIDGE_RETURN *psRetOUT,
3754 PVRSRV_PER_PROCESS_DATA *psPerProc)
3755{
3756 IMG_VOID *pvBufClassInfo;
3757
3758 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE);
3759
3760 psRetOUT->eError =
3761 PVRSRVLookupHandle(psPerProc->psHandleBase,
3762 &pvBufClassInfo,
3763 psCloseBufferClassDeviceIN->hDeviceKM,
3764 PVRSRV_HANDLE_TYPE_BUF_INFO);
3765 if(psRetOUT->eError != PVRSRV_OK)
3766 {
3767 return 0;
3768 }
3769
3770 psRetOUT->eError =
3771 PVRSRVCloseBCDeviceKM(pvBufClassInfo);
3772
3773 if(psRetOUT->eError != PVRSRV_OK)
3774 {
3775 return 0;
3776 }
3777
3778 psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
3779 psCloseBufferClassDeviceIN->hDeviceKM,
3780 PVRSRV_HANDLE_TYPE_BUF_INFO);
3781
3782 return 0;
3783}
3784
3785static IMG_INT
3786PVRSRVGetBCInfoBW(IMG_UINT32 ui32BridgeID,
3787 PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO *psGetBufferClassInfoIN,
3788 PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO *psGetBufferClassInfoOUT,
3789 PVRSRV_PER_PROCESS_DATA *psPerProc)
3790{
3791 IMG_VOID *pvBufClassInfo;
3792
3793 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO);
3794
3795 psGetBufferClassInfoOUT->eError =
3796 PVRSRVLookupHandle(psPerProc->psHandleBase,
3797 &pvBufClassInfo,
3798 psGetBufferClassInfoIN->hDeviceKM,
3799 PVRSRV_HANDLE_TYPE_BUF_INFO);
3800 if(psGetBufferClassInfoOUT->eError != PVRSRV_OK)
3801 {
3802 return 0;
3803 }
3804
3805 psGetBufferClassInfoOUT->eError =
3806 PVRSRVGetBCInfoKM(pvBufClassInfo,
3807 &psGetBufferClassInfoOUT->sBufferInfo);
3808 return 0;
3809}
3810
3811static IMG_INT
3812PVRSRVGetBCBufferBW(IMG_UINT32 ui32BridgeID,
3813 PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferIN,
3814 PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferOUT,
3815 PVRSRV_PER_PROCESS_DATA *psPerProc)
3816{
3817 IMG_VOID *pvBufClassInfo;
3818 IMG_HANDLE hBufferInt;
3819
3820 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER);
3821
3822 NEW_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc, 1)
3823
3824 psGetBufferClassBufferOUT->eError =
3825 PVRSRVLookupHandle(psPerProc->psHandleBase,
3826 &pvBufClassInfo,
3827 psGetBufferClassBufferIN->hDeviceKM,
3828 PVRSRV_HANDLE_TYPE_BUF_INFO);
3829 if(psGetBufferClassBufferOUT->eError != PVRSRV_OK)
3830 {
3831 return 0;
3832 }
3833
3834 psGetBufferClassBufferOUT->eError =
3835 PVRSRVGetBCBufferKM(pvBufClassInfo,
3836 psGetBufferClassBufferIN->ui32BufferIndex,
3837 &hBufferInt);
3838
3839 if(psGetBufferClassBufferOUT->eError != PVRSRV_OK)
3840 {
3841 return 0;
3842 }
3843
3844 /* PRQA S 1461 6 */ /* ignore warning about enum type being converted */
3845 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
3846 &psGetBufferClassBufferOUT->hBuffer,
3847 hBufferInt,
3848 PVRSRV_HANDLE_TYPE_BUF_BUFFER,
3849 (PVRSRV_HANDLE_ALLOC_FLAG)(PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE | PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
3850 psGetBufferClassBufferIN->hDeviceKM);
3851
3852 COMMIT_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc)
3853
3854 return 0;
3855}
3856
3857
3858static IMG_INT
3859PVRSRVAllocSharedSysMemoryBW(IMG_UINT32 ui32BridgeID,
3860 PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemIN,
3861 PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemOUT,
3862 PVRSRV_PER_PROCESS_DATA *psPerProc)
3863{
3864 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
3865
3866 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM);
3867
3868 NEW_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc, 1)
3869
3870 psAllocSharedSysMemOUT->eError =
3871 PVRSRVAllocSharedSysMemoryKM(psPerProc,
3872 psAllocSharedSysMemIN->ui32Flags,
3873 psAllocSharedSysMemIN->ui32Size,
3874 &psKernelMemInfo);
3875 if(psAllocSharedSysMemOUT->eError != PVRSRV_OK)
3876 {
3877 return 0;
3878 }
3879
3880 OSMemSet(&psAllocSharedSysMemOUT->sClientMemInfo,
3881 0,
3882 sizeof(psAllocSharedSysMemOUT->sClientMemInfo));
3883
3884 psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM =
3885 psKernelMemInfo->pvLinAddrKM;
3886
3887 psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddr = 0;
3888 psAllocSharedSysMemOUT->sClientMemInfo.ui32Flags =
3889 psKernelMemInfo->ui32Flags;
3890 psAllocSharedSysMemOUT->sClientMemInfo.uAllocSize =
3891 psKernelMemInfo->uAllocSize;
3892#if defined (SUPPORT_SID_INTERFACE)
3893 if (psKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
3894 {
3895 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
3896 &psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo,
3897 psKernelMemInfo->sMemBlk.hOSMemHandle,
3898 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
3899 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
3900 }
3901 else
3902 {
3903 psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = 0;
3904 }
3905#else
3906 psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
3907#endif
3908
3909 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
3910 &psAllocSharedSysMemOUT->sClientMemInfo.hKernelMemInfo,
3911 psKernelMemInfo,
3912 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
3913 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
3914
3915 COMMIT_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc)
3916
3917 return 0;
3918}
3919
3920static IMG_INT
3921PVRSRVFreeSharedSysMemoryBW(IMG_UINT32 ui32BridgeID,
3922 PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM *psFreeSharedSysMemIN,
3923 PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM *psFreeSharedSysMemOUT,
3924 PVRSRV_PER_PROCESS_DATA *psPerProc)
3925{
3926 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
3927
3928 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM);
3929
3930 psFreeSharedSysMemOUT->eError =
3931 PVRSRVLookupHandle(psPerProc->psHandleBase,
3932 (IMG_VOID **)&psKernelMemInfo,
3933#if defined (SUPPORT_SID_INTERFACE)
3934 psFreeSharedSysMemIN->hKernelMemInfo,
3935#else
3936 psFreeSharedSysMemIN->psKernelMemInfo,
3937#endif
3938 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
3939
3940 if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
3941 return 0;
3942
3943 psFreeSharedSysMemOUT->eError =
3944 PVRSRVFreeSharedSysMemoryKM(psKernelMemInfo);
3945 if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
3946 return 0;
3947#if defined (SUPPORT_SID_INTERFACE)
3948 if (psFreeSharedSysMemIN->hMappingInfo != 0)
3949 {
3950 psFreeSharedSysMemOUT->eError =
3951 PVRSRVReleaseHandle(psPerProc->psHandleBase,
3952 psFreeSharedSysMemIN->hMappingInfo,
3953 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
3954 if(psFreeSharedSysMemOUT->eError != PVRSRV_OK)
3955 {
3956 return 0;
3957 }
3958 }
3959#endif
3960
3961 psFreeSharedSysMemOUT->eError =
3962 PVRSRVReleaseHandle(psPerProc->psHandleBase,
3963#if defined (SUPPORT_SID_INTERFACE)
3964 psFreeSharedSysMemIN->hKernelMemInfo,
3965#else
3966 psFreeSharedSysMemIN->psKernelMemInfo,
3967#endif
3968 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
3969 return 0;
3970}
3971
3972static IMG_INT
3973PVRSRVMapMemInfoMemBW(IMG_UINT32 ui32BridgeID,
3974 PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM *psMapMemInfoMemIN,
3975 PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM *psMapMemInfoMemOUT,
3976 PVRSRV_PER_PROCESS_DATA *psPerProc)
3977{
3978 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
3979 PVRSRV_HANDLE_TYPE eHandleType;
3980#if defined (SUPPORT_SID_INTERFACE)
3981 IMG_SID hParent;
3982#else
3983 IMG_HANDLE hParent;
3984#endif
3985 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_MEMINFO_MEM);
3986
3987 NEW_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc, 2)
3988
3989 psMapMemInfoMemOUT->eError =
3990 PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
3991 (IMG_VOID **)&psKernelMemInfo,
3992 &eHandleType,
3993 psMapMemInfoMemIN->hKernelMemInfo);
3994 if(psMapMemInfoMemOUT->eError != PVRSRV_OK)
3995 {
3996 return 0;
3997 }
3998
3999 switch (eHandleType)
4000 {
4001#if defined(PVR_SECURE_HANDLES) || defined (SUPPORT_SID_INTERFACE)
4002 case PVRSRV_HANDLE_TYPE_MEM_INFO:
4003 case PVRSRV_HANDLE_TYPE_MEM_INFO_REF:
4004 case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO:
4005#else
4006 case PVRSRV_HANDLE_TYPE_NONE:
4007#endif
4008 break;
4009 default:
4010 psMapMemInfoMemOUT->eError = PVRSRV_ERROR_INVALID_HANDLE_TYPE;
4011 return 0;
4012 }
4013
4014 /*
4015 * To prevent the building up of deep chains of subhandles, parent
4016 * the new meminfo off the parent of the input meminfo, if it has
4017 * a parent.
4018 */
4019 psMapMemInfoMemOUT->eError =
4020 PVRSRVGetParentHandle(psPerProc->psHandleBase,
4021 &hParent,
4022 psMapMemInfoMemIN->hKernelMemInfo,
4023 eHandleType);
4024 if (psMapMemInfoMemOUT->eError != PVRSRV_OK)
4025 {
4026 return 0;
4027 }
4028#if defined (SUPPORT_SID_INTERFACE)
4029 if (hParent == 0)
4030#else
4031 if (hParent == IMG_NULL)
4032#endif
4033 {
4034 hParent = psMapMemInfoMemIN->hKernelMemInfo;
4035 }
4036
4037 OSMemSet(&psMapMemInfoMemOUT->sClientMemInfo,
4038 0,
4039 sizeof(psMapMemInfoMemOUT->sClientMemInfo));
4040
4041 psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM =
4042 psKernelMemInfo->pvLinAddrKM;
4043
4044 psMapMemInfoMemOUT->sClientMemInfo.pvLinAddr = 0;
4045 psMapMemInfoMemOUT->sClientMemInfo.sDevVAddr =
4046 psKernelMemInfo->sDevVAddr;
4047 psMapMemInfoMemOUT->sClientMemInfo.ui32Flags =
4048 psKernelMemInfo->ui32Flags;
4049 psMapMemInfoMemOUT->sClientMemInfo.uAllocSize =
4050 psKernelMemInfo->uAllocSize;
4051#if defined (SUPPORT_SID_INTERFACE)
4052 if (psKernelMemInfo->sMemBlk.hOSMemHandle != IMG_NULL)
4053 {
4054 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
4055 &psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo,
4056 psKernelMemInfo->sMemBlk.hOSMemHandle,
4057 PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
4058 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
4059 hParent);
4060 }
4061 else
4062 {
4063 psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = 0;
4064 }
4065#else
4066 psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo = psKernelMemInfo->sMemBlk.hOSMemHandle;
4067#endif
4068
4069 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
4070 &psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo,
4071 psKernelMemInfo,
4072 PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
4073 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
4074 hParent);
4075
4076 if(psKernelMemInfo->ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
4077 {
4078 /* signal no syncinfo */
4079 OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo,
4080 0,
4081 sizeof (PVRSRV_CLIENT_SYNC_INFO));
4082 }
4083 else
4084 {
4085 /* and setup the sync info */
4086#if !defined(PVRSRV_DISABLE_UM_SYNCOBJ_MAPPINGS)
4087 psMapMemInfoMemOUT->sClientSyncInfo.psSyncData =
4088 psKernelMemInfo->psKernelSyncInfo->psSyncData;
4089 psMapMemInfoMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
4090 psKernelMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
4091 psMapMemInfoMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
4092 psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
4093 psMapMemInfoMemOUT->sClientSyncInfo.sReadOps2CompleteDevVAddr =
4094 psKernelMemInfo->psKernelSyncInfo->sReadOps2CompleteDevVAddr;
4095
4096#if defined (SUPPORT_SID_INTERFACE)
4097 if (psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle != IMG_NULL)
4098 {
4099 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
4100 &psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo,
4101 psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle,
4102 PVRSRV_HANDLE_TYPE_SYNC_INFO,
4103 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
4104 psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo);
4105 }
4106 else
4107 {
4108 psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo = 0;
4109 }
4110#else
4111 psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo =
4112 psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
4113#endif
4114#endif
4115
4116 psMapMemInfoMemOUT->sClientMemInfo.psClientSyncInfo = &psMapMemInfoMemOUT->sClientSyncInfo;
4117
4118 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
4119 &psMapMemInfoMemOUT->sClientSyncInfo.hKernelSyncInfo,
4120 psKernelMemInfo->psKernelSyncInfo,
4121 PVRSRV_HANDLE_TYPE_SYNC_INFO,
4122 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
4123 psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo);
4124 }
4125
4126 COMMIT_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc)
4127
4128 return 0;
4129}
4130
4131
4132
4133IMG_INT
4134DummyBW(IMG_UINT32 ui32BridgeID,
4135 IMG_VOID *psBridgeIn,
4136 IMG_VOID *psBridgeOut,
4137 PVRSRV_PER_PROCESS_DATA *psPerProc)
4138{
4139#if !defined(DEBUG)
4140 PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
4141#endif
4142 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
4143 PVR_UNREFERENCED_PARAMETER(psBridgeOut);
4144 PVR_UNREFERENCED_PARAMETER(psPerProc);
4145
4146#if defined(DEBUG_BRIDGE_KM)
4147 PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %u (%s) mapped to "
4148 "Dummy Wrapper (probably not what you want!)",
4149 __FUNCTION__, ui32BridgeID, g_BridgeDispatchTable[ui32BridgeID].pszIOCName));
4150#else
4151 PVR_DPF((PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %u mapped to "
4152 "Dummy Wrapper (probably not what you want!)",
4153 __FUNCTION__, ui32BridgeID));
4154#endif
4155 return -ENOTTY;
4156}
4157
4158
4159/*!
4160 * *****************************************************************************
4161 * @brief A wrapper for filling in the g_BridgeDispatchTable array that does
4162 * error checking.
4163 *
4164 * @param ui32Index
4165 * @param pszIOCName
4166 * @param pfFunction
4167 * @param pszFunctionName
4168 *
4169 * @return
4170 ********************************************************************************/
4171IMG_VOID
4172_SetDispatchTableEntry(IMG_UINT32 ui32Index,
4173 const IMG_CHAR *pszIOCName,
4174 BridgeWrapperFunction pfFunction,
4175 const IMG_CHAR *pszFunctionName)
4176{
4177 static IMG_UINT32 ui32PrevIndex = ~0UL; /* -1 */
4178#if !defined(DEBUG)
4179 PVR_UNREFERENCED_PARAMETER(pszIOCName);
4180#endif
4181#if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM)
4182 PVR_UNREFERENCED_PARAMETER(pszFunctionName);
4183#endif
4184
4185#if defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE)
4186 /* INTEGRATION_POINT: Enable this to dump out the dispatch table entries */
4187 PVR_DPF((PVR_DBG_WARNING, "%s: %d %s %s", __FUNCTION__, ui32Index, pszIOCName, pszFunctionName));
4188#endif
4189
4190 /* We should never be over-writing a previous entry.
4191 * If we are, tell the world about it.
4192 * NOTE: This shouldn't be debug only since switching from debug->release
4193 * etc is likly to modify the available ioctls and thus be a point where
4194 * mistakes are exposed. This isn't run at at a performance critical time.
4195 */
4196 if(g_BridgeDispatchTable[ui32Index].pfFunction)
4197 {
4198#if defined(DEBUG_BRIDGE_KM)
4199 PVR_DPF((PVR_DBG_ERROR,
4200 "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry for %s",
4201 __FUNCTION__, pszIOCName, g_BridgeDispatchTable[ui32Index].pszIOCName));
4202#else
4203 PVR_DPF((PVR_DBG_ERROR,
4204 "%s: BUG!: Adding dispatch table entry for %s clobbers an existing entry (index=%u)",
4205 __FUNCTION__, pszIOCName, ui32Index));
4206#endif
4207 PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue."));
4208 }
4209
4210 /* Any gaps are sub-optimal in-terms of memory usage, but we are mainly
4211 * interested in spotting any large gap of wasted memory that could be
4212 * accidentally introduced.
4213 *
4214 * This will currently flag up any gaps > 5 entries.
4215 *
4216 * NOTE: This shouldn't be debug only since switching from debug->release
4217 * etc is likly to modify the available ioctls and thus be a point where
4218 * mistakes are exposed. This isn't run at at a performance critical time.
4219 */
4220// if((ui32PrevIndex != (IMG_UINT32)-1) &&
4221 if((ui32PrevIndex != ~0UL) &&
4222 ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) ||
4223 (ui32Index <= ui32PrevIndex)))
4224 {
4225#if defined(DEBUG_BRIDGE_KM)
4226 PVR_DPF((PVR_DBG_WARNING,
4227 "%s: There is a gap in the dispatch table between indices %u (%s) and %u (%s)",
4228 __FUNCTION__, ui32PrevIndex, g_BridgeDispatchTable[ui32PrevIndex].pszIOCName,
4229 ui32Index, pszIOCName));
4230#else
4231 PVR_DPF((PVR_DBG_WARNING,
4232 "%s: There is a gap in the dispatch table between indices %u and %u (%s)",
4233 __FUNCTION__, (IMG_UINT)ui32PrevIndex, (IMG_UINT)ui32Index, pszIOCName));
4234#endif
4235 PVR_DPF((PVR_DBG_ERROR, "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue."));
4236 }
4237
4238 g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction;
4239#if defined(DEBUG_BRIDGE_KM)
4240 g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName;
4241 g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName;
4242 g_BridgeDispatchTable[ui32Index].ui32CallCount = 0;
4243 g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0;
4244#endif
4245
4246 ui32PrevIndex = ui32Index;
4247}
4248
4249static IMG_INT
4250PVRSRVInitSrvConnectBW(IMG_UINT32 ui32BridgeID,
4251 IMG_VOID *psBridgeIn,
4252 PVRSRV_BRIDGE_RETURN *psRetOUT,
4253 PVRSRV_PER_PROCESS_DATA *psPerProc)
4254{
4255 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
4256
4257 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_CONNECT);
4258 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
4259
4260 /* PRQA S 3415 1 */ /* side effects needed - if any step fails */
4261 if((OSProcHasPrivSrvInit() == IMG_FALSE) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
4262 {
4263 psRetOUT->eError = PVRSRV_ERROR_SRV_CONNECT_FAILED;
4264 return 0;
4265 }
4266
4267#if defined (__linux__) || defined (__QNXNTO__)
4268 PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE);
4269#endif
4270 psPerProc->bInitProcess = IMG_TRUE;
4271
4272 psRetOUT->eError = PVRSRV_OK;
4273
4274 return 0;
4275}
4276
4277
4278static IMG_INT
4279PVRSRVInitSrvDisconnectBW(IMG_UINT32 ui32BridgeID,
4280 PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT *psInitSrvDisconnectIN,
4281 PVRSRV_BRIDGE_RETURN *psRetOUT,
4282 PVRSRV_PER_PROCESS_DATA *psPerProc)
4283{
4284 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_DISCONNECT);
4285
4286 if(!psPerProc->bInitProcess)
4287 {
4288 psRetOUT->eError = PVRSRV_ERROR_SRV_DISCONNECT_FAILED;
4289 return 0;
4290 }
4291
4292 psPerProc->bInitProcess = IMG_FALSE;
4293
4294#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
4295 psPerProc->bPDumpActive = IMG_FALSE;
4296#endif
4297
4298 PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE);
4299 PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE);
4300
4301 psRetOUT->eError = PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful);
4302
4303 PVRSRVSetInitServerState( PVRSRV_INIT_SERVER_SUCCESSFUL ,
4304 ((psRetOUT->eError == PVRSRV_OK) && (psInitSrvDisconnectIN->bInitSuccesful))
4305 ? IMG_TRUE : IMG_FALSE);
4306
4307 return 0;
4308}
4309
4310
4311static IMG_INT
4312PVRSRVEventObjectWaitBW(IMG_UINT32 ui32BridgeID,
4313 PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT *psEventObjectWaitIN,
4314 PVRSRV_BRIDGE_RETURN *psRetOUT,
4315 PVRSRV_PER_PROCESS_DATA *psPerProc)
4316{
4317 IMG_HANDLE hOSEventKM;
4318
4319 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT);
4320
4321 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
4322 &hOSEventKM,
4323 psEventObjectWaitIN->hOSEventKM,
4324 PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
4325
4326 if(psRetOUT->eError != PVRSRV_OK)
4327 {
4328 return 0;
4329 }
4330
4331 psRetOUT->eError = OSEventObjectWaitKM(hOSEventKM);
4332
4333 return 0;
4334}
4335
4336
4337static IMG_INT
4338PVRSRVEventObjectOpenBW(IMG_UINT32 ui32BridgeID,
4339 PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN,
4340 PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT,
4341 PVRSRV_PER_PROCESS_DATA *psPerProc)
4342{
4343#if defined (SUPPORT_SID_INTERFACE)
4344 PVRSRV_EVENTOBJECT_KM sEventObject;
4345 IMG_HANDLE hOSEvent;
4346#endif
4347
4348 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN);
4349
4350 NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1)
4351
4352 psEventObjectOpenOUT->eError =
4353 PVRSRVLookupHandle(psPerProc->psHandleBase,
4354#if defined (SUPPORT_SID_INTERFACE)
4355 &sEventObject.hOSEventKM,
4356#else
4357 &psEventObjectOpenIN->sEventObject.hOSEventKM,
4358#endif
4359 psEventObjectOpenIN->sEventObject.hOSEventKM,
4360 PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
4361
4362 if(psEventObjectOpenOUT->eError != PVRSRV_OK)
4363 {
4364 return 0;
4365 }
4366
4367#if defined (SUPPORT_SID_INTERFACE)
4368 OSMemCopy(&sEventObject.szName,
4369 &psEventObjectOpenIN->sEventObject.szName,
4370 EVENTOBJNAME_MAXLENGTH);
4371
4372 psEventObjectOpenOUT->eError = OSEventObjectOpenKM(&sEventObject, &hOSEvent);
4373#else
4374 psEventObjectOpenOUT->eError = OSEventObjectOpenKM(&psEventObjectOpenIN->sEventObject, &psEventObjectOpenOUT->hOSEvent);
4375#endif
4376
4377 if(psEventObjectOpenOUT->eError != PVRSRV_OK)
4378 {
4379 return 0;
4380 }
4381
4382#if defined (SUPPORT_SID_INTERFACE)
4383/* Windows7, WinXP and Vista already use an Index type handle which the client glue uses directly */
4384/* Linux requires a SID handle */
4385#if !defined (WINXP) && !defined(SUPPORT_VISTA)
4386 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
4387 &psEventObjectOpenOUT->hOSEvent,
4388 hOSEvent,
4389 PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
4390 PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
4391#endif
4392#else
4393 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
4394 &psEventObjectOpenOUT->hOSEvent,
4395 psEventObjectOpenOUT->hOSEvent,
4396 PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
4397 PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
4398#endif
4399
4400 COMMIT_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc)
4401
4402 return 0;
4403}
4404
4405
4406static IMG_INT
4407PVRSRVEventObjectCloseBW(IMG_UINT32 ui32BridgeID,
4408 PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN,
4409 PVRSRV_BRIDGE_RETURN *psRetOUT,
4410 PVRSRV_PER_PROCESS_DATA *psPerProc)
4411{
4412 IMG_HANDLE hOSEventKM;
4413#if defined (SUPPORT_SID_INTERFACE)
4414 PVRSRV_EVENTOBJECT_KM sEventObject;
4415#endif
4416
4417 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE);
4418
4419 psRetOUT->eError =
4420 PVRSRVLookupHandle(psPerProc->psHandleBase,
4421#if defined (SUPPORT_SID_INTERFACE)
4422 &sEventObject.hOSEventKM,
4423#else
4424 &psEventObjectCloseIN->sEventObject.hOSEventKM,
4425#endif
4426 psEventObjectCloseIN->sEventObject.hOSEventKM,
4427 PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
4428 if(psRetOUT->eError != PVRSRV_OK)
4429 {
4430 return 0;
4431 }
4432
4433 psRetOUT->eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
4434 &hOSEventKM,
4435 psEventObjectCloseIN->hOSEventKM,
4436 PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
4437
4438 if(psRetOUT->eError != PVRSRV_OK)
4439 {
4440 return 0;
4441 }
4442
4443#if defined (SUPPORT_SID_INTERFACE)
4444 if(CopyFromUserWrapper(psPerProc, ui32BridgeID,
4445 &sEventObject.szName,
4446 &psEventObjectCloseIN->sEventObject.szName,
4447 EVENTOBJNAME_MAXLENGTH) != PVRSRV_OK)
4448 {
4449 /*not nulling pointer, out of scope*/
4450 return -EFAULT;
4451 }
4452
4453 psRetOUT->eError = OSEventObjectCloseKM(&sEventObject, hOSEventKM);
4454#else
4455 psRetOUT->eError = OSEventObjectCloseKM(&psEventObjectCloseIN->sEventObject, hOSEventKM);
4456#endif
4457
4458 return 0;
4459}
4460
4461
4462typedef struct _MODIFY_SYNC_OP_INFO
4463{
4464 IMG_HANDLE hResItem;
4465 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
4466 IMG_UINT32 ui32ModifyFlags;
4467 IMG_UINT32 ui32ReadOpsPendingSnapShot;
4468 IMG_UINT32 ui32WriteOpsPendingSnapShot;
4469 IMG_UINT32 ui32ReadOps2PendingSnapShot;
4470} MODIFY_SYNC_OP_INFO;
4471
4472
4473static PVRSRV_ERROR DoQuerySyncOpsSatisfied(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
4474 IMG_UINT32 ui32ReadOpsPendingSnapShot,
4475 IMG_UINT32 ui32WriteOpsPendingSnapShot,
4476 IMG_UINT32 ui32ReadOps2PendingSnapShot)
4477{
4478 IMG_UINT32 ui32WriteOpsPending;
4479 IMG_UINT32 ui32ReadOpsPending;
4480 IMG_UINT32 ui32ReadOps2Pending;
4481
4482 /*
4483 *
4484 * We wait until the complete count reaches _or_moves_past_ the
4485 * snapshot value.
4486 *
4487 */
4488
4489 if (!psKernelSyncInfo)
4490 {
4491 return PVRSRV_ERROR_INVALID_PARAMS;
4492 }
4493
4494 /*
4495 let p be the pending ops count
4496 let c be the complete ops count
4497 let p' be the previously taken snapshot
4498
4499 if p exceeds c by an amount greater than that by which
4500 p exceeds p', then the condition is not yet satisfied.
4501
4502 Note that (p - c) can never be negative, and neither can (p - p')
4503 so we can do the comparison using unsigned arithmetic
4504 */
4505 ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
4506 ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
4507 ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
4508
4509 if((ui32WriteOpsPending - ui32WriteOpsPendingSnapShot >=
4510 ui32WriteOpsPending - psKernelSyncInfo->psSyncData->ui32WriteOpsComplete) &&
4511 (ui32ReadOpsPending - ui32ReadOpsPendingSnapShot >=
4512 ui32ReadOpsPending - psKernelSyncInfo->psSyncData->ui32ReadOpsComplete) &&
4513 (ui32ReadOps2Pending - ui32ReadOps2PendingSnapShot >=
4514 ui32ReadOps2Pending - psKernelSyncInfo->psSyncData->ui32ReadOps2Complete))
4515 {
4516#if defined(PDUMP) && !defined(SUPPORT_VGX)
4517 /* pdump the sync pol: reads */
4518 PDumpComment("Poll for read ops complete to reach value (pdump: %u, actual snapshot: %u)",
4519 psKernelSyncInfo->psSyncData->ui32LastReadOpDumpVal,
4520 ui32ReadOpsPendingSnapShot);
4521 PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM,
4522 offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
4523 psKernelSyncInfo->psSyncData->ui32LastReadOpDumpVal,
4524 0xFFFFFFFF,
4525 PDUMP_POLL_OPERATOR_EQUAL, /* * see "NB" below */
4526 0,
4527 MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
4528
4529 /* pdump the sync pol: writes */
4530 PDumpComment("Poll for write ops complete to reach value (pdump: %u, actual snapshot: %u)",
4531 psKernelSyncInfo->psSyncData->ui32LastOpDumpVal,
4532 ui32WriteOpsPendingSnapShot);
4533 PDumpMemPolKM(psKernelSyncInfo->psSyncDataMemInfoKM,
4534 offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
4535 psKernelSyncInfo->psSyncData->ui32LastOpDumpVal,
4536 0xFFFFFFFF,
4537 PDUMP_POLL_OPERATOR_EQUAL, /* * see "NB" below */
4538 0,
4539 MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
4540 /* NB: FIXME -- really need to POL on an expression to
4541 accurately reflect the condition we need to check. How to
4542 do this in PDUMP? */
4543#endif
4544 return PVRSRV_OK;
4545 }
4546 else
4547 {
4548 return PVRSRV_ERROR_RETRY;
4549 }
4550}
4551
4552
4553static PVRSRV_ERROR DoModifyCompleteSyncOps(MODIFY_SYNC_OP_INFO *psModSyncOpInfo)
4554{
4555 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
4556
4557 psKernelSyncInfo = psModSyncOpInfo->psKernelSyncInfo;
4558
4559 if (!psKernelSyncInfo)
4560 {
4561 return PVRSRV_ERROR_INVALID_PARAMS;
4562 }
4563
4564 /* If user has used the API correctly, we will always have reached the pending snapshot.
4565 We should catch this error on the client side of the bridge and report it in an obvious way */
4566 if((psModSyncOpInfo->ui32WriteOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32WriteOpsComplete)
4567 || (psModSyncOpInfo->ui32ReadOpsPendingSnapShot != psKernelSyncInfo->psSyncData->ui32ReadOpsComplete))
4568 {
4569 return PVRSRV_ERROR_BAD_SYNC_STATE;
4570 }
4571
4572 /* update the WOpComplete */
4573 if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
4574 {
4575 psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++;
4576 }
4577
4578 /* update the ROpComplete */
4579 if(psModSyncOpInfo->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
4580 {
4581 psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++;
4582 }
4583
4584 return PVRSRV_OK;
4585}
4586
4587
4588static PVRSRV_ERROR ModifyCompleteSyncOpsCallBack(IMG_PVOID pvParam,
4589 IMG_UINT32 ui32Param,
4590 IMG_BOOL bDummy)
4591{
4592 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
4593
4594 PVR_UNREFERENCED_PARAMETER(ui32Param);
4595 PVR_UNREFERENCED_PARAMETER(bDummy);
4596
4597 if (!pvParam)
4598 {
4599 PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: invalid parameter"));
4600 return PVRSRV_ERROR_INVALID_PARAMS;
4601 }
4602
4603 psModSyncOpInfo = (MODIFY_SYNC_OP_INFO*)pvParam;
4604
4605 if (psModSyncOpInfo->psKernelSyncInfo)
4606 {
4607 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
4608 {
4609 if (DoQuerySyncOpsSatisfied(psModSyncOpInfo->psKernelSyncInfo,
4610 psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
4611 psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
4612 psModSyncOpInfo->ui32ReadOps2PendingSnapShot) == PVRSRV_OK)
4613 {
4614 goto OpFlushedComplete;
4615 }
4616 PVR_DPF((PVR_DBG_WARNING, "ModifyCompleteSyncOpsCallBack: waiting for current Ops to flush"));
4617 OSSleepms(1);
4618 } END_LOOP_UNTIL_TIMEOUT();
4619
4620 PVR_DPF((PVR_DBG_ERROR, "ModifyCompleteSyncOpsCallBack: timeout whilst waiting for current Ops to flush."));
4621 PVR_DPF((PVR_DBG_ERROR, " Write ops pending snapshot = %d, write ops complete = %d",
4622 psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
4623 psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32WriteOpsComplete));
4624 PVR_DPF((PVR_DBG_ERROR, " Read ops pending snapshot = %d, read ops complete = %d",
4625 psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
4626 psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32ReadOpsComplete));
4627 PVR_DPF((PVR_DBG_ERROR, " Read ops pending snapshot = %d, read ops2 complete = %d",
4628 psModSyncOpInfo->ui32ReadOps2PendingSnapShot,
4629 psModSyncOpInfo->psKernelSyncInfo->psSyncData->ui32ReadOps2Complete));
4630 return PVRSRV_ERROR_TIMEOUT;
4631
4632OpFlushedComplete:
4633 DoModifyCompleteSyncOps(psModSyncOpInfo);
4634 PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL);
4635 }
4636
4637 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(MODIFY_SYNC_OP_INFO), (IMG_VOID *)psModSyncOpInfo, 0);
4638
4639 /* re-kick all services managed devices */
4640 PVRSRVScheduleDeviceCallbacks();
4641
4642 return PVRSRV_OK;
4643}
4644
4645
4646static IMG_INT
4647PVRSRVCreateSyncInfoModObjBW(IMG_UINT32 ui32BridgeID,
4648 IMG_VOID *psBridgeIn,
4649 PVRSRV_BRIDGE_OUT_CREATE_SYNC_INFO_MOD_OBJ *psCreateSyncInfoModObjOUT,
4650 PVRSRV_PER_PROCESS_DATA *psPerProc)
4651{
4652 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
4653
4654 PVR_UNREFERENCED_PARAMETER(psBridgeIn);
4655
4656 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ);
4657
4658 NEW_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc, 1)
4659
4660 ASSIGN_AND_EXIT_ON_ERROR(psCreateSyncInfoModObjOUT->eError,
4661 OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
4662 sizeof(MODIFY_SYNC_OP_INFO),
4663 (IMG_VOID **)&psModSyncOpInfo, 0,
4664 "ModSyncOpInfo (MODIFY_SYNC_OP_INFO)"));
4665
4666 psModSyncOpInfo->psKernelSyncInfo = IMG_NULL; /* mark it as empty */
4667
4668 psCreateSyncInfoModObjOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
4669 &psCreateSyncInfoModObjOUT->hKernelSyncInfoModObj,
4670 psModSyncOpInfo,
4671 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ,
4672 PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE);
4673
4674 if (psCreateSyncInfoModObjOUT->eError != PVRSRV_OK)
4675 {
4676 return 0;
4677 }
4678
4679 psModSyncOpInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
4680 RESMAN_TYPE_MODIFY_SYNC_OPS,
4681 psModSyncOpInfo,
4682 0,
4683 &ModifyCompleteSyncOpsCallBack);
4684
4685 COMMIT_HANDLE_BATCH_OR_ERROR(psCreateSyncInfoModObjOUT->eError, psPerProc)
4686
4687 return 0;
4688}
4689
4690
4691static IMG_INT
4692PVRSRVDestroySyncInfoModObjBW(IMG_UINT32 ui32BridgeID,
4693 PVRSRV_BRIDGE_IN_DESTROY_SYNC_INFO_MOD_OBJ *psDestroySyncInfoModObjIN,
4694 PVRSRV_BRIDGE_RETURN *psDestroySyncInfoModObjOUT,
4695 PVRSRV_PER_PROCESS_DATA *psPerProc)
4696{
4697 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
4698
4699 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ);
4700
4701 psDestroySyncInfoModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
4702 (IMG_VOID**)&psModSyncOpInfo,
4703 psDestroySyncInfoModObjIN->hKernelSyncInfoModObj,
4704 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
4705 if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
4706 {
4707 PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVLookupHandle failed"));
4708 return 0;
4709 }
4710
4711 if(psModSyncOpInfo->psKernelSyncInfo != IMG_NULL)
4712 {
4713 /* Not empty */
4714 psDestroySyncInfoModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
4715 return 0;
4716 }
4717
4718 PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL);
4719
4720 psDestroySyncInfoModObjOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
4721 psDestroySyncInfoModObjIN->hKernelSyncInfoModObj,
4722 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
4723
4724 if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
4725 {
4726 PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: PVRSRVReleaseHandle failed"));
4727 return 0;
4728 }
4729
4730 psDestroySyncInfoModObjOUT->eError = ResManFreeResByPtr(psModSyncOpInfo->hResItem, CLEANUP_WITH_POLL);
4731 if (psDestroySyncInfoModObjOUT->eError != PVRSRV_OK)
4732 {
4733 PVR_DPF((PVR_DBG_ERROR, "PVRSRVDestroySyncInfoModObjBW: ResManFreeResByPtr failed"));
4734 return 0;
4735 }
4736
4737 return 0;
4738}
4739
4740
4741static IMG_INT
4742PVRSRVModifyPendingSyncOpsBW(IMG_UINT32 ui32BridgeID,
4743 PVRSRV_BRIDGE_IN_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsIN,
4744 PVRSRV_BRIDGE_OUT_MODIFY_PENDING_SYNC_OPS *psModifySyncOpsOUT,
4745 PVRSRV_PER_PROCESS_DATA *psPerProc)
4746{
4747 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
4748 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
4749
4750 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS);
4751
4752 psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
4753 (IMG_VOID**)&psModSyncOpInfo,
4754 psModifySyncOpsIN->hKernelSyncInfoModObj,
4755 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
4756 if (psModifySyncOpsOUT->eError != PVRSRV_OK)
4757 {
4758 PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
4759 return 0;
4760 }
4761
4762 psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
4763 (IMG_VOID**)&psKernelSyncInfo,
4764 psModifySyncOpsIN->hKernelSyncInfo,
4765 PVRSRV_HANDLE_TYPE_SYNC_INFO);
4766 if (psModifySyncOpsOUT->eError != PVRSRV_OK)
4767 {
4768 PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
4769 return 0;
4770 }
4771
4772 if(psModSyncOpInfo->psKernelSyncInfo)
4773 {
4774 /* SyncInfoModification is not empty */
4775 psModifySyncOpsOUT->eError = PVRSRV_ERROR_RETRY;
4776 PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVModifyPendingSyncOpsBW: SyncInfo Modification object is not empty"));
4777 return 0;
4778 }
4779
4780 /* Should never happen, but check to be sure */
4781 if (psKernelSyncInfo == IMG_NULL)
4782 {
4783 psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
4784 PVR_DPF((PVR_DBG_VERBOSE, "PVRSRVModifyPendingSyncOpsBW: SyncInfo bad handle"));
4785 return 0;
4786 }
4787
4788 PVRSRVKernelSyncInfoIncRef(psKernelSyncInfo, IMG_NULL);
4789 /* setup info to store in resman */
4790 psModSyncOpInfo->psKernelSyncInfo = psKernelSyncInfo;
4791 psModSyncOpInfo->ui32ModifyFlags = psModifySyncOpsIN->ui32ModifyFlags;
4792 psModSyncOpInfo->ui32ReadOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
4793 psModSyncOpInfo->ui32WriteOpsPendingSnapShot = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
4794 psModSyncOpInfo->ui32ReadOps2PendingSnapShot = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
4795
4796 /* We return PRE-INCREMENTED versions of all sync Op Values */
4797
4798 psModifySyncOpsOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
4799 psModifySyncOpsOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
4800 psModifySyncOpsOUT->ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
4801
4802 if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_WO_INC)
4803 {
4804 psKernelSyncInfo->psSyncData->ui32WriteOpsPending++;
4805 }
4806
4807 if(psModifySyncOpsIN->ui32ModifyFlags & PVRSRV_MODIFYSYNCOPS_FLAGS_RO_INC)
4808 {
4809 psKernelSyncInfo->psSyncData->ui32ReadOpsPending++;
4810 }
4811
4812 /* pull the resman item to the front of the list */
4813 psModifySyncOpsOUT->eError = ResManDissociateRes(psModSyncOpInfo->hResItem,
4814 psPerProc->hResManContext);
4815
4816 if (psModifySyncOpsOUT->eError != PVRSRV_OK)
4817 {
4818 PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyPendingSyncOpsBW: PVRSRVLookupHandle failed"));
4819 return 0;
4820 }
4821
4822 return 0;
4823}
4824
4825
4826static IMG_INT
4827PVRSRVModifyCompleteSyncOpsBW(IMG_UINT32 ui32BridgeID,
4828 PVRSRV_BRIDGE_IN_MODIFY_COMPLETE_SYNC_OPS *psModifySyncOpsIN,
4829 PVRSRV_BRIDGE_RETURN *psModifySyncOpsOUT,
4830 PVRSRV_PER_PROCESS_DATA *psPerProc)
4831{
4832 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
4833
4834 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS);
4835
4836 psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
4837 (IMG_VOID**)&psModSyncOpInfo,
4838 psModifySyncOpsIN->hKernelSyncInfoModObj,
4839 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
4840 if (psModifySyncOpsOUT->eError != PVRSRV_OK)
4841 {
4842 PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: PVRSRVLookupHandle failed"));
4843 return 0;
4844 }
4845
4846 if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL)
4847 {
4848 /* Empty */
4849 psModifySyncOpsOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
4850 return 0;
4851 }
4852
4853 psModifySyncOpsOUT->eError = DoModifyCompleteSyncOps(psModSyncOpInfo);
4854
4855 if (psModifySyncOpsOUT->eError != PVRSRV_OK)
4856 {
4857 PVR_DPF((PVR_DBG_ERROR, "PVRSRVModifyCompleteSyncOpsBW: DoModifyCompleteSyncOps failed"));
4858 return 0;
4859 }
4860
4861 PVRSRVKernelSyncInfoDecRef(psModSyncOpInfo->psKernelSyncInfo, IMG_NULL);
4862 psModSyncOpInfo->psKernelSyncInfo = IMG_NULL;
4863
4864 /* re-kick all services managed devices */
4865 PVRSRVScheduleDeviceCallbacks();
4866
4867 return 0;
4868}
4869
4870
4871static IMG_INT
4872PVRSRVSyncOpsTakeTokenBW(IMG_UINT32 ui32BridgeID,
4873 PVRSRV_BRIDGE_IN_SYNC_OPS_TAKE_TOKEN *psSyncOpsTakeTokenIN,
4874 PVRSRV_BRIDGE_OUT_SYNC_OPS_TAKE_TOKEN *psSyncOpsTakeTokenOUT,
4875 PVRSRV_PER_PROCESS_DATA *psPerProc)
4876{
4877 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
4878
4879 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN);
4880
4881 psSyncOpsTakeTokenOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
4882 (IMG_VOID**)&psKernelSyncInfo,
4883 psSyncOpsTakeTokenIN->hKernelSyncInfo,
4884 PVRSRV_HANDLE_TYPE_SYNC_INFO);
4885 if (psSyncOpsTakeTokenOUT->eError != PVRSRV_OK)
4886 {
4887 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsTakeTokenBW: PVRSRVLookupHandle failed"));
4888 return 0;
4889 }
4890
4891 /* We return PRE-INCREMENTED versions of all sync Op Values */
4892
4893 psSyncOpsTakeTokenOUT->ui32ReadOpsPending = psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
4894 psSyncOpsTakeTokenOUT->ui32WriteOpsPending = psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
4895 psSyncOpsTakeTokenOUT->ui32ReadOps2Pending = psKernelSyncInfo->psSyncData->ui32ReadOps2Pending;
4896
4897 return 0;
4898}
4899
4900
4901static IMG_INT
4902PVRSRVSyncOpsFlushToTokenBW(IMG_UINT32 ui32BridgeID,
4903 PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_TOKEN *psSyncOpsFlushToTokenIN,
4904 PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToTokenOUT,
4905 PVRSRV_PER_PROCESS_DATA *psPerProc)
4906{
4907 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
4908 IMG_UINT32 ui32ReadOpsPendingSnapshot;
4909 IMG_UINT32 ui32WriteOpsPendingSnapshot;
4910 IMG_UINT32 ui32ReadOps2PendingSnapshot;
4911
4912 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN);
4913
4914 psSyncOpsFlushToTokenOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
4915 (IMG_VOID**)&psKernelSyncInfo,
4916 psSyncOpsFlushToTokenIN->hKernelSyncInfo,
4917 PVRSRV_HANDLE_TYPE_SYNC_INFO);
4918 if (psSyncOpsFlushToTokenOUT->eError != PVRSRV_OK)
4919 {
4920 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToTokenBW: PVRSRVLookupHandle failed"));
4921 return 0;
4922 }
4923
4924 ui32ReadOpsPendingSnapshot = psSyncOpsFlushToTokenIN->ui32ReadOpsPendingSnapshot;
4925 ui32WriteOpsPendingSnapshot = psSyncOpsFlushToTokenIN->ui32WriteOpsPendingSnapshot;
4926 ui32ReadOps2PendingSnapshot = psSyncOpsFlushToTokenIN->ui32ReadOps2PendingSnapshot;
4927
4928 psSyncOpsFlushToTokenOUT->eError = DoQuerySyncOpsSatisfied(psKernelSyncInfo,
4929 ui32ReadOpsPendingSnapshot,
4930 ui32WriteOpsPendingSnapshot,
4931 ui32ReadOps2PendingSnapshot);
4932
4933 if (psSyncOpsFlushToTokenOUT->eError != PVRSRV_OK && psSyncOpsFlushToTokenOUT->eError != PVRSRV_ERROR_RETRY)
4934 {
4935 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToTokenBW: DoQuerySyncOpsSatisfied failed"));
4936 return 0;
4937 }
4938
4939 return 0;
4940}
4941
4942
4943static IMG_INT
4944PVRSRVSyncOpsFlushToModObjBW(IMG_UINT32 ui32BridgeID,
4945 PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_MOD_OBJ *psSyncOpsFlushToModObjIN,
4946 PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToModObjOUT,
4947 PVRSRV_PER_PROCESS_DATA *psPerProc)
4948{
4949 MODIFY_SYNC_OP_INFO *psModSyncOpInfo;
4950
4951 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ);
4952
4953 psSyncOpsFlushToModObjOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
4954 (IMG_VOID**)&psModSyncOpInfo,
4955 psSyncOpsFlushToModObjIN->hKernelSyncInfoModObj,
4956 PVRSRV_HANDLE_TYPE_SYNC_INFO_MOD_OBJ);
4957 if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK)
4958 {
4959 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: PVRSRVLookupHandle failed"));
4960 return 0;
4961 }
4962
4963 if(psModSyncOpInfo->psKernelSyncInfo == IMG_NULL)
4964 {
4965 /* Empty */
4966 psSyncOpsFlushToModObjOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
4967 return 0;
4968 }
4969
4970 psSyncOpsFlushToModObjOUT->eError = DoQuerySyncOpsSatisfied(psModSyncOpInfo->psKernelSyncInfo,
4971 psModSyncOpInfo->ui32ReadOpsPendingSnapShot,
4972 psModSyncOpInfo->ui32WriteOpsPendingSnapShot,
4973 psModSyncOpInfo->ui32ReadOps2PendingSnapShot);
4974
4975 if (psSyncOpsFlushToModObjOUT->eError != PVRSRV_OK && psSyncOpsFlushToModObjOUT->eError != PVRSRV_ERROR_RETRY)
4976 {
4977 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToModObjBW: DoQuerySyncOpsSatisfied failed"));
4978 return 0;
4979 }
4980
4981 return 0;
4982}
4983
4984
4985static IMG_INT
4986PVRSRVSyncOpsFlushToDeltaBW(IMG_UINT32 ui32BridgeID,
4987 PVRSRV_BRIDGE_IN_SYNC_OPS_FLUSH_TO_DELTA *psSyncOpsFlushToDeltaIN,
4988 PVRSRV_BRIDGE_RETURN *psSyncOpsFlushToDeltaOUT,
4989 PVRSRV_PER_PROCESS_DATA *psPerProc)
4990{
4991 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
4992 IMG_UINT32 ui32DeltaRead;
4993 IMG_UINT32 ui32DeltaWrite;
4994
4995 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA);
4996
4997 psSyncOpsFlushToDeltaOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
4998 (IMG_VOID**)&psSyncInfo,
4999 psSyncOpsFlushToDeltaIN->hKernelSyncInfo,
5000 PVRSRV_HANDLE_TYPE_SYNC_INFO);
5001 if (psSyncOpsFlushToDeltaOUT->eError != PVRSRV_OK)
5002 {
5003 PVR_DPF((PVR_DBG_ERROR, "PVRSRVSyncOpsFlushToDeltaBW: PVRSRVLookupHandle failed"));
5004 return 0;
5005 }
5006
5007 /* FIXME: there's logic here in the bridge-wrapper - this needs to be moved to
5008 a better place */
5009
5010 ui32DeltaRead = psSyncInfo->psSyncData->ui32ReadOpsPending - psSyncInfo->psSyncData->ui32ReadOpsComplete;
5011 ui32DeltaWrite = psSyncInfo->psSyncData->ui32WriteOpsPending - psSyncInfo->psSyncData->ui32WriteOpsComplete;
5012
5013 if (ui32DeltaRead <= psSyncOpsFlushToDeltaIN->ui32Delta && ui32DeltaWrite <= psSyncOpsFlushToDeltaIN->ui32Delta)
5014 {
5015#if defined(PDUMP) && !defined(SUPPORT_VGX)
5016 /* pdump the sync pol: reads */
5017 PDumpComment("Poll for read ops complete to delta (%u)",
5018 psSyncOpsFlushToDeltaIN->ui32Delta);
5019 psSyncOpsFlushToDeltaOUT->eError =
5020 PDumpMemPolKM(psSyncInfo->psSyncDataMemInfoKM,
5021 offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete),
5022 psSyncInfo->psSyncData->ui32LastReadOpDumpVal,
5023 0xFFFFFFFF,
5024 PDUMP_POLL_OPERATOR_GREATEREQUAL,
5025 0,
5026 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
5027
5028 /* pdump the sync pol: writes */
5029 PDumpComment("Poll for write ops complete to delta (%u)",
5030 psSyncOpsFlushToDeltaIN->ui32Delta);
5031 psSyncOpsFlushToDeltaOUT->eError =
5032 PDumpMemPolKM(psSyncInfo->psSyncDataMemInfoKM,
5033 offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete),
5034 psSyncInfo->psSyncData->ui32LastOpDumpVal,
5035 0xFFFFFFFF,
5036 PDUMP_POLL_OPERATOR_GREATEREQUAL,
5037 0,
5038 MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM));
5039#endif
5040
5041 psSyncOpsFlushToDeltaOUT->eError = PVRSRV_OK;
5042 }
5043 else
5044 {
5045 psSyncOpsFlushToDeltaOUT->eError = PVRSRV_ERROR_RETRY;
5046 }
5047
5048 return 0;
5049}
5050
5051
5052static PVRSRV_ERROR
5053FreeSyncInfoCallback(IMG_PVOID pvParam,
5054 IMG_UINT32 ui32Param,
5055 IMG_BOOL bDummy)
5056{
5057 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
5058
5059 PVR_UNREFERENCED_PARAMETER(ui32Param);
5060 PVR_UNREFERENCED_PARAMETER(bDummy);
5061
5062 psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)pvParam;
5063
5064 PVRSRVKernelSyncInfoDecRef(psSyncInfo, IMG_NULL);
5065
5066 return PVRSRV_OK;
5067}
5068
5069
5070static IMG_INT
5071PVRSRVAllocSyncInfoBW(IMG_UINT32 ui32BridgeID,
5072 PVRSRV_BRIDGE_IN_ALLOC_SYNC_INFO *psAllocSyncInfoIN,
5073 PVRSRV_BRIDGE_OUT_ALLOC_SYNC_INFO *psAllocSyncInfoOUT,
5074 PVRSRV_PER_PROCESS_DATA *psPerProc)
5075{
5076 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
5077 PVRSRV_ERROR eError;
5078 PVRSRV_DEVICE_NODE *psDeviceNode;
5079 IMG_HANDLE hDevMemContext;
5080
5081 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_SYNC_INFO);
5082
5083 NEW_HANDLE_BATCH_OR_ERROR(psAllocSyncInfoOUT->eError, psPerProc, 1)
5084
5085 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
5086 (IMG_HANDLE *)&psDeviceNode,
5087 psAllocSyncInfoIN->hDevCookie,
5088 PVRSRV_HANDLE_TYPE_DEV_NODE);
5089 if(eError != PVRSRV_OK)
5090 {
5091 goto allocsyncinfo_errorexit;
5092 }
5093
5094 hDevMemContext = psDeviceNode->sDevMemoryInfo.pBMKernelContext;
5095
5096 eError = PVRSRVAllocSyncInfoKM(psDeviceNode,
5097 hDevMemContext,
5098 &psSyncInfo);
5099
5100 if (eError != PVRSRV_OK)
5101 {
5102 goto allocsyncinfo_errorexit;
5103 }
5104
5105 eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
5106 &psAllocSyncInfoOUT->hKernelSyncInfo,
5107 psSyncInfo,
5108 PVRSRV_HANDLE_TYPE_SYNC_INFO,
5109 PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE);
5110
5111 if(eError != PVRSRV_OK)
5112 {
5113 goto allocsyncinfo_errorexit_freesyncinfo;
5114 }
5115
5116 psSyncInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
5117 RESMAN_TYPE_SYNC_INFO,
5118 psSyncInfo,
5119 0,
5120 &FreeSyncInfoCallback);
5121
5122 /* Success */
5123 goto allocsyncinfo_commit;
5124
5125 /* Error handling */
5126 allocsyncinfo_errorexit_freesyncinfo:
5127 PVRSRVKernelSyncInfoDecRef(psSyncInfo, IMG_NULL);
5128
5129 allocsyncinfo_errorexit:
5130
5131 /* Common exit */
5132 allocsyncinfo_commit:
5133 psAllocSyncInfoOUT->eError = eError;
5134 COMMIT_HANDLE_BATCH_OR_ERROR(eError, psPerProc);
5135
5136 return 0;
5137}
5138
5139
5140static IMG_INT
5141PVRSRVFreeSyncInfoBW(IMG_UINT32 ui32BridgeID,
5142 PVRSRV_BRIDGE_IN_FREE_SYNC_INFO *psFreeSyncInfoIN,
5143 PVRSRV_BRIDGE_RETURN *psFreeSyncInfoOUT,
5144 PVRSRV_PER_PROCESS_DATA *psPerProc)
5145{
5146 PVRSRV_KERNEL_SYNC_INFO *psSyncInfo;
5147 PVRSRV_ERROR eError;
5148
5149 PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_SYNC_INFO);
5150
5151 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
5152 (IMG_VOID**)&psSyncInfo,
5153 psFreeSyncInfoIN->hKernelSyncInfo,
5154 PVRSRV_HANDLE_TYPE_SYNC_INFO);
5155 if (eError != PVRSRV_OK)
5156 {
5157 PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVLookupHandle failed"));
5158 psFreeSyncInfoOUT->eError = eError;
5159 return 0;
5160 }
5161
5162 eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
5163 psFreeSyncInfoIN->hKernelSyncInfo,
5164 PVRSRV_HANDLE_TYPE_SYNC_INFO);
5165
5166 if (eError != PVRSRV_OK)
5167 {
5168 PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: PVRSRVReleaseHandle failed"));
5169 psFreeSyncInfoOUT->eError = eError;
5170 return 0;
5171 }
5172
5173 eError = ResManFreeResByPtr(psSyncInfo->hResItem, CLEANUP_WITH_POLL);
5174 if (eError != PVRSRV_OK)
5175 {
5176 PVR_DPF((PVR_DBG_ERROR, "PVRSRVFreeSyncInfoBW: ResManFreeResByPtr failed"));
5177 psFreeSyncInfoOUT->eError = eError;
5178 return 0;
5179 }
5180
5181 return 0;
5182}
5183
5184
5185PVRSRV_ERROR
5186CommonBridgeInit(IMG_VOID)
5187{
5188 IMG_UINT32 i;
5189
5190 SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DEVICES, PVRSRVEnumerateDevicesBW);
5191 SetDispatchTableEntry(PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO, PVRSRVAcquireDeviceDataBW);
5192 SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_DEVICEINFO, DummyBW);
5193 SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT, PVRSRVCreateDeviceMemContextBW);
5194 SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT, PVRSRVDestroyDeviceMemContextBW);
5195 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO, PVRSRVGetDeviceMemHeapInfoBW);
5196 SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_DEVICEMEM, PVRSRVAllocDeviceMemBW);
5197 SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEVICEMEM, PVRSRVFreeDeviceMemBW);
5198 SetDispatchTableEntry(PVRSRV_BRIDGE_GETFREE_DEVICEMEM, PVRSRVGetFreeDeviceMemBW);
5199 SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_COMMANDQUEUE, DummyBW);
5200 SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE, DummyBW);
5201 SetDispatchTableEntry(PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA, PVRMMapOSMemHandleToMMapDataBW);
5202 SetDispatchTableEntry(PVRSRV_BRIDGE_CONNECT_SERVICES, PVRSRVConnectBW);
5203 SetDispatchTableEntry(PVRSRV_BRIDGE_DISCONNECT_SERVICES, PVRSRVDisconnectBW);
5204 SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_DEVICE_MEM, DummyBW);
5205 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVICEMEMINFO, DummyBW);
5206 SetDispatchTableEntry(PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM , DummyBW);
5207 SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEV_VIRTMEM, DummyBW);
5208 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_EXT_MEMORY, DummyBW);
5209 SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_EXT_MEMORY, DummyBW);
5210 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY, PVRSRVMapDeviceMemoryBW);
5211 SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEV_MEMORY, PVRSRVUnmapDeviceMemoryBW);
5212 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY, PVRSRVMapDeviceClassMemoryBW);
5213 SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY, PVRSRVUnmapDeviceClassMemoryBW);
5214 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER, DummyBW);
5215 SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER, DummyBW);
5216 SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM, PVRSRVExportDeviceMemBW);
5217 SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MMAP_DATA, PVRMMapReleaseMMapDataBW);
5218 SetDispatchTableEntry(PVRSRV_BRIDGE_CHG_DEV_MEM_ATTRIBS, PVRSRVChangeDeviceMemoryAttributesBW);
5219 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY_2, PVRSRVMapDeviceMemoryBW);
5220 SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM_2, PVRSRVExportDeviceMemBW);
5221 SetDispatchTableEntry(PVRSRV_BRIDGE_MULTI_MANAGE_DEV_MEM, PVRSRVMultiManageDevMemBW);
5222 SetDispatchTableEntry(PVRSRV_BRIDGE_CORE_CMD_RESERVED_1, DummyBW);
5223 SetDispatchTableEntry(PVRSRV_BRIDGE_CORE_CMD_RESERVED_2, DummyBW);
5224 SetDispatchTableEntry(PVRSRV_BRIDGE_CORE_CMD_RESERVED_3, DummyBW);
5225#if defined(SUPPORT_ION)
5226 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_ION_HANDLE, PVRSRVMapIonHandleBW);
5227 SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_ION_HANDLE, PVRSRVUnmapIonHandleBW);
5228#endif
5229
5230 /* SIM */
5231 SetDispatchTableEntry(PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT, DummyBW);
5232 SetDispatchTableEntry(PVRSRV_BRIDGE_REGISTER_SIM_PROCESS, DummyBW);
5233 SetDispatchTableEntry(PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS, DummyBW);
5234
5235 /* User Mapping */
5236 SetDispatchTableEntry(PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE, DummyBW);
5237 SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE, DummyBW);
5238 SetDispatchTableEntry(PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP, DummyBW);
5239
5240 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_FB_STATS, DummyBW);
5241
5242 /* API to retrieve misc. info. from services */
5243 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_MISC_INFO, PVRSRVGetMiscInfoBW);
5244 SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MISC_INFO, DummyBW);
5245
5246 /* Overlay ioctls */
5247#if defined (SUPPORT_OVERLAY_ROTATE_BLIT)
5248 SetDispatchTableEntry(PVRSRV_BRIDGE_INIT_3D_OVL_BLT_RES, DummyBW);
5249 SetDispatchTableEntry(PVRSRV_BRIDGE_DEINIT_3D_OVL_BLT_RES, DummyBW);
5250#endif
5251
5252
5253 /* PDUMP */
5254#if defined(PDUMP)
5255 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_INIT, DummyBW);
5256 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_MEMPOL, PDumpMemPolBW);
5257 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPMEM, PDumpMemBW);
5258 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REG, PDumpRegWithFlagsBW);
5259 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REGPOL, PDumpRegPolBW);
5260 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_COMMENT, PDumpCommentBW);
5261 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SETFRAME, PDumpSetFrameBW);
5262 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_ISCAPTURING, PDumpIsCaptureFrameBW);
5263 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPBITMAP, PDumpBitmapBW);
5264 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPREADREG, PDumpReadRegBW);
5265 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SYNCPOL, PDumpSyncPolBW);
5266 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPSYNC, PDumpSyncDumpBW);
5267 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_MEMPAGES, PDumpMemPagesBW);
5268 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DRIVERINFO, PDumpDriverInfoBW);
5269 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR, PDumpPDDevPAddrBW);
5270 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ, PDumpCycleCountRegReadBW);
5271 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STARTINITPHASE, PDumpStartInitPhaseBW);
5272 SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STOPINITPHASE, PDumpStopInitPhaseBW);
5273#endif /* defined(PDUMP) */
5274
5275 /* DisplayClass APIs */
5276 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_OEMJTABLE, DummyBW);
5277
5278 /* device class enum */
5279 SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_CLASS, PVRSRVEnumerateDCBW);
5280
5281 /* display class API */
5282 SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE, PVRSRVOpenDCDeviceBW);
5283 SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE, PVRSRVCloseDCDeviceBW);
5284 SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS, PVRSRVEnumDCFormatsBW);
5285 SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS, PVRSRVEnumDCDimsBW);
5286#if defined(SUPPORT_PVRSRV_GET_DC_SYSTEM_BUFFER)
5287 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER, PVRSRVGetDCSystemBufferBW);
5288#else
5289 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER, DummyBW);
5290#endif
5291 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_INFO, PVRSRVGetDCInfoBW);
5292 SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN, PVRSRVCreateDCSwapChainBW);
5293 SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN, PVRSRVDestroyDCSwapChainBW);
5294 SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT, PVRSRVSetDCDstRectBW);
5295 SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT, PVRSRVSetDCSrcRectBW);
5296 SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY, PVRSRVSetDCDstColourKeyBW);
5297 SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY, PVRSRVSetDCSrcColourKeyBW);
5298 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS, PVRSRVGetDCBuffersBW);
5299 SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER, PVRSRVSwapToDCBufferBW);
5300 SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER2, PVRSRVSwapToDCBuffer2BW);
5301 SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM, PVRSRVSwapToDCSystemBW);
5302
5303 /* buffer class API */
5304 SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE, PVRSRVOpenBCDeviceBW);
5305 SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE, PVRSRVCloseBCDeviceBW);
5306 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO, PVRSRVGetBCInfoBW);
5307 SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER, PVRSRVGetBCBufferBW);
5308
5309 /* Wrap/Unwrap external memory */
5310 SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_EXT_MEMORY, PVRSRVWrapExtMemoryBW);
5311 SetDispatchTableEntry(PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY, PVRSRVUnwrapExtMemoryBW);
5312
5313 /* Shared memory */
5314 SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM, PVRSRVAllocSharedSysMemoryBW);
5315 SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM, PVRSRVFreeSharedSysMemoryBW);
5316 SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEMINFO_MEM, PVRSRVMapMemInfoMemBW);
5317
5318 /* Intialisation Service support */
5319 SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_CONNECT, &PVRSRVInitSrvConnectBW);
5320 SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_DISCONNECT, &PVRSRVInitSrvDisconnectBW);
5321
5322 /* Event Object */
5323 SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_WAIT, &PVRSRVEventObjectWaitBW);
5324 SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_OPEN, &PVRSRVEventObjectOpenBW);
5325 SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE, &PVRSRVEventObjectCloseBW);
5326
5327 SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_SYNC_INFO_MOD_OBJ, PVRSRVCreateSyncInfoModObjBW);
5328 SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_SYNC_INFO_MOD_OBJ, PVRSRVDestroySyncInfoModObjBW);
5329 SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_PENDING_SYNC_OPS, PVRSRVModifyPendingSyncOpsBW);
5330 SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_COMPLETE_SYNC_OPS, PVRSRVModifyCompleteSyncOpsBW);
5331 SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_TAKE_TOKEN, PVRSRVSyncOpsTakeTokenBW);
5332 SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_TOKEN, PVRSRVSyncOpsFlushToTokenBW);
5333 SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_MOD_OBJ, PVRSRVSyncOpsFlushToModObjBW);
5334 SetDispatchTableEntry(PVRSRV_BRIDGE_SYNC_OPS_FLUSH_TO_DELTA, PVRSRVSyncOpsFlushToDeltaBW);
5335 SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SYNC_INFO, PVRSRVAllocSyncInfoBW);
5336 SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SYNC_INFO, PVRSRVFreeSyncInfoBW);
5337
5338#if defined (SUPPORT_SGX)
5339 SetSGXDispatchTableEntry();
5340#endif
5341#if defined (SUPPORT_VGX)
5342 SetVGXDispatchTableEntry();
5343#endif
5344#if defined (SUPPORT_MSVDX)
5345 SetMSVDXDispatchTableEntry();
5346#endif
5347
5348 /* A safety net to help ensure there won't be any un-initialised dispatch
5349 * table entries... */
5350 /* Note: This is specifically done _after_ setting all the dispatch entries
5351 * so that SetDispatchTableEntry can detect mistakes where entries
5352 * overlap */
5353 for(i=0;i<BRIDGE_DISPATCH_TABLE_ENTRY_COUNT;i++)
5354 {
5355 if(!g_BridgeDispatchTable[i].pfFunction)
5356 {
5357 g_BridgeDispatchTable[i].pfFunction = &DummyBW;
5358#if defined(DEBUG_BRIDGE_KM)
5359 g_BridgeDispatchTable[i].pszIOCName = "_PVRSRV_BRIDGE_DUMMY";
5360 g_BridgeDispatchTable[i].pszFunctionName = "DummyBW";
5361 g_BridgeDispatchTable[i].ui32CallCount = 0;
5362 g_BridgeDispatchTable[i].ui32CopyFromUserTotalBytes = 0;
5363 g_BridgeDispatchTable[i].ui32CopyToUserTotalBytes = 0;
5364#endif
5365 }
5366 }
5367
5368 return PVRSRV_OK;
5369}
5370
5371IMG_INT BridgedDispatchKM(PVRSRV_PER_PROCESS_DATA * psPerProc,
5372 PVRSRV_BRIDGE_PACKAGE * psBridgePackageKM)
5373{
5374 IMG_VOID * psBridgeIn;
5375 IMG_VOID * psBridgeOut;
5376 BridgeWrapperFunction pfBridgeHandler;
5377 IMG_UINT32 ui32BridgeID = psBridgePackageKM->ui32BridgeID;
5378 IMG_INT err = -EFAULT;
5379
5380#if defined(DEBUG_TRACE_BRIDGE_KM)
5381 PVR_DPF((PVR_DBG_ERROR, "%s: %s",
5382 __FUNCTION__,
5383 g_BridgeDispatchTable[ui32BridgeID].pszIOCName));
5384#endif
5385
5386#if defined(DEBUG_BRIDGE_KM)
5387 g_BridgeDispatchTable[ui32BridgeID].ui32CallCount++;
5388 g_BridgeGlobalStats.ui32IOCTLCount++;
5389#endif
5390
5391 if(!psPerProc->bInitProcess)
5392 {
5393 if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN))
5394 {
5395 if(!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL))
5396 {
5397 PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation failed. Driver unusable.",
5398 __FUNCTION__));
5399 goto return_fault;
5400 }
5401 }
5402 else
5403 {
5404 if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING))
5405 {
5406 PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation is in progress",
5407 __FUNCTION__));
5408 goto return_fault;
5409 }
5410 else
5411 {
5412 /* Only certain operations are allowed */
5413 switch(ui32BridgeID)
5414 {
5415 case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_CONNECT_SERVICES):
5416 case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_DISCONNECT_SERVICES):
5417 case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_CONNECT):
5418 case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_INITSRV_DISCONNECT):
5419 break;
5420 default:
5421 PVR_DPF((PVR_DBG_ERROR, "%s: Driver initialisation not completed yet.",
5422 __FUNCTION__));
5423 goto return_fault;
5424 }
5425 }
5426 }
5427 }
5428
5429#if defined(__linux__)
5430 {
5431 /* This should be moved into the linux specific code */
5432 SYS_DATA *psSysData;
5433
5434 SysAcquireData(&psSysData);
5435
5436 /* We have already set up some static buffers to store our ioctl data... */
5437 psBridgeIn = ((ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData;
5438 psBridgeOut = (IMG_PVOID)((IMG_PBYTE)psBridgeIn + PVRSRV_MAX_BRIDGE_IN_SIZE);
5439
5440 /* check we are not using a bigger bridge than allocated */
5441 if((psBridgePackageKM->ui32InBufferSize > PVRSRV_MAX_BRIDGE_IN_SIZE) ||
5442 (psBridgePackageKM->ui32OutBufferSize > PVRSRV_MAX_BRIDGE_OUT_SIZE))
5443 {
5444 goto return_fault;
5445 }
5446
5447
5448 if(psBridgePackageKM->ui32InBufferSize > 0)
5449 {
5450 if(!OSAccessOK(PVR_VERIFY_READ,
5451 psBridgePackageKM->pvParamIn,
5452 psBridgePackageKM->ui32InBufferSize))
5453 {
5454 PVR_DPF((PVR_DBG_ERROR, "%s: Invalid pvParamIn pointer", __FUNCTION__));
5455 }
5456
5457 if(CopyFromUserWrapper(psPerProc,
5458 ui32BridgeID,
5459 psBridgeIn,
5460 psBridgePackageKM->pvParamIn,
5461 psBridgePackageKM->ui32InBufferSize)
5462 != PVRSRV_OK)
5463 {
5464 goto return_fault;
5465 }
5466 }
5467 }
5468#else
5469 psBridgeIn = psBridgePackageKM->pvParamIn;
5470 psBridgeOut = psBridgePackageKM->pvParamOut;
5471#endif
5472
5473 if(ui32BridgeID >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT))
5474 {
5475 PVR_DPF((PVR_DBG_ERROR, "%s: ui32BridgeID = %d is out if range!",
5476 __FUNCTION__, ui32BridgeID));
5477 goto return_fault;
5478 }
5479 pfBridgeHandler =
5480 (BridgeWrapperFunction)g_BridgeDispatchTable[ui32BridgeID].pfFunction;
5481 err = pfBridgeHandler(ui32BridgeID,
5482 psBridgeIn,
5483 psBridgeOut,
5484 psPerProc);
5485 if(err < 0)
5486 {
5487 goto return_fault;
5488 }
5489
5490#if defined(__linux__)
5491 /* This should be moved into the linux specific code */
5492 if(CopyToUserWrapper(psPerProc,
5493 ui32BridgeID,
5494 psBridgePackageKM->pvParamOut,
5495 psBridgeOut,
5496 psBridgePackageKM->ui32OutBufferSize)
5497 != PVRSRV_OK)
5498 {
5499 goto return_fault;
5500 }
5501#endif
5502
5503 err = 0;
5504return_fault:
5505
5506 ReleaseHandleBatch(psPerProc);
5507 return err;
5508}
5509
5510/******************************************************************************
5511 End of file (bridged_pvr_bridge.c)
5512******************************************************************************/