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"
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 = PVRSRV_ERROR_GENERIC;
61 psSGXDevInfo = ((struct PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
63 psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
64 if (psStubPBDesc != NULL) {
65 if (psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
66 PVR_DPF(PVR_DBG_WARNING, "SGXFindSharedPBDescKM: "
67 "Shared PB requested with different size "
68 "(0x%x) from existing shared PB (0x%x) - "
69 "requested size ignored",
71 psStubPBDesc->ui32TotalPBSize);
74 struct RESMAN_ITEM *psResItem;
76 if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
77 sizeof(struct PVRSRV_KERNEL_MEM_INFO *)*
78 psStubPBDesc->ui32SubKernelMemInfosCount,
80 ppsSharedPBDescSubKernelMemInfos,
82 PVR_DPF(PVR_DBG_ERROR, "SGXFindSharedPBDescKM:"
83 " OSAllocMem failed");
84 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
88 psResItem = ResManRegisterRes(psPerProc->hResManContext,
89 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");
103 eError = PVRSRV_ERROR_GENERIC;
107 *ppsSharedPBDescKernelMemInfo =
108 psStubPBDesc->psSharedPBDescKernelMemInfo;
109 *ppsHWPBDescKernelMemInfo =
110 psStubPBDesc->psHWPBDescKernelMemInfo;
111 *ppsBlockKernelMemInfo =
112 psStubPBDesc->psBlockKernelMemInfo;
114 *ui32SharedPBDescSubKernelMemInfosCount =
115 psStubPBDesc->ui32SubKernelMemInfosCount;
117 *pppsSharedPBDescSubKernelMemInfos =
118 ppsSharedPBDescSubKernelMemInfos;
121 i < psStubPBDesc->ui32SubKernelMemInfosCount;
123 ppsSharedPBDescSubKernelMemInfos[i] =
124 psStubPBDesc->ppsSubKernelMemInfos[i];
126 psStubPBDesc->ui32RefCount++;
127 *phSharedPBDesc = (void *) psResItem;
133 if (bLockOnFailure) {
134 if (psResItemCreateSharedPB == NULL) {
135 psResItemCreateSharedPB =
136 ResManRegisterRes(psPerProc->hResManContext,
137 RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
139 &SGXCleanupSharedPBDescCreateLockCallback);
141 if (psResItemCreateSharedPB == NULL) {
142 PVR_DPF(PVR_DBG_ERROR, "SGXFindSharedPBDescKM:"
143 " ResManRegisterRes failed");
145 eError = PVRSRV_ERROR_GENERIC;
148 PVR_ASSERT(psPerProcCreateSharedPB == NULL);
149 psPerProcCreateSharedPB = psPerProc;
151 eError = PVRSRV_ERROR_PROCESSING_BLOCKED;
155 *phSharedPBDesc = NULL;
160 static enum PVRSRV_ERROR
161 SGXCleanupSharedPBDescKM(struct PVRSRV_STUB_PBDESC *psStubPBDescIn)
163 struct PVRSRV_STUB_PBDESC **ppsStubPBDesc;
165 struct PVRSRV_SGXDEV_INFO *psSGXDevInfo;
167 psSGXDevInfo = (struct PVRSRV_SGXDEV_INFO *)
168 ((struct PVRSRV_DEVICE_NODE *)psStubPBDescIn->hDevCookie)->
171 for (ppsStubPBDesc = (struct PVRSRV_STUB_PBDESC **)
172 &psSGXDevInfo->psStubPBDescListKM;
173 *ppsStubPBDesc != NULL;
174 ppsStubPBDesc = &(*ppsStubPBDesc)->psNext) {
175 struct PVRSRV_STUB_PBDESC *psStubPBDesc = *ppsStubPBDesc;
177 if (psStubPBDesc == psStubPBDescIn) {
178 psStubPBDesc->ui32RefCount--;
179 PVR_ASSERT((s32) psStubPBDesc->ui32RefCount >= 0);
181 if (psStubPBDesc->ui32RefCount == 0) {
182 struct PVRSRV_SGX_HOST_CTL *psSGXHostCtl =
183 (struct PVRSRV_SGX_HOST_CTL *)
184 psSGXDevInfo->psSGXHostCtl;
186 void *hUniqueTag = MAKEUNIQUETAG(
187 psSGXDevInfo->psKernelSGXHostCtlMemInfo);
189 psSGXHostCtl->sTAHWPBDesc.uiAddr = 0;
190 psSGXHostCtl->s3DHWPBDesc.uiAddr = 0;
192 PDUMPCOMMENT("TA/3D CCB Control - "
193 "Reset HW PBDesc records");
195 psSGXDevInfo->psKernelSGXHostCtlMemInfo,
196 offsetof(struct PVRSRV_SGX_HOST_CTL,
198 sizeof(struct IMG_DEV_VIRTADDR),
199 PDUMP_FLAGS_CONTINUOUS, hUniqueTag);
201 psSGXDevInfo->psKernelSGXHostCtlMemInfo,
202 offsetof(struct PVRSRV_SGX_HOST_CTL,
204 sizeof(struct IMG_DEV_VIRTADDR),
205 PDUMP_FLAGS_CONTINUOUS, hUniqueTag);
207 *ppsStubPBDesc = psStubPBDesc->psNext;
210 i < psStubPBDesc->ui32SubKernelMemInfosCount;
212 PVRSRVFreeDeviceMemKM(psStubPBDesc->
214 psStubPBDesc->ppsSubKernelMemInfos[i]);
216 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
217 sizeof(struct PVRSRV_KERNEL_MEM_INFO *)*
219 ui32SubKernelMemInfosCount,
220 psStubPBDesc->ppsSubKernelMemInfos,
223 PVRSRVFreeSharedSysMemoryKM(psStubPBDesc->
224 psBlockKernelMemInfo);
226 PVRSRVFreeDeviceMemKM(psStubPBDesc->hDevCookie,
228 psHWPBDescKernelMemInfo);
230 PVRSRVFreeSharedSysMemoryKM(psStubPBDesc->
231 psSharedPBDescKernelMemInfo);
233 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
234 sizeof(struct PVRSRV_STUB_PBDESC),
242 return PVRSRV_ERROR_INVALID_PARAMS;
245 static enum PVRSRV_ERROR SGXCleanupSharedPBDescCallback(void *pvParam,
248 struct PVRSRV_STUB_PBDESC *psStubPBDesc =
249 (struct PVRSRV_STUB_PBDESC *)pvParam;
251 PVR_UNREFERENCED_PARAMETER(ui32Param);
253 return SGXCleanupSharedPBDescKM(psStubPBDesc);
256 static enum PVRSRV_ERROR SGXCleanupSharedPBDescCreateLockCallback(void *pvParam,
260 struct PVRSRV_PER_PROCESS_DATA *psPerProc =
261 (struct PVRSRV_PER_PROCESS_DATA *)pvParam;
263 PVR_UNREFERENCED_PARAMETER(pvParam);
266 PVR_UNREFERENCED_PARAMETER(ui32Param);
268 PVR_ASSERT(psPerProc == psPerProcCreateSharedPB);
270 psPerProcCreateSharedPB = NULL;
271 psResItemCreateSharedPB = NULL;
276 enum PVRSRV_ERROR SGXUnrefSharedPBDescKM(void *hSharedPBDesc)
278 PVR_ASSERT(hSharedPBDesc != NULL);
280 ResManFreeResByPtr(hSharedPBDesc);
284 enum PVRSRV_ERROR SGXAddSharedPBDescKM(
285 struct PVRSRV_PER_PROCESS_DATA *psPerProc,
287 struct PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo,
288 struct PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo,
289 struct PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo,
290 u32 ui32TotalPBSize, void **phSharedPBDesc,
291 struct PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos,
292 u32 ui32SharedPBDescSubKernelMemInfosCount)
294 struct PVRSRV_STUB_PBDESC *psStubPBDesc = NULL;
295 enum PVRSRV_ERROR eRet = PVRSRV_ERROR_GENERIC;
297 struct PVRSRV_SGXDEV_INFO *psSGXDevInfo;
298 struct RESMAN_ITEM *psResItem;
300 if (psPerProcCreateSharedPB != psPerProc) {
303 PVR_ASSERT(psResItemCreateSharedPB != NULL);
305 ResManFreeResByPtr(psResItemCreateSharedPB);
307 PVR_ASSERT(psResItemCreateSharedPB == NULL);
308 PVR_ASSERT(psPerProcCreateSharedPB == NULL);
311 psSGXDevInfo = (struct PVRSRV_SGXDEV_INFO *)
312 ((struct PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;
314 psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
315 if (psStubPBDesc != NULL) {
316 if (psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
317 PVR_DPF(PVR_DBG_WARNING, "SGXAddSharedPBDescKM: "
318 "Shared PB requested with different size "
319 "(0x%x) from existing shared PB (0x%x) - "
320 "requested size ignored",
322 psStubPBDesc->ui32TotalPBSize);
326 psResItem = ResManRegisterRes(psPerProc->hResManContext,
327 RESMAN_TYPE_SHARED_PB_DESC,
329 &SGXCleanupSharedPBDescCallback);
330 if (psResItem == NULL) {
331 PVR_DPF(PVR_DBG_ERROR,
332 "SGXAddSharedPBDescKM: "
333 "Failed to register existing shared "
334 "PBDesc with the resource manager");
338 psStubPBDesc->ui32RefCount++;
340 *phSharedPBDesc = (void *) psResItem;
346 if (OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
347 sizeof(struct PVRSRV_STUB_PBDESC),
348 (void **)&psStubPBDesc, NULL) != PVRSRV_OK) {
349 PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc "
351 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
355 psStubPBDesc->ppsSubKernelMemInfos = NULL;
357 if (OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
358 sizeof(struct PVRSRV_KERNEL_MEM_INFO *) *
359 ui32SharedPBDescSubKernelMemInfosCount,
360 (void **)&psStubPBDesc->ppsSubKernelMemInfos, NULL) !=
362 PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
364 "StubPBDesc->ppsSubKernelMemInfos");
365 eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
369 if (PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo)
373 if (PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo)
377 if (PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo)
381 psStubPBDesc->ui32RefCount = 1;
382 psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
383 psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
384 psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
385 psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;
387 psStubPBDesc->ui32SubKernelMemInfosCount =
388 ui32SharedPBDescSubKernelMemInfosCount;
389 for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) {
390 psStubPBDesc->ppsSubKernelMemInfos[i] =
391 ppsSharedPBDescSubKernelMemInfos[i];
392 if (PVRSRVDissociateMemFromResmanKM
393 (ppsSharedPBDescSubKernelMemInfos[i])
395 PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
396 "Failed to dissociate shared PBDesc "
402 psResItem = ResManRegisterRes(psPerProc->hResManContext,
403 RESMAN_TYPE_SHARED_PB_DESC,
405 0, &SGXCleanupSharedPBDescCallback);
406 if (psResItem == NULL) {
407 PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
408 "Failed to register shared PBDesc "
409 " with the resource manager");
412 psStubPBDesc->hDevCookie = hDevCookie;
414 psStubPBDesc->psNext = psSGXDevInfo->psStubPBDescListKM;
415 psSGXDevInfo->psStubPBDescListKM = psStubPBDesc;
417 *phSharedPBDesc = (void *) psResItem;
423 if (psStubPBDesc->ppsSubKernelMemInfos)
424 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
425 sizeof(struct PVRSRV_KERNEL_MEM_INFO *) *
426 ui32SharedPBDescSubKernelMemInfosCount,
427 psStubPBDesc->ppsSubKernelMemInfos, NULL);
428 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
429 sizeof(struct PVRSRV_STUB_PBDESC), psStubPBDesc,
434 for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
435 PVRSRVFreeDeviceMemKM(hDevCookie,
436 ppsSharedPBDescSubKernelMemInfos[i]);
438 PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
439 PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);
441 PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);