gpu: pvr: add tracing to the SGX queryblits command
[sgx.git] / pvr / bridged_sgx_bridge.c
1 /**********************************************************************
2  *
3  * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful but, except
10  * as otherwise stated in writing, without any warranty; without even the
11  * implied warranty of merchantability or fitness for a particular purpose.
12  * See the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * The full GNU General Public License is included in this distribution in
19  * the file called "COPYING".
20  *
21  * Contact Information:
22  * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23  * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24  *
25  ******************************************************************************/
26
27 #include <linux/errno.h>
28
29 #include <stddef.h>
30
31 #include "img_defs.h"
32
33 #include "services.h"
34 #include "pvr_debug.h"
35 #include "pvr_bridge.h"
36 #include "sgx_bridge.h"
37 #include "perproc.h"
38 #include "power.h"
39 #include "pvr_bridge_km.h"
40 #include "sgx_bridge_km.h"
41 #include "bridged_pvr_bridge.h"
42 #include "bridged_sgx_bridge.h"
43 #include "sgxutils.h"
44 #include "pvr_pdump.h"
45 #include "pvr_events.h"
46 #include "pvr_trace_cmd.h"
47
48 int SGXGetClientInfoBW(u32 ui32BridgeID,
49               struct PVRSRV_BRIDGE_IN_GETCLIENTINFO *psGetClientInfoIN,
50               struct PVRSRV_BRIDGE_OUT_GETCLIENTINFO *psGetClientInfoOUT,
51               struct PVRSRV_PER_PROCESS_DATA *psPerProc)
52 {
53         void *hDevCookieInt;
54
55         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETCLIENTINFO);
56
57         psGetClientInfoOUT->eError =
58             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
59                                psGetClientInfoIN->hDevCookie,
60                                PVRSRV_HANDLE_TYPE_DEV_NODE);
61         if (psGetClientInfoOUT->eError != PVRSRV_OK)
62                 return 0;
63
64         psGetClientInfoOUT->eError =
65             SGXGetClientInfoKM(hDevCookieInt, &psGetClientInfoOUT->sClientInfo);
66         return 0;
67 }
68
69 int SGXReleaseClientInfoBW(u32 ui32BridgeID,
70           struct PVRSRV_BRIDGE_IN_RELEASECLIENTINFO *psReleaseClientInfoIN,
71           struct PVRSRV_BRIDGE_RETURN *psRetOUT,
72           struct PVRSRV_PER_PROCESS_DATA *psPerProc)
73 {
74         struct PVRSRV_SGXDEV_INFO *psDevInfo;
75         void *hDevCookieInt;
76
77         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
78                                  PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO);
79
80         psRetOUT->eError =
81             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
82                                psReleaseClientInfoIN->hDevCookie,
83                                PVRSRV_HANDLE_TYPE_DEV_NODE);
84         if (psRetOUT->eError != PVRSRV_OK)
85                 return 0;
86
87         psDevInfo =
88             (struct PVRSRV_SGXDEV_INFO *)((struct PVRSRV_DEVICE_NODE *)
89                                           hDevCookieInt)->pvDevice;
90
91         PVR_ASSERT(psDevInfo->ui32ClientRefCount > 0);
92
93         psDevInfo->ui32ClientRefCount--;
94
95         psRetOUT->eError = PVRSRV_OK;
96
97         return 0;
98 }
99
100 int SGXGetInternalDevInfoBW(u32 ui32BridgeID,
101         struct PVRSRV_BRIDGE_IN_GETINTERNALDEVINFO *psSGXGetInternalDevInfoIN,
102         struct PVRSRV_BRIDGE_OUT_GETINTERNALDEVINFO *psSGXGetInternalDevInfoOUT,
103         struct PVRSRV_PER_PROCESS_DATA *psPerProc)
104 {
105         void *hDevCookieInt;
106
107         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
108                                  PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO);
109
110         psSGXGetInternalDevInfoOUT->eError =
111             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
112                                psSGXGetInternalDevInfoIN->hDevCookie,
113                                PVRSRV_HANDLE_TYPE_DEV_NODE);
114         if (psSGXGetInternalDevInfoOUT->eError != PVRSRV_OK)
115                 return 0;
116
117         psSGXGetInternalDevInfoOUT->eError =
118             SGXGetInternalDevInfoKM(hDevCookieInt,
119                             &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo);
120
121         psSGXGetInternalDevInfoOUT->eError =
122             PVRSRVAllocHandle(psPerProc->psHandleBase,
123                               &psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.
124                                               hHostCtlKernelMemInfoHandle,
125                               psSGXGetInternalDevInfoOUT->sSGXInternalDevInfo.
126                                               hHostCtlKernelMemInfoHandle,
127                               PVRSRV_HANDLE_TYPE_MEM_INFO,
128                               PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
129
130         return 0;
131 }
132
133 int SGXDoKickBW(u32 ui32BridgeID,
134                        struct PVRSRV_BRIDGE_IN_DOKICK *psDoKickIN,
135                        struct PVRSRV_BRIDGE_RETURN *psRetOUT,
136                        size_t in_size,
137                        struct PVRSRV_PER_PROCESS_DATA *psPerProc)
138 {
139         void *hDevCookieInt;
140         u32 i;
141
142         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DOKICK);
143
144         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
145                                               &hDevCookieInt,
146                                               psDoKickIN->hDevCookie,
147                                               PVRSRV_HANDLE_TYPE_DEV_NODE);
148
149         if (psRetOUT->eError != PVRSRV_OK)
150                 return 0;
151
152         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
153                                 &psDoKickIN->sCCBKick.hCCBKernelMemInfo,
154                                 psDoKickIN->sCCBKick.hCCBKernelMemInfo,
155                                 PVRSRV_HANDLE_TYPE_MEM_INFO);
156
157         if (psRetOUT->eError != PVRSRV_OK)
158                 return 0;
159
160         if (psDoKickIN->sCCBKick.hTA3DSyncInfo != NULL) {
161                 psRetOUT->eError =
162                     PVRSRVLookupHandle(psPerProc->psHandleBase,
163                                        &psDoKickIN->sCCBKick.hTA3DSyncInfo,
164                                        psDoKickIN->sCCBKick.hTA3DSyncInfo,
165                                        PVRSRV_HANDLE_TYPE_SYNC_INFO);
166
167                 if (psRetOUT->eError != PVRSRV_OK)
168                         return 0;
169         }
170
171         if (psDoKickIN->sCCBKick.hTASyncInfo != NULL) {
172                 psRetOUT->eError =
173                     PVRSRVLookupHandle(psPerProc->psHandleBase,
174                                        &psDoKickIN->sCCBKick.hTASyncInfo,
175                                        psDoKickIN->sCCBKick.hTASyncInfo,
176                                        PVRSRV_HANDLE_TYPE_SYNC_INFO);
177
178                 if (psRetOUT->eError != PVRSRV_OK)
179                         return 0;
180         }
181
182         if (psDoKickIN->sCCBKick.h3DSyncInfo != NULL) {
183                 psRetOUT->eError =
184                     PVRSRVLookupHandle(psPerProc->psHandleBase,
185                                        &psDoKickIN->sCCBKick.h3DSyncInfo,
186                                        psDoKickIN->sCCBKick.h3DSyncInfo,
187                                        PVRSRV_HANDLE_TYPE_SYNC_INFO);
188
189                 if (psRetOUT->eError != PVRSRV_OK)
190                         return 0;
191         }
192
193         if (psDoKickIN->sCCBKick.ui32NumSrcSyncs > SGX_MAX_SRC_SYNCS) {
194                 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
195                 return 0;
196         }
197         for (i = 0; i < psDoKickIN->sCCBKick.ui32NumSrcSyncs; i++) {
198                 psRetOUT->eError =
199                     PVRSRVLookupHandle(psPerProc->psHandleBase,
200                                        &psDoKickIN->sCCBKick.
201                                        ahSrcKernelSyncInfo[i],
202                                        psDoKickIN->sCCBKick.
203                                        ahSrcKernelSyncInfo[i],
204                                        PVRSRV_HANDLE_TYPE_SYNC_INFO);
205
206                 if (psRetOUT->eError != PVRSRV_OK)
207                         return 0;
208         }
209
210         if (psDoKickIN->sCCBKick.ui32NumTAStatusVals > SGX_MAX_TA_STATUS_VALS) {
211                 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
212                 return 0;
213         }
214         for (i = 0; i < psDoKickIN->sCCBKick.ui32NumTAStatusVals; i++) {
215                 psRetOUT->eError =
216                     PVRSRVLookupHandle(psPerProc->psHandleBase,
217                                     &psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i],
218                                     psDoKickIN->sCCBKick.ahTAStatusSyncInfo[i],
219                                     PVRSRV_HANDLE_TYPE_SYNC_INFO);
220                 if (psRetOUT->eError != PVRSRV_OK)
221                         return 0;
222         }
223
224         if (psDoKickIN->sCCBKick.ui32Num3DStatusVals > SGX_MAX_3D_STATUS_VALS) {
225                 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
226                 return 0;
227         }
228         for (i = 0; i < psDoKickIN->sCCBKick.ui32Num3DStatusVals; i++) {
229                 psRetOUT->eError =
230                     PVRSRVLookupHandle(psPerProc->psHandleBase,
231                                     &psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
232                                     psDoKickIN->sCCBKick.ah3DStatusSyncInfo[i],
233                                     PVRSRV_HANDLE_TYPE_SYNC_INFO);
234
235                 if (psRetOUT->eError != PVRSRV_OK)
236                         return 0;
237         }
238
239         if (psDoKickIN->sCCBKick.ui32NumDstSyncObjects > 0) {
240                 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
241                                        &psDoKickIN->sCCBKick.
242                                                        hKernelHWSyncListMemInfo,
243                                        psDoKickIN->sCCBKick.
244                                                        hKernelHWSyncListMemInfo,
245                                        PVRSRV_HANDLE_TYPE_MEM_INFO);
246
247                 if (psRetOUT->eError != PVRSRV_OK)
248                         return 0;
249
250                 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
251                                       &psDoKickIN->sCCBKick.sDstSyncHandle,
252                                       psDoKickIN->sCCBKick.sDstSyncHandle,
253                                       PVRSRV_HANDLE_TYPE_SYNC_INFO);
254
255                 if (psRetOUT->eError != PVRSRV_OK)
256                         return 0;
257         }
258
259         psRetOUT->eError = SGXDoKickKM(hDevCookieInt, &psDoKickIN->sCCBKick,
260                                         psPerProc);
261
262         return 0;
263 }
264
265 int SGXScheduleProcessQueuesBW(u32 ui32BridgeID,
266       struct PVRSRV_BRIDGE_IN_SGX_SCHEDULE_PROCESS_QUEUES *psScheduleProcQIN,
267       struct PVRSRV_BRIDGE_RETURN *psRetOUT,
268       struct PVRSRV_PER_PROCESS_DATA *psPerProc)
269 {
270         void *hDevCookieInt;
271
272         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
273                                  PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES);
274
275         psRetOUT->eError =
276             PVRSRVLookupHandle(psPerProc->psHandleBase,
277                                &hDevCookieInt,
278                                psScheduleProcQIN->hDevCookie,
279                                PVRSRV_HANDLE_TYPE_DEV_NODE);
280
281         if (psRetOUT->eError != PVRSRV_OK)
282                 return 0;
283
284         psRetOUT->eError = SGXScheduleProcessQueuesKM(hDevCookieInt);
285
286         return 0;
287 }
288
289 int SGXSubmitTransferBW(u32 ui32BridgeID,
290                struct PVRSRV_BRIDGE_IN_SUBMITTRANSFER *psSubmitTransferIN,
291                struct PVRSRV_BRIDGE_RETURN *psRetOUT,
292                struct PVRSRV_PER_PROCESS_DATA *psPerProc)
293 {
294         void *hDevCookieInt;
295         struct PVRSRV_TRANSFER_SGX_KICK *psKick;
296         u32 i;
297
298         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
299                                  PVRSRV_BRIDGE_SGX_SUBMITTRANSFER);
300         PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
301
302         psKick = &psSubmitTransferIN->sKick;
303
304         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
305                                                &hDevCookieInt,
306                                                psSubmitTransferIN->hDevCookie,
307                                                PVRSRV_HANDLE_TYPE_DEV_NODE);
308         if (psRetOUT->eError != PVRSRV_OK)
309                 return 0;
310
311         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
312                                               &psKick->hCCBMemInfo,
313                                               psKick->hCCBMemInfo,
314                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
315         if (psRetOUT->eError != PVRSRV_OK)
316                 return 0;
317
318         if (psKick->hTASyncInfo != NULL) {
319                 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
320                                                   &psKick->hTASyncInfo,
321                                                   psKick->hTASyncInfo,
322                                                   PVRSRV_HANDLE_TYPE_SYNC_INFO);
323                 if (psRetOUT->eError != PVRSRV_OK)
324                         return 0;
325         }
326
327         if (psKick->h3DSyncInfo != NULL) {
328                 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
329                                              &psKick->h3DSyncInfo,
330                                              psKick->h3DSyncInfo,
331                                              PVRSRV_HANDLE_TYPE_SYNC_INFO);
332                 if (psRetOUT->eError != PVRSRV_OK)
333                         return 0;
334         }
335
336         if (psKick->ui32NumSrcSync > SGX_MAX_TRANSFER_SYNC_OPS) {
337                 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
338                 return 0;
339         }
340         for (i = 0; i < psKick->ui32NumSrcSync; i++) {
341                 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
342                                        &psKick->ahSrcSyncInfo[i],
343                                        psKick->ahSrcSyncInfo[i],
344                                        PVRSRV_HANDLE_TYPE_SYNC_INFO);
345                 if (psRetOUT->eError != PVRSRV_OK)
346                         return 0;
347         }
348
349         if (psKick->ui32NumDstSync > SGX_MAX_TRANSFER_SYNC_OPS) {
350                 psRetOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
351                 return 0;
352         }
353         for (i = 0; i < psKick->ui32NumDstSync; i++) {
354                 psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
355                                        &psKick->ahDstSyncInfo[i],
356                                        psKick->ahDstSyncInfo[i],
357                                        PVRSRV_HANDLE_TYPE_SYNC_INFO);
358                 if (psRetOUT->eError != PVRSRV_OK)
359                         return 0;
360         }
361
362         psRetOUT->eError = SGXSubmitTransferKM(hDevCookieInt, psKick,
363                                                 psPerProc);
364
365         return 0;
366 }
367
368 int SGXGetMiscInfoBW(u32 ui32BridgeID,
369                     struct PVRSRV_BRIDGE_IN_SGXGETMISCINFO *psSGXGetMiscInfoIN,
370                     struct PVRSRV_BRIDGE_RETURN *psRetOUT,
371                     struct PVRSRV_PER_PROCESS_DATA *psPerProc)
372 {
373         void *hDevCookieInt;
374         struct PVRSRV_SGXDEV_INFO *psDevInfo;
375         struct SGX_MISC_INFO sMiscInfo;
376         struct PVRSRV_DEVICE_NODE *psDeviceNode;
377
378         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_GETMISCINFO);
379
380         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
381                                               &hDevCookieInt,
382                                               psSGXGetMiscInfoIN->hDevCookie,
383                                               PVRSRV_HANDLE_TYPE_DEV_NODE);
384
385         if (psRetOUT->eError != PVRSRV_OK)
386                 return 0;
387
388         psDeviceNode = hDevCookieInt;
389         PVR_ASSERT(psDeviceNode != NULL);
390         if (psDeviceNode == NULL)
391                 return -EFAULT;
392
393         psDevInfo = psDeviceNode->pvDevice;
394
395         psRetOUT->eError = CopyFromUserWrapper(psPerProc, ui32BridgeID,
396                                                &sMiscInfo,
397                                                psSGXGetMiscInfoIN->psMiscInfo,
398                                                sizeof(struct SGX_MISC_INFO));
399         if (psRetOUT->eError != PVRSRV_OK)
400                 return -EFAULT;
401
402         if (sMiscInfo.eRequest == SGX_MISC_INFO_REQUEST_HWPERF_RETRIEVE_CB) {
403                 void *pAllocated;
404                 void *hAllocatedHandle;
405                 void __user *psTmpUserData;
406                 u32 allocatedSize;
407
408                 allocatedSize =
409                     (u32) (sMiscInfo.uData.sRetrieveCB.ui32ArraySize *
410                            sizeof(struct PVRSRV_SGX_HWPERF_CBDATA));
411
412                 ASSIGN_AND_EXIT_ON_ERROR(psRetOUT->eError,
413                                          OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
414                                                     allocatedSize,
415                                                     &pAllocated,
416                                                     &hAllocatedHandle));
417
418                 psTmpUserData = (void __force __user *)
419                                 sMiscInfo.uData.sRetrieveCB.psHWPerfData;
420                 sMiscInfo.uData.sRetrieveCB.psHWPerfData = pAllocated;
421
422                 psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo,
423                                                     &sMiscInfo, psDeviceNode);
424                 if (psRetOUT->eError != PVRSRV_OK) {
425                         OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
426                                   allocatedSize, pAllocated, hAllocatedHandle);
427                         return 0;
428                 }
429
430                 psRetOUT->eError = CopyToUserWrapper(psPerProc,
431                                      ui32BridgeID, psTmpUserData,
432                                      sMiscInfo.uData.sRetrieveCB.psHWPerfData,
433                                      allocatedSize);
434
435                 sMiscInfo.uData.sRetrieveCB.psHWPerfData =
436                                                 (void __force *)psTmpUserData;
437
438                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
439                           allocatedSize, pAllocated, hAllocatedHandle);
440
441                 if (psRetOUT->eError != PVRSRV_OK)
442                         return -EFAULT;
443         } else {
444                 psRetOUT->eError = SGXGetMiscInfoKM(psDevInfo,
445                                                     &sMiscInfo, psDeviceNode);
446
447                 if (psRetOUT->eError != PVRSRV_OK)
448                         return 0;
449         }
450
451         psRetOUT->eError = CopyToUserWrapper(psPerProc,
452                                              ui32BridgeID,
453                                              psSGXGetMiscInfoIN->psMiscInfo,
454                                              &sMiscInfo,
455                                              sizeof(struct SGX_MISC_INFO));
456         if (psRetOUT->eError != PVRSRV_OK)
457                 return -EFAULT;
458         return 0;
459 }
460
461 int SGXReadDiffCountersBW(u32 ui32BridgeID,
462         struct PVRSRV_BRIDGE_IN_SGX_READ_DIFF_COUNTERS *psSGXReadDiffCountersIN,
463         struct PVRSRV_BRIDGE_OUT_SGX_READ_DIFF_COUNTERS
464                                                 *psSGXReadDiffCountersOUT,
465         struct PVRSRV_PER_PROCESS_DATA *psPerProc)
466 {
467         void *hDevCookieInt;
468
469         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
470                                  PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS);
471
472         psSGXReadDiffCountersOUT->eError =
473             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
474                                psSGXReadDiffCountersIN->hDevCookie,
475                                PVRSRV_HANDLE_TYPE_DEV_NODE);
476
477         if (psSGXReadDiffCountersOUT->eError != PVRSRV_OK)
478                 return 0;
479
480         psSGXReadDiffCountersOUT->eError = SGXReadDiffCountersKM(
481                                 hDevCookieInt,
482                                 psSGXReadDiffCountersIN->ui32Reg,
483                                 &psSGXReadDiffCountersOUT->ui32Old,
484                                 psSGXReadDiffCountersIN->bNew,
485                                 psSGXReadDiffCountersIN->ui32New,
486                                 psSGXReadDiffCountersIN->ui32NewReset,
487                                 psSGXReadDiffCountersIN->ui32CountersReg,
488                                 &psSGXReadDiffCountersOUT->ui32Time,
489                                 &psSGXReadDiffCountersOUT->bActive,
490                                 &psSGXReadDiffCountersOUT->sDiffs);
491
492         return 0;
493 }
494
495 int SGXReadHWPerfCBBW(u32 ui32BridgeID,
496              struct PVRSRV_BRIDGE_IN_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBIN,
497              struct PVRSRV_BRIDGE_OUT_SGX_READ_HWPERF_CB *psSGXReadHWPerfCBOUT,
498              struct PVRSRV_PER_PROCESS_DATA *psPerProc)
499 {
500         void *hDevCookieInt;
501         struct PVRSRV_SGX_HWPERF_CB_ENTRY *psAllocated;
502         void *hAllocatedHandle;
503         u32 ui32AllocatedSize;
504
505         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
506                                  PVRSRV_BRIDGE_SGX_READ_HWPERF_CB);
507
508         psSGXReadHWPerfCBOUT->eError =
509             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
510                                psSGXReadHWPerfCBIN->hDevCookie,
511                                PVRSRV_HANDLE_TYPE_DEV_NODE);
512
513         if (psSGXReadHWPerfCBOUT->eError != PVRSRV_OK)
514                 return 0;
515
516         ui32AllocatedSize = psSGXReadHWPerfCBIN->ui32ArraySize *
517                                 sizeof(psSGXReadHWPerfCBIN->psHWPerfCBData[0]);
518         ASSIGN_AND_EXIT_ON_ERROR(psSGXReadHWPerfCBOUT->eError,
519                                  OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
520                                             ui32AllocatedSize,
521                                             (void **)&psAllocated,
522                                             &hAllocatedHandle));
523
524         psSGXReadHWPerfCBOUT->eError = SGXReadHWPerfCBKM(hDevCookieInt,
525                                  psSGXReadHWPerfCBIN->ui32ArraySize,
526                                  psAllocated,
527                                  &psSGXReadHWPerfCBOUT->ui32DataCount,
528                                  &psSGXReadHWPerfCBOUT->ui32ClockSpeed,
529                                  &psSGXReadHWPerfCBOUT->ui32HostTimeStamp);
530         if (psSGXReadHWPerfCBOUT->eError == PVRSRV_OK)
531                 psSGXReadHWPerfCBOUT->eError = CopyToUserWrapper(
532                                          psPerProc, ui32BridgeID,
533                                          psSGXReadHWPerfCBIN->psHWPerfCBData,
534                                          psAllocated, ui32AllocatedSize);
535
536         OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
537                   ui32AllocatedSize, psAllocated, hAllocatedHandle);
538
539         return 0;
540 }
541
542 int SGXDevInitPart2BW(u32 ui32BridgeID,
543                 struct PVRSRV_BRIDGE_IN_SGXDEVINITPART2 *psSGXDevInitPart2IN,
544                 struct PVRSRV_BRIDGE_RETURN *psRetOUT,
545                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
546 {
547         void *hDevCookieInt;
548         enum PVRSRV_ERROR eError;
549         IMG_BOOL bDissociateFailed = IMG_FALSE;
550         IMG_BOOL bLookupFailed = IMG_FALSE;
551         IMG_BOOL bReleaseFailed = IMG_FALSE;
552         void *hDummy;
553         void **edm_mi;
554         u32 i;
555
556         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SGX_DEVINITPART2);
557
558         if (!psPerProc->bInitProcess) {
559                 psRetOUT->eError = PVRSRV_ERROR_GENERIC;
560                 return 0;
561         }
562
563         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
564                                                 &hDevCookieInt,
565                                                 psSGXDevInitPart2IN->hDevCookie,
566                                                 PVRSRV_HANDLE_TYPE_DEV_NODE);
567         if (psRetOUT->eError != PVRSRV_OK)
568                 return 0;
569
570         eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy,
571                                     psSGXDevInitPart2IN->sInitInfo.
572                                             hKernelCCBMemInfo,
573                                     PVRSRV_HANDLE_TYPE_MEM_INFO);
574         bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
575
576         eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy,
577                                     psSGXDevInitPart2IN->sInitInfo.
578                                             hKernelCCBCtlMemInfo,
579                                     PVRSRV_HANDLE_TYPE_MEM_INFO);
580         bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
581
582         eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy,
583                                     psSGXDevInitPart2IN->sInitInfo.
584                                             hKernelCCBEventKickerMemInfo,
585                                     PVRSRV_HANDLE_TYPE_MEM_INFO);
586         bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
587
588         eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy,
589                                     psSGXDevInitPart2IN->sInitInfo.
590                                             hKernelSGXHostCtlMemInfo,
591                                     PVRSRV_HANDLE_TYPE_MEM_INFO);
592         bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
593
594         eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy,
595                                     psSGXDevInitPart2IN->sInitInfo.
596                                             hKernelSGXTA3DCtlMemInfo,
597                                     PVRSRV_HANDLE_TYPE_MEM_INFO);
598         bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
599
600         eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy,
601                                     psSGXDevInitPart2IN->sInitInfo.
602                                             hKernelSGXMiscMemInfo,
603                                     PVRSRV_HANDLE_TYPE_MEM_INFO);
604         bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
605
606         eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy,
607                                     psSGXDevInitPart2IN->sInitInfo.
608                                             hKernelHWPerfCBMemInfo,
609                                     PVRSRV_HANDLE_TYPE_MEM_INFO);
610         bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
611
612         edm_mi = &psSGXDevInitPart2IN->sInitInfo.hKernelEDMStatusBufferMemInfo;
613         if (*edm_mi) {
614                 eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy,
615                                           *edm_mi, PVRSRV_HANDLE_TYPE_MEM_INFO);
616                 bLookupFailed |= eError != PVRSRV_OK;
617         }
618
619         for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) {
620                 void *hHandle =
621                     psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
622
623                 if (hHandle == NULL)
624                         continue;
625
626                 eError = PVRSRVLookupHandle(psPerProc->psHandleBase, &hDummy,
627                                             hHandle,
628                                             PVRSRV_HANDLE_TYPE_MEM_INFO);
629                 bLookupFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
630         }
631
632         if (bLookupFailed) {
633                 PVR_DPF(PVR_DBG_ERROR,
634                          "DevInitSGXPart2BW: A handle lookup failed");
635                 psRetOUT->eError = PVRSRV_ERROR_GENERIC;
636                 return 0;
637         }
638
639         eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
640                                               &psSGXDevInitPart2IN->sInitInfo.
641                                                       hKernelCCBMemInfo,
642                                               psSGXDevInitPart2IN->sInitInfo.
643                                                       hKernelCCBMemInfo,
644                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
645         bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
646
647         eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
648                                               &psSGXDevInitPart2IN->sInitInfo.
649                                                       hKernelCCBCtlMemInfo,
650                                               psSGXDevInitPart2IN->sInitInfo.
651                                                       hKernelCCBCtlMemInfo,
652                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
653         bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
654
655         eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
656                                               &psSGXDevInitPart2IN->sInitInfo.
657                                                   hKernelCCBEventKickerMemInfo,
658                                               psSGXDevInitPart2IN->sInitInfo.
659                                                   hKernelCCBEventKickerMemInfo,
660                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
661         bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
662
663         eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
664                                               &psSGXDevInitPart2IN->sInitInfo.
665                                                   hKernelSGXHostCtlMemInfo,
666                                               psSGXDevInitPart2IN->sInitInfo.
667                                                   hKernelSGXHostCtlMemInfo,
668                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
669         bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
670
671         eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
672                                               &psSGXDevInitPart2IN->sInitInfo.
673                                                   hKernelSGXTA3DCtlMemInfo,
674                                               psSGXDevInitPart2IN->sInitInfo.
675                                                   hKernelSGXTA3DCtlMemInfo,
676                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
677         bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
678
679         eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
680                                               &psSGXDevInitPart2IN->sInitInfo.
681                                                   hKernelSGXMiscMemInfo,
682                                               psSGXDevInitPart2IN->sInitInfo.
683                                                   hKernelSGXMiscMemInfo,
684                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
685         bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
686
687         eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
688                                               &psSGXDevInitPart2IN->sInitInfo.
689                                                   hKernelHWPerfCBMemInfo,
690                                               psSGXDevInitPart2IN->sInitInfo.
691                                                   hKernelHWPerfCBMemInfo,
692                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
693         bReleaseFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
694
695         if (*edm_mi) {
696                 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
697                                               edm_mi, *edm_mi,
698                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
699                 bReleaseFailed |= eError != PVRSRV_OK;
700         }
701
702         for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) {
703                 void **phHandle =
704                     &psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
705
706                 if (*phHandle == NULL)
707                         continue;
708
709                 eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
710                                               phHandle, *phHandle,
711                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
712                 bReleaseFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
713         }
714
715         if (bReleaseFailed) {
716                 PVR_DPF(PVR_DBG_ERROR,
717                          "DevInitSGXPart2BW: A handle release failed");
718                 psRetOUT->eError = PVRSRV_ERROR_GENERIC;
719
720                 PVR_DBG_BREAK;
721                 return 0;
722         }
723
724         eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt,
725                                         psSGXDevInitPart2IN->sInitInfo.
726                                                 hKernelCCBMemInfo);
727         bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
728
729         eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt,
730                                         psSGXDevInitPart2IN->sInitInfo.
731                                                 hKernelCCBCtlMemInfo);
732         bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
733
734         eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt,
735                                         psSGXDevInitPart2IN->sInitInfo.
736                                                 hKernelCCBEventKickerMemInfo);
737         bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
738
739         eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt,
740                                         psSGXDevInitPart2IN->sInitInfo.
741                                                 hKernelSGXHostCtlMemInfo);
742         bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
743
744         eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt,
745                                         psSGXDevInitPart2IN->sInitInfo.
746                                                 hKernelSGXTA3DCtlMemInfo);
747         bDissociateFailed |= (IMG_BOOL)(eError != PVRSRV_OK);
748
749         eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt,
750                                         psSGXDevInitPart2IN->sInitInfo.
751                                                 hKernelSGXMiscMemInfo);
752         bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
753
754         eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt,
755                                         psSGXDevInitPart2IN->sInitInfo.
756                                                 hKernelHWPerfCBMemInfo);
757         bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
758
759         if (*edm_mi) {
760                 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, *edm_mi);
761                 bDissociateFailed |= eError != PVRSRV_OK;
762         }
763
764         for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) {
765                 void *hHandle =
766                     psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
767
768                 if (hHandle == NULL)
769                         continue;
770
771                 eError = PVRSRVDissociateDeviceMemKM(hDevCookieInt, hHandle);
772                 bDissociateFailed |= (IMG_BOOL) (eError != PVRSRV_OK);
773         }
774
775         if (bDissociateFailed) {
776                 PVRSRVFreeDeviceMemKM(hDevCookieInt,
777                                       psSGXDevInitPart2IN->sInitInfo.
778                                                 hKernelCCBMemInfo);
779                 PVRSRVFreeDeviceMemKM(hDevCookieInt,
780                                       psSGXDevInitPart2IN->sInitInfo.
781                                                 hKernelCCBCtlMemInfo);
782                 PVRSRVFreeDeviceMemKM(hDevCookieInt,
783                                       psSGXDevInitPart2IN->sInitInfo.
784                                                 hKernelSGXHostCtlMemInfo);
785                 PVRSRVFreeDeviceMemKM(hDevCookieInt,
786                                       psSGXDevInitPart2IN->sInitInfo.
787                                                 hKernelSGXTA3DCtlMemInfo);
788                 PVRSRVFreeDeviceMemKM(hDevCookieInt,
789                                       psSGXDevInitPart2IN->sInitInfo.
790                                                 hKernelSGXMiscMemInfo);
791
792                 for (i = 0; i < SGX_MAX_INIT_MEM_HANDLES; i++) {
793                         void *hHandle =
794                             psSGXDevInitPart2IN->sInitInfo.asInitMemHandles[i];
795
796                         if (hHandle == NULL)
797                                 continue;
798
799                         PVRSRVFreeDeviceMemKM(hDevCookieInt,
800                                               (struct PVRSRV_KERNEL_MEM_INFO *)
801                                               hHandle);
802
803                 }
804
805                 PVR_DPF(PVR_DBG_ERROR,
806                          "DevInitSGXPart2BW: A dissociate failed");
807
808                 psRetOUT->eError = PVRSRV_ERROR_GENERIC;
809
810                 PVR_DBG_BREAK;
811                 return 0;
812         }
813
814         psRetOUT->eError = DevInitSGXPart2KM(psPerProc, hDevCookieInt,
815                                              &psSGXDevInitPart2IN->sInitInfo);
816
817         return 0;
818 }
819
820 int SGXRegisterHWRenderContextBW(u32 ui32BridgeID,
821                 struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_RENDER_CONTEXT
822                                                 *psSGXRegHWRenderContextIN,
823                 struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_RENDER_CONTEXT
824                                                 *psSGXRegHWRenderContextOUT,
825                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
826 {
827         void *hDevCookieInt;
828         void *hHWRenderContextInt;
829
830         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
831                                  PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT);
832
833         NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError, psPerProc,
834                                   1);
835
836         psSGXRegHWRenderContextOUT->eError =
837             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
838                                psSGXRegHWRenderContextIN->hDevCookie,
839                                PVRSRV_HANDLE_TYPE_DEV_NODE);
840         if (psSGXRegHWRenderContextOUT->eError != PVRSRV_OK)
841                 return 0;
842
843         hHWRenderContextInt =
844             SGXRegisterHWRenderContextKM(hDevCookieInt,
845                          &psSGXRegHWRenderContextIN->sHWRenderContextDevVAddr,
846                          psPerProc);
847
848         if (hHWRenderContextInt == NULL) {
849                 psSGXRegHWRenderContextOUT->eError = PVRSRV_ERROR_GENERIC;
850                 return 0;
851         }
852
853         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
854                             &psSGXRegHWRenderContextOUT->hHWRenderContext,
855                             hHWRenderContextInt,
856                             PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT,
857                             PVRSRV_HANDLE_ALLOC_FLAG_NONE);
858
859         COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWRenderContextOUT->eError,
860                                      psPerProc);
861
862         return 0;
863 }
864
865 int SGXUnregisterHWRenderContextBW(u32 ui32BridgeID,
866                   struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_RENDER_CONTEXT
867                                           *psSGXUnregHWRenderContextIN,
868                   struct PVRSRV_BRIDGE_RETURN *psRetOUT,
869                   struct PVRSRV_PER_PROCESS_DATA *psPerProc)
870 {
871         void *hHWRenderContextInt;
872
873         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
874                          PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT);
875
876         psRetOUT->eError =
877             PVRSRVLookupHandle(psPerProc->psHandleBase,
878                                &hHWRenderContextInt,
879                                psSGXUnregHWRenderContextIN->hHWRenderContext,
880                                PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
881         if (psRetOUT->eError != PVRSRV_OK)
882                 return 0;
883
884         psRetOUT->eError = SGXUnregisterHWRenderContextKM(hHWRenderContextInt);
885         if (psRetOUT->eError != PVRSRV_OK)
886                 return 0;
887
888         psRetOUT->eError =
889             PVRSRVReleaseHandle(psPerProc->psHandleBase,
890                                 psSGXUnregHWRenderContextIN->hHWRenderContext,
891                                 PVRSRV_HANDLE_TYPE_SGX_HW_RENDER_CONTEXT);
892
893         return 0;
894 }
895
896 int SGXRegisterHWTransferContextBW(u32 ui32BridgeID,
897                   struct PVRSRV_BRIDGE_IN_SGX_REGISTER_HW_TRANSFER_CONTEXT
898                                           *psSGXRegHWTransferContextIN,
899                   struct PVRSRV_BRIDGE_OUT_SGX_REGISTER_HW_TRANSFER_CONTEXT
900                                           *psSGXRegHWTransferContextOUT,
901                   struct PVRSRV_PER_PROCESS_DATA *psPerProc)
902 {
903         void *hDevCookieInt;
904         void *hHWTransferContextInt;
905
906         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
907                          PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT);
908
909         NEW_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError,
910                                   psPerProc, 1);
911
912         psSGXRegHWTransferContextOUT->eError =
913             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
914                                psSGXRegHWTransferContextIN->hDevCookie,
915                                PVRSRV_HANDLE_TYPE_DEV_NODE);
916         if (psSGXRegHWTransferContextOUT->eError != PVRSRV_OK)
917                 return 0;
918
919         hHWTransferContextInt =
920             SGXRegisterHWTransferContextKM(hDevCookieInt,
921                                            &psSGXRegHWTransferContextIN->
922                                                    sHWTransferContextDevVAddr,
923                                            psPerProc);
924
925         if (hHWTransferContextInt == NULL) {
926                 psSGXRegHWTransferContextOUT->eError = PVRSRV_ERROR_GENERIC;
927                 return 0;
928         }
929
930         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
931                             &psSGXRegHWTransferContextOUT->hHWTransferContext,
932                             hHWTransferContextInt,
933                             PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT,
934                             PVRSRV_HANDLE_ALLOC_FLAG_NONE);
935
936         COMMIT_HANDLE_BATCH_OR_ERROR(psSGXRegHWTransferContextOUT->eError,
937                                      psPerProc);
938
939         return 0;
940 }
941
942 int SGXUnregisterHWTransferContextBW(u32 ui32BridgeID,
943                     struct PVRSRV_BRIDGE_IN_SGX_UNREGISTER_HW_TRANSFER_CONTEXT
944                                             *psSGXUnregHWTransferContextIN,
945                     struct PVRSRV_BRIDGE_RETURN *psRetOUT,
946                     struct PVRSRV_PER_PROCESS_DATA *psPerProc)
947 {
948         void *hHWTransferContextInt;
949
950         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
951                          PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT);
952
953         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
954                                &hHWTransferContextInt,
955                                psSGXUnregHWTransferContextIN->
956                                                      hHWTransferContext,
957                                PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
958         if (psRetOUT->eError != PVRSRV_OK)
959                 return 0;
960
961         psRetOUT->eError =
962                     SGXUnregisterHWTransferContextKM(hHWTransferContextInt);
963         if (psRetOUT->eError != PVRSRV_OK)
964                 return 0;
965
966         psRetOUT->eError =
967             PVRSRVReleaseHandle(psPerProc->psHandleBase,
968                                 psSGXUnregHWTransferContextIN->
969                                                         hHWTransferContext,
970                                 PVRSRV_HANDLE_TYPE_SGX_HW_TRANSFER_CONTEXT);
971
972         return 0;
973 }
974
975 int SGXFlushHWRenderTargetBW(u32 ui32BridgeID,
976             struct PVRSRV_BRIDGE_IN_SGX_FLUSH_HW_RENDER_TARGET
977                                     *psSGXFlushHWRenderTargetIN,
978             struct PVRSRV_BRIDGE_RETURN *psRetOUT,
979             struct PVRSRV_PER_PROCESS_DATA *psPerProc)
980 {
981         void *hDevCookieInt;
982         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
983                                  PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET);
984
985         psRetOUT->eError =
986             PVRSRVLookupHandle(psPerProc->psHandleBase,
987                                &hDevCookieInt,
988                                psSGXFlushHWRenderTargetIN->hDevCookie,
989                                PVRSRV_HANDLE_TYPE_DEV_NODE);
990         if (psRetOUT->eError != PVRSRV_OK)
991                 return 0;
992
993         SGXFlushHWRenderTargetKM(hDevCookieInt,
994                          psSGXFlushHWRenderTargetIN->sHWRTDataSetDevVAddr);
995
996         return 0;
997 }
998
999 static void trace_query_cmd(struct PVRSRV_PER_PROCESS_DATA *proc, int type,
1000                              struct PVRSRV_KERNEL_SYNC_INFO *si)
1001 {
1002         struct pvr_trcmd_syn *ts;
1003         size_t size;
1004
1005         size = si ? sizeof(*ts) : 0;
1006         pvr_trcmd_lock();
1007
1008         ts = pvr_trcmd_alloc(type, proc->ui32PID, proc->name, size);
1009         if (si)
1010                 pvr_trcmd_set_syn(ts, si);
1011
1012         pvr_trcmd_unlock();
1013 }
1014
1015 int SGX2DQueryBlitsCompleteBW(struct file *filp, u32 ui32BridgeID,
1016      struct PVRSRV_BRIDGE_IN_2DQUERYBLTSCOMPLETE *ps2DQueryBltsCompleteIN,
1017      struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1018      struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1019 {
1020         void *hDevCookieInt;
1021         void *pvSyncInfo;
1022         struct PVRSRV_SGXDEV_INFO *psDevInfo;
1023         struct PVRSRV_FILE_PRIVATE_DATA *priv = filp->private_data;
1024
1025         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1026                                  PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE);
1027
1028         psRetOUT->eError =
1029             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
1030                                ps2DQueryBltsCompleteIN->hDevCookie,
1031                                PVRSRV_HANDLE_TYPE_DEV_NODE);
1032         if (psRetOUT->eError != PVRSRV_OK)
1033                 return 0;
1034
1035         if (ps2DQueryBltsCompleteIN->type == _PVR_SYNC_WAIT_FLIP ||
1036             ps2DQueryBltsCompleteIN->type == _PVR_SYNC_WAIT_UPDATE) {
1037                 int     cmd_type;
1038
1039                 if (ps2DQueryBltsCompleteIN->type == _PVR_SYNC_WAIT_FLIP)
1040                         cmd_type = PVR_TRCMD_SGX_QBLT_FLPREQ;
1041                 else
1042                         cmd_type = PVR_TRCMD_SGX_QBLT_UPDREQ;
1043
1044                 trace_query_cmd(psPerProc, cmd_type, NULL);
1045
1046                 if (pvr_flip_event_req(priv,
1047                                        (long)ps2DQueryBltsCompleteIN->
1048                                                        hKernSyncInfo,
1049                                        ps2DQueryBltsCompleteIN->type,
1050                                        ps2DQueryBltsCompleteIN->user_data))
1051                         psRetOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1052
1053                 return 0;
1054         }
1055
1056         psRetOUT->eError =
1057             PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
1058                                ps2DQueryBltsCompleteIN->hKernSyncInfo,
1059                                PVRSRV_HANDLE_TYPE_SYNC_INFO);
1060         if (psRetOUT->eError != PVRSRV_OK)
1061                 return 0;
1062
1063         psDevInfo =
1064             (struct PVRSRV_SGXDEV_INFO *)((struct PVRSRV_DEVICE_NODE *)
1065                                           hDevCookieInt)->pvDevice;
1066
1067         if (ps2DQueryBltsCompleteIN->type == _PVR_SYNC_WAIT_EVENT) {
1068                 if (pvr_sync_event_req(priv,
1069                                 (struct PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo,
1070                                 ps2DQueryBltsCompleteIN->user_data))
1071                         psRetOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1072                 else
1073                         trace_query_cmd(psPerProc,
1074                                          PVR_TRCMD_SGX_QBLT_SYNREQ,
1075                                          pvSyncInfo);
1076
1077                 return 0;
1078         }
1079
1080         psRetOUT->eError =
1081             SGX2DQueryBlitsCompleteKM(psDevInfo,
1082                                       (struct PVRSRV_KERNEL_SYNC_INFO *)
1083                                                               pvSyncInfo,
1084                         ps2DQueryBltsCompleteIN->type == _PVR_SYNC_WAIT_BLOCK);
1085
1086         trace_query_cmd(psPerProc, PVR_TRCMD_SGX_QBLT_SYNCHK, pvSyncInfo);
1087
1088         return 0;
1089 }
1090
1091 int SGXFindSharedPBDescBW(u32 ui32BridgeID,
1092         struct PVRSRV_BRIDGE_IN_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescIN,
1093         struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC *psSGXFindSharedPBDescOUT,
1094         struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1095 {
1096         void *hDevCookieInt;
1097         struct PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
1098         struct PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
1099         struct PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
1100         struct PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = NULL;
1101         u32 ui32SharedPBDescSubKernelMemInfosCount = 0;
1102         u32 i;
1103         void *hSharedPBDesc = NULL;
1104
1105         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1106                                  PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC);
1107
1108         NEW_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError, psPerProc,
1109                                   PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS
1110                                   + 4);
1111
1112         psSGXFindSharedPBDescOUT->hSharedPBDesc = NULL;
1113
1114         psSGXFindSharedPBDescOUT->eError =
1115             PVRSRVLookupHandle(psPerProc->psHandleBase,
1116                                &hDevCookieInt,
1117                                psSGXFindSharedPBDescIN->hDevCookie,
1118                                PVRSRV_HANDLE_TYPE_DEV_NODE);
1119         if (psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
1120                 goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
1121
1122         psSGXFindSharedPBDescOUT->eError =
1123             SGXFindSharedPBDescKM(psPerProc, hDevCookieInt,
1124                                   psSGXFindSharedPBDescIN->bLockOnFailure,
1125                                   psSGXFindSharedPBDescIN->ui32TotalPBSize,
1126                                   &hSharedPBDesc,
1127                                   &psSharedPBDescKernelMemInfo,
1128                                   &psHWPBDescKernelMemInfo,
1129                                   &psBlockKernelMemInfo,
1130                                   &ppsSharedPBDescSubKernelMemInfos,
1131                                   &ui32SharedPBDescSubKernelMemInfosCount);
1132         if (psSGXFindSharedPBDescOUT->eError != PVRSRV_OK)
1133                 goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
1134
1135         PVR_ASSERT(ui32SharedPBDescSubKernelMemInfosCount <=
1136                    PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS);
1137
1138         psSGXFindSharedPBDescOUT->ui32SharedPBDescSubKernelMemInfoHandlesCount =
1139             ui32SharedPBDescSubKernelMemInfosCount;
1140
1141         if (hSharedPBDesc == NULL) {
1142                 psSGXFindSharedPBDescOUT->hSharedPBDescKernelMemInfoHandle =
1143                                                                         NULL;
1144
1145                 goto PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT;
1146         }
1147
1148         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1149                             &psSGXFindSharedPBDescOUT->hSharedPBDesc,
1150                             hSharedPBDesc,
1151                             PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
1152                             PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1153
1154         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1155                                &psSGXFindSharedPBDescOUT->
1156                                        hSharedPBDescKernelMemInfoHandle,
1157                                psSharedPBDescKernelMemInfo,
1158                                PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
1159                                PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1160                                psSGXFindSharedPBDescOUT->hSharedPBDesc);
1161
1162         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1163                                &psSGXFindSharedPBDescOUT->
1164                                        hHWPBDescKernelMemInfoHandle,
1165                                psHWPBDescKernelMemInfo,
1166                                PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
1167                                PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1168                                psSGXFindSharedPBDescOUT->hSharedPBDesc);
1169
1170         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1171                                &psSGXFindSharedPBDescOUT->
1172                                        hBlockKernelMemInfoHandle,
1173                                psBlockKernelMemInfo,
1174                                PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
1175                                PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1176                                psSGXFindSharedPBDescOUT->hSharedPBDesc);
1177
1178         for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) {
1179                 struct PVRSRV_BRIDGE_OUT_SGXFINDSHAREDPBDESC
1180                     *psSGXFindSharedPBDescOut = psSGXFindSharedPBDescOUT;
1181
1182                 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1183                                &psSGXFindSharedPBDescOut->
1184                                        ahSharedPBDescSubKernelMemInfoHandles[i],
1185                                ppsSharedPBDescSubKernelMemInfos[i],
1186                                PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
1187                                PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
1188                                psSGXFindSharedPBDescOUT->
1189                                        hSharedPBDescKernelMemInfoHandle);
1190         }
1191
1192 PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC_EXIT:
1193         if (ppsSharedPBDescSubKernelMemInfos != NULL)
1194                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1195                           sizeof(struct PVRSRV_KERNEL_MEM_INFO *) *
1196                                   ui32SharedPBDescSubKernelMemInfosCount,
1197                           ppsSharedPBDescSubKernelMemInfos, NULL);
1198
1199         if (psSGXFindSharedPBDescOUT->eError != PVRSRV_OK) {
1200                 if (hSharedPBDesc != NULL)
1201                         SGXUnrefSharedPBDescKM(hSharedPBDesc);
1202         } else
1203                 COMMIT_HANDLE_BATCH_OR_ERROR(psSGXFindSharedPBDescOUT->eError,
1204                                              psPerProc);
1205
1206         return 0;
1207 }
1208
1209 int SGXUnrefSharedPBDescBW(u32 ui32BridgeID,
1210         struct PVRSRV_BRIDGE_IN_SGXUNREFSHAREDPBDESC *psSGXUnrefSharedPBDescIN,
1211         struct PVRSRV_BRIDGE_OUT_SGXUNREFSHAREDPBDESC
1212                                                 *psSGXUnrefSharedPBDescOUT,
1213         struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1214 {
1215         void *hSharedPBDesc;
1216
1217         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1218                                  PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC);
1219
1220         psSGXUnrefSharedPBDescOUT->eError =
1221             PVRSRVLookupHandle(psPerProc->psHandleBase,
1222                                &hSharedPBDesc,
1223                                psSGXUnrefSharedPBDescIN->hSharedPBDesc,
1224                                PVRSRV_HANDLE_TYPE_SHARED_PB_DESC);
1225         if (psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK)
1226                 return 0;
1227
1228         psSGXUnrefSharedPBDescOUT->eError =
1229             SGXUnrefSharedPBDescKM(hSharedPBDesc);
1230
1231         if (psSGXUnrefSharedPBDescOUT->eError != PVRSRV_OK)
1232                 return 0;
1233
1234         psSGXUnrefSharedPBDescOUT->eError =
1235             PVRSRVReleaseHandle(psPerProc->psHandleBase,
1236                                 psSGXUnrefSharedPBDescIN->hSharedPBDesc,
1237                                 PVRSRV_HANDLE_TYPE_SHARED_PB_DESC);
1238
1239         return 0;
1240 }
1241
1242 int SGXAddSharedPBDescBW(u32 ui32BridgeID,
1243         struct PVRSRV_BRIDGE_IN_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescIN,
1244         struct PVRSRV_BRIDGE_OUT_SGXADDSHAREDPBDESC *psSGXAddSharedPBDescOUT,
1245         struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1246 {
1247         void *hDevCookieInt;
1248         struct PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo;
1249         struct PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo;
1250         struct PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo;
1251         u32 ui32KernelMemInfoHandlesCount =
1252             psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount;
1253         int ret = 0;
1254         void **phKernelMemInfoHandles = NULL;
1255         struct PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfos = NULL;
1256         u32 i;
1257         enum PVRSRV_ERROR eError;
1258         void *hSharedPBDesc = NULL;
1259
1260         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1261                                  PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC);
1262
1263         NEW_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError, psPerProc,
1264                                   1);
1265
1266         psSGXAddSharedPBDescOUT->hSharedPBDesc = NULL;
1267
1268         PVR_ASSERT(ui32KernelMemInfoHandlesCount <=
1269                    PVRSRV_BRIDGE_SGX_SHAREDPBDESC_MAX_SUBMEMINFOS);
1270
1271         eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1272                                     &hDevCookieInt,
1273                                     psSGXAddSharedPBDescIN->hDevCookie,
1274                                     PVRSRV_HANDLE_TYPE_DEV_NODE);
1275         if (eError != PVRSRV_OK)
1276                 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1277
1278         eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1279                                     (void **)&psSharedPBDescKernelMemInfo,
1280                                     psSGXAddSharedPBDescIN->
1281                                                     hSharedPBDescKernelMemInfo,
1282                                     PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
1283         if (eError != PVRSRV_OK)
1284                 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1285
1286         eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1287                                     (void **)&psHWPBDescKernelMemInfo,
1288                                     psSGXAddSharedPBDescIN->
1289                                                     hHWPBDescKernelMemInfo,
1290                                     PVRSRV_HANDLE_TYPE_MEM_INFO);
1291         if (eError != PVRSRV_OK)
1292                 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1293
1294         eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1295                                     (void **)&psBlockKernelMemInfo,
1296                                     psSGXAddSharedPBDescIN->hBlockKernelMemInfo,
1297                                     PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
1298         if (eError != PVRSRV_OK)
1299                 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1300
1301         if (!OSAccessOK(PVR_VERIFY_READ,
1302                         psSGXAddSharedPBDescIN->phKernelMemInfoHandles,
1303                         ui32KernelMemInfoHandlesCount * sizeof(void *))) {
1304                 PVR_DPF(PVR_DBG_ERROR, "%s: PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC:"
1305                          " Invalid phKernelMemInfos pointer", __func__);
1306                 ret = -EFAULT;
1307                 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1308         }
1309
1310         eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1311                             ui32KernelMemInfoHandlesCount * sizeof(void *),
1312                             (void **)&phKernelMemInfoHandles, NULL);
1313         if (eError != PVRSRV_OK)
1314                 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1315
1316         if (CopyFromUserWrapper(psPerProc,
1317                                 ui32BridgeID,
1318                                 phKernelMemInfoHandles,
1319                                 psSGXAddSharedPBDescIN->phKernelMemInfoHandles,
1320                                 ui32KernelMemInfoHandlesCount * sizeof(void *))
1321             != PVRSRV_OK) {
1322                 ret = -EFAULT;
1323                 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1324         }
1325
1326         eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1327                             ui32KernelMemInfoHandlesCount *
1328                             sizeof(struct PVRSRV_KERNEL_MEM_INFO *),
1329                             (void **)&ppsKernelMemInfos, NULL);
1330         if (eError != PVRSRV_OK)
1331                 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1332
1333         for (i = 0; i < ui32KernelMemInfoHandlesCount; i++) {
1334                 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1335                                             (void **)&ppsKernelMemInfos[i],
1336                                             phKernelMemInfoHandles[i],
1337                                             PVRSRV_HANDLE_TYPE_MEM_INFO);
1338                 if (eError != PVRSRV_OK)
1339                         goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1340         }
1341
1342         eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
1343                                      psSGXAddSharedPBDescIN->
1344                                                      hSharedPBDescKernelMemInfo,
1345                                      PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
1346         PVR_ASSERT(eError == PVRSRV_OK);
1347
1348         eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
1349                                      psSGXAddSharedPBDescIN->
1350                                                      hHWPBDescKernelMemInfo,
1351                                      PVRSRV_HANDLE_TYPE_MEM_INFO);
1352         PVR_ASSERT(eError == PVRSRV_OK);
1353
1354         eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
1355                                      psSGXAddSharedPBDescIN->
1356                                                      hBlockKernelMemInfo,
1357                                      PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
1358         PVR_ASSERT(eError == PVRSRV_OK);
1359
1360         for (i = 0; i < ui32KernelMemInfoHandlesCount; i++) {
1361                 eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
1362                                              phKernelMemInfoHandles[i],
1363                                              PVRSRV_HANDLE_TYPE_MEM_INFO);
1364                 PVR_ASSERT(eError == PVRSRV_OK);
1365         }
1366
1367         eError = SGXAddSharedPBDescKM(psPerProc, hDevCookieInt,
1368                                       psSharedPBDescKernelMemInfo,
1369                                       psHWPBDescKernelMemInfo,
1370                                       psBlockKernelMemInfo,
1371                                       psSGXAddSharedPBDescIN->ui32TotalPBSize,
1372                                       &hSharedPBDesc,
1373                                       ppsKernelMemInfos,
1374                                       ui32KernelMemInfoHandlesCount);
1375
1376         if (eError != PVRSRV_OK)
1377                 goto PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT;
1378
1379         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1380                             &psSGXAddSharedPBDescOUT->hSharedPBDesc,
1381                             hSharedPBDesc,
1382                             PVRSRV_HANDLE_TYPE_SHARED_PB_DESC,
1383                             PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1384
1385 PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC_RETURN_RESULT:
1386
1387         if (phKernelMemInfoHandles)
1388                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1389                           psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount
1390                                                           * sizeof(void *),
1391                           (void *)phKernelMemInfoHandles, NULL);
1392         if (ppsKernelMemInfos)
1393                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1394                           psSGXAddSharedPBDescIN->ui32KernelMemInfoHandlesCount
1395                                   * sizeof(struct PVRSRV_KERNEL_MEM_INFO *),
1396                           (void *)ppsKernelMemInfos, NULL);
1397
1398         if (ret == 0 && eError == PVRSRV_OK)
1399                 COMMIT_HANDLE_BATCH_OR_ERROR(psSGXAddSharedPBDescOUT->eError,
1400                                              psPerProc);
1401
1402         psSGXAddSharedPBDescOUT->eError = eError;
1403
1404         return ret;
1405 }
1406
1407 int SGXGetInfoForSrvinitBW(u32 ui32BridgeID,
1408           struct PVRSRV_BRIDGE_IN_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitIN,
1409           struct PVRSRV_BRIDGE_OUT_SGXINFO_FOR_SRVINIT *psSGXInfoForSrvinitOUT,
1410           struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1411 {
1412         void *hDevCookieInt;
1413         u32 i;
1414         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1415                                  PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT);
1416
1417         NEW_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc,
1418                                   PVRSRV_MAX_CLIENT_HEAPS);
1419
1420         if (!psPerProc->bInitProcess) {
1421                 psSGXInfoForSrvinitOUT->eError = PVRSRV_ERROR_GENERIC;
1422                 return 0;
1423         }
1424
1425         psSGXInfoForSrvinitOUT->eError =
1426             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
1427                                psSGXInfoForSrvinitIN->hDevCookie,
1428                                PVRSRV_HANDLE_TYPE_DEV_NODE);
1429
1430         if (psSGXInfoForSrvinitOUT->eError != PVRSRV_OK)
1431                 return 0;
1432
1433         psSGXInfoForSrvinitOUT->eError =
1434             SGXGetInfoForSrvinitKM(hDevCookieInt,
1435                                    &psSGXInfoForSrvinitOUT->sInitInfo);
1436
1437         if (psSGXInfoForSrvinitOUT->eError != PVRSRV_OK)
1438                 return 0;
1439
1440         for (i = 0; i < PVRSRV_MAX_CLIENT_HEAPS; i++) {
1441                 struct PVRSRV_HEAP_INFO *psHeapInfo;
1442
1443                 psHeapInfo = &psSGXInfoForSrvinitOUT->sInitInfo.asHeapInfo[i];
1444
1445                 if (psHeapInfo->ui32HeapID != (u32)SGX_UNDEFINED_HEAP_ID) {
1446                         void *hDevMemHeapExt;
1447
1448                         if (psHeapInfo->hDevMemHeap != NULL) {
1449
1450                                 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1451                                             &hDevMemHeapExt,
1452                                             psHeapInfo->hDevMemHeap,
1453                                             PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
1454                                             PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
1455                                 psHeapInfo->hDevMemHeap = hDevMemHeapExt;
1456                         }
1457                 }
1458         }
1459
1460         COMMIT_HANDLE_BATCH_OR_ERROR(psSGXInfoForSrvinitOUT->eError, psPerProc);
1461
1462         return 0;
1463 }
1464
1465 #if defined(PDUMP)
1466 static void DumpBufferArray(struct PVRSRV_PER_PROCESS_DATA *psPerProc,
1467                             struct SGX_KICKTA_DUMP_BUFFER *psBufferArray,
1468                             u32 ui32BufferArrayLength, IMG_BOOL bDumpPolls)
1469 {
1470         u32 i;
1471
1472         for (i = 0; i < ui32BufferArrayLength; i++) {
1473                 struct SGX_KICKTA_DUMP_BUFFER *psBuffer;
1474                 struct PVRSRV_KERNEL_MEM_INFO *psCtrlMemInfoKM;
1475                 char *pszName;
1476                 void *hUniqueTag;
1477                 u32 ui32Offset;
1478
1479                 psBuffer = &psBufferArray[i];
1480                 pszName = psBuffer->pszName;
1481                 if (!pszName)
1482                         pszName = "Nameless buffer";
1483
1484                 hUniqueTag =
1485                     MAKEUNIQUETAG((struct PVRSRV_KERNEL_MEM_INFO *)psBuffer->
1486                                   hKernelMemInfo);
1487
1488                 psCtrlMemInfoKM =
1489                     ((struct PVRSRV_KERNEL_MEM_INFO *)psBuffer->
1490                      hKernelMemInfo)->psKernelSyncInfo->psSyncDataMemInfoKM;
1491                 ui32Offset =
1492                     offsetof(struct PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
1493
1494                 if (psBuffer->ui32Start <= psBuffer->ui32End) {
1495                         if (bDumpPolls) {
1496                                 PDUMPCOMMENTWITHFLAGS(0,
1497                                                       "Wait for %s space\r\n",
1498                                                       pszName);
1499                                 PDUMPCBP(psCtrlMemInfoKM, ui32Offset,
1500                                          psBuffer->ui32Start,
1501                                          psBuffer->ui32SpaceUsed,
1502                                          psBuffer->ui32BufferSize,
1503                                          MAKEUNIQUETAG(psCtrlMemInfoKM));
1504                         }
1505
1506                         PDUMPCOMMENTWITHFLAGS(0, "%s\r\n", pszName);
1507                         PDUMPMEMUM(NULL, psBuffer->pvLinAddr,
1508                                    (struct PVRSRV_KERNEL_MEM_INFO *)psBuffer->
1509                                                            hKernelMemInfo,
1510                                    psBuffer->ui32Start,
1511                                    psBuffer->ui32End - psBuffer->ui32Start, 0,
1512                                    hUniqueTag);
1513                 } else {
1514
1515                         if (bDumpPolls) {
1516                                 PDUMPCOMMENTWITHFLAGS(0,
1517                                                       "Wait for %s space\r\n",
1518                                                       pszName);
1519                                 PDUMPCBP(psCtrlMemInfoKM, ui32Offset,
1520                                          psBuffer->ui32Start,
1521                                          psBuffer->ui32BackEndLength,
1522                                          psBuffer->ui32BufferSize,
1523                                          MAKEUNIQUETAG(psCtrlMemInfoKM));
1524                         }
1525                         PDUMPCOMMENTWITHFLAGS(0, "%s (part 1)\r\n", pszName);
1526                         PDUMPMEMUM(NULL, psBuffer->pvLinAddr,
1527                                    (struct PVRSRV_KERNEL_MEM_INFO *)psBuffer->
1528                                                            hKernelMemInfo,
1529                                    psBuffer->ui32Start,
1530                                    psBuffer->ui32BackEndLength, 0, hUniqueTag);
1531
1532                         if (bDumpPolls) {
1533                                 PDUMPMEMPOL(psCtrlMemInfoKM, ui32Offset,
1534                                             0, 0xFFFFFFFF,
1535                                             PDUMP_POLL_OPERATOR_NOTEQUAL,
1536                                             MAKEUNIQUETAG(psCtrlMemInfoKM));
1537
1538                                 PDUMPCOMMENTWITHFLAGS(0,
1539                                                       "Wait for %s space\r\n",
1540                                                       pszName);
1541                                 PDUMPCBP(psCtrlMemInfoKM, ui32Offset, 0,
1542                                          psBuffer->ui32End,
1543                                          psBuffer->ui32BufferSize,
1544                                          MAKEUNIQUETAG(psCtrlMemInfoKM));
1545                         }
1546                         PDUMPCOMMENTWITHFLAGS(0, "%s (part 2)\r\n", pszName);
1547                         PDUMPMEMUM(NULL, psBuffer->pvLinAddr,
1548                                    (struct PVRSRV_KERNEL_MEM_INFO *)psBuffer->
1549                                                    hKernelMemInfo,
1550                                    0, psBuffer->ui32End, 0, hUniqueTag);
1551                 }
1552         }
1553 }
1554
1555 int SGXPDumpBufferArrayBW(u32 ui32BridgeID,
1556          struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY *psPDumpBufferArrayIN,
1557          void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1558 {
1559         u32 i;
1560         struct SGX_KICKTA_DUMP_BUFFER *psKickTADumpBuffer;
1561         u32 ui32BufferArrayLength = psPDumpBufferArrayIN->ui32BufferArrayLength;
1562         u32 ui32BufferArraySize =
1563             ui32BufferArrayLength * sizeof(struct SGX_KICKTA_DUMP_BUFFER);
1564         enum PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC;
1565
1566         PVR_UNREFERENCED_PARAMETER(psBridgeOut);
1567
1568         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1569                                  PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY);
1570
1571         if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize,
1572                        (void **)&psKickTADumpBuffer, NULL) != PVRSRV_OK)
1573                 return -ENOMEM;
1574
1575         if (CopyFromUserWrapper(psPerProc, ui32BridgeID, psKickTADumpBuffer,
1576                                 psPDumpBufferArrayIN->psBufferArray,
1577                                 ui32BufferArraySize) != PVRSRV_OK) {
1578                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize,
1579                           psKickTADumpBuffer, NULL);
1580                 return -EFAULT;
1581         }
1582
1583         for (i = 0; i < ui32BufferArrayLength; i++) {
1584                 void *pvMemInfo;
1585
1586                 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1587                                             &pvMemInfo,
1588                                             psKickTADumpBuffer[i].
1589                                                             hKernelMemInfo,
1590                                             PVRSRV_HANDLE_TYPE_MEM_INFO);
1591
1592                 if (eError != PVRSRV_OK) {
1593                         PVR_DPF(PVR_DBG_ERROR,
1594                                  "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: "
1595                                  "PVRSRVLookupHandle failed (%d)", eError);
1596                         break;
1597                 }
1598                 psKickTADumpBuffer[i].hKernelMemInfo = pvMemInfo;
1599
1600         }
1601
1602         if (eError == PVRSRV_OK)
1603                 DumpBufferArray(psPerProc, psKickTADumpBuffer,
1604                                 ui32BufferArrayLength,
1605                                 psPDumpBufferArrayIN->bDumpPolls);
1606
1607         OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize,
1608                   psKickTADumpBuffer, NULL);
1609
1610         return 0;
1611 }
1612
1613 int SGXPDump3DSignatureRegistersBW(u32 ui32BridgeID,
1614                   struct PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS
1615                                           *psPDump3DSignatureRegistersIN,
1616                   void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1617 {
1618         u32 ui32RegisterArraySize =
1619             psPDump3DSignatureRegistersIN->ui32NumRegisters * sizeof(u32);
1620         u32 *pui32Registers = NULL;
1621         int ret = -EFAULT;
1622
1623         PVR_UNREFERENCED_PARAMETER(psBridgeOut);
1624
1625         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1626                          PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS);
1627
1628         if (ui32RegisterArraySize == 0)
1629                 goto ExitNoError;
1630
1631         if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1632                        ui32RegisterArraySize,
1633                        (void **)&pui32Registers, NULL) != PVRSRV_OK) {
1634                 PVR_DPF(PVR_DBG_ERROR,
1635                          "PDump3DSignatureRegistersBW: OSAllocMem failed");
1636                 goto Exit;
1637         }
1638
1639         if (CopyFromUserWrapper(psPerProc, ui32BridgeID, pui32Registers,
1640                                 psPDump3DSignatureRegistersIN->pui32Registers,
1641                                 ui32RegisterArraySize) != PVRSRV_OK) {
1642                 PVR_DPF(PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: "
1643                                         "CopyFromUserWrapper failed");
1644                 goto Exit;
1645         }
1646
1647         PDump3DSignatureRegisters(psPDump3DSignatureRegistersIN->
1648                                                           ui32DumpFrameNum,
1649                                   pui32Registers,
1650                                   psPDump3DSignatureRegistersIN->
1651                                                           ui32NumRegisters);
1652
1653 ExitNoError:
1654         ret = 0;
1655 Exit:
1656         if (pui32Registers != NULL)
1657                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize,
1658                           pui32Registers, NULL);
1659
1660         return ret;
1661 }
1662
1663 int SGXPDumpCounterRegistersBW(u32 ui32BridgeID,
1664               struct PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS
1665                                       *psPDumpCounterRegistersIN,
1666               void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1667 {
1668         u32 ui32RegisterArraySize =
1669             psPDumpCounterRegistersIN->ui32NumRegisters * sizeof(u32);
1670         u32 *pui32Registers = NULL;
1671         int ret = -EFAULT;
1672
1673         PVR_UNREFERENCED_PARAMETER(psBridgeOut);
1674
1675         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1676                                  PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS);
1677
1678         if (ui32RegisterArraySize == 0)
1679                 goto ExitNoError;
1680
1681         if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize,
1682                        (void **)&pui32Registers, NULL) != PVRSRV_OK) {
1683                 PVR_DPF(PVR_DBG_ERROR,
1684                          "PDumpCounterRegistersBW: OSAllocMem failed");
1685                 ret = -ENOMEM;
1686                 goto Exit;
1687         }
1688
1689         if (CopyFromUserWrapper(psPerProc, ui32BridgeID, pui32Registers,
1690                                 psPDumpCounterRegistersIN->pui32Registers,
1691                                 ui32RegisterArraySize) != PVRSRV_OK) {
1692                 PVR_DPF(PVR_DBG_ERROR,
1693                          "PDumpCounterRegistersBW: CopyFromUserWrapper failed");
1694                 goto Exit;
1695         }
1696
1697         PDumpCounterRegisters(psPDumpCounterRegistersIN->ui32DumpFrameNum,
1698                               pui32Registers,
1699                               psPDumpCounterRegistersIN->ui32NumRegisters);
1700
1701 ExitNoError:
1702         ret = 0;
1703 Exit:
1704         if (pui32Registers != NULL)
1705                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize,
1706                           pui32Registers, NULL);
1707
1708         return ret;
1709 }
1710
1711 int SGXPDumpTASignatureRegistersBW(u32 ui32BridgeID,
1712           struct PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS
1713                                           *psPDumpTASignatureRegistersIN,
1714           void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1715 {
1716         u32 ui32RegisterArraySize =
1717             psPDumpTASignatureRegistersIN->ui32NumRegisters * sizeof(u32);
1718         u32 *pui32Registers = NULL;
1719         int ret = -EFAULT;
1720
1721         PVR_UNREFERENCED_PARAMETER(psBridgeOut);
1722
1723         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1724                          PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS);
1725
1726         if (ui32RegisterArraySize == 0)
1727                 goto ExitNoError;
1728
1729         if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1730                        ui32RegisterArraySize,
1731                        (void **)&pui32Registers, NULL) != PVRSRV_OK) {
1732                 PVR_DPF(PVR_DBG_ERROR,
1733                          "PDumpTASignatureRegistersBW: OSAllocMem failed");
1734                 ret = -ENOMEM;
1735                 goto Exit;
1736         }
1737
1738         if (CopyFromUserWrapper(psPerProc, ui32BridgeID, pui32Registers,
1739                                 psPDumpTASignatureRegistersIN->pui32Registers,
1740                                 ui32RegisterArraySize) != PVRSRV_OK) {
1741                 PVR_DPF(PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: "
1742                                         "CopyFromUserWrapper failed");
1743                 goto Exit;
1744         }
1745
1746         PDumpTASignatureRegisters(psPDumpTASignatureRegistersIN->
1747                                                           ui32DumpFrameNum,
1748                                   psPDumpTASignatureRegistersIN->
1749                                                           ui32TAKickCount,
1750                                   pui32Registers,
1751                                   psPDumpTASignatureRegistersIN->
1752                                                           ui32NumRegisters);
1753
1754 ExitNoError:
1755         ret = 0;
1756 Exit:
1757         if (pui32Registers != NULL)
1758                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize,
1759                           pui32Registers, NULL);
1760
1761         return ret;
1762 }
1763
1764 int SGXPDumpHWPerfCBBW(u32 ui32BridgeID,
1765                 struct PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB *psPDumpHWPerfCBIN,
1766                 struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1767                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1768 {
1769         struct PVRSRV_SGXDEV_INFO *psDevInfo;
1770         void *hDevCookieInt;
1771
1772         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1773                                  PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB);
1774
1775         psRetOUT->eError =
1776             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
1777                                psPDumpHWPerfCBIN->hDevCookie,
1778                                PVRSRV_HANDLE_TYPE_DEV_NODE);
1779         if (psRetOUT->eError != PVRSRV_OK)
1780                 return 0;
1781
1782         psDevInfo = ((struct PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
1783
1784         PDumpHWPerfCBKM(&psPDumpHWPerfCBIN->szFileName[0],
1785                         psPDumpHWPerfCBIN->ui32FileOffset,
1786                         psDevInfo->psKernelHWPerfCBMemInfo->sDevVAddr,
1787                         psDevInfo->psKernelHWPerfCBMemInfo->ui32AllocSize,
1788                         psPDumpHWPerfCBIN->ui32PDumpFlags);
1789
1790         return 0;
1791 }
1792
1793 #endif
1794
1795 void SetSGXDispatchTableEntry(void)
1796 {
1797
1798         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETCLIENTINFO,
1799                               SGXGetClientInfoBW);
1800         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO,
1801                               SGXReleaseClientInfoBW);
1802         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO,
1803                               SGXGetInternalDevInfoBW);
1804         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DOKICK, SGXDoKickBW);
1805         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR, DummyBW);
1806         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READREGISTRYDWORD, DummyBW);
1807         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULECOMMAND, DummyBW);
1808
1809         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE,
1810                               SGX2DQueryBlitsCompleteBW);
1811
1812         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMMUPDADDR, DummyBW);
1813
1814         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMITTRANSFER,
1815                               SGXSubmitTransferBW);
1816         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMISCINFO, SGXGetMiscInfoBW);
1817         SetDispatchTableEntry(PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT,
1818                               SGXGetInfoForSrvinitBW);
1819         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DEVINITPART2,
1820                               SGXDevInitPart2BW);
1821
1822         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC,
1823                               SGXFindSharedPBDescBW);
1824         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC,
1825                               SGXUnrefSharedPBDescBW);
1826         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC,
1827                               SGXAddSharedPBDescBW);
1828         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT,
1829                               SGXRegisterHWRenderContextBW);
1830         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET,
1831                               SGXFlushHWRenderTargetBW);
1832         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT,
1833                               SGXUnregisterHWRenderContextBW);
1834         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT,
1835                               SGXRegisterHWTransferContextBW);
1836         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT,
1837                               SGXUnregisterHWTransferContextBW);
1838
1839         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS,
1840                               SGXReadDiffCountersBW);
1841         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_CB,
1842                               SGXReadHWPerfCBBW);
1843
1844         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES,
1845                               SGXScheduleProcessQueuesBW);
1846
1847 #if defined(PDUMP)
1848         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY,
1849                               SGXPDumpBufferArrayBW);
1850         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS,
1851                               SGXPDump3DSignatureRegistersBW);
1852         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS,
1853                               SGXPDumpCounterRegistersBW);
1854         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS,
1855                               SGXPDumpTASignatureRegistersBW);
1856         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB,
1857                               SGXPDumpHWPerfCBBW);
1858 #endif
1859 }