gpu: pvr: pdump: rewrite PDumpMemUM()
[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(NULL, psBuffer->pvLinAddr,
1474                                    (struct PVRSRV_KERNEL_MEM_INFO *)psBuffer->
1475                                                            hKernelMemInfo,
1476                                    psBuffer->ui32Start,
1477                                    psBuffer->ui32End - psBuffer->ui32Start, 0,
1478                                    hUniqueTag);
1479                 } else {
1480
1481                         if (bDumpPolls) {
1482                                 PDUMPCOMMENTWITHFLAGS(0,
1483                                                       "Wait for %s space\r\n",
1484                                                       pszName);
1485                                 PDUMPCBP(psCtrlMemInfoKM, ui32Offset,
1486                                          psBuffer->ui32Start,
1487                                          psBuffer->ui32BackEndLength,
1488                                          psBuffer->ui32BufferSize, 0,
1489                                          MAKEUNIQUETAG(psCtrlMemInfoKM));
1490                         }
1491                         PDUMPCOMMENTWITHFLAGS(0, "%s (part 1)\r\n", pszName);
1492                         PDUMPMEMUM(NULL, psBuffer->pvLinAddr,
1493                                    (struct PVRSRV_KERNEL_MEM_INFO *)psBuffer->
1494                                                            hKernelMemInfo,
1495                                    psBuffer->ui32Start,
1496                                    psBuffer->ui32BackEndLength, 0, hUniqueTag);
1497
1498                         if (bDumpPolls) {
1499                                 PDUMPMEMPOL(psCtrlMemInfoKM, ui32Offset,
1500                                             0, 0xFFFFFFFF,
1501                                             PDUMP_POLL_OPERATOR_NOTEQUAL,
1502                                             MAKEUNIQUETAG(psCtrlMemInfoKM));
1503
1504                                 PDUMPCOMMENTWITHFLAGS(0,
1505                                                       "Wait for %s space\r\n",
1506                                                       pszName);
1507                                 PDUMPCBP(psCtrlMemInfoKM, ui32Offset, 0,
1508                                          psBuffer->ui32End,
1509                                          psBuffer->ui32BufferSize, 0,
1510                                          MAKEUNIQUETAG(psCtrlMemInfoKM));
1511                         }
1512                         PDUMPCOMMENTWITHFLAGS(0, "%s (part 2)\r\n", pszName);
1513                         PDUMPMEMUM(NULL, psBuffer->pvLinAddr,
1514                                    (struct PVRSRV_KERNEL_MEM_INFO *)psBuffer->
1515                                                    hKernelMemInfo,
1516                                    0, psBuffer->ui32End, 0, hUniqueTag);
1517                 }
1518         }
1519 }
1520
1521 int SGXPDumpBufferArrayBW(u32 ui32BridgeID,
1522          struct PVRSRV_BRIDGE_IN_PDUMP_BUFFER_ARRAY *psPDumpBufferArrayIN,
1523          void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1524 {
1525         u32 i;
1526         struct SGX_KICKTA_DUMP_BUFFER *psKickTADumpBuffer;
1527         u32 ui32BufferArrayLength = psPDumpBufferArrayIN->ui32BufferArrayLength;
1528         u32 ui32BufferArraySize =
1529             ui32BufferArrayLength * sizeof(struct SGX_KICKTA_DUMP_BUFFER);
1530         enum PVRSRV_ERROR eError = PVRSRV_ERROR_GENERIC;
1531
1532         PVR_UNREFERENCED_PARAMETER(psBridgeOut);
1533
1534         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1535                                  PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY);
1536
1537         if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize,
1538                        (void **)&psKickTADumpBuffer, NULL) != PVRSRV_OK)
1539                 return -ENOMEM;
1540
1541         if (CopyFromUserWrapper(psPerProc, ui32BridgeID, psKickTADumpBuffer,
1542                                 psPDumpBufferArrayIN->psBufferArray,
1543                                 ui32BufferArraySize) != PVRSRV_OK) {
1544                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize,
1545                           psKickTADumpBuffer, NULL);
1546                 return -EFAULT;
1547         }
1548
1549         for (i = 0; i < ui32BufferArrayLength; i++) {
1550                 void *pvMemInfo;
1551
1552                 eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1553                                             &pvMemInfo,
1554                                             psKickTADumpBuffer[i].
1555                                                             hKernelMemInfo,
1556                                             PVRSRV_HANDLE_TYPE_MEM_INFO);
1557
1558                 if (eError != PVRSRV_OK) {
1559                         PVR_DPF(PVR_DBG_ERROR,
1560                                  "PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY: "
1561                                  "PVRSRVLookupHandle failed (%d)", eError);
1562                         break;
1563                 }
1564                 psKickTADumpBuffer[i].hKernelMemInfo = pvMemInfo;
1565
1566         }
1567
1568         if (eError == PVRSRV_OK)
1569                 DumpBufferArray(psPerProc, psKickTADumpBuffer,
1570                                 ui32BufferArrayLength,
1571                                 psPDumpBufferArrayIN->bDumpPolls);
1572
1573         OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32BufferArraySize,
1574                   psKickTADumpBuffer, NULL);
1575
1576         return 0;
1577 }
1578
1579 int SGXPDump3DSignatureRegistersBW(u32 ui32BridgeID,
1580                   struct PVRSRV_BRIDGE_IN_PDUMP_3D_SIGNATURE_REGISTERS
1581                                           *psPDump3DSignatureRegistersIN,
1582                   void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1583 {
1584         u32 ui32RegisterArraySize =
1585             psPDump3DSignatureRegistersIN->ui32NumRegisters * sizeof(u32);
1586         u32 *pui32Registers = NULL;
1587         int ret = -EFAULT;
1588
1589         PVR_UNREFERENCED_PARAMETER(psBridgeOut);
1590
1591         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1592                          PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS);
1593
1594         if (ui32RegisterArraySize == 0)
1595                 goto ExitNoError;
1596
1597         if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1598                        ui32RegisterArraySize,
1599                        (void **)&pui32Registers, NULL) != PVRSRV_OK) {
1600                 PVR_DPF(PVR_DBG_ERROR,
1601                          "PDump3DSignatureRegistersBW: OSAllocMem failed");
1602                 goto Exit;
1603         }
1604
1605         if (CopyFromUserWrapper(psPerProc, ui32BridgeID, pui32Registers,
1606                                 psPDump3DSignatureRegistersIN->pui32Registers,
1607                                 ui32RegisterArraySize) != PVRSRV_OK) {
1608                 PVR_DPF(PVR_DBG_ERROR, "PDump3DSignatureRegistersBW: "
1609                                         "CopyFromUserWrapper failed");
1610                 goto Exit;
1611         }
1612
1613         PDump3DSignatureRegisters(psPDump3DSignatureRegistersIN->
1614                                                           ui32DumpFrameNum,
1615                                   pui32Registers,
1616                                   psPDump3DSignatureRegistersIN->
1617                                                           ui32NumRegisters);
1618
1619 ExitNoError:
1620         ret = 0;
1621 Exit:
1622         if (pui32Registers != NULL)
1623                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize,
1624                           pui32Registers, NULL);
1625
1626         return ret;
1627 }
1628
1629 int SGXPDumpCounterRegistersBW(u32 ui32BridgeID,
1630               struct PVRSRV_BRIDGE_IN_PDUMP_COUNTER_REGISTERS
1631                                       *psPDumpCounterRegistersIN,
1632               void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1633 {
1634         u32 ui32RegisterArraySize =
1635             psPDumpCounterRegistersIN->ui32NumRegisters * sizeof(u32);
1636         u32 *pui32Registers = NULL;
1637         int ret = -EFAULT;
1638
1639         PVR_UNREFERENCED_PARAMETER(psBridgeOut);
1640
1641         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1642                                  PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS);
1643
1644         if (ui32RegisterArraySize == 0)
1645                 goto ExitNoError;
1646
1647         if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize,
1648                        (void **)&pui32Registers, NULL) != PVRSRV_OK) {
1649                 PVR_DPF(PVR_DBG_ERROR,
1650                          "PDumpCounterRegistersBW: OSAllocMem failed");
1651                 ret = -ENOMEM;
1652                 goto Exit;
1653         }
1654
1655         if (CopyFromUserWrapper(psPerProc, ui32BridgeID, pui32Registers,
1656                                 psPDumpCounterRegistersIN->pui32Registers,
1657                                 ui32RegisterArraySize) != PVRSRV_OK) {
1658                 PVR_DPF(PVR_DBG_ERROR,
1659                          "PDumpCounterRegistersBW: CopyFromUserWrapper failed");
1660                 goto Exit;
1661         }
1662
1663         PDumpCounterRegisters(psPDumpCounterRegistersIN->ui32DumpFrameNum,
1664                               pui32Registers,
1665                               psPDumpCounterRegistersIN->ui32NumRegisters);
1666
1667 ExitNoError:
1668         ret = 0;
1669 Exit:
1670         if (pui32Registers != NULL)
1671                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize,
1672                           pui32Registers, NULL);
1673
1674         return ret;
1675 }
1676
1677 int SGXPDumpTASignatureRegistersBW(u32 ui32BridgeID,
1678           struct PVRSRV_BRIDGE_IN_PDUMP_TA_SIGNATURE_REGISTERS
1679                                           *psPDumpTASignatureRegistersIN,
1680           void *psBridgeOut, struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1681 {
1682         u32 ui32RegisterArraySize =
1683             psPDumpTASignatureRegistersIN->ui32NumRegisters * sizeof(u32);
1684         u32 *pui32Registers = NULL;
1685         int ret = -EFAULT;
1686
1687         PVR_UNREFERENCED_PARAMETER(psBridgeOut);
1688
1689         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1690                          PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS);
1691
1692         if (ui32RegisterArraySize == 0)
1693                 goto ExitNoError;
1694
1695         if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1696                        ui32RegisterArraySize,
1697                        (void **)&pui32Registers, NULL) != PVRSRV_OK) {
1698                 PVR_DPF(PVR_DBG_ERROR,
1699                          "PDumpTASignatureRegistersBW: OSAllocMem failed");
1700                 ret = -ENOMEM;
1701                 goto Exit;
1702         }
1703
1704         if (CopyFromUserWrapper(psPerProc, ui32BridgeID, pui32Registers,
1705                                 psPDumpTASignatureRegistersIN->pui32Registers,
1706                                 ui32RegisterArraySize) != PVRSRV_OK) {
1707                 PVR_DPF(PVR_DBG_ERROR, "PDumpTASignatureRegistersBW: "
1708                                         "CopyFromUserWrapper failed");
1709                 goto Exit;
1710         }
1711
1712         PDumpTASignatureRegisters(psPDumpTASignatureRegistersIN->
1713                                                           ui32DumpFrameNum,
1714                                   psPDumpTASignatureRegistersIN->
1715                                                           ui32TAKickCount,
1716                                   pui32Registers,
1717                                   psPDumpTASignatureRegistersIN->
1718                                                           ui32NumRegisters);
1719
1720 ExitNoError:
1721         ret = 0;
1722 Exit:
1723         if (pui32Registers != NULL)
1724                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32RegisterArraySize,
1725                           pui32Registers, NULL);
1726
1727         return ret;
1728 }
1729
1730 int SGXPDumpHWPerfCBBW(u32 ui32BridgeID,
1731                 struct PVRSRV_BRIDGE_IN_PDUMP_HWPERFCB *psPDumpHWPerfCBIN,
1732                 struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1733                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1734 {
1735         struct PVRSRV_SGXDEV_INFO *psDevInfo;
1736         void *hDevCookieInt;
1737
1738         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1739                                  PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB);
1740
1741         psRetOUT->eError =
1742             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
1743                                psPDumpHWPerfCBIN->hDevCookie,
1744                                PVRSRV_HANDLE_TYPE_DEV_NODE);
1745         if (psRetOUT->eError != PVRSRV_OK)
1746                 return 0;
1747
1748         psDevInfo = ((struct PVRSRV_DEVICE_NODE *)hDevCookieInt)->pvDevice;
1749
1750         PDumpHWPerfCBKM(&psPDumpHWPerfCBIN->szFileName[0],
1751                         psPDumpHWPerfCBIN->ui32FileOffset,
1752                         psDevInfo->psKernelHWPerfCBMemInfo->sDevVAddr,
1753                         psDevInfo->psKernelHWPerfCBMemInfo->ui32AllocSize,
1754                         psPDumpHWPerfCBIN->ui32PDumpFlags);
1755
1756         return 0;
1757 }
1758
1759 #endif
1760
1761 void SetSGXDispatchTableEntry(void)
1762 {
1763
1764         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETCLIENTINFO,
1765                               SGXGetClientInfoBW);
1766         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO,
1767                               SGXReleaseClientInfoBW);
1768         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO,
1769                               SGXGetInternalDevInfoBW);
1770         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DOKICK, SGXDoKickBW);
1771         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR, DummyBW);
1772         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READREGISTRYDWORD, DummyBW);
1773         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULECOMMAND, DummyBW);
1774
1775         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE,
1776                               SGX2DQueryBlitsCompleteBW);
1777
1778         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMMUPDADDR, DummyBW);
1779
1780         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SUBMITTRANSFER,
1781                               SGXSubmitTransferBW);
1782         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_GETMISCINFO, SGXGetMiscInfoBW);
1783         SetDispatchTableEntry(PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT,
1784                               SGXGetInfoForSrvinitBW);
1785         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_DEVINITPART2,
1786                               SGXDevInitPart2BW);
1787
1788         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC,
1789                               SGXFindSharedPBDescBW);
1790         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC,
1791                               SGXUnrefSharedPBDescBW);
1792         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC,
1793                               SGXAddSharedPBDescBW);
1794         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT,
1795                               SGXRegisterHWRenderContextBW);
1796         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET,
1797                               SGXFlushHWRenderTargetBW);
1798         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT,
1799                               SGXUnregisterHWRenderContextBW);
1800         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT,
1801                               SGXRegisterHWTransferContextBW);
1802         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT,
1803                               SGXUnregisterHWTransferContextBW);
1804
1805         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS,
1806                               SGXReadDiffCountersBW);
1807         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_READ_HWPERF_CB,
1808                               SGXReadHWPerfCBBW);
1809
1810         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES,
1811                               SGXScheduleProcessQueuesBW);
1812
1813 #if defined(PDUMP)
1814         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY,
1815                               SGXPDumpBufferArrayBW);
1816         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS,
1817                               SGXPDump3DSignatureRegistersBW);
1818         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS,
1819                               SGXPDumpCounterRegistersBW);
1820         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS,
1821                               SGXPDumpTASignatureRegistersBW);
1822         SetDispatchTableEntry(PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB,
1823                               SGXPDumpHWPerfCBBW);
1824 #endif
1825 }