staging: emgd: experimental build 2667
[profile/ivi/intel-emgd-kmod.git] / pvr / services4 / srvkm / devices / sgx / pb.c
1 /**********************************************************************
2  Copyright (c) Imagination Technologies Ltd.
3
4  Permission is hereby granted, free of charge, to any person obtaining a copy
5  of this software and associated documentation files (the "Software"), to deal
6  in the Software without restriction, including without limitation the rights
7  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  copies of the Software, and to permit persons to whom the Software is
9  furnished to do so, subject to the following conditions:
10
11  The above copyright notice and this permission notice shall be included in
12  all copies or substantial portions of the Software.
13
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  THE SOFTWARE.
21  ******************************************************************************/
22
23 #include <stddef.h>
24
25 #include "services_headers.h"
26 #include "sgxapi_km.h"
27 #include "sgxinfo.h"
28 #include "sgxinfokm.h"
29 #include "pvr_bridge_km.h"
30 #include "pdump_km.h"
31 #include "sgxutils.h"
32
33 #ifndef __linux__
34 #pragma message("TODO: Review use of OS_PAGEABLE vs OS_NON_PAGEABLE")
35 #endif
36
37 #include "lists.h"
38
39 static IMPLEMENT_LIST_INSERT(PVRSRV_STUB_PBDESC)
40 static IMPLEMENT_LIST_REMOVE(PVRSRV_STUB_PBDESC)
41
42 static PRESMAN_ITEM psResItemCreateSharedPB = IMG_NULL;
43 static PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB = IMG_NULL;
44
45 static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param);
46 static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param);
47
48 IMG_EXPORT PVRSRV_ERROR
49 SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA   *psPerProc,
50                                           IMG_HANDLE                            hDevCookie,
51                                           IMG_BOOL                              bLockOnFailure,
52                                           IMG_UINT32                            ui32TotalPBSize,
53                                           IMG_HANDLE                            *phSharedPBDesc,
54                                           PVRSRV_KERNEL_MEM_INFO        **ppsSharedPBDescKernelMemInfo,
55                                           PVRSRV_KERNEL_MEM_INFO        **ppsHWPBDescKernelMemInfo,
56                                           PVRSRV_KERNEL_MEM_INFO        **ppsBlockKernelMemInfo,
57                                           PVRSRV_KERNEL_MEM_INFO        **ppsHWBlockKernelMemInfo,
58                                           PVRSRV_KERNEL_MEM_INFO        ***pppsSharedPBDescSubKernelMemInfos,
59                                           IMG_UINT32                            *ui32SharedPBDescSubKernelMemInfosCount)
60 {
61         PVRSRV_STUB_PBDESC *psStubPBDesc;
62         PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos=IMG_NULL;
63         PVRSRV_SGXDEV_INFO *psSGXDevInfo;
64         PVRSRV_ERROR eError;
65
66         psSGXDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
67
68         psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
69         if (psStubPBDesc != IMG_NULL)
70         {
71                 IMG_UINT32 i;
72                 PRESMAN_ITEM psResItem;
73
74                 if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
75                 {
76                         PVR_DPF((PVR_DBG_WARNING,
77                                         "SGXFindSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
78                                         ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
79                 }
80
81                 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
82                                           sizeof(PVRSRV_KERNEL_MEM_INFO *)
83                                                 * psStubPBDesc->ui32SubKernelMemInfosCount,
84                                           (IMG_VOID **)&ppsSharedPBDescSubKernelMemInfos,
85                                           IMG_NULL,
86                                           "Array of Kernel Memory Info") != PVRSRV_OK)
87                 {
88                         PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: OSAllocMem failed"));
89
90                         eError = PVRSRV_ERROR_OUT_OF_MEMORY;
91                         goto ExitNotFound;
92                 }
93
94                 psResItem = ResManRegisterRes(psPerProc->hResManContext,
95                                                                           RESMAN_TYPE_SHARED_PB_DESC,
96                                                                           psStubPBDesc,
97                                                                           0,
98                                                                           &SGXCleanupSharedPBDescCallback);
99
100                 if (psResItem == IMG_NULL)
101                 {
102                         OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
103                                           sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDesc->ui32SubKernelMemInfosCount,
104                                           ppsSharedPBDescSubKernelMemInfos,
105                                           0);
106
107
108                         PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
109
110                         eError = PVRSRV_ERROR_GENERIC;
111                         goto ExitNotFound;
112                 }
113
114                 *ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo;
115                 *ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo;
116                 *ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo;
117                 *ppsHWBlockKernelMemInfo = psStubPBDesc->psHWBlockKernelMemInfo;
118
119                 *ui32SharedPBDescSubKernelMemInfosCount =
120                         psStubPBDesc->ui32SubKernelMemInfosCount;
121
122                 *pppsSharedPBDescSubKernelMemInfos = ppsSharedPBDescSubKernelMemInfos;
123
124                 for(i=0; i<psStubPBDesc->ui32SubKernelMemInfosCount; i++)
125                 {
126                         ppsSharedPBDescSubKernelMemInfos[i] =
127                                 psStubPBDesc->ppsSubKernelMemInfos[i];
128                 }
129
130                 psStubPBDesc->ui32RefCount++;
131                 *phSharedPBDesc = (IMG_HANDLE)psResItem;
132                 return PVRSRV_OK;
133         }
134
135         eError = PVRSRV_OK;
136         if (bLockOnFailure)
137         {
138                 if (psResItemCreateSharedPB == IMG_NULL)
139                 {
140                         psResItemCreateSharedPB = ResManRegisterRes(psPerProc->hResManContext,
141                                   RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
142                                   psPerProc,
143                                   0,
144                                   &SGXCleanupSharedPBDescCreateLockCallback);
145
146                         if (psResItemCreateSharedPB == IMG_NULL)
147                         {
148                                 PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
149
150                                 eError = PVRSRV_ERROR_GENERIC;
151                                 goto ExitNotFound;
152                         }
153                         PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
154                         psPerProcCreateSharedPB = psPerProc;
155                 }
156                 else
157                 {
158                          eError = PVRSRV_ERROR_PROCESSING_BLOCKED;
159                 }
160         }
161 ExitNotFound:
162         *phSharedPBDesc = IMG_NULL;
163
164         return eError;
165 }
166
167
168 static PVRSRV_ERROR
169 SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn)
170 {
171
172         IMG_UINT32 i;
173         PVRSRV_DEVICE_NODE *psDeviceNode;
174
175         psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie;
176
177
178
179
180         psStubPBDescIn->ui32RefCount--;
181         if (psStubPBDescIn->ui32RefCount == 0)
182         {
183                 List_PVRSRV_STUB_PBDESC_Remove(psStubPBDescIn);
184                 for(i=0 ; i<psStubPBDescIn->ui32SubKernelMemInfosCount; i++)
185                 {
186
187                         PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie,
188                                                                   psStubPBDescIn->ppsSubKernelMemInfos[i]);
189                 }
190
191                 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
192                                   sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDescIn->ui32SubKernelMemInfosCount,
193                                   psStubPBDescIn->ppsSubKernelMemInfos,
194                                   0);
195                 psStubPBDescIn->ppsSubKernelMemInfos = IMG_NULL;
196
197                 PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psBlockKernelMemInfo);
198
199                 PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWBlockKernelMemInfo);
200
201                 PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWPBDescKernelMemInfo);
202
203                 PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psSharedPBDescKernelMemInfo);
204
205                 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
206                                   sizeof(PVRSRV_STUB_PBDESC),
207                                   psStubPBDescIn,
208                                   0);
209
210
211
212                 SGXCleanupRequest(psDeviceNode,
213                                                   IMG_NULL,
214                                                   PVRSRV_CLEANUPCMD_PB);
215         }
216         return PVRSRV_OK;
217
218 }
219
220 static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
221 {
222         PVRSRV_STUB_PBDESC *psStubPBDesc = (PVRSRV_STUB_PBDESC *)pvParam;
223
224         PVR_UNREFERENCED_PARAMETER(ui32Param);
225
226         return SGXCleanupSharedPBDescKM(psStubPBDesc);
227 }
228
229 static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
230 {
231 #ifdef DEBUG
232         PVRSRV_PER_PROCESS_DATA *psPerProc = (PVRSRV_PER_PROCESS_DATA *)pvParam;
233         PVR_ASSERT(psPerProc == psPerProcCreateSharedPB);
234 #else
235         PVR_UNREFERENCED_PARAMETER(pvParam);
236 #endif
237
238         PVR_UNREFERENCED_PARAMETER(ui32Param);
239
240         psPerProcCreateSharedPB = IMG_NULL;
241         psResItemCreateSharedPB = IMG_NULL;
242
243         return PVRSRV_OK;
244 }
245
246
247 IMG_EXPORT PVRSRV_ERROR
248 SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc)
249 {
250         PVR_ASSERT(hSharedPBDesc != IMG_NULL);
251
252         return ResManFreeResByPtr(hSharedPBDesc);
253 }
254
255
256 IMG_EXPORT PVRSRV_ERROR
257 SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA    *psPerProc,
258                                          IMG_HANDLE                                     hDevCookie,
259                                          PVRSRV_KERNEL_MEM_INFO         *psSharedPBDescKernelMemInfo,
260                                          PVRSRV_KERNEL_MEM_INFO         *psHWPBDescKernelMemInfo,
261                                          PVRSRV_KERNEL_MEM_INFO         *psBlockKernelMemInfo,
262                                          PVRSRV_KERNEL_MEM_INFO         *psHWBlockKernelMemInfo,
263                                          IMG_UINT32                                     ui32TotalPBSize,
264                                          IMG_HANDLE                                     *phSharedPBDesc,
265                                          PVRSRV_KERNEL_MEM_INFO         **ppsSharedPBDescSubKernelMemInfos,
266                                          IMG_UINT32                                     ui32SharedPBDescSubKernelMemInfosCount)
267 {
268         PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL;
269         PVRSRV_ERROR eRet = PVRSRV_ERROR_GENERIC;
270         IMG_UINT32 i;
271         PVRSRV_SGXDEV_INFO *psSGXDevInfo;
272         PRESMAN_ITEM psResItem;
273
274
275         if (psPerProcCreateSharedPB != psPerProc)
276         {
277                 goto NoAdd;
278         }
279         else
280         {
281                 PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL);
282
283                 ResManFreeResByPtr(psResItemCreateSharedPB);
284
285                 PVR_ASSERT(psResItemCreateSharedPB == IMG_NULL);
286                 PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
287         }
288
289         psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
290
291         psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
292         if (psStubPBDesc != IMG_NULL)
293         {
294                 if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
295                 {
296                         PVR_DPF((PVR_DBG_WARNING,
297                                         "SGXAddSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
298                                         ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
299
300                 }
301
302
303                 psResItem = ResManRegisterRes(psPerProc->hResManContext,
304                                                                           RESMAN_TYPE_SHARED_PB_DESC,
305                                                                           psStubPBDesc,
306                                                                           0,
307                                                                           &SGXCleanupSharedPBDescCallback);
308                 if (psResItem == IMG_NULL)
309                 {
310                         PVR_DPF((PVR_DBG_ERROR,
311                                 "SGXAddSharedPBDescKM: "
312                                 "Failed to register existing shared "
313                                 "PBDesc with the resource manager"));
314                         goto NoAddKeepPB;
315                 }
316
317
318                 psStubPBDesc->ui32RefCount++;
319
320                 *phSharedPBDesc = (IMG_HANDLE)psResItem;
321                 eRet = PVRSRV_OK;
322                 goto NoAddKeepPB;
323         }
324
325         if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
326                                   sizeof(PVRSRV_STUB_PBDESC),
327                                   (IMG_VOID **)&psStubPBDesc,
328                                   0,
329                                   "Stub Parameter Buffer Description") != PVRSRV_OK)
330         {
331                 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc "
332                                         "StubPBDesc"));
333                 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
334                 goto NoAdd;
335         }
336
337
338         psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
339
340         if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
341                                   sizeof(PVRSRV_KERNEL_MEM_INFO *)
342                                   * ui32SharedPBDescSubKernelMemInfosCount,
343                                   (IMG_VOID **)&psStubPBDesc->ppsSubKernelMemInfos,
344                                   0,
345                                   "Array of Kernel Memory Info") != PVRSRV_OK)
346         {
347                 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
348                                  "Failed to alloc "
349                                  "StubPBDesc->ppsSubKernelMemInfos"));
350                 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
351                 goto NoAdd;
352         }
353
354         if(PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo)
355            != PVRSRV_OK)
356         {
357                 goto NoAdd;
358         }
359
360         if(PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo)
361            != PVRSRV_OK)
362         {
363                 goto NoAdd;
364         }
365
366         if(PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo)
367            != PVRSRV_OK)
368         {
369                 goto NoAdd;
370         }
371
372         if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo)
373            != PVRSRV_OK)
374         {
375                 goto NoAdd;
376         }
377
378         psStubPBDesc->ui32RefCount = 1;
379         psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
380         psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
381         psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
382         psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;
383         psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo;
384
385         psStubPBDesc->ui32SubKernelMemInfosCount =
386                 ui32SharedPBDescSubKernelMemInfosCount;
387         for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
388         {
389                 psStubPBDesc->ppsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i];
390                 if(PVRSRVDissociateMemFromResmanKM(ppsSharedPBDescSubKernelMemInfos[i])
391                    != PVRSRV_OK)
392                 {
393                         PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
394                                          "Failed to dissociate shared PBDesc "
395                                          "from process"));
396                         goto NoAdd;
397                 }
398         }
399
400         psResItem = ResManRegisterRes(psPerProc->hResManContext,
401                                                                   RESMAN_TYPE_SHARED_PB_DESC,
402                                                                   psStubPBDesc,
403                                                                   0,
404                                                                   &SGXCleanupSharedPBDescCallback);
405         if (psResItem == IMG_NULL)
406         {
407                 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
408                                          "Failed to register shared PBDesc "
409                                          " with the resource manager"));
410                 goto NoAdd;
411         }
412         psStubPBDesc->hDevCookie = hDevCookie;
413
414
415         List_PVRSRV_STUB_PBDESC_Insert(&(psSGXDevInfo->psStubPBDescListKM),
416                                                                         psStubPBDesc);
417
418         *phSharedPBDesc = (IMG_HANDLE)psResItem;
419
420         return PVRSRV_OK;
421
422 NoAdd:
423         if(psStubPBDesc)
424         {
425                 if(psStubPBDesc->ppsSubKernelMemInfos)
426                 {
427                         OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
428                                           sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
429                                           psStubPBDesc->ppsSubKernelMemInfos,
430                                           0);
431                         psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
432                 }
433                 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
434                                   sizeof(PVRSRV_STUB_PBDESC),
435                                   psStubPBDesc,
436                                   0);
437
438         }
439
440 NoAddKeepPB:
441         for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
442         {
443                 PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]);
444         }
445
446         PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
447         PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);
448
449         PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);
450         PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo);
451
452         return eRet;
453 }
454