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