aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/devicemem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/devicemem.c')
-rw-r--r--drivers/gpu/pvr/devicemem.c1554
1 files changed, 1554 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/devicemem.c b/drivers/gpu/pvr/devicemem.c
new file mode 100644
index 00000000000..f15ff9143eb
--- /dev/null
+++ b/drivers/gpu/pvr/devicemem.c
@@ -0,0 +1,1554 @@
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 "buffer_manager.h"
31#include "pdump_km.h"
32#include "pvr_bridge_km.h"
33
34static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie,
35 IMG_HANDLE hDevMemHeap,
36 IMG_UINT32 ui32Flags,
37 IMG_SIZE_T ui32Size,
38 IMG_SIZE_T ui32Alignment,
39 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo);
40
41typedef struct _RESMAN_MAP_DEVICE_MEM_DATA_
42{
43
44 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
45
46 PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo;
47} RESMAN_MAP_DEVICE_MEM_DATA;
48
49typedef struct _PVRSRV_DC_MAPINFO_
50{
51 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
52 PVRSRV_DEVICE_NODE *psDeviceNode;
53 IMG_UINT32 ui32RangeIndex;
54 IMG_UINT32 ui32TilingStride;
55} PVRSRV_DC_MAPINFO;
56
57
58IMG_EXPORT
59PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapsKM(IMG_HANDLE hDevCookie,
60 PVRSRV_HEAP_INFO *psHeapInfo)
61{
62 PVRSRV_DEVICE_NODE *psDeviceNode;
63 IMG_UINT32 ui32HeapCount;
64 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
65 IMG_UINT32 i;
66
67 if (hDevCookie == IMG_NULL)
68 {
69 PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapsKM: hDevCookie invalid"));
70 PVR_DBG_BREAK;
71 return PVRSRV_ERROR_INVALID_PARAMS;
72 }
73
74 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
75
76
77 ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
78 psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
79
80
81 PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
82
83
84 for(i=0; i<ui32HeapCount; i++)
85 {
86
87 psHeapInfo[i].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
88 psHeapInfo[i].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
89 psHeapInfo[i].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
90 psHeapInfo[i].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
91 psHeapInfo[i].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
92 }
93
94 for(; i < PVRSRV_MAX_CLIENT_HEAPS; i++)
95 {
96 OSMemSet(psHeapInfo + i, 0, sizeof(*psHeapInfo));
97 psHeapInfo[i].ui32HeapID = (IMG_UINT32)PVRSRV_UNDEFINED_HEAP_ID;
98 }
99
100 return PVRSRV_OK;
101}
102
103IMG_EXPORT
104PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateDeviceMemContextKM(IMG_HANDLE hDevCookie,
105 PVRSRV_PER_PROCESS_DATA *psPerProc,
106 IMG_HANDLE *phDevMemContext,
107 IMG_UINT32 *pui32ClientHeapCount,
108 PVRSRV_HEAP_INFO *psHeapInfo,
109 IMG_BOOL *pbCreated,
110 IMG_BOOL *pbShared)
111{
112 PVRSRV_DEVICE_NODE *psDeviceNode;
113 IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
114 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
115 IMG_HANDLE hDevMemContext;
116 IMG_HANDLE hDevMemHeap;
117 IMG_DEV_PHYADDR sPDDevPAddr;
118 IMG_UINT32 i;
119
120#if !defined(PVR_SECURE_HANDLES)
121 PVR_UNREFERENCED_PARAMETER(pbShared);
122#endif
123
124 if (hDevCookie == IMG_NULL)
125 {
126 PVR_DPF((PVR_DBG_ERROR, "PVRSRVCreateDeviceMemContextKM: hDevCookie invalid"));
127 PVR_DBG_BREAK;
128 return PVRSRV_ERROR_INVALID_PARAMS;
129 }
130
131 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
132
133
134
135 ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
136 psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
137
138
139
140 PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
141
142
143
144 hDevMemContext = BM_CreateContext(psDeviceNode,
145 &sPDDevPAddr,
146 psPerProc,
147 pbCreated);
148 if (hDevMemContext == IMG_NULL)
149 {
150 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateDeviceMemContextKM: Failed BM_CreateContext"));
151 return PVRSRV_ERROR_OUT_OF_MEMORY;
152 }
153
154
155 for(i=0; i<ui32HeapCount; i++)
156 {
157 switch(psDeviceMemoryHeap[i].DevMemHeapType)
158 {
159 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
160 {
161
162 psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
163 psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
164 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
165 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
166 psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
167#if defined(PVR_SECURE_HANDLES)
168 pbShared[ui32ClientHeapCount] = IMG_TRUE;
169#endif
170 ui32ClientHeapCount++;
171 break;
172 }
173 case DEVICE_MEMORY_HEAP_PERCONTEXT:
174 {
175 hDevMemHeap = BM_CreateHeap(hDevMemContext,
176 &psDeviceMemoryHeap[i]);
177
178
179 psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
180 psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
181 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
182 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
183 psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
184#if defined(PVR_SECURE_HANDLES)
185 pbShared[ui32ClientHeapCount] = IMG_FALSE;
186#endif
187
188 ui32ClientHeapCount++;
189 break;
190 }
191 }
192 }
193
194
195 *pui32ClientHeapCount = ui32ClientHeapCount;
196 *phDevMemContext = hDevMemContext;
197
198 return PVRSRV_OK;
199}
200
201IMG_EXPORT
202PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyDeviceMemContextKM(IMG_HANDLE hDevCookie,
203 IMG_HANDLE hDevMemContext,
204 IMG_BOOL *pbDestroyed)
205{
206 PVR_UNREFERENCED_PARAMETER(hDevCookie);
207
208 return BM_DestroyContext(hDevMemContext, pbDestroyed);
209}
210
211
212
213
214IMG_EXPORT
215PVRSRV_ERROR IMG_CALLCONV PVRSRVGetDeviceMemHeapInfoKM(IMG_HANDLE hDevCookie,
216 IMG_HANDLE hDevMemContext,
217 IMG_UINT32 *pui32ClientHeapCount,
218 PVRSRV_HEAP_INFO *psHeapInfo,
219 IMG_BOOL *pbShared)
220{
221 PVRSRV_DEVICE_NODE *psDeviceNode;
222 IMG_UINT32 ui32HeapCount, ui32ClientHeapCount=0;
223 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
224 IMG_HANDLE hDevMemHeap;
225 IMG_UINT32 i;
226
227#if !defined(PVR_SECURE_HANDLES)
228 PVR_UNREFERENCED_PARAMETER(pbShared);
229#endif
230
231 if (hDevCookie == IMG_NULL)
232 {
233 PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetDeviceMemHeapInfoKM: hDevCookie invalid"));
234 PVR_DBG_BREAK;
235 return PVRSRV_ERROR_INVALID_PARAMS;
236 }
237
238 psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;
239
240
241
242 ui32HeapCount = psDeviceNode->sDevMemoryInfo.ui32HeapCount;
243 psDeviceMemoryHeap = psDeviceNode->sDevMemoryInfo.psDeviceMemoryHeap;
244
245
246
247 PVR_ASSERT(ui32HeapCount <= PVRSRV_MAX_CLIENT_HEAPS);
248
249
250 for(i=0; i<ui32HeapCount; i++)
251 {
252 switch(psDeviceMemoryHeap[i].DevMemHeapType)
253 {
254 case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
255 {
256
257 psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
258 psHeapInfo[ui32ClientHeapCount].hDevMemHeap = psDeviceMemoryHeap[i].hDevMemHeap;
259 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
260 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
261 psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
262#if defined(PVR_SECURE_HANDLES)
263 pbShared[ui32ClientHeapCount] = IMG_TRUE;
264#endif
265 ui32ClientHeapCount++;
266 break;
267 }
268 case DEVICE_MEMORY_HEAP_PERCONTEXT:
269 {
270 hDevMemHeap = BM_CreateHeap(hDevMemContext,
271 &psDeviceMemoryHeap[i]);
272
273
274 psHeapInfo[ui32ClientHeapCount].ui32HeapID = psDeviceMemoryHeap[i].ui32HeapID;
275 psHeapInfo[ui32ClientHeapCount].hDevMemHeap = hDevMemHeap;
276 psHeapInfo[ui32ClientHeapCount].sDevVAddrBase = psDeviceMemoryHeap[i].sDevVAddrBase;
277 psHeapInfo[ui32ClientHeapCount].ui32HeapByteSize = psDeviceMemoryHeap[i].ui32HeapSize;
278 psHeapInfo[ui32ClientHeapCount].ui32Attribs = psDeviceMemoryHeap[i].ui32Attribs;
279#if defined(PVR_SECURE_HANDLES)
280 pbShared[ui32ClientHeapCount] = IMG_FALSE;
281#endif
282
283 ui32ClientHeapCount++;
284 break;
285 }
286 }
287 }
288
289
290 *pui32ClientHeapCount = ui32ClientHeapCount;
291
292 return PVRSRV_OK;
293}
294
295
296static PVRSRV_ERROR AllocDeviceMem(IMG_HANDLE hDevCookie,
297 IMG_HANDLE hDevMemHeap,
298 IMG_UINT32 ui32Flags,
299 IMG_SIZE_T ui32Size,
300 IMG_SIZE_T ui32Alignment,
301 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
302{
303 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
304 BM_HANDLE hBuffer;
305
306 PVRSRV_MEMBLK *psMemBlock;
307 IMG_BOOL bBMError;
308
309 PVR_UNREFERENCED_PARAMETER(hDevCookie);
310
311 *ppsMemInfo = IMG_NULL;
312
313 if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
314 sizeof(PVRSRV_KERNEL_MEM_INFO),
315 (IMG_VOID **)&psMemInfo, IMG_NULL,
316 "Kernel Memory Info") != PVRSRV_OK)
317 {
318 PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: Failed to alloc memory for block"));
319 return (PVRSRV_ERROR_OUT_OF_MEMORY);
320 }
321
322 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
323
324 psMemBlock = &(psMemInfo->sMemBlk);
325
326
327 psMemInfo->ui32Flags = ui32Flags | PVRSRV_MEM_RAM_BACKED_ALLOCATION;
328
329 bBMError = BM_Alloc (hDevMemHeap,
330 IMG_NULL,
331 ui32Size,
332 &psMemInfo->ui32Flags,
333 IMG_CAST_TO_DEVVADDR_UINT(ui32Alignment),
334 &hBuffer);
335
336 if (!bBMError)
337 {
338 PVR_DPF((PVR_DBG_ERROR,"AllocDeviceMem: BM_Alloc Failed"));
339 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
340
341 return PVRSRV_ERROR_OUT_OF_MEMORY;
342 }
343
344
345 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
346 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
347
348
349 psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
350
351
352
353 psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
354
355 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
356
357 psMemInfo->ui32AllocSize = ui32Size;
358
359
360 psMemInfo->pvSysBackupBuffer = IMG_NULL;
361
362
363 *ppsMemInfo = psMemInfo;
364
365
366 return (PVRSRV_OK);
367}
368
369static PVRSRV_ERROR FreeDeviceMem2(PVRSRV_KERNEL_MEM_INFO *psMemInfo, IMG_BOOL bFromAllocator)
370{
371 BM_HANDLE hBuffer;
372
373 if (!psMemInfo)
374 {
375 return PVRSRV_ERROR_INVALID_PARAMS;
376 }
377
378 hBuffer = psMemInfo->sMemBlk.hBuffer;
379
380
381 if (bFromAllocator)
382 BM_Free(hBuffer, psMemInfo->ui32Flags);
383 else
384 BM_FreeExport(hBuffer, psMemInfo->ui32Flags);
385
386
387 if ((psMemInfo->pvSysBackupBuffer) && bFromAllocator)
388 {
389
390 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->ui32AllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL);
391 psMemInfo->pvSysBackupBuffer = IMG_NULL;
392 }
393
394 if (psMemInfo->ui32RefCount == 0)
395 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
396
397
398 return(PVRSRV_OK);
399}
400
401static PVRSRV_ERROR FreeDeviceMem(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
402{
403 BM_HANDLE hBuffer;
404
405 if (!psMemInfo)
406 {
407 return PVRSRV_ERROR_INVALID_PARAMS;
408 }
409
410 hBuffer = psMemInfo->sMemBlk.hBuffer;
411
412
413 BM_Free(hBuffer, psMemInfo->ui32Flags);
414
415 if(psMemInfo->pvSysBackupBuffer)
416 {
417
418 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, psMemInfo->ui32AllocSize, psMemInfo->pvSysBackupBuffer, IMG_NULL);
419 psMemInfo->pvSysBackupBuffer = IMG_NULL;
420 }
421
422 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
423
424
425 return(PVRSRV_OK);
426}
427
428
429IMG_EXPORT
430PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie,
431 IMG_HANDLE hDevMemContext,
432 PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo)
433{
434 IMG_HANDLE hSyncDevMemHeap;
435 DEVICE_MEMORY_INFO *psDevMemoryInfo;
436 BM_CONTEXT *pBMContext;
437 PVRSRV_ERROR eError;
438 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
439 PVRSRV_SYNC_DATA *psSyncData;
440
441 eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
442 sizeof(PVRSRV_KERNEL_SYNC_INFO),
443 (IMG_VOID **)&psKernelSyncInfo, IMG_NULL,
444 "Kernel Synchronization Info");
445 if (eError != PVRSRV_OK)
446 {
447 PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
448 return PVRSRV_ERROR_OUT_OF_MEMORY;
449 }
450
451 psKernelSyncInfo->ui32RefCount = 0;
452
453
454 pBMContext = (BM_CONTEXT*)hDevMemContext;
455 psDevMemoryInfo = &pBMContext->psDeviceNode->sDevMemoryInfo;
456
457
458 hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo->ui32SyncHeapID].hDevMemHeap;
459
460
461
462
463 eError = AllocDeviceMem(hDevCookie,
464 hSyncDevMemHeap,
465 PVRSRV_MEM_CACHE_CONSISTENT,
466 sizeof(PVRSRV_SYNC_DATA),
467 sizeof(IMG_UINT32),
468 &psKernelSyncInfo->psSyncDataMemInfoKM);
469
470 if (eError != PVRSRV_OK)
471 {
472
473 PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory"));
474 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
475
476 return PVRSRV_ERROR_OUT_OF_MEMORY;
477 }
478
479
480 psKernelSyncInfo->psSyncData = psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM;
481 psSyncData = psKernelSyncInfo->psSyncData;
482
483 psSyncData->ui32WriteOpsPending = 0;
484 psSyncData->ui32WriteOpsComplete = 0;
485 psSyncData->ui32ReadOpsPending = 0;
486 psSyncData->ui32ReadOpsComplete = 0;
487 psSyncData->ui32LastOpDumpVal = 0;
488 psSyncData->ui32LastReadOpDumpVal = 0;
489
490#if defined(PDUMP)
491 PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM,
492 psKernelSyncInfo->psSyncDataMemInfoKM,
493 0,
494 psKernelSyncInfo->psSyncDataMemInfoKM->ui32AllocSize,
495 PDUMP_FLAGS_CONTINUOUS,
496 MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM));
497#endif
498
499 psKernelSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete);
500 psKernelSyncInfo->sReadOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete);
501
502
503 psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = IMG_NULL;
504
505
506 *ppsKernelSyncInfo = psKernelSyncInfo;
507
508 return PVRSRV_OK;
509}
510
511
512IMG_EXPORT
513PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeSyncInfoKM(PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo)
514{
515 PVRSRV_ERROR eError;
516
517 if (psKernelSyncInfo->ui32RefCount != 0)
518 {
519 PVR_DPF((PVR_DBG_ERROR, "oops: sync info ref count not zero at destruction"));
520
521 return PVRSRV_ERROR_OUT_OF_MEMORY;
522 }
523
524 eError = FreeDeviceMem(psKernelSyncInfo->psSyncDataMemInfoKM);
525 (IMG_VOID)OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL);
526
527
528 return eError;
529}
530
531static IMG_VOID freeWrapped(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
532{
533 IMG_HANDLE hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem;
534
535
536 if(psMemInfo->sMemBlk.psIntSysPAddr)
537 {
538 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
539 psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
540 }
541
542 if(hOSWrapMem)
543 {
544 OSReleasePhysPageAddr(hOSWrapMem);
545 }
546}
547
548static PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo,
549 IMG_UINT32 ui32Param,
550 IMG_BOOL bFromAllocator)
551{
552 PVRSRV_ERROR eError = PVRSRV_OK;
553
554 PVR_UNREFERENCED_PARAMETER(ui32Param);
555
556
557 psMemInfo->ui32RefCount--;
558
559
560 if((psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED) && (bFromAllocator == IMG_TRUE))
561 {
562 IMG_HANDLE hMemInfo = IMG_NULL;
563
564
565 eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE,
566 &hMemInfo,
567 psMemInfo,
568 PVRSRV_HANDLE_TYPE_MEM_INFO);
569 if(eError != PVRSRV_OK)
570 {
571 PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: can't find exported meminfo in the global handle list"));
572 return eError;
573 }
574
575
576 eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE,
577 hMemInfo,
578 PVRSRV_HANDLE_TYPE_MEM_INFO);
579 if(eError != PVRSRV_OK)
580 {
581 PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: PVRSRVReleaseHandle failed for exported meminfo"));
582 return eError;
583 }
584 }
585
586
587 if (psMemInfo->ui32RefCount == 0)
588 {
589 switch(psMemInfo->memType)
590 {
591
592 case PVRSRV_MEMTYPE_WRAPPED:
593 freeWrapped(psMemInfo);
594 case PVRSRV_MEMTYPE_DEVICE:
595 if (psMemInfo->psKernelSyncInfo)
596 {
597 psMemInfo->psKernelSyncInfo->ui32RefCount--;
598
599 if (psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
600 {
601 eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo);
602 }
603 }
604 case PVRSRV_MEMTYPE_DEVICECLASS:
605 break;
606 default:
607 PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: Unknown memType"));
608 eError = PVRSRV_ERROR_INVALID_MEMINFO;
609 }
610 }
611
612
613
614 eError = FreeDeviceMem2(psMemInfo, bFromAllocator);
615
616 return eError;
617}
618
619static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_PVOID pvParam,
620 IMG_UINT32 ui32Param)
621{
622 PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
623
624 return FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE);
625}
626
627
628IMG_EXPORT
629PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMemKM(IMG_HANDLE hDevCookie,
630 PVRSRV_KERNEL_MEM_INFO *psMemInfo)
631{
632 PVRSRV_ERROR eError;
633
634 PVR_UNREFERENCED_PARAMETER(hDevCookie);
635
636 if (!psMemInfo)
637 {
638 return PVRSRV_ERROR_INVALID_PARAMS;
639 }
640
641 if (psMemInfo->sMemBlk.hResItem != IMG_NULL)
642 {
643 eError = ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
644 }
645 else
646 {
647
648 eError = FreeDeviceMemCallBack(psMemInfo, 0);
649 }
650
651 return eError;
652}
653
654
655IMG_EXPORT
656PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE hDevCookie,
657 PVRSRV_PER_PROCESS_DATA *psPerProc,
658 IMG_HANDLE hDevMemHeap,
659 IMG_UINT32 ui32Flags,
660 IMG_SIZE_T ui32Size,
661 IMG_SIZE_T ui32Alignment,
662 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
663{
664 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
665 PVRSRV_ERROR eError;
666 BM_HEAP *psBMHeap;
667 IMG_HANDLE hDevMemContext;
668
669 if (!hDevMemHeap ||
670 (ui32Size == 0))
671 {
672 return PVRSRV_ERROR_INVALID_PARAMS;
673 }
674
675
676 if (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
677 {
678
679 if (((ui32Size % HOST_PAGESIZE()) != 0) ||
680 ((ui32Alignment % HOST_PAGESIZE()) != 0))
681 {
682 return PVRSRV_ERROR_INVALID_PARAMS;
683 }
684 }
685
686 eError = AllocDeviceMem(hDevCookie,
687 hDevMemHeap,
688 ui32Flags,
689 ui32Size,
690 ui32Alignment,
691 &psMemInfo);
692
693 if (eError != PVRSRV_OK)
694 {
695 return eError;
696 }
697
698 if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
699 {
700 psMemInfo->psKernelSyncInfo = IMG_NULL;
701 }
702 else
703 {
704
705
706
707 psBMHeap = (BM_HEAP*)hDevMemHeap;
708 hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
709 eError = PVRSRVAllocSyncInfoKM(hDevCookie,
710 hDevMemContext,
711 &psMemInfo->psKernelSyncInfo);
712 if(eError != PVRSRV_OK)
713 {
714 goto free_mainalloc;
715 }
716 psMemInfo->psKernelSyncInfo->ui32RefCount++;
717 }
718
719
720 *ppsMemInfo = psMemInfo;
721
722 if (ui32Flags & PVRSRV_MEM_NO_RESMAN)
723 {
724 psMemInfo->sMemBlk.hResItem = IMG_NULL;
725 }
726 else
727 {
728
729 psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
730 RESMAN_TYPE_DEVICEMEM_ALLOCATION,
731 psMemInfo,
732 0,
733 &FreeDeviceMemCallBack);
734 if (psMemInfo->sMemBlk.hResItem == IMG_NULL)
735 {
736
737 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
738 goto free_mainalloc;
739 }
740 }
741
742
743 psMemInfo->ui32RefCount++;
744
745 psMemInfo->memType = PVRSRV_MEMTYPE_DEVICE;
746
747
748 return (PVRSRV_OK);
749
750free_mainalloc:
751 FreeDeviceMem(psMemInfo);
752
753 return eError;
754}
755
756
757IMG_EXPORT
758PVRSRV_ERROR IMG_CALLCONV PVRSRVDissociateDeviceMemKM(IMG_HANDLE hDevCookie,
759 PVRSRV_KERNEL_MEM_INFO *psMemInfo)
760{
761 PVRSRV_ERROR eError;
762 PVRSRV_DEVICE_NODE *psDeviceNode = hDevCookie;
763
764 PVR_UNREFERENCED_PARAMETER(hDevCookie);
765
766 if (!psMemInfo)
767 {
768 return PVRSRV_ERROR_INVALID_PARAMS;
769 }
770
771 eError = ResManDissociateRes(psMemInfo->sMemBlk.hResItem, psDeviceNode->hResManContext);
772
773 PVR_ASSERT(eError == PVRSRV_OK);
774
775 return eError;
776}
777
778
779IMG_EXPORT
780PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMemKM(IMG_UINT32 ui32Flags,
781 IMG_SIZE_T *pui32Total,
782 IMG_SIZE_T *pui32Free,
783 IMG_SIZE_T *pui32LargestBlock)
784{
785
786
787 PVR_UNREFERENCED_PARAMETER(ui32Flags);
788 PVR_UNREFERENCED_PARAMETER(pui32Total);
789 PVR_UNREFERENCED_PARAMETER(pui32Free);
790 PVR_UNREFERENCED_PARAMETER(pui32LargestBlock);
791
792 return PVRSRV_OK;
793}
794
795
796
797
798IMG_EXPORT
799PVRSRV_ERROR IMG_CALLCONV PVRSRVUnwrapExtMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo)
800{
801 if (!psMemInfo)
802 {
803 return PVRSRV_ERROR_INVALID_PARAMS;
804 }
805
806 return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
807}
808
809
810static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID pvParam,
811 IMG_UINT32 ui32Param)
812{
813 PVRSRV_KERNEL_MEM_INFO *psMemInfo = (PVRSRV_KERNEL_MEM_INFO *)pvParam;
814
815 return FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE);
816}
817
818
819IMG_EXPORT
820PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE hDevCookie,
821 PVRSRV_PER_PROCESS_DATA *psPerProc,
822 IMG_HANDLE hDevMemContext,
823 IMG_SIZE_T ui32ByteSize,
824 IMG_SIZE_T ui32PageOffset,
825 IMG_BOOL bPhysContig,
826 IMG_SYS_PHYADDR *psExtSysPAddr,
827 IMG_VOID *pvLinAddr,
828 IMG_UINT32 ui32Flags,
829 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
830{
831 PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
832 DEVICE_MEMORY_INFO *psDevMemoryInfo;
833 IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
834 IMG_HANDLE hDevMemHeap = IMG_NULL;
835 PVRSRV_DEVICE_NODE* psDeviceNode;
836 BM_HANDLE hBuffer;
837 PVRSRV_MEMBLK *psMemBlock;
838 IMG_BOOL bBMError;
839 BM_HEAP *psBMHeap;
840 PVRSRV_ERROR eError;
841 IMG_VOID *pvPageAlignedCPUVAddr;
842 IMG_SYS_PHYADDR *psIntSysPAddr = IMG_NULL;
843 IMG_HANDLE hOSWrapMem = IMG_NULL;
844 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
845 IMG_UINT32 i;
846 IMG_SIZE_T ui32PageCount = 0;
847
848
849 psDeviceNode = (PVRSRV_DEVICE_NODE*)hDevCookie;
850 PVR_ASSERT(psDeviceNode != IMG_NULL);
851
852 if (psDeviceNode == IMG_NULL)
853 {
854 PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter"));
855 return PVRSRV_ERROR_INVALID_PARAMS;
856 }
857
858 if(pvLinAddr)
859 {
860
861 ui32PageOffset = (IMG_UINTPTR_T)pvLinAddr & (ui32HostPageSize - 1);
862
863
864 ui32PageCount = HOST_PAGEALIGN(ui32ByteSize + ui32PageOffset) / ui32HostPageSize;
865 pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvLinAddr - ui32PageOffset);
866
867
868 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
869 ui32PageCount * sizeof(IMG_SYS_PHYADDR),
870 (IMG_VOID **)&psIntSysPAddr, IMG_NULL,
871 "Array of Page Addresses") != PVRSRV_OK)
872 {
873 PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
874 return PVRSRV_ERROR_OUT_OF_MEMORY;
875 }
876
877 eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
878 ui32PageCount * ui32HostPageSize,
879 psIntSysPAddr,
880 &hOSWrapMem);
881 if(eError != PVRSRV_OK)
882 {
883 PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
884 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
885 goto ErrorExitPhase1;
886 }
887
888
889 psExtSysPAddr = psIntSysPAddr;
890
891
892
893 bPhysContig = IMG_FALSE;
894 }
895 else
896 {
897
898 }
899
900
901 psDevMemoryInfo = &((BM_CONTEXT*)hDevMemContext)->psDeviceNode->sDevMemoryInfo;
902 psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
903 for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
904 {
905 if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
906 {
907 if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
908 {
909
910 hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
911 }
912 else
913 {
914 hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
915 }
916 break;
917 }
918 }
919
920 if(hDevMemHeap == IMG_NULL)
921 {
922 PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: unable to find mapping heap"));
923 eError = PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP;
924 goto ErrorExitPhase2;
925 }
926
927 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
928 sizeof(PVRSRV_KERNEL_MEM_INFO),
929 (IMG_VOID **)&psMemInfo, IMG_NULL,
930 "Kernel Memory Info") != PVRSRV_OK)
931 {
932 PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
933 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
934 goto ErrorExitPhase2;
935 }
936
937 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
938 psMemInfo->ui32Flags = ui32Flags;
939
940 psMemBlock = &(psMemInfo->sMemBlk);
941
942 bBMError = BM_Wrap(hDevMemHeap,
943 ui32ByteSize,
944 ui32PageOffset,
945 bPhysContig,
946 psExtSysPAddr,
947 IMG_NULL,
948 &psMemInfo->ui32Flags,
949 &hBuffer);
950 if (!bBMError)
951 {
952 PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: BM_Wrap Failed"));
953 eError = PVRSRV_ERROR_BAD_MAPPING;
954 goto ErrorExitPhase3;
955 }
956
957
958 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
959 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
960 psMemBlock->hOSWrapMem = hOSWrapMem;
961 psMemBlock->psIntSysPAddr = psIntSysPAddr;
962
963
964 psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
965
966
967 psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
968 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
969 psMemInfo->ui32AllocSize = ui32ByteSize;
970
971
972
973 psMemInfo->pvSysBackupBuffer = IMG_NULL;
974
975
976
977
978 psBMHeap = (BM_HEAP*)hDevMemHeap;
979 hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
980 eError = PVRSRVAllocSyncInfoKM(hDevCookie,
981 hDevMemContext,
982 &psMemInfo->psKernelSyncInfo);
983 if(eError != PVRSRV_OK)
984 {
985 goto ErrorExitPhase4;
986 }
987
988 psMemInfo->psKernelSyncInfo->ui32RefCount++;
989
990
991 psMemInfo->ui32RefCount++;
992
993 psMemInfo->memType = PVRSRV_MEMTYPE_WRAPPED;
994
995
996 psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
997 RESMAN_TYPE_DEVICEMEM_WRAP,
998 psMemInfo,
999 0,
1000 &UnwrapExtMemoryCallBack);
1001
1002
1003 *ppsMemInfo = psMemInfo;
1004
1005 return PVRSRV_OK;
1006
1007
1008
1009ErrorExitPhase4:
1010 if(psMemInfo)
1011 {
1012 FreeDeviceMem(psMemInfo);
1013
1014
1015
1016 psMemInfo = IMG_NULL;
1017 }
1018
1019ErrorExitPhase3:
1020 if(psMemInfo)
1021 {
1022 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
1023
1024 }
1025
1026ErrorExitPhase2:
1027 if(psIntSysPAddr)
1028 {
1029 OSReleasePhysPageAddr(hOSWrapMem);
1030 }
1031
1032ErrorExitPhase1:
1033 if(psIntSysPAddr)
1034 {
1035 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL);
1036
1037 }
1038
1039 return eError;
1040}
1041
1042
1043IMG_EXPORT
1044PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceMemoryKM (PVRSRV_KERNEL_MEM_INFO *psMemInfo)
1045{
1046 if (!psMemInfo)
1047 {
1048 return PVRSRV_ERROR_INVALID_PARAMS;
1049 }
1050
1051 return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
1052}
1053
1054
1055static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID pvParam,
1056 IMG_UINT32 ui32Param)
1057{
1058 PVRSRV_ERROR eError;
1059 RESMAN_MAP_DEVICE_MEM_DATA *psMapData = pvParam;
1060
1061 PVR_UNREFERENCED_PARAMETER(ui32Param);
1062
1063 if(psMapData->psMemInfo->sMemBlk.psIntSysPAddr)
1064 {
1065 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMapData->psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL);
1066 psMapData->psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL;
1067 }
1068
1069 psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount--;
1070 if (psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount == 0)
1071 {
1072 eError = PVRSRVFreeSyncInfoKM(psMapData->psMemInfo->psKernelSyncInfo);
1073 if(eError != PVRSRV_OK)
1074 {
1075 PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free sync info"));
1076 return eError;
1077 }
1078 }
1079
1080 eError = FreeDeviceMem(psMapData->psMemInfo);
1081 if(eError != PVRSRV_OK)
1082 {
1083 PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free DST meminfo"));
1084 return eError;
1085 }
1086
1087
1088 eError = FreeMemCallBackCommon(psMapData->psSrcMemInfo, 0, IMG_FALSE);
1089
1090 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
1091
1092
1093 return eError;
1094}
1095
1096
1097IMG_EXPORT
1098PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
1099 PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo,
1100 IMG_HANDLE hDstDevMemHeap,
1101 PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo)
1102{
1103 PVRSRV_ERROR eError;
1104 IMG_UINT32 i;
1105 IMG_SIZE_T ui32PageCount, ui32PageOffset;
1106 IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();
1107 IMG_SYS_PHYADDR *psSysPAddr = IMG_NULL;
1108 IMG_DEV_PHYADDR sDevPAddr;
1109 BM_BUF *psBuf;
1110 IMG_DEV_VIRTADDR sDevVAddr;
1111 PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
1112 BM_HANDLE hBuffer;
1113 PVRSRV_MEMBLK *psMemBlock;
1114 IMG_BOOL bBMError;
1115 PVRSRV_DEVICE_NODE *psDeviceNode;
1116 IMG_VOID *pvPageAlignedCPUVAddr;
1117 RESMAN_MAP_DEVICE_MEM_DATA *psMapData = IMG_NULL;
1118
1119
1120 if(!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo)
1121 {
1122 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: invalid parameters"));
1123 return PVRSRV_ERROR_INVALID_PARAMS;
1124 }
1125
1126
1127 *ppsDstMemInfo = IMG_NULL;
1128
1129 ui32PageOffset = psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1);
1130 ui32PageCount = HOST_PAGEALIGN(psSrcMemInfo->ui32AllocSize + ui32PageOffset) / ui32HostPageSize;
1131 pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psSrcMemInfo->pvLinAddrKM - ui32PageOffset);
1132
1133
1134
1135
1136
1137 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1138 ui32PageCount*sizeof(IMG_SYS_PHYADDR),
1139 (IMG_VOID **)&psSysPAddr, IMG_NULL,
1140 "Array of Page Addresses") != PVRSRV_OK)
1141 {
1142 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block"));
1143 return PVRSRV_ERROR_OUT_OF_MEMORY;
1144 }
1145
1146 psBuf = psSrcMemInfo->sMemBlk.hBuffer;
1147
1148
1149 psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode;
1150
1151
1152 sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - IMG_CAST_TO_DEVVADDR_UINT(ui32PageOffset);
1153 for(i=0; i<ui32PageCount; i++)
1154 {
1155 BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr);
1156
1157
1158 psSysPAddr[i] = SysDevPAddrToSysPAddr (psDeviceNode->sDevId.eDeviceType, sDevPAddr);
1159
1160
1161 sDevVAddr.uiAddr += IMG_CAST_TO_DEVVADDR_UINT(ui32HostPageSize);
1162 }
1163
1164
1165 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1166 sizeof(RESMAN_MAP_DEVICE_MEM_DATA),
1167 (IMG_VOID **)&psMapData, IMG_NULL,
1168 "Resource Manager Map Data") != PVRSRV_OK)
1169 {
1170 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc resman map data"));
1171 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1172 goto ErrorExit;
1173 }
1174
1175
1176 if(OSAllocMem(PVRSRV_PAGEABLE_SELECT,
1177 sizeof(PVRSRV_KERNEL_MEM_INFO),
1178 (IMG_VOID **)&psMemInfo, IMG_NULL,
1179 "Kernel Memory Info") != PVRSRV_OK)
1180 {
1181 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc memory for block"));
1182 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1183 goto ErrorExit;
1184 }
1185
1186 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
1187 psMemInfo->ui32Flags = psSrcMemInfo->ui32Flags;
1188
1189 psMemBlock = &(psMemInfo->sMemBlk);
1190
1191 bBMError = BM_Wrap(hDstDevMemHeap,
1192 psSrcMemInfo->ui32AllocSize,
1193 ui32PageOffset,
1194 IMG_FALSE,
1195 psSysPAddr,
1196 pvPageAlignedCPUVAddr,
1197 &psMemInfo->ui32Flags,
1198 &hBuffer);
1199
1200 if (!bBMError)
1201 {
1202 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: BM_Wrap Failed"));
1203 eError = PVRSRV_ERROR_BAD_MAPPING;
1204 goto ErrorExit;
1205 }
1206
1207
1208 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
1209 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
1210
1211
1212 psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
1213
1214
1215 psMemBlock->psIntSysPAddr = psSysPAddr;
1216
1217
1218 psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM;
1219
1220
1221 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
1222 psMemInfo->ui32AllocSize = psSrcMemInfo->ui32AllocSize;
1223 psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo;
1224
1225
1226 psMemInfo->psKernelSyncInfo->ui32RefCount++;
1227
1228
1229
1230 psMemInfo->pvSysBackupBuffer = IMG_NULL;
1231
1232
1233 psMemInfo->ui32RefCount++;
1234
1235
1236 psSrcMemInfo->ui32RefCount++;
1237
1238
1239 BM_Export(psSrcMemInfo->sMemBlk.hBuffer);
1240
1241 psMemInfo->memType = PVRSRV_MEMTYPE_MAPPED;
1242
1243
1244 psMapData->psMemInfo = psMemInfo;
1245 psMapData->psSrcMemInfo = psSrcMemInfo;
1246
1247
1248 psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
1249 RESMAN_TYPE_DEVICEMEM_MAPPING,
1250 psMapData,
1251 0,
1252 &UnmapDeviceMemoryCallBack);
1253
1254 *ppsDstMemInfo = psMemInfo;
1255
1256 return PVRSRV_OK;
1257
1258
1259
1260ErrorExit:
1261
1262 if(psSysPAddr)
1263 {
1264
1265 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL);
1266
1267 }
1268
1269 if(psMemInfo)
1270 {
1271
1272 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
1273
1274 }
1275
1276 if(psMapData)
1277 {
1278
1279 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
1280
1281 }
1282
1283 return eError;
1284}
1285
1286
1287IMG_EXPORT
1288PVRSRV_ERROR IMG_CALLCONV PVRSRVUnmapDeviceClassMemoryKM(PVRSRV_KERNEL_MEM_INFO *psMemInfo)
1289{
1290 if (!psMemInfo)
1291 {
1292 return PVRSRV_ERROR_INVALID_PARAMS;
1293 }
1294
1295 return ResManFreeResByPtr(psMemInfo->sMemBlk.hResItem);
1296}
1297
1298
1299static PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(IMG_PVOID pvParam,
1300 IMG_UINT32 ui32Param)
1301{
1302 PVRSRV_DC_MAPINFO *psDCMapInfo = pvParam;
1303 PVRSRV_KERNEL_MEM_INFO *psMemInfo;
1304
1305 PVR_UNREFERENCED_PARAMETER(ui32Param);
1306
1307 psMemInfo = psDCMapInfo->psMemInfo;
1308
1309#if defined(SUPPORT_MEMORY_TILING)
1310 if(psDCMapInfo->ui32TilingStride > 0)
1311 {
1312 PVRSRV_DEVICE_NODE *psDeviceNode = psDCMapInfo->psDeviceNode;
1313
1314 if (psDeviceNode->pfnFreeMemTilingRange(psDeviceNode,
1315 psDCMapInfo->ui32RangeIndex) != PVRSRV_OK)
1316 {
1317 PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceClassMemoryCallBack: FreeMemTilingRange failed"));
1318 }
1319 }
1320#endif
1321
1322 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_MAPINFO), psDCMapInfo, IMG_NULL);
1323
1324 return FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE);
1325}
1326
1327
1328IMG_EXPORT
1329PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc,
1330 IMG_HANDLE hDevMemContext,
1331 IMG_HANDLE hDeviceClassBuffer,
1332 PVRSRV_KERNEL_MEM_INFO **ppsMemInfo,
1333 IMG_HANDLE *phOSMapInfo)
1334{
1335 PVRSRV_ERROR eError;
1336 PVRSRV_DEVICE_NODE* psDeviceNode;
1337 PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
1338 PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer;
1339 IMG_SYS_PHYADDR *psSysPAddr;
1340 IMG_VOID *pvCPUVAddr, *pvPageAlignedCPUVAddr;
1341 IMG_BOOL bPhysContig;
1342 BM_CONTEXT *psBMContext;
1343 DEVICE_MEMORY_INFO *psDevMemoryInfo;
1344 DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
1345 IMG_HANDLE hDevMemHeap = IMG_NULL;
1346 IMG_SIZE_T ui32ByteSize;
1347 IMG_SIZE_T ui32Offset;
1348 IMG_SIZE_T ui32PageSize = HOST_PAGESIZE();
1349 BM_HANDLE hBuffer;
1350 PVRSRV_MEMBLK *psMemBlock;
1351 IMG_BOOL bBMError;
1352 IMG_UINT32 i;
1353 PVRSRV_DC_MAPINFO *psDCMapInfo = IMG_NULL;
1354
1355 if(!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || !hDevMemContext)
1356 {
1357 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: invalid parameters"));
1358 return PVRSRV_ERROR_INVALID_PARAMS;
1359 }
1360
1361
1362 if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1363 sizeof(PVRSRV_DC_MAPINFO),
1364 (IMG_VOID **)&psDCMapInfo, IMG_NULL,
1365 "PVRSRV_DC_MAPINFO") != PVRSRV_OK)
1366 {
1367 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for psDCMapInfo"));
1368 return PVRSRV_ERROR_OUT_OF_MEMORY;
1369 }
1370 OSMemSet(psDCMapInfo, 0, sizeof(PVRSRV_DC_MAPINFO));
1371
1372 psDeviceClassBuffer = (PVRSRV_DEVICECLASS_BUFFER*)hDeviceClassBuffer;
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393 eError = psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->hExtDevice,
1394 psDeviceClassBuffer->hExtBuffer,
1395 &psSysPAddr,
1396 &ui32ByteSize,
1397 &pvCPUVAddr,
1398 phOSMapInfo,
1399 &bPhysContig,
1400 &psDCMapInfo->ui32TilingStride);
1401 if(eError != PVRSRV_OK)
1402 {
1403 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to get buffer address"));
1404 goto ErrorExitPhase1;
1405 }
1406
1407
1408 psBMContext = (BM_CONTEXT*)psDeviceClassBuffer->hDevMemContext;
1409 psDeviceNode = psBMContext->psDeviceNode;
1410 psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;
1411 psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
1412 for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
1413 {
1414 if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
1415 {
1416 if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
1417 {
1418
1419 hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
1420 }
1421 else
1422 {
1423 hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
1424 }
1425 break;
1426 }
1427 }
1428
1429 if(hDevMemHeap == IMG_NULL)
1430 {
1431 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to find mapping heap"));
1432 eError = PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE;
1433 goto ErrorExitPhase1;
1434 }
1435
1436
1437 ui32Offset = ((IMG_UINTPTR_T)pvCPUVAddr) & (ui32PageSize - 1);
1438 pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvCPUVAddr - ui32Offset);
1439
1440 eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
1441 sizeof(PVRSRV_KERNEL_MEM_INFO),
1442 (IMG_VOID **)&psMemInfo, IMG_NULL,
1443 "Kernel Memory Info");
1444 if(eError != PVRSRV_OK)
1445 {
1446 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for block"));
1447 goto ErrorExitPhase1;
1448 }
1449
1450 OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
1451
1452 psMemBlock = &(psMemInfo->sMemBlk);
1453
1454 bBMError = BM_Wrap(hDevMemHeap,
1455 ui32ByteSize,
1456 ui32Offset,
1457 bPhysContig,
1458 psSysPAddr,
1459 pvPageAlignedCPUVAddr,
1460 &psMemInfo->ui32Flags,
1461 &hBuffer);
1462
1463 if (!bBMError)
1464 {
1465 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed"));
1466
1467 eError = PVRSRV_ERROR_BAD_MAPPING;
1468 goto ErrorExitPhase2;
1469 }
1470
1471
1472 psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
1473 psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
1474
1475
1476 psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;
1477
1478
1479
1480 psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
1481
1482
1483 psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
1484 psMemInfo->ui32AllocSize = ui32ByteSize;
1485 psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo;
1486
1487
1488
1489 psMemInfo->pvSysBackupBuffer = IMG_NULL;
1490
1491
1492 psDCMapInfo->psMemInfo = psMemInfo;
1493
1494#if defined(SUPPORT_MEMORY_TILING)
1495 psDCMapInfo->psDeviceNode = psDeviceNode;
1496
1497 if(psDCMapInfo->ui32TilingStride > 0)
1498 {
1499
1500 eError = psDeviceNode->pfnAllocMemTilingRange(psDeviceNode,
1501 psMemInfo,
1502 psDCMapInfo->ui32TilingStride,
1503 &psDCMapInfo->ui32RangeIndex);
1504 if (eError != PVRSRV_OK)
1505 {
1506 PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: AllocMemTilingRange failed"));
1507 goto ErrorExitPhase3;
1508 }
1509 }
1510#endif
1511
1512
1513 psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
1514 RESMAN_TYPE_DEVICECLASSMEM_MAPPING,
1515 psDCMapInfo,
1516 0,
1517 &UnmapDeviceClassMemoryCallBack);
1518
1519 psMemInfo->ui32RefCount++;
1520
1521 psMemInfo->memType = PVRSRV_MEMTYPE_DEVICECLASS;
1522
1523
1524 *ppsMemInfo = psMemInfo;
1525
1526 return PVRSRV_OK;
1527
1528#if defined(SUPPORT_MEMORY_TILING)
1529ErrorExitPhase3:
1530 if(psMemInfo)
1531 {
1532 FreeDeviceMem(psMemInfo);
1533
1534
1535
1536 psMemInfo = IMG_NULL;
1537 }
1538#endif
1539
1540ErrorExitPhase2:
1541 if(psMemInfo)
1542 {
1543 OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
1544 }
1545
1546ErrorExitPhase1:
1547 if(psDCMapInfo)
1548 {
1549 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psDCMapInfo, IMG_NULL);
1550 }
1551
1552 return eError;
1553}
1554