1 /**********************************************************************
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
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.
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.
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.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25 ******************************************************************************/
29 #include "services_headers.h"
30 #include "sgxapi_km.h"
32 #include "sgxinfokm.h"
33 #include "pvr_bridge_km.h"
34 #include "sgx_bridge_km.h"
35 #include "pvr_pdump.h"
38 static struct RESMAN_ITEM *psResItemCreateSharedPB;
39 static struct PVRSRV_PER_PROCESS_DATA *psPerProcCreateSharedPB;
41 static enum PVRSRV_ERROR SGXCleanupSharedPBDescCallback(void *pvParam,
43 static enum PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(void *pvParam,
46 enum PVRSRV_ERROR SGXFindSharedPBDescKM(
47 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
48 void *hDevCookie, IMG_BOOL bLockOnFailure,
49 u32 ui32TotalPBSize, void **phSharedPBDesc,
50 struct PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo,
51 struct PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo,
52 struct PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo,
53 struct PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos,
54 u32 *ui32SharedPBDescSubKernelMemInfosCount)
56 struct PVRSRV_STUB_PBDESC *psStubPBDesc;
57 struct PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = NULL;
58 struct PVRSRV_SGXDEV_INFO *psSGXDevInfo;
59 enum PVRSRV_ERROR eError;
61 psSGXDevInfo = ((struct PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
63 psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
64 if (psStubPBDesc != NULL) {
66 struct RESMAN_ITEM *psResItem;
68 if (psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize) {
69 PVR_DPF(PVR_DBG_WARNING, "SGXFindSharedPBDescKM: "
70 "Shared PB requested with different size "
71 "(0x%x) from existing shared PB (0x%x) - "
72 "requested size ignored",
74 psStubPBDesc->ui32TotalPBSize);
77 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
78 sizeof(struct PVRSRV_KERNEL_MEM_INFO *) *
79 psStubPBDesc->ui32SubKernelMemInfosCount,
80 (void **) &ppsSharedPBDescSubKernelMemInfos,
82 PVR_DPF(PVR_DBG_ERROR,
83 "SGXFindSharedPBDescKM: OSAllocMem failed");
85 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
89 psResItem = ResManRegisterRes(psPerProc->hResManContext,
90 RESMAN_TYPE_SHARED_PB_DESC,
92 &SGXCleanupSharedPBDescCallback);
94 if (psResItem == NULL) {
95 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
96 sizeof(struct PVRSRV_KERNEL_MEM_INFO *)*
97 psStubPBDesc->ui32SubKernelMemInfosCount,
98 ppsSharedPBDescSubKernelMemInfos, NULL);
100 PVR_DPF(PVR_DBG_ERROR, "SGXFindSharedPBDescKM: "
101 "ResManRegisterRes failed");
102 eError = PVRSRV_ERROR_GENERIC;
106 *ppsSharedPBDescKernelMemInfo =
107 psStubPBDesc->psSharedPBDescKernelMemInfo;
108 *ppsHWPBDescKernelMemInfo =
109 psStubPBDesc->psHWPBDescKernelMemInfo;
110 *ppsBlockKernelMemInfo =
111 psStubPBDesc->psBlockKernelMemInfo;
113 *ui32SharedPBDescSubKernelMemInfosCount =
114 psStubPBDesc->ui32SubKernelMemInfosCount;
116 *pppsSharedPBDescSubKernelMemInfos =
117 ppsSharedPBDescSubKernelMemInfos;
120 i < psStubPBDesc->ui32SubKernelMemInfosCount;
122 ppsSharedPBDescSubKernelMemInfos[i] =
123 psStubPBDesc->ppsSubKernelMemInfos[i];
126 psStubPBDesc->ui32RefCount++;
127 *phSharedPBDesc = (void *) psResItem;
132 if (bLockOnFailure) {
133 if (psResItemCreateSharedPB == NULL) {
134 psResItemCreateSharedPB =
135 ResManRegisterRes(psPerProc->hResManContext,
136 RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
138 &SGXCleanupSharedPBDescCreateLockCallback);
140 if (psResItemCreateSharedPB == NULL) {
141 PVR_DPF(PVR_DBG_ERROR, "SGXFindSharedPBDescKM: "
142 "ResManRegisterRes failed");
144 eError = PVRSRV_ERROR_GENERIC;
147 PVR_ASSERT(psPerProcCreateSharedPB == NULL);
148 psPerProcCreateSharedPB = psPerProc;
150 eError = PVRSRV_ERROR_PROCESSING_BLOCKED;
154 *phSharedPBDesc = NULL;
159 static enum PVRSRV_ERROR SGXCleanupSharedPBDescKM(
160 struct PVRSRV_STUB_PBDESC *psStubPBDescIn)
162 struct PVRSRV_STUB_PBDESC **ppsStubPBDesc;
164 struct PVRSRV_DEVICE_NODE *psDeviceNode;
165 struct PVRSRV_SGXDEV_INFO *psSGXDevInfo;
167 psDeviceNode = (struct PVRSRV_DEVICE_NODE *)psStubPBDescIn->hDevCookie;
168 psSGXDevInfo = (struct PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
170 for (ppsStubPBDesc = (struct PVRSRV_STUB_PBDESC **)
171 &psSGXDevInfo->psStubPBDescListKM;
172 *ppsStubPBDesc != NULL;
173 ppsStubPBDesc = &(*ppsStubPBDesc)->psNext) {
174 struct PVRSRV_STUB_PBDESC *psStubPBDesc = *ppsStubPBDesc;
176 if (psStubPBDesc == psStubPBDescIn) {
177 psStubPBDesc->ui32RefCount--;
178 PVR_ASSERT((s32) psStubPBDesc->ui32RefCount >= 0);
180 if (psStubPBDesc->ui32RefCount == 0) {
181 *ppsStubPBDesc = psStubPBDesc->psNext;
184 i < psStubPBDesc->ui32SubKernelMemInfosCount;
186 PVRSRVFreeDeviceMemKM(psStubPBDesc->
188 psStubPBDesc->ppsSubKernelMemInfos[i]);
190 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
191 sizeof(struct PVRSRV_KERNEL_MEM_INFO *)*
193 ui32SubKernelMemInfosCount,
194 psStubPBDesc->ppsSubKernelMemInfos,
197 PVRSRVFreeSharedSysMemoryKM(psStubPBDesc->
198 psBlockKernelMemInfo);
200 PVRSRVFreeDeviceMemKM(psStubPBDesc->hDevCookie,
202 psHWPBDescKernelMemInfo);
204 PVRSRVFreeSharedSysMemoryKM(psStubPBDesc->
205 psSharedPBDescKernelMemInfo);
207 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
208 sizeof(struct PVRSRV_STUB_PBDESC),
211 SGXCleanupRequest(psDeviceNode, NULL,
212 PVRSRV_USSE_EDM_RESMAN_CLEANUP_SHAREDPBDESC);
218 return PVRSRV_ERROR_INVALID_PARAMS;
221 static enum PVRSRV_ERROR SGXCleanupSharedPBDescCallback(void *pvParam,
224 struct PVRSRV_STUB_PBDESC *psStubPBDesc =
225 (struct PVRSRV_STUB_PBDESC *)pvParam;
227 PVR_UNREFERENCED_PARAMETER(ui32Param);
229 return SGXCleanupSharedPBDescKM(psStubPBDesc);
232 static enum PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(void *pvParam,
235 #ifdef CONFIG_PVR_DEBUG_EXTRA
236 struct PVRSRV_PER_PROCESS_DATA *psPerProc =
237 (struct PVRSRV_PER_PROCESS_DATA *)pvParam;
238 PVR_ASSERT(psPerProc == psPerProcCreateSharedPB);
240 PVR_UNREFERENCED_PARAMETER(pvParam);
243 PVR_UNREFERENCED_PARAMETER(ui32Param);
245 psPerProcCreateSharedPB = NULL;
246 psResItemCreateSharedPB = NULL;
251 enum PVRSRV_ERROR SGXUnrefSharedPBDescKM(void *hSharedPBDesc)
253 PVR_ASSERT(hSharedPBDesc != NULL);
255 ResManFreeResByPtr(hSharedPBDesc);
260 enum PVRSRV_ERROR SGXAddSharedPBDescKM(
261 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
263 struct PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo,
264 struct PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo,
265 struct PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo,
266 u32 ui32TotalPBSize, void **phSharedPBDesc,
267 struct PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos,
268 u32 ui32SharedPBDescSubKernelMemInfosCount)
270 struct PVRSRV_STUB_PBDESC *psStubPBDesc = NULL;
271 enum PVRSRV_ERROR eRet = PVRSRV_ERROR_GENERIC;
273 struct PVRSRV_SGXDEV_INFO *psSGXDevInfo;
274 struct RESMAN_ITEM *psResItem;
276 if (psPerProcCreateSharedPB != psPerProc) {
279 PVR_ASSERT(psResItemCreateSharedPB != NULL);
281 ResManFreeResByPtr(psResItemCreateSharedPB);
283 PVR_ASSERT(psResItemCreateSharedPB == NULL);
284 PVR_ASSERT(psPerProcCreateSharedPB == NULL);
287 psSGXDevInfo = (struct PVRSRV_SGXDEV_INFO *)
288 ((struct PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
290 psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
291 if (psStubPBDesc != NULL) {
292 if (psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize) {
293 PVR_DPF(PVR_DBG_WARNING, "SGXAddSharedPBDescKM: "
294 "Shared PB requested with different size "
295 "(0x%x) from existing shared PB (0x%x) - "
296 "requested size ignored",
298 psStubPBDesc->ui32TotalPBSize);
302 psResItem = ResManRegisterRes(psPerProc->hResManContext,
303 RESMAN_TYPE_SHARED_PB_DESC,
305 &SGXCleanupSharedPBDescCallback);
306 if (psResItem == NULL) {
307 PVR_DPF(PVR_DBG_ERROR,
308 "SGXAddSharedPBDescKM: "
309 "Failed to register existing shared "
310 "PBDesc with the resource manager");
314 psStubPBDesc->ui32RefCount++;
316 *phSharedPBDesc = (void *) psResItem;
321 if (OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
322 sizeof(struct PVRSRV_STUB_PBDESC),
323 (void **)&psStubPBDesc, NULL) != PVRSRV_OK) {
324 PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc "
326 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
330 psStubPBDesc->ppsSubKernelMemInfos = NULL;
332 if (OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
333 sizeof(struct PVRSRV_KERNEL_MEM_INFO *) *
334 ui32SharedPBDescSubKernelMemInfosCount,
335 (void **)&psStubPBDesc->ppsSubKernelMemInfos, NULL) !=
337 PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
339 "StubPBDesc->ppsSubKernelMemInfos");
340 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
344 if (PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo)
348 if (PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo)
352 if (PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo)
356 psStubPBDesc->ui32RefCount = 1;
357 psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
358 psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
359 psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
360 psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;
362 psStubPBDesc->ui32SubKernelMemInfosCount =
363 ui32SharedPBDescSubKernelMemInfosCount;
364 for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) {
365 psStubPBDesc->ppsSubKernelMemInfos[i] =
366 ppsSharedPBDescSubKernelMemInfos[i];
367 if (PVRSRVDissociateMemFromResmanKM
368 (ppsSharedPBDescSubKernelMemInfos[i]) != PVRSRV_OK) {
369 PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
370 "Failed to dissociate shared PBDesc "
376 psResItem = ResManRegisterRes(psPerProc->hResManContext,
377 RESMAN_TYPE_SHARED_PB_DESC,
379 0, &SGXCleanupSharedPBDescCallback);
380 if (psResItem == NULL) {
381 PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
382 "Failed to register shared PBDesc "
383 " with the resource manager");
386 psStubPBDesc->hDevCookie = hDevCookie;
388 psStubPBDesc->psNext = psSGXDevInfo->psStubPBDescListKM;
389 psSGXDevInfo->psStubPBDescListKM = psStubPBDesc;
391 *phSharedPBDesc = (void *) psResItem;
397 if (psStubPBDesc->ppsSubKernelMemInfos) {
398 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
399 sizeof(struct PVRSRV_KERNEL_MEM_INFO *) *
400 ui32SharedPBDescSubKernelMemInfosCount,
401 psStubPBDesc->ppsSubKernelMemInfos, NULL);
403 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
404 sizeof(struct PVRSRV_STUB_PBDESC), psStubPBDesc,
409 for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
410 PVRSRVFreeDeviceMemKM(hDevCookie,
411 ppsSharedPBDescSubKernelMemInfos[i]);
413 PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
414 PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);
416 PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);