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