1 /**********************************************************************
2 Copyright (c) Imagination Technologies Ltd.
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:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
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
21 ******************************************************************************/
25 #include "services_headers.h"
26 #include "sgxapi_km.h"
28 #include "sgxinfokm.h"
29 #include "pvr_bridge_km.h"
34 #pragma message("TODO: Review use of OS_PAGEABLE vs OS_NON_PAGEABLE")
39 static IMPLEMENT_LIST_INSERT(PVRSRV_STUB_PBDESC)
40 static IMPLEMENT_LIST_REMOVE(PVRSRV_STUB_PBDESC)
42 static PRESMAN_ITEM psResItemCreateSharedPB = IMG_NULL;
43 static PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB = IMG_NULL;
45 static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param);
46 static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param);
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)
61 PVRSRV_STUB_PBDESC *psStubPBDesc;
62 PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos=IMG_NULL;
63 PVRSRV_SGXDEV_INFO *psSGXDevInfo;
66 psSGXDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
68 psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
69 if (psStubPBDesc != IMG_NULL)
72 PRESMAN_ITEM psResItem;
74 if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
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));
81 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
82 sizeof(PVRSRV_KERNEL_MEM_INFO *)
83 * psStubPBDesc->ui32SubKernelMemInfosCount,
84 (IMG_VOID **)&ppsSharedPBDescSubKernelMemInfos,
86 "Array of Kernel Memory Info") != PVRSRV_OK)
88 PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: OSAllocMem failed"));
90 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
94 psResItem = ResManRegisterRes(psPerProc->hResManContext,
95 RESMAN_TYPE_SHARED_PB_DESC,
98 &SGXCleanupSharedPBDescCallback);
100 if (psResItem == IMG_NULL)
102 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
103 sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDesc->ui32SubKernelMemInfosCount,
104 ppsSharedPBDescSubKernelMemInfos,
108 PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
110 eError = PVRSRV_ERROR_GENERIC;
114 *ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo;
115 *ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo;
116 *ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo;
117 *ppsHWBlockKernelMemInfo = psStubPBDesc->psHWBlockKernelMemInfo;
119 *ui32SharedPBDescSubKernelMemInfosCount =
120 psStubPBDesc->ui32SubKernelMemInfosCount;
122 *pppsSharedPBDescSubKernelMemInfos = ppsSharedPBDescSubKernelMemInfos;
124 for(i=0; i<psStubPBDesc->ui32SubKernelMemInfosCount; i++)
126 ppsSharedPBDescSubKernelMemInfos[i] =
127 psStubPBDesc->ppsSubKernelMemInfos[i];
130 psStubPBDesc->ui32RefCount++;
131 *phSharedPBDesc = (IMG_HANDLE)psResItem;
138 if (psResItemCreateSharedPB == IMG_NULL)
140 psResItemCreateSharedPB = ResManRegisterRes(psPerProc->hResManContext,
141 RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
144 &SGXCleanupSharedPBDescCreateLockCallback);
146 if (psResItemCreateSharedPB == IMG_NULL)
148 PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));
150 eError = PVRSRV_ERROR_GENERIC;
153 PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
154 psPerProcCreateSharedPB = psPerProc;
158 eError = PVRSRV_ERROR_PROCESSING_BLOCKED;
162 *phSharedPBDesc = IMG_NULL;
169 SGXCleanupSharedPBDescKM(PVRSRV_STUB_PBDESC *psStubPBDescIn)
173 PVRSRV_DEVICE_NODE *psDeviceNode;
175 psDeviceNode = (PVRSRV_DEVICE_NODE*)psStubPBDescIn->hDevCookie;
180 psStubPBDescIn->ui32RefCount--;
181 if (psStubPBDescIn->ui32RefCount == 0)
183 List_PVRSRV_STUB_PBDESC_Remove(psStubPBDescIn);
184 for(i=0 ; i<psStubPBDescIn->ui32SubKernelMemInfosCount; i++)
187 PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie,
188 psStubPBDescIn->ppsSubKernelMemInfos[i]);
191 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
192 sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDescIn->ui32SubKernelMemInfosCount,
193 psStubPBDescIn->ppsSubKernelMemInfos,
195 psStubPBDescIn->ppsSubKernelMemInfos = IMG_NULL;
197 PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psBlockKernelMemInfo);
199 PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWBlockKernelMemInfo);
201 PVRSRVFreeDeviceMemKM(psStubPBDescIn->hDevCookie, psStubPBDescIn->psHWPBDescKernelMemInfo);
203 PVRSRVFreeSharedSysMemoryKM(psStubPBDescIn->psSharedPBDescKernelMemInfo);
205 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
206 sizeof(PVRSRV_STUB_PBDESC),
212 SGXCleanupRequest(psDeviceNode,
214 PVRSRV_CLEANUPCMD_PB);
220 static PVRSRV_ERROR SGXCleanupSharedPBDescCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
222 PVRSRV_STUB_PBDESC *psStubPBDesc = (PVRSRV_STUB_PBDESC *)pvParam;
224 PVR_UNREFERENCED_PARAMETER(ui32Param);
226 return SGXCleanupSharedPBDescKM(psStubPBDesc);
229 static PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(IMG_PVOID pvParam, IMG_UINT32 ui32Param)
232 PVRSRV_PER_PROCESS_DATA *psPerProc = (PVRSRV_PER_PROCESS_DATA *)pvParam;
233 PVR_ASSERT(psPerProc == psPerProcCreateSharedPB);
235 PVR_UNREFERENCED_PARAMETER(pvParam);
238 PVR_UNREFERENCED_PARAMETER(ui32Param);
240 psPerProcCreateSharedPB = IMG_NULL;
241 psResItemCreateSharedPB = IMG_NULL;
247 IMG_EXPORT PVRSRV_ERROR
248 SGXUnrefSharedPBDescKM(IMG_HANDLE hSharedPBDesc)
250 PVR_ASSERT(hSharedPBDesc != IMG_NULL);
252 return ResManFreeResByPtr(hSharedPBDesc);
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)
268 PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL;
269 PVRSRV_ERROR eRet = PVRSRV_ERROR_GENERIC;
271 PVRSRV_SGXDEV_INFO *psSGXDevInfo;
272 PRESMAN_ITEM psResItem;
275 if (psPerProcCreateSharedPB != psPerProc)
281 PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL);
283 ResManFreeResByPtr(psResItemCreateSharedPB);
285 PVR_ASSERT(psResItemCreateSharedPB == IMG_NULL);
286 PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
289 psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
291 psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
292 if (psStubPBDesc != IMG_NULL)
294 if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
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));
303 psResItem = ResManRegisterRes(psPerProc->hResManContext,
304 RESMAN_TYPE_SHARED_PB_DESC,
307 &SGXCleanupSharedPBDescCallback);
308 if (psResItem == IMG_NULL)
310 PVR_DPF((PVR_DBG_ERROR,
311 "SGXAddSharedPBDescKM: "
312 "Failed to register existing shared "
313 "PBDesc with the resource manager"));
318 psStubPBDesc->ui32RefCount++;
320 *phSharedPBDesc = (IMG_HANDLE)psResItem;
325 if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
326 sizeof(PVRSRV_STUB_PBDESC),
327 (IMG_VOID **)&psStubPBDesc,
329 "Stub Parameter Buffer Description") != PVRSRV_OK)
331 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc "
333 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
338 psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
340 if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
341 sizeof(PVRSRV_KERNEL_MEM_INFO *)
342 * ui32SharedPBDescSubKernelMemInfosCount,
343 (IMG_VOID **)&psStubPBDesc->ppsSubKernelMemInfos,
345 "Array of Kernel Memory Info") != PVRSRV_OK)
347 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
349 "StubPBDesc->ppsSubKernelMemInfos"));
350 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
354 if(PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo)
360 if(PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo)
366 if(PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo)
372 if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo)
378 psStubPBDesc->ui32RefCount = 1;
379 psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
380 psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
381 psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
382 psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;
383 psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo;
385 psStubPBDesc->ui32SubKernelMemInfosCount =
386 ui32SharedPBDescSubKernelMemInfosCount;
387 for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
389 psStubPBDesc->ppsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i];
390 if(PVRSRVDissociateMemFromResmanKM(ppsSharedPBDescSubKernelMemInfos[i])
393 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
394 "Failed to dissociate shared PBDesc "
400 psResItem = ResManRegisterRes(psPerProc->hResManContext,
401 RESMAN_TYPE_SHARED_PB_DESC,
404 &SGXCleanupSharedPBDescCallback);
405 if (psResItem == IMG_NULL)
407 PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
408 "Failed to register shared PBDesc "
409 " with the resource manager"));
412 psStubPBDesc->hDevCookie = hDevCookie;
415 List_PVRSRV_STUB_PBDESC_Insert(&(psSGXDevInfo->psStubPBDescListKM),
418 *phSharedPBDesc = (IMG_HANDLE)psResItem;
425 if(psStubPBDesc->ppsSubKernelMemInfos)
427 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
428 sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
429 psStubPBDesc->ppsSubKernelMemInfos,
431 psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
433 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
434 sizeof(PVRSRV_STUB_PBDESC),
441 for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
443 PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]);
446 PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
447 PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);
449 PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);
450 PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo);