aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/sgx/pb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/sgx/pb.c')
-rw-r--r--drivers/gpu/pvr/sgx/pb.c459
1 files changed, 459 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/sgx/pb.c b/drivers/gpu/pvr/sgx/pb.c
new file mode 100644
index 00000000000..f9e8b19a70a
--- /dev/null
+++ b/drivers/gpu/pvr/sgx/pb.c
@@ -0,0 +1,459 @@
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 <stddef.h>
28
29#include "services_headers.h"
30#include "sgx_bridge_km.h"
31#include "sgxapi_km.h"
32#include "sgxinfo.h"
33#include "sgxinfokm.h"
34#include "pvr_bridge_km.h"
35#include "pdump_km.h"
36#include "sgxutils.h"
37
38#ifndef __linux__
39#pragma message("TODO: Review use of OS_PAGEABLE vs OS_NON_PAGEABLE")
40#endif
41
42#include "lists.h"
43
44static IMPLEMENT_LIST_INSERT(PVRSRV_STUB_PBDESC)
45static IMPLEMENT_LIST_REMOVE(PVRSRV_STUB_PBDESC)
46
47static PRESMAN_ITEM psResItemCreateSharedPB = IMG_NULL;
48static PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB = IMG_NULL;
49
50static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param);
51static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param);
52
53IMG_EXPORT PVRSRV_ERROR
54SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
55 IMG_HANDLE hDevCookie,
56 IMG_BOOL bLockOnFailure,
57 IMG_UINT32 ui32TotalPBSize,
58 IMG_HANDLE *phSharedPBDesc,
59 PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo,
60 PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo,
61 PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo,
62 PVRSRV_KERNEL_MEM_INFO **ppsHWBlockKernelMemInfo,
63 PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos,
64 IMG_UINT32 *ui32SharedPBDescSubKernelMemInfosCount)
65{
66 PVRSRV_STUB_PBDESC *psStubPBDesc;
67 PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos=IMG_NULL;
68 PVRSRV_SGXDEV_INFO *psSGXDevInfo;
69 PVRSRV_ERROR eError;
70
71 psSGXDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
72
73 psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
74 if (psStubPBDesc != IMG_NULL)
75 {
76 IMG_UINT32 i;
77 PRESMAN_ITEM psResItem;
78
79 if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
80 {
81 PVR_DPF((PVR_DBG_WARNING,
82 "SGXFindSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
83 ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
84 }
85
86 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
87 sizeof(PVRSRV_KERNEL_MEM_INFO *)
88 * psStubPBDesc->ui32SubKernelMemInfosCount,
89 (IMG_VOID **)&ppsSharedPBDescSubKernelMemInfos,
90 IMG_NULL,
91 "Array of Kernel Memory Info") != PVRSRV_OK)
92 {
93 PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: OSAllocMem failed"));
94
95 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
96 goto ExitNotFound;
97 }
98
99 psResItem = ResManRegisterRes(psPerProc->hResManContext,
100 RESMAN_TYPE_SHARED_PB_DESC,
101 psStubPBDesc,
102 0,
103 &SGXCleanupSharedPBDescCallback);
104
105 if (psResItem == IMG_NULL)
106 {
107 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
108 sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDesc->ui32SubKernelMemInfosCount,
109 ppsSharedPBDescSubKernelMemInfos,
110 0);
111
112
113 PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
114
115 eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
116 goto ExitNotFound;
117 }
118
119 *ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo;
120 *ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo;
121 *ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo;
122 *ppsHWBlockKernelMemInfo = psStubPBDesc->psHWBlockKernelMemInfo;
123
124 *ui32SharedPBDescSubKernelMemInfosCount =
125 psStubPBDesc->ui32SubKernelMemInfosCount;
126
127 *pppsSharedPBDescSubKernelMemInfos = ppsSharedPBDescSubKernelMemInfos;
128
129 for(i=0; i<psStubPBDesc->ui32SubKernelMemInfosCount; i++)
130 {
131 ppsSharedPBDescSubKernelMemInfos[i] =
132 psStubPBDesc->ppsSubKernelMemInfos[i];
133 }
134
135 psStubPBDesc->ui32RefCount++;
136 *phSharedPBDesc = (IMG_HANDLE)psResItem;
137 return PVRSRV_OK;
138 }
139
140 eError = PVRSRV_OK;
141 if (bLockOnFailure)
142 {
143 if (psResItemCreateSharedPB == IMG_NULL)
144 {
145 psResItemCreateSharedPB = ResManRegisterRes(psPerProc->hResManContext,
146 RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
147 psPerProc,
148 0,
149 &SGXCleanupSharedPBDescCreateLockCallback);
150
151 if (psResItemCreateSharedPB == IMG_NULL)
152 {
153 PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
154
155 eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
156 goto ExitNotFound;
157 }
158 PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
159 psPerProcCreateSharedPB = psPerProc;
160 }
161 else
162 {
163 eError = PVRSRV_ERROR_PROCESSING_BLOCKED;
164 }
165 }
166ExitNotFound:
167 *phSharedPBDesc = IMG_NULL;
168
169 return eError;
170}
171
172
173static PVRSRV_ERROR
174SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn)
175{
176
177 IMG_UINT32 i;
178 PVRSRV_DEVICE_NODE *psDeviceNode;
179
180 psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie;
181
182
183
184
185 psStubPBDescIn->ui32RefCount--;
186 if (psStubPBDescIn->ui32RefCount == 0)
187 {
188 List_PVRSRV_STUB_PBDESC_Remove(psStubPBDescIn);
189 for(i=0 ; i<psStubPBDescIn->ui32SubKernelMemInfosCount; i++)
190 {
191
192 PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie,
193 psStubPBDescIn->ppsSubKernelMemInfos[i]);
194 }
195
196 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
197 sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDescIn->ui32SubKernelMemInfosCount,
198 psStubPBDescIn->ppsSubKernelMemInfos,
199 0);
200 psStubPBDescIn->ppsSubKernelMemInfos = IMG_NULL;
201
202 PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psBlockKernelMemInfo);
203
204 PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWBlockKernelMemInfo);
205
206 PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWPBDescKernelMemInfo);
207
208 PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psSharedPBDescKernelMemInfo);
209
210 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
211 sizeof(PVRSRV_STUB_PBDESC),
212 psStubPBDescIn,
213 0);
214
215
216
217 SGXCleanupRequest(psDeviceNode,
218 IMG_NULL,
219 PVRSRV_CLEANUPCMD_PB);
220 }
221 return PVRSRV_OK;
222
223}
224
225static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
226{
227 PVRSRV_STUB_PBDESC *psStubPBDesc = (PVRSRV_STUB_PBDESC *)pvParam;
228
229 PVR_UNREFERENCED_PARAMETER(ui32Param);
230
231 return SGXCleanupSharedPBDescKM(psStubPBDesc);
232}
233
234static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
235{
236#ifdef DEBUG
237 PVRSRV_PER_PROCESS_DATA *psPerProc = (PVRSRV_PER_PROCESS_DATA *)pvParam;
238 PVR_ASSERT(psPerProc == psPerProcCreateSharedPB);
239#else
240 PVR_UNREFERENCED_PARAMETER(pvParam);
241#endif
242
243 PVR_UNREFERENCED_PARAMETER(ui32Param);
244
245 psPerProcCreateSharedPB = IMG_NULL;
246 psResItemCreateSharedPB = IMG_NULL;
247
248 return PVRSRV_OK;
249}
250
251
252IMG_EXPORT PVRSRV_ERROR
253SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc)
254{
255 PVR_ASSERT(hSharedPBDesc != IMG_NULL);
256
257 return ResManFreeResByPtr(hSharedPBDesc);
258}
259
260
261IMG_EXPORT PVRSRV_ERROR
262SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
263 IMG_HANDLE hDevCookie,
264 PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo,
265 PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo,
266 PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo,
267 PVRSRV_KERNEL_MEM_INFO *psHWBlockKernelMemInfo,
268 IMG_UINT32 ui32TotalPBSize,
269 IMG_HANDLE *phSharedPBDesc,
270 PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos,
271 IMG_UINT32 ui32SharedPBDescSubKernelMemInfosCount)
272{
273 PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL;
274 PVRSRV_ERROR eRet = PVRSRV_ERROR_INVALID_PERPROC;
275 IMG_UINT32 i;
276 PVRSRV_SGXDEV_INFO *psSGXDevInfo;
277 PRESMAN_ITEM psResItem;
278
279
280 if (psPerProcCreateSharedPB != psPerProc)
281 {
282 goto NoAdd;
283 }
284 else
285 {
286 PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL);
287
288 ResManFreeResByPtr(psResItemCreateSharedPB);
289
290 PVR_ASSERT(psResItemCreateSharedPB == IMG_NULL);
291 PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
292 }
293
294 psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
295
296 psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
297 if (psStubPBDesc != IMG_NULL)
298 {
299 if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
300 {
301 PVR_DPF((PVR_DBG_WARNING,
302 "SGXAddSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
303 ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
304
305 }
306
307
308 psResItem = ResManRegisterRes(psPerProc->hResManContext,
309 RESMAN_TYPE_SHARED_PB_DESC,
310 psStubPBDesc,
311 0,
312 &SGXCleanupSharedPBDescCallback);
313 if (psResItem == IMG_NULL)
314 {
315 PVR_DPF((PVR_DBG_ERROR,
316 "SGXAddSharedPBDescKM: "
317 "Failed to register existing shared "
318 "PBDesc with the resource manager"));
319 goto NoAddKeepPB;
320 }
321
322
323 psStubPBDesc->ui32RefCount++;
324
325 *phSharedPBDesc = (IMG_HANDLE)psResItem;
326 eRet = PVRSRV_OK;
327 goto NoAddKeepPB;
328 }
329
330 if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
331 sizeof(PVRSRV_STUB_PBDESC),
332 (IMG_VOID **)&psStubPBDesc,
333 0,
334 "Stub Parameter Buffer Description") != PVRSRV_OK)
335 {
336 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc "
337 "StubPBDesc"));
338 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
339 goto NoAdd;
340 }
341
342
343 psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
344
345 if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
346 sizeof(PVRSRV_KERNEL_MEM_INFO *)
347 * ui32SharedPBDescSubKernelMemInfosCount,
348 (IMG_VOID **)&psStubPBDesc->ppsSubKernelMemInfos,
349 0,
350 "Array of Kernel Memory Info") != PVRSRV_OK)
351 {
352 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
353 "Failed to alloc "
354 "StubPBDesc->ppsSubKernelMemInfos"));
355 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
356 goto NoAdd;
357 }
358
359 if(PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo)
360 != PVRSRV_OK)
361 {
362 goto NoAdd;
363 }
364
365 if(PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo)
366 != PVRSRV_OK)
367 {
368 goto NoAdd;
369 }
370
371 if(PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo)
372 != PVRSRV_OK)
373 {
374 goto NoAdd;
375 }
376
377 if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo)
378 != PVRSRV_OK)
379 {
380 goto NoAdd;
381 }
382
383 psStubPBDesc->ui32RefCount = 1;
384 psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
385 psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
386 psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
387 psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;
388 psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo;
389
390 psStubPBDesc->ui32SubKernelMemInfosCount =
391 ui32SharedPBDescSubKernelMemInfosCount;
392 for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
393 {
394 psStubPBDesc->ppsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i];
395 if(PVRSRVDissociateMemFromResmanKM(ppsSharedPBDescSubKernelMemInfos[i])
396 != PVRSRV_OK)
397 {
398 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
399 "Failed to dissociate shared PBDesc "
400 "from process"));
401 goto NoAdd;
402 }
403 }
404
405 psResItem = ResManRegisterRes(psPerProc->hResManContext,
406 RESMAN_TYPE_SHARED_PB_DESC,
407 psStubPBDesc,
408 0,
409 &SGXCleanupSharedPBDescCallback);
410 if (psResItem == IMG_NULL)
411 {
412 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
413 "Failed to register shared PBDesc "
414 " with the resource manager"));
415 goto NoAdd;
416 }
417 psStubPBDesc->hDevCookie = hDevCookie;
418
419
420 List_PVRSRV_STUB_PBDESC_Insert(&(psSGXDevInfo->psStubPBDescListKM),
421 psStubPBDesc);
422
423 *phSharedPBDesc = (IMG_HANDLE)psResItem;
424
425 return PVRSRV_OK;
426
427NoAdd:
428 if(psStubPBDesc)
429 {
430 if(psStubPBDesc->ppsSubKernelMemInfos)
431 {
432 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
433 sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
434 psStubPBDesc->ppsSubKernelMemInfos,
435 0);
436 psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
437 }
438 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
439 sizeof(PVRSRV_STUB_PBDESC),
440 psStubPBDesc,
441 0);
442
443 }
444
445NoAddKeepPB:
446 for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
447 {
448 PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]);
449 }
450
451 PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
452 PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);
453
454 PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);
455 PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo);
456
457 return eRet;
458}
459